PIP: Apply the animation spec for the PIP in Recents
Bug: 27540465 Change-Id: Ibdd4a4e3fd194978ccbc29235a1c620ebddff942
This commit is contained in:
@@ -17,13 +17,13 @@
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<objectAnimator
|
||||
android:propertyName="translationY"
|
||||
android:valueTo="10dp"
|
||||
android:interpolator="@android:interpolator/linear_out_slow_in"
|
||||
android:propertyName="scaleX"
|
||||
android:valueTo="1.0"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"
|
||||
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
|
||||
<objectAnimator
|
||||
android:propertyName="alpha"
|
||||
android:propertyName="scaleY"
|
||||
android:valueTo="1.0"
|
||||
android:interpolator="@android:interpolator/linear_out_slow_in"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"
|
||||
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
|
||||
</set>
|
||||
@@ -17,13 +17,13 @@
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<objectAnimator
|
||||
android:propertyName="translationY"
|
||||
android:valueTo="0dp"
|
||||
android:interpolator="@android:interpolator/fast_out_linear_in"
|
||||
android:propertyName="scaleX"
|
||||
android:valueTo="0.7"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"
|
||||
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
|
||||
<objectAnimator
|
||||
android:propertyName="alpha"
|
||||
android:valueTo="0.0"
|
||||
android:interpolator="@android:interpolator/fast_out_linear_in"
|
||||
android:propertyName="scaleY"
|
||||
android:valueTo="0.7"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"
|
||||
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
|
||||
</set>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 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.
|
||||
-->
|
||||
|
||||
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:propertyName="translationY"
|
||||
android:valueTo="0dp"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"
|
||||
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 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.
|
||||
-->
|
||||
|
||||
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:propertyName="translationY"
|
||||
android:valueTo="-57dp"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"
|
||||
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 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.
|
||||
-->
|
||||
|
||||
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:propertyName="alpha"
|
||||
android:valueTo="1"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"
|
||||
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 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.
|
||||
-->
|
||||
|
||||
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:propertyName="alpha"
|
||||
android:valueTo="0"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"
|
||||
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
|
||||
@@ -17,8 +17,8 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<size
|
||||
android:width="36dp"
|
||||
android:height="36dp" />
|
||||
android:width="34dp"
|
||||
android:height="34dp" />
|
||||
<solid
|
||||
android:color="#4DFFFFFF" />
|
||||
</shape>
|
||||
|
||||
@@ -31,18 +31,12 @@
|
||||
android:focusable="true"
|
||||
android:layoutDirection="rtl" />
|
||||
|
||||
<!-- Placeholder view to give focus to the PIP menus. -->
|
||||
<View
|
||||
android:id="@+id/pip_shade"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"
|
||||
android:background="#76000000" />
|
||||
|
||||
<include
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top|center_horizontal"
|
||||
android:layout_marginTop="132dp"
|
||||
layout="@layout/tv_pip_controls" />
|
||||
android:id="@+id/pip"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:focusable="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
</com.android.systemui.recents.tv.views.RecentsTvView>
|
||||
|
||||
@@ -17,13 +17,8 @@
|
||||
*/
|
||||
-->
|
||||
|
||||
<com.android.systemui.tv.pip.PipControlsView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/pip_controls"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
<!-- Layout for {@link com.android.systemui.tv.pip.PipControlsView}. -->
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="100dp"
|
||||
@@ -98,4 +93,4 @@
|
||||
android:textSize="12sp"
|
||||
android:textColor="#EEEEEE" />
|
||||
</LinearLayout>
|
||||
</com.android.systemui.tv.pip.PipControlsView>
|
||||
</merge>
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
android:gravity="top|center_horizontal"
|
||||
android:clipChildren="false">
|
||||
|
||||
<include
|
||||
layout="@layout/tv_pip_controls"
|
||||
android:clipChildren="false" />
|
||||
<com.android.systemui.tv.pip.PipControlsView
|
||||
android:id="@+id/pip_controls"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
@@ -38,25 +38,4 @@
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:text="@string/pip_hold_home" />
|
||||
<LinearLayout
|
||||
android:id="@+id/guide_buttons"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:orientation="horizontal">
|
||||
<ImageView
|
||||
android:layout_width="19dp"
|
||||
android:layout_height="19dp"
|
||||
android:src="@drawable/ic_fullscreen_white_24dp" />
|
||||
<ImageView
|
||||
android:layout_width="19dp"
|
||||
android:layout_height="19dp"
|
||||
android:src="@drawable/ic_close_white" />
|
||||
<ImageView
|
||||
android:id="@+id/guide_button_play_pause"
|
||||
android:layout_width="19dp"
|
||||
android:layout_height="19dp"
|
||||
android:src="@drawable/ic_pause_white_24dp" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
33
packages/SystemUI/res/layout/tv_pip_recents_overlay.xml
Normal file
33
packages/SystemUI/res/layout/tv_pip_recents_overlay.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 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.
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="top|center_horizontal">
|
||||
|
||||
<com.android.systemui.tv.pip.PipRecentsControlsView
|
||||
android:id="@+id/pip_controls"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/recents"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="1dp"
|
||||
android:focusable="true" />
|
||||
</LinearLayout>
|
||||
@@ -38,9 +38,6 @@
|
||||
<dimen name="recents_tv_unselected_item_z">6dp</dimen>
|
||||
<dimen name="recents_tv_selected_item_z_delta">10dp</dimen>
|
||||
|
||||
<!-- Extra space around the PIP and its outline in PIP onboarding activity -->
|
||||
<dimen name="tv_pip_bounds_space">3dp</dimen>
|
||||
|
||||
<!-- Values for text on recents cards on tv -->
|
||||
<dimen name="recents_tv_title_text_size">12sp</dimen>
|
||||
|
||||
@@ -52,4 +49,10 @@
|
||||
<dimen name="recents_tv_dismiss_icon_bottom_margin">1dip</dimen>
|
||||
<dimen name="recents_tv_dismiss_text_size">12sp</dimen>
|
||||
|
||||
<!-- Values for PIP in recents -->
|
||||
<dimen name="recents_tv_pip_controls_margin_top">10dp</dimen>
|
||||
|
||||
<!-- Extra space around the PIP and its outline in PIP onboarding activity -->
|
||||
<dimen name="tv_pip_bounds_space">3dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.android.systemui.recents.tv;
|
||||
|
||||
import android.animation.AnimatorInflater;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityOptions;
|
||||
import android.content.Intent;
|
||||
@@ -55,11 +53,12 @@ import com.android.systemui.recents.model.RecentsTaskLoadPlan;
|
||||
import com.android.systemui.recents.model.RecentsTaskLoader;
|
||||
import com.android.systemui.recents.model.Task;
|
||||
import com.android.systemui.recents.model.TaskStack;
|
||||
import com.android.systemui.recents.tv.animations.FocusAnimationHolder;
|
||||
import com.android.systemui.recents.tv.views.RecentsTvView;
|
||||
import com.android.systemui.recents.tv.views.TaskStackHorizontalViewAdapter;
|
||||
import com.android.systemui.statusbar.BaseStatusBar;
|
||||
import com.android.systemui.tv.pip.PipManager;
|
||||
import com.android.systemui.tv.pip.PipControlsView;
|
||||
import com.android.systemui.tv.pip.PipRecentsOverlayManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -80,15 +79,13 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
|
||||
private boolean mIgnoreAltTabRelease;
|
||||
|
||||
private RecentsTvView mRecentsView;
|
||||
private PipControlsView mPipControlsView;
|
||||
private View mPipShadeView;
|
||||
private AnimatorSet mPipControlsViewFadeInAnimator;
|
||||
private AnimatorSet mPipControlsViewFadeOutAnimator;
|
||||
private FocusAnimationHolder mRecentsFocusAnimationHolder;
|
||||
private View mPipView;
|
||||
private TaskStackHorizontalViewAdapter mTaskStackViewAdapter;
|
||||
private FinishRecentsRunnable mFinishLaunchHomeRunnable;
|
||||
|
||||
private PipManager mPipManager;
|
||||
private PipManager.Listener mPipListener = new PipManager.Listener() {
|
||||
private final PipManager mPipManager = PipManager.getInstance();
|
||||
private final PipManager.Listener mPipListener = new PipManager.Listener() {
|
||||
@Override
|
||||
public void onPipEntered() {
|
||||
updatePipUI();
|
||||
@@ -113,10 +110,38 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
|
||||
|
||||
@Override
|
||||
public void onPipResizeAboutToStart() { }
|
||||
|
||||
@Override
|
||||
public void onMediaControllerChanged() { }
|
||||
};
|
||||
private PipRecentsOverlayManager mPipRecentsOverlayManager;
|
||||
private final PipRecentsOverlayManager.Callback mPipRecentsOverlayManagerCallback =
|
||||
new PipRecentsOverlayManager.Callback() {
|
||||
@Override
|
||||
public void onClosed() {
|
||||
dismissRecentsToLaunchTargetTaskOrHome();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
RecentsTvActivity.this.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecentsFocused() {
|
||||
mRecentsView.requestFocus();
|
||||
}
|
||||
};
|
||||
private final View.OnFocusChangeListener mPipViewFocusChangeListener =
|
||||
new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (hasFocus) {
|
||||
mRecentsFocusAnimationHolder.startFocusLoseAnimation();
|
||||
mPipRecentsOverlayManager.requestFocus(
|
||||
mTaskStackViewAdapter.getItemCount() > 0);
|
||||
} else {
|
||||
mRecentsFocusAnimationHolder.startFocusGainAnimation();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A common Runnable to finish Recents by launching Home with an animation depending on the
|
||||
@@ -248,7 +273,7 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
mPipManager = PipManager.getInstance();
|
||||
mPipRecentsOverlayManager = PipManager.getInstance().getPipRecentsOverlayManager();
|
||||
|
||||
// Register this activity with the event bus
|
||||
EventBus.getDefault().register(this, EVENT_BUS_PRIORITY);
|
||||
@@ -263,21 +288,19 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
|
||||
mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||
mPipControlsView = (PipControlsView) findViewById(R.id.pip_controls);
|
||||
mPipControlsView.setListener(new PipControlsView.Listener() {
|
||||
@Override
|
||||
public void onClosed() {
|
||||
dismissRecentsToLaunchTargetTaskOrHome();
|
||||
}
|
||||
});
|
||||
mPipShadeView = findViewById(R.id.pip_shade);
|
||||
mRecentsFocusAnimationHolder = new FocusAnimationHolder(mRecentsView);
|
||||
|
||||
mPipControlsViewFadeInAnimator = (AnimatorSet) AnimatorInflater.loadAnimator(this,
|
||||
R.anim.tv_pip_controls_fade_in);
|
||||
mPipControlsViewFadeInAnimator.setTarget(mPipControlsView);
|
||||
mPipControlsViewFadeOutAnimator = (AnimatorSet) AnimatorInflater.loadAnimator(this,
|
||||
R.anim.tv_pip_controls_fade_out);
|
||||
mPipControlsViewFadeOutAnimator.setTarget(mPipControlsView);
|
||||
mPipView = findViewById(R.id.pip);
|
||||
// Place mPipView at the PIP bounds for fine tuned focus handling.
|
||||
Rect pipBounds = mPipManager.getPipBounds();
|
||||
LayoutParams lp = (LayoutParams) mPipView.getLayoutParams();
|
||||
lp.width = pipBounds.width();
|
||||
lp.height = pipBounds.height();
|
||||
lp.leftMargin = pipBounds.left;
|
||||
lp.topMargin = pipBounds.top;
|
||||
mPipView.setLayoutParams(lp);
|
||||
|
||||
mPipRecentsOverlayManager.setCallback(mPipRecentsOverlayManagerCallback);
|
||||
|
||||
getWindow().getAttributes().privateFlags |=
|
||||
WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
|
||||
@@ -289,7 +312,6 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
|
||||
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
|
||||
mFinishLaunchHomeRunnable = new FinishRecentsRunnable(homeIntent);
|
||||
|
||||
updatePipUI();
|
||||
mPipManager.addListener(mPipListener);
|
||||
}
|
||||
|
||||
@@ -321,9 +343,7 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true));
|
||||
|
||||
mPipManager.onRecentsStarted();
|
||||
// Give focus to the recents row whenever its visible to an user.
|
||||
mRecentsView.requestFocus();
|
||||
updatePipUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -332,11 +352,22 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
|
||||
EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mPipRecentsOverlayManager.onRecentsResumed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mPipRecentsOverlayManager.onRecentsPaused();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
|
||||
mPipManager.onRecentsStopped();
|
||||
mIgnoreAltTabRelease = false;
|
||||
// Notify that recents is now hidden
|
||||
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, false));
|
||||
@@ -480,25 +511,13 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
|
||||
|
||||
private void updatePipUI() {
|
||||
if (mPipManager.isPipShown()) {
|
||||
mPipControlsView.setAlpha(0);
|
||||
mPipControlsView.setVisibility(View.VISIBLE);
|
||||
mPipShadeView.setVisibility(View.INVISIBLE);
|
||||
mPipControlsView.setOnChildFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
mPipManager.onPipViewFocusChangedInRecents(hasFocus);
|
||||
if (hasFocus) {
|
||||
mPipControlsViewFadeInAnimator.start();
|
||||
} else {
|
||||
mPipControlsViewFadeOutAnimator.start();
|
||||
}
|
||||
mPipShadeView.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE);
|
||||
}
|
||||
});
|
||||
mPipShadeView.setVisibility(View.GONE);
|
||||
mPipView.setVisibility(View.VISIBLE);
|
||||
mPipView.setOnFocusChangeListener(mPipViewFocusChangeListener);
|
||||
mPipView.requestFocus();
|
||||
} else {
|
||||
mPipControlsView.setVisibility(View.GONE);
|
||||
mPipShadeView.setVisibility(View.GONE);
|
||||
mPipView.setVisibility(View.GONE);
|
||||
mPipRecentsOverlayManager.removePipRecentsOverlayView();
|
||||
mRecentsFocusAnimationHolder.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.systemui.recents.tv.animations;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.recents.tv.views.TaskCardView;
|
||||
|
||||
/**
|
||||
* Collections of Recents row's animation depending on the PIP's focus.
|
||||
*/
|
||||
public class FocusAnimationHolder {
|
||||
private final float DIM_ALPHA = 0.5f;
|
||||
|
||||
private View mRecentsRowView;
|
||||
private int mCardYDelta;
|
||||
private long mDuration;
|
||||
|
||||
public FocusAnimationHolder(View recentsRowView) {
|
||||
mRecentsRowView = recentsRowView;
|
||||
|
||||
Resources res = recentsRowView.getResources();
|
||||
mCardYDelta = res.getDimensionPixelOffset(R.dimen.recents_tv_dismiss_shift_down);
|
||||
mDuration = res.getInteger(R.integer.recents_tv_pip_focus_anim_duration);
|
||||
}
|
||||
|
||||
public void startFocusGainAnimation() {
|
||||
mRecentsRowView.animate()
|
||||
.setDuration(mDuration)
|
||||
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
|
||||
.alpha(1f)
|
||||
.translationY(0);
|
||||
}
|
||||
|
||||
public void startFocusLoseAnimation() {
|
||||
mRecentsRowView.animate()
|
||||
.setDuration(mDuration)
|
||||
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
|
||||
.alpha(DIM_ALPHA)
|
||||
.translationY(mCardYDelta);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
mRecentsRowView.setTransitionAlpha(1f);
|
||||
mRecentsRowView.setTranslationY(0);
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,12 @@
|
||||
|
||||
package com.android.systemui.tv.pip;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.media.session.MediaController;
|
||||
import android.media.session.PlaybackState;
|
||||
import android.view.View;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View.OnFocusChangeListener;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
@@ -40,28 +41,29 @@ import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_UNAVAILABLE;
|
||||
/**
|
||||
* A view containing PIP controls including fullscreen, close, and media controls.
|
||||
*/
|
||||
public class PipControlsView extends LinearLayout implements PipManager.Listener {
|
||||
public class PipControlsView extends LinearLayout {
|
||||
/**
|
||||
* An interface to listen user action.
|
||||
*/
|
||||
public interface Listener {
|
||||
public abstract static interface Listener {
|
||||
/**
|
||||
* Called when an user clicks close PIP button.
|
||||
*/
|
||||
void onClosed();
|
||||
}
|
||||
public abstract void onClosed();
|
||||
};
|
||||
|
||||
private final PipManager mPipManager = PipManager.getInstance();
|
||||
private MediaController mMediaController;
|
||||
private Listener mListener;
|
||||
|
||||
private View mFullButtonView;
|
||||
private View mFullDescriptionView;
|
||||
private View mPlayPauseView;
|
||||
private ImageView mPlayPauseButtonImageView;
|
||||
private TextView mPlayPauseDescriptionTextView;
|
||||
private View mCloseButtonView;
|
||||
private View mCloseDescriptionView;
|
||||
final PipManager mPipManager = PipManager.getInstance();
|
||||
Listener mListener;
|
||||
|
||||
View mFullButtonView;
|
||||
View mFullDescriptionView;
|
||||
View mPlayPauseView;
|
||||
ImageView mPlayPauseButtonImageView;
|
||||
TextView mPlayPauseDescriptionTextView;
|
||||
View mCloseButtonView;
|
||||
View mCloseDescriptionView;
|
||||
|
||||
private boolean mHasFocus;
|
||||
private OnFocusChangeListener mOnChildFocusChangeListener;
|
||||
@@ -73,6 +75,13 @@ public class PipControlsView extends LinearLayout implements PipManager.Listener
|
||||
}
|
||||
};
|
||||
|
||||
private PipManager.MediaListener mPipMediaListener = new PipManager.MediaListener() {
|
||||
@Override
|
||||
public void onMediaControllerChanged() {
|
||||
updateMediaController();
|
||||
}
|
||||
};
|
||||
|
||||
public PipControlsView(Context context) {
|
||||
this(context, null, 0, 0);
|
||||
}
|
||||
@@ -87,6 +96,12 @@ public class PipControlsView extends LinearLayout implements PipManager.Listener
|
||||
|
||||
public PipControlsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
LayoutInflater inflater = (LayoutInflater) getContext()
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
inflater.inflate(R.layout.tv_pip_controls, this);
|
||||
|
||||
setOrientation(LinearLayout.HORIZONTAL);
|
||||
setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -161,13 +176,13 @@ public class PipControlsView extends LinearLayout implements PipManager.Listener
|
||||
public void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
updateMediaController();
|
||||
mPipManager.addListener(this);
|
||||
mPipManager.addMediaListener(mPipMediaListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
mPipManager.removeListener(this);
|
||||
mPipManager.removeMediaListener(mPipMediaListener);
|
||||
if (mMediaController != null) {
|
||||
mMediaController.unregisterCallback(mMediaControllerCallback);
|
||||
}
|
||||
@@ -230,24 +245,4 @@ public class PipControlsView extends LinearLayout implements PipManager.Listener
|
||||
public void setListener(Listener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPipEntered() { }
|
||||
|
||||
@Override
|
||||
public void onPipActivityClosed() { }
|
||||
|
||||
@Override
|
||||
public void onShowPipMenu() { }
|
||||
|
||||
@Override
|
||||
public void onMoveToFullscreen() { }
|
||||
|
||||
@Override
|
||||
public void onMediaControllerChanged() {
|
||||
updateMediaController();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPipResizeAboutToStart() { }
|
||||
}
|
||||
|
||||
@@ -62,9 +62,27 @@ public class PipManager {
|
||||
|
||||
private static final int MAX_RUNNING_TASKS_COUNT = 10;
|
||||
|
||||
/**
|
||||
* State when there's no PIP.
|
||||
*/
|
||||
public static final int STATE_NO_PIP = 0;
|
||||
/**
|
||||
* State when PIP is shown with an overlay message on top of it.
|
||||
* This is used as default PIP state.
|
||||
*/
|
||||
public static final int STATE_PIP_OVERLAY = 1;
|
||||
/**
|
||||
* State when PIP menu dialog is shown.
|
||||
*/
|
||||
public static final int STATE_PIP_MENU = 2;
|
||||
/**
|
||||
* State when PIP is shown in Recents.
|
||||
*/
|
||||
public static final int STATE_PIP_RECENTS = 3;
|
||||
/**
|
||||
* State when PIP is shown in Recents and it's focused to allow an user to control.
|
||||
*/
|
||||
public static final int STATE_PIP_RECENTS_FOCUSED = 4;
|
||||
|
||||
private static final int TASK_ID_NO_PIP = -1;
|
||||
private static final int INVALID_RESOURCE_TYPE = -1;
|
||||
@@ -90,11 +108,13 @@ public class PipManager {
|
||||
private int mSuspendPipResizingReason;
|
||||
|
||||
private Context mContext;
|
||||
private PipRecentsOverlayManager mPipRecentsOverlayManager;
|
||||
private IActivityManager mActivityManager;
|
||||
private MediaSessionManager mMediaSessionManager;
|
||||
private int mState = STATE_NO_PIP;
|
||||
private final Handler mHandler = new Handler();
|
||||
private List<Listener> mListeners = new ArrayList<>();
|
||||
private List<MediaListener> mMediaListeners = new ArrayList<>();
|
||||
private Rect mCurrentPipBounds;
|
||||
private Rect mPipBounds;
|
||||
private Rect mMenuModePipBounds;
|
||||
@@ -107,9 +127,6 @@ public class PipManager {
|
||||
private MediaController mPipMediaController;
|
||||
private boolean mOnboardingShown;
|
||||
|
||||
private boolean mIsRecentsShown;
|
||||
private boolean mIsPipFocusedInRecent;
|
||||
|
||||
private final Runnable mResizePinnedStackRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -178,6 +195,7 @@ public class PipManager {
|
||||
mOnboardingShown = Prefs.getBoolean(
|
||||
mContext, TV_PICTURE_IN_PICTURE_ONBOARDING_SHOWN, false);
|
||||
|
||||
mPipRecentsOverlayManager = new PipRecentsOverlayManager(context);
|
||||
mMediaSessionManager =
|
||||
(MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
|
||||
}
|
||||
@@ -231,7 +249,7 @@ public class PipManager {
|
||||
/**
|
||||
* Moves the PIPed activity to the fullscreen and closes PIP system UI.
|
||||
*/
|
||||
public void movePipToFullscreen() {
|
||||
void movePipToFullscreen() {
|
||||
mState = STATE_NO_PIP;
|
||||
mPipTaskId = TASK_ID_NO_PIP;
|
||||
for (int i = mListeners.size() - 1; i >= 0; --i) {
|
||||
@@ -247,8 +265,11 @@ public class PipManager {
|
||||
*/
|
||||
private void showPipOverlay() {
|
||||
if (DEBUG) Log.d(TAG, "showPipOverlay()");
|
||||
mState = STATE_PIP_OVERLAY;
|
||||
PipOverlayActivity.showPipOverlay(mContext);
|
||||
Intent intent = new Intent(mContext, PipOverlayActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
final ActivityOptions options = ActivityOptions.makeBasic();
|
||||
options.setLaunchStackId(PINNED_STACK_ID);
|
||||
mContext.startActivity(intent, options.toBundle());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,8 +300,10 @@ public class PipManager {
|
||||
* Resize the Pip to the appropriate size for the input state.
|
||||
* @param state In Pip state also used to determine the new size for the Pip.
|
||||
*/
|
||||
public void resizePinnedStack(int state) {
|
||||
void resizePinnedStack(int state) {
|
||||
if (DEBUG) Log.d(TAG, "resizePinnedStack() state=" + state);
|
||||
boolean wasRecentsShown =
|
||||
(mState == STATE_PIP_RECENTS || mState == STATE_PIP_RECENTS_FOCUSED);
|
||||
mState = state;
|
||||
for (int i = mListeners.size() - 1; i >= 0; --i) {
|
||||
mListeners.get(i).onPipResizeAboutToStart();
|
||||
@@ -291,7 +314,6 @@ public class PipManager {
|
||||
mSuspendPipResizingReason);
|
||||
return;
|
||||
}
|
||||
int animationDurationMs = -1;
|
||||
switch (mState) {
|
||||
case STATE_NO_PIP:
|
||||
mCurrentPipBounds = null;
|
||||
@@ -300,25 +322,24 @@ public class PipManager {
|
||||
mCurrentPipBounds = mMenuModePipBounds;
|
||||
break;
|
||||
case STATE_PIP_OVERLAY:
|
||||
if (mIsRecentsShown) {
|
||||
if (mCurrentPipBounds == mRecentsFocusedPipBounds
|
||||
|| mCurrentPipBounds == mRecentsFocusedPipBounds) {
|
||||
animationDurationMs = mRecentsFocusChangedAnimationDurationMs;
|
||||
}
|
||||
if (mIsPipFocusedInRecent) {
|
||||
mCurrentPipBounds = mRecentsFocusedPipBounds;
|
||||
} else {
|
||||
mCurrentPipBounds = mRecentsPipBounds;
|
||||
}
|
||||
} else {
|
||||
mCurrentPipBounds = mPipBounds;
|
||||
}
|
||||
mCurrentPipBounds = mPipBounds;
|
||||
break;
|
||||
case STATE_PIP_RECENTS:
|
||||
mCurrentPipBounds = mRecentsPipBounds;
|
||||
break;
|
||||
case STATE_PIP_RECENTS_FOCUSED:
|
||||
mCurrentPipBounds = mRecentsFocusedPipBounds;
|
||||
break;
|
||||
default:
|
||||
mCurrentPipBounds = mPipBounds;
|
||||
break;
|
||||
}
|
||||
try {
|
||||
int animationDurationMs = -1;
|
||||
if (wasRecentsShown
|
||||
&& (mState == STATE_PIP_RECENTS || mState == STATE_PIP_RECENTS_FOCUSED)) {
|
||||
animationDurationMs = mRecentsFocusChangedAnimationDurationMs;
|
||||
}
|
||||
mActivityManager.resizeStack(PINNED_STACK_ID, mCurrentPipBounds,
|
||||
true, true, true, animationDurationMs);
|
||||
} catch (RemoteException e) {
|
||||
@@ -327,67 +348,18 @@ public class PipManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current PIP bound for activities to sync their UI with PIP.
|
||||
* Returns the default PIP bound.
|
||||
*/
|
||||
public Rect getPipBounds() {
|
||||
return mCurrentPipBounds;
|
||||
return mPipBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when Recents is started.
|
||||
* PIPed activity will be resized accordingly and overlay will show available buttons.
|
||||
* Returns the focused PIP bound while Recents is shown.
|
||||
* This is used to place PIP controls in Recents.
|
||||
*/
|
||||
public void onRecentsStarted() {
|
||||
mIsRecentsShown = true;
|
||||
mIsPipFocusedInRecent = false;
|
||||
if (mState == STATE_NO_PIP) {
|
||||
return;
|
||||
}
|
||||
resizePinnedStack(STATE_PIP_OVERLAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when Recents is stopped.
|
||||
* PIPed activity will be resized accordingly and overlay will hide available buttons.
|
||||
*/
|
||||
public void onRecentsStopped() {
|
||||
mIsRecentsShown = false;
|
||||
mIsPipFocusedInRecent = false;
|
||||
if (mState == STATE_NO_PIP) {
|
||||
return;
|
||||
}
|
||||
resizePinnedStack(STATE_PIP_OVERLAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if recents is shown.
|
||||
*/
|
||||
boolean isRecentsShown() {
|
||||
return mIsRecentsShown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the PIP view in {@link com.android.systemui.recents.tv.RecentsTvActivity}
|
||||
* is focused.
|
||||
* This only resizes pinned stack so it looks like it's in Recents.
|
||||
* This should be called only by {@link com.android.systemui.recents.tv.RecentsTvActivity}.
|
||||
*/
|
||||
public void onPipViewFocusChangedInRecents(boolean hasFocus) {
|
||||
mIsPipFocusedInRecent = hasFocus;
|
||||
if (mState != STATE_PIP_OVERLAY) {
|
||||
Log.w(TAG, "There is no pinned stack to handle focus change.");
|
||||
return;
|
||||
}
|
||||
resizePinnedStack(STATE_PIP_OVERLAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the PIP view in
|
||||
* {@link com.android.systemui.recents.tv.RecentsTvActivity} is focused in Recents.
|
||||
* This API is valid only when {@link isRecentsShown()} returns {@code true}.
|
||||
*/
|
||||
boolean isPipViewFocusdInRecents() {
|
||||
return mIsPipFocusedInRecent;
|
||||
public Rect getRecentsFocusedPipBounds() {
|
||||
return mRecentsFocusedPipBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -396,6 +368,10 @@ public class PipManager {
|
||||
*/
|
||||
private void showPipMenu() {
|
||||
if (DEBUG) Log.d(TAG, "showPipMenu()");
|
||||
if (mPipRecentsOverlayManager.isRecentsShown()) {
|
||||
if (DEBUG) Log.d(TAG, "Ignore showing PIP menu");
|
||||
return;
|
||||
}
|
||||
mState = STATE_PIP_MENU;
|
||||
for (int i = mListeners.size() - 1; i >= 0; --i) {
|
||||
mListeners.get(i).onShowPipMenu();
|
||||
@@ -405,14 +381,34 @@ public class PipManager {
|
||||
mContext.startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link Listener} to PipManager.
|
||||
*/
|
||||
public void addListener(Listener listener) {
|
||||
mListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a {@link Listener} from PipManager.
|
||||
*/
|
||||
public void removeListener(Listener listener) {
|
||||
mListeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link MediaListener} to PipManager.
|
||||
*/
|
||||
public void addMediaListener(MediaListener listener) {
|
||||
mMediaListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a {@link MediaListener} from PipManager.
|
||||
*/
|
||||
public void removeMediaListener(MediaListener listener) {
|
||||
mMediaListeners.remove(listener);
|
||||
}
|
||||
|
||||
private void launchPipOnboardingActivityIfNeeded() {
|
||||
if (DEBUG_FORCE_ONBOARDING || !mOnboardingShown) {
|
||||
mOnboardingShown = true;
|
||||
@@ -485,8 +481,8 @@ public class PipManager {
|
||||
}
|
||||
if (mPipMediaController != mediaController) {
|
||||
mPipMediaController = mediaController;
|
||||
for (int i = mListeners.size() - 1; i >= 0; i--) {
|
||||
mListeners.get(i).onMediaControllerChanged();
|
||||
for (int i = mMediaListeners.size() - 1; i >= 0; i--) {
|
||||
mMediaListeners.get(i).onMediaControllerChanged();
|
||||
}
|
||||
if (mPipMediaController == null) {
|
||||
mHandler.postDelayed(mClosePipRunnable,
|
||||
@@ -530,7 +526,7 @@ public class PipManager {
|
||||
return PLAYBACK_STATE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
TaskStackListener mTaskStackListener = new TaskStackListener() {
|
||||
private TaskStackListener mTaskStackListener = new TaskStackListener() {
|
||||
@Override
|
||||
public void onTaskStackChanged() {
|
||||
if (mState != STATE_NO_PIP) {
|
||||
@@ -582,10 +578,10 @@ public class PipManager {
|
||||
mMediaSessionManager.addOnActiveSessionsChangedListener(
|
||||
mActiveMediaSessionListener, null);
|
||||
updateMediaController(mMediaSessionManager.getActiveSessions(null));
|
||||
if (mIsRecentsShown) {
|
||||
if (mPipRecentsOverlayManager.isRecentsShown()) {
|
||||
// If an activity becomes PIPed again after the fullscreen, the Recents is shown
|
||||
// behind so we need to resize the pinned stack and show the correct overlay.
|
||||
resizePinnedStack(STATE_PIP_OVERLAY);
|
||||
resizePinnedStack(STATE_PIP_RECENTS);
|
||||
}
|
||||
for (int i = mListeners.size() - 1; i >= 0; i--) {
|
||||
mListeners.get(i).onPipEntered();
|
||||
@@ -604,7 +600,18 @@ public class PipManager {
|
||||
if (DEBUG) Log.d(TAG, "onPinnedStackAnimationEnded()");
|
||||
switch (mState) {
|
||||
case STATE_PIP_OVERLAY:
|
||||
showPipOverlay();
|
||||
if (!mPipRecentsOverlayManager.isRecentsShown()) {
|
||||
showPipOverlay();
|
||||
break;
|
||||
} else {
|
||||
// This happens only if an activity is PIPed after the Recents is shown.
|
||||
// See {@link PipRecentsOverlayManager.requestFocus} for more details.
|
||||
resizePinnedStack(mState);
|
||||
break;
|
||||
}
|
||||
case STATE_PIP_RECENTS:
|
||||
case STATE_PIP_RECENTS_FOCUSED:
|
||||
mPipRecentsOverlayManager.addPipRecentsOverlayView();
|
||||
break;
|
||||
case STATE_PIP_MENU:
|
||||
showPipMenu();
|
||||
@@ -621,7 +628,7 @@ public class PipManager {
|
||||
* Invoked when an activity is pinned and PIP manager is set corresponding information.
|
||||
* Classes must use this instead of {@link android.app.ITaskStackListener.onActivityPinned}
|
||||
* because there's no guarantee for the PIP manager be return relavent information
|
||||
* correctly. (e.g. {@link isPipShown}, {@link getPipBounds})
|
||||
* correctly. (e.g. {@link isPipShown}).
|
||||
*/
|
||||
void onPipEntered();
|
||||
/** Invoked when a PIPed activity is closed. */
|
||||
@@ -632,6 +639,12 @@ public class PipManager {
|
||||
void onMoveToFullscreen();
|
||||
/** Invoked when we are above to start resizing the Pip. */
|
||||
void onPipResizeAboutToStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* A listener interface to receive change in PIP's media controller
|
||||
*/
|
||||
public interface MediaListener {
|
||||
/** Invoked when the MediaController on PIPed activity is changed. */
|
||||
void onMediaControllerChanged();
|
||||
}
|
||||
@@ -645,4 +658,11 @@ public class PipManager {
|
||||
}
|
||||
return sPipManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of {@link PipRecentsOverlayManager}.
|
||||
*/
|
||||
public PipRecentsOverlayManager getPipRecentsOverlayManager() {
|
||||
return mPipRecentsOverlayManager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,12 +20,6 @@ import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SystemUI;
|
||||
import com.android.systemui.SystemUIApplication;
|
||||
import com.android.systemui.recents.Recents;
|
||||
|
||||
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
|
||||
import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
|
||||
|
||||
/**
|
||||
* Activity to show the PIP menu to control PIP.
|
||||
@@ -36,7 +30,6 @@ public class PipMenuActivity extends Activity implements PipManager.Listener {
|
||||
private final PipManager mPipManager = PipManager.getInstance();
|
||||
|
||||
private PipControlsView mPipControlsView;
|
||||
private boolean mPipMovedToFullscreen;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle bundle) {
|
||||
@@ -47,17 +40,10 @@ public class PipMenuActivity extends Activity implements PipManager.Listener {
|
||||
mPipControlsView = (PipControlsView) findViewById(R.id.pip_controls);
|
||||
}
|
||||
|
||||
private void restorePipAndFinish() {
|
||||
if (!mPipMovedToFullscreen) {
|
||||
mPipManager.resizePinnedStack(PipManager.STATE_PIP_OVERLAY);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
restorePipAndFinish();
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,11 +54,6 @@ public class PipMenuActivity extends Activity implements PipManager.Listener {
|
||||
PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
restorePipAndFinish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPipEntered() { }
|
||||
|
||||
@@ -86,31 +67,13 @@ public class PipMenuActivity extends Activity implements PipManager.Listener {
|
||||
|
||||
@Override
|
||||
public void onMoveToFullscreen() {
|
||||
mPipMovedToFullscreen = true;
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaControllerChanged() { }
|
||||
|
||||
@Override
|
||||
public void onPipResizeAboutToStart() {
|
||||
finish();
|
||||
mPipManager.suspendPipResizing(
|
||||
PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
if (mPipManager.isRecentsShown() && !mPipMovedToFullscreen) {
|
||||
SystemUI[] services = ((SystemUIApplication) getApplication()).getServices();
|
||||
for (int i = services.length - 1; i >= 0; i--) {
|
||||
if (services[i] instanceof Recents) {
|
||||
((Recents) services[i]).showRecents(false, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,4 @@ public class PipOnboardingActivity extends Activity implements PipManager.Listen
|
||||
|
||||
@Override
|
||||
public void onPipResizeAboutToStart() { }
|
||||
|
||||
@Override
|
||||
public void onMediaControllerChanged() { }
|
||||
}
|
||||
|
||||
@@ -35,14 +35,6 @@ import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
public class PipOverlayActivity extends Activity implements PipManager.Listener {
|
||||
private static final long SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS = 4000;
|
||||
|
||||
/**
|
||||
* The single instance of PipOverlayActivity to prevent it from restarting.
|
||||
* Note that {@link PipManager} moves the PIPed activity to fullscreen if the activity is
|
||||
* restarted. It's because the activity may be started by the Launcher or an intent again,
|
||||
* but we don't want do so for the PipOverlayActivity.
|
||||
*/
|
||||
private static PipOverlayActivity sPipOverlayActivity;
|
||||
|
||||
private final PipManager mPipManager = PipManager.getInstance();
|
||||
private final Handler mHandler = new Handler();
|
||||
private View mGuideOverlayView;
|
||||
@@ -54,47 +46,17 @@ public class PipOverlayActivity extends Activity implements PipManager.Listener
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Launches the PIP overlay. This should be only called on the main thread.
|
||||
*/
|
||||
public static void showPipOverlay(Context context) {
|
||||
if (sPipOverlayActivity == null) {
|
||||
Intent intent = new Intent(context, PipOverlayActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
final ActivityOptions options = ActivityOptions.makeBasic();
|
||||
options.setLaunchStackId(PINNED_STACK_ID);
|
||||
context.startActivity(intent, options.toBundle());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
setContentView(R.layout.tv_pip_overlay);
|
||||
mGuideOverlayView = findViewById(R.id.guide_overlay);
|
||||
mGuideButtonsView = findViewById(R.id.guide_buttons);
|
||||
mGuideButtonPlayPauseImageView = (ImageView) findViewById(R.id.guide_button_play_pause);
|
||||
mPipManager.addListener(this);
|
||||
|
||||
sPipOverlayActivity = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
// TODO: Implement animation for this
|
||||
if (mPipManager.isRecentsShown()) {
|
||||
mGuideOverlayView.setVisibility(View.GONE);
|
||||
if (mPipManager.isPipViewFocusdInRecents()) {
|
||||
mGuideButtonsView.setVisibility(View.GONE);
|
||||
} else {
|
||||
mGuideButtonsView.setVisibility(View.VISIBLE);
|
||||
updateGuideButtonsView();
|
||||
}
|
||||
} else {
|
||||
mGuideOverlayView.setVisibility(View.VISIBLE);
|
||||
mGuideButtonsView.setVisibility(View.GONE);
|
||||
}
|
||||
mHandler.removeCallbacks(mHideGuideOverlayRunnable);
|
||||
mHandler.postDelayed(mHideGuideOverlayRunnable, SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS);
|
||||
}
|
||||
@@ -109,7 +71,6 @@ public class PipOverlayActivity extends Activity implements PipManager.Listener
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
sPipOverlayActivity = null;
|
||||
mHandler.removeCallbacksAndMessages(null);
|
||||
mPipManager.removeListener(this);
|
||||
mPipManager.resumePipResizing(
|
||||
@@ -140,32 +101,4 @@ public class PipOverlayActivity extends Activity implements PipManager.Listener
|
||||
mPipManager.suspendPipResizing(
|
||||
PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_OVERLAY_ACTIVITY_FINISH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaControllerChanged() {
|
||||
updateGuideButtonsView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
sPipOverlayActivity = null;
|
||||
super.finish();
|
||||
}
|
||||
|
||||
private void updateGuideButtonsView() {
|
||||
switch (mPipManager.getPlaybackState()) {
|
||||
case PipManager.PLAYBACK_STATE_PLAYING:
|
||||
mGuideButtonPlayPauseImageView.setVisibility(View.VISIBLE);
|
||||
mGuideButtonPlayPauseImageView.setImageResource(R.drawable.ic_pause_white_24dp);
|
||||
break;
|
||||
case PipManager.PLAYBACK_STATE_PAUSED:
|
||||
mGuideButtonPlayPauseImageView.setVisibility(View.VISIBLE);
|
||||
mGuideButtonPlayPauseImageView.setImageResource(
|
||||
R.drawable.ic_play_arrow_white_24dp);
|
||||
break;
|
||||
case PipManager.PLAYBACK_STATE_UNAVAILABLE:
|
||||
mGuideButtonPlayPauseImageView.setVisibility(View.GONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.systemui.tv.pip;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorInflater;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnFocusChangeListener;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_PLAYING;
|
||||
import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_PAUSED;
|
||||
import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
* An extended version of {@link PipControlsView} that supports animation in Recents.
|
||||
*/
|
||||
public class PipRecentsControlsView extends PipControlsView {
|
||||
/**
|
||||
* An interface to listen user action.
|
||||
*/
|
||||
public interface Listener extends PipControlsView.Listener {
|
||||
/**
|
||||
* Called when an user presses BACK key and up.
|
||||
*/
|
||||
abstract void onBackPressed();
|
||||
}
|
||||
|
||||
private AnimatorSet mFocusGainAnimatorSet;
|
||||
private AnimatorSet mFocusLoseAnimatorSet;
|
||||
|
||||
public PipRecentsControlsView(Context context) {
|
||||
this(context, null, 0, 0);
|
||||
}
|
||||
|
||||
public PipRecentsControlsView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0, 0);
|
||||
}
|
||||
|
||||
public PipRecentsControlsView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public PipRecentsControlsView(
|
||||
Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
|
||||
int buttonsFocusGainAnim = R.anim.tv_pip_controls_buttons_in_recents_focus_gain_animation;
|
||||
int textFocusGainAnim = R.anim.tv_pip_controls_text_in_recents_focus_gain_animation;
|
||||
mFocusGainAnimatorSet = new AnimatorSet();
|
||||
mFocusGainAnimatorSet.playTogether(
|
||||
loadAnimator(this, R.anim.tv_pip_controls_in_recents_focus_gain_animation),
|
||||
loadAnimator(mFullButtonView,buttonsFocusGainAnim),
|
||||
loadAnimator(mPlayPauseButtonImageView, buttonsFocusGainAnim),
|
||||
loadAnimator(mCloseButtonView, buttonsFocusGainAnim),
|
||||
loadAnimator(mFullDescriptionView, textFocusGainAnim),
|
||||
loadAnimator(mPlayPauseDescriptionTextView, textFocusGainAnim),
|
||||
loadAnimator(mCloseDescriptionView, textFocusGainAnim));
|
||||
|
||||
int buttonsFocusLoseAnim = R.anim.tv_pip_controls_buttons_in_recents_focus_lose_animation;
|
||||
int textFocusLoseAnim = R.anim.tv_pip_controls_text_in_recents_focus_lose_animation;
|
||||
mFocusLoseAnimatorSet = new AnimatorSet();
|
||||
mFocusLoseAnimatorSet.playTogether(
|
||||
loadAnimator(this, R.anim.tv_pip_controls_in_recents_focus_lose_animation),
|
||||
loadAnimator(mFullButtonView, buttonsFocusLoseAnim),
|
||||
loadAnimator(mPlayPauseButtonImageView, buttonsFocusLoseAnim),
|
||||
loadAnimator(mCloseButtonView, buttonsFocusLoseAnim),
|
||||
loadAnimator(mFullDescriptionView, textFocusLoseAnim),
|
||||
loadAnimator(mPlayPauseDescriptionTextView, textFocusLoseAnim),
|
||||
loadAnimator(mCloseDescriptionView, textFocusLoseAnim));
|
||||
|
||||
Rect pipBounds = mPipManager.getRecentsFocusedPipBounds();
|
||||
int pipControlsMarginTop = getContext().getResources().getDimensionPixelSize(
|
||||
R.dimen.recents_tv_pip_controls_margin_top);
|
||||
setPadding(0, pipBounds.bottom + pipControlsMarginTop, 0, 0);
|
||||
}
|
||||
|
||||
private Animator loadAnimator(View view, int animatorResId) {
|
||||
Animator animator = AnimatorInflater.loadAnimator(getContext(), animatorResId);
|
||||
animator.setTarget(view);
|
||||
return animator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts focus gaining animation.
|
||||
*/
|
||||
public void startFocusGainAnimation() {
|
||||
if (mFocusLoseAnimatorSet.isStarted()) {
|
||||
mFocusLoseAnimatorSet.cancel();
|
||||
}
|
||||
mFocusGainAnimatorSet.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts focus losing animation.
|
||||
*/
|
||||
public void startFocusLoseAnimation() {
|
||||
if (mFocusGainAnimatorSet.isStarted()) {
|
||||
mFocusGainAnimatorSet.cancel();
|
||||
}
|
||||
mFocusLoseAnimatorSet.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the view to the initial state. (i.e. end of the focus gain)
|
||||
*/
|
||||
public void reset() {
|
||||
if (mFocusGainAnimatorSet.isStarted()) {
|
||||
mFocusGainAnimatorSet.cancel();
|
||||
}
|
||||
if (mFocusLoseAnimatorSet.isStarted()) {
|
||||
mFocusLoseAnimatorSet.cancel();
|
||||
}
|
||||
|
||||
// Reset to initial state (i.e. end of focused)
|
||||
requestFocus();
|
||||
setTranslationY(0);
|
||||
setScaleXY(mFullButtonView, 1);
|
||||
setScaleXY(mPlayPauseButtonImageView, 1);
|
||||
setScaleXY(mCloseButtonView, 1);
|
||||
mFullDescriptionView.setAlpha(1);
|
||||
mPlayPauseDescriptionTextView.setAlpha(1);
|
||||
mCloseDescriptionView.setAlpha(1);
|
||||
}
|
||||
|
||||
private void setScaleXY(View view, float scale) {
|
||||
view.setScaleX(scale);
|
||||
view.setScaleY(scale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||
if (!event.isCanceled()
|
||||
&& event.getKeyCode() == KeyEvent.KEYCODE_BACK
|
||||
&& event.getAction() == KeyEvent.ACTION_UP) {
|
||||
if (mListener != null) {
|
||||
((PipRecentsControlsView.Listener) mListener).onBackPressed();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.dispatchKeyEvent(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.systemui.tv.pip;
|
||||
|
||||
import android.animation.AnimatorInflater;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.content.Context;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
import static com.android.systemui.tv.pip.PipManager.STATE_PIP_OVERLAY;
|
||||
import static com.android.systemui.tv.pip.PipManager.STATE_PIP_RECENTS;
|
||||
import static com.android.systemui.tv.pip.PipManager.STATE_PIP_RECENTS_FOCUSED;
|
||||
|
||||
public class PipRecentsOverlayManager {
|
||||
private static final String TAG = "PipRecentsOverlayManager";
|
||||
|
||||
public interface Callback {
|
||||
void onClosed();
|
||||
void onBackPressed();
|
||||
void onRecentsFocused();
|
||||
}
|
||||
|
||||
private final PipManager mPipManager = PipManager.getInstance();
|
||||
private final WindowManager mWindowManager;
|
||||
private final View mOverlayView;
|
||||
private final PipRecentsControlsView mPipControlsView;
|
||||
private final View mRecentsView;
|
||||
|
||||
private final LayoutParams mPipRecentsControlsViewLayoutParams;
|
||||
private final LayoutParams mPipRecentsControlsViewFocusedLayoutParams;
|
||||
|
||||
private boolean mIsPipRecentsOverlayShown;
|
||||
private boolean mIsRecentsShown;
|
||||
private boolean mIsPipFocusedInRecent;
|
||||
private Callback mCallback;
|
||||
private PipRecentsControlsView.Listener mPipControlsViewListener =
|
||||
new PipRecentsControlsView.Listener() {
|
||||
@Override
|
||||
public void onClosed() {
|
||||
if (mCallback != null) {
|
||||
mCallback.onClosed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mCallback != null) {
|
||||
mCallback.onBackPressed();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
PipRecentsOverlayManager(Context context) {
|
||||
mWindowManager = (WindowManager) context.getSystemService(WindowManager.class);
|
||||
|
||||
LayoutInflater inflater = (LayoutInflater) context
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
mOverlayView = inflater.inflate(R.layout.tv_pip_recents_overlay, null);
|
||||
mPipControlsView = (PipRecentsControlsView) mOverlayView.findViewById(R.id.pip_controls);
|
||||
mRecentsView = mOverlayView.findViewById(R.id.recents);
|
||||
mRecentsView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (hasFocus) {
|
||||
clearFocus();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mPipRecentsControlsViewLayoutParams = new WindowManager.LayoutParams(
|
||||
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.TYPE_SYSTEM_DIALOG,
|
||||
LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCHABLE,
|
||||
PixelFormat.TRANSLUCENT);
|
||||
mPipRecentsControlsViewFocusedLayoutParams = new WindowManager.LayoutParams(
|
||||
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.TYPE_SYSTEM_DIALOG,
|
||||
0,
|
||||
PixelFormat.TRANSLUCENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Recents overlay view.
|
||||
* This is expected to be called after the PIP animation is over.
|
||||
*/
|
||||
void addPipRecentsOverlayView() {
|
||||
if (mIsPipRecentsOverlayShown) {
|
||||
return;
|
||||
}
|
||||
mIsPipRecentsOverlayShown = true;
|
||||
mIsPipFocusedInRecent = true;
|
||||
mPipControlsView.reset();
|
||||
mWindowManager.addView(mOverlayView, mPipRecentsControlsViewFocusedLayoutParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove Recents overlay view.
|
||||
* This should be called when Recents or PIP is closed.
|
||||
*/
|
||||
public void removePipRecentsOverlayView() {
|
||||
if (!mIsPipRecentsOverlayShown) {
|
||||
return;
|
||||
}
|
||||
mWindowManager.removeView(mOverlayView);
|
||||
mIsPipRecentsOverlayShown = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request focus to the PIP Recents overlay.
|
||||
* Called when the PIP view in {@link com.android.systemui.recents.tv.RecentsTvActivity}
|
||||
* is focused.
|
||||
* This should be called only by {@link com.android.systemui.recents.tv.RecentsTvActivity}.
|
||||
* @param hasRecentsFocusable {@code true} if Recents can have focus. (i.e. Has a recent task)
|
||||
*/
|
||||
public void requestFocus(boolean hasRecentsFocusable) {
|
||||
if (!mIsRecentsShown || mIsPipFocusedInRecent) {
|
||||
return;
|
||||
}
|
||||
mIsPipFocusedInRecent = true;
|
||||
mPipManager.resizePinnedStack(STATE_PIP_RECENTS_FOCUSED);
|
||||
|
||||
mWindowManager.updateViewLayout(mOverlayView, mPipRecentsControlsViewFocusedLayoutParams);
|
||||
mPipControlsView.requestFocus();
|
||||
mPipControlsView.startFocusGainAnimation();
|
||||
mRecentsView.setVisibility(hasRecentsFocusable ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request focus to the PIP Recents overlay.
|
||||
* Called when the PIP view in {@link com.android.systemui.recents.tv.RecentsTvActivity}
|
||||
* is focused.
|
||||
* This should be called only by {@link com.android.systemui.recents.tv.RecentsTvActivity}.
|
||||
*/
|
||||
private void clearFocus() {
|
||||
if (!mIsRecentsShown || !mIsPipFocusedInRecent) {
|
||||
return;
|
||||
}
|
||||
mIsPipFocusedInRecent = false;
|
||||
mPipManager.resizePinnedStack(STATE_PIP_RECENTS);
|
||||
mWindowManager.updateViewLayout(mOverlayView, mPipRecentsControlsViewLayoutParams);
|
||||
mPipControlsView.startFocusLoseAnimation();
|
||||
if (mCallback != null) {
|
||||
mCallback.onRecentsFocused();
|
||||
}
|
||||
}
|
||||
|
||||
public void setCallback(Callback listener) {
|
||||
mCallback = listener;
|
||||
mPipControlsView.setListener(mCallback != null ? mPipControlsViewListener : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when Recents is resumed.
|
||||
* PIPed activity will be resized accordingly and overlay will show available buttons.
|
||||
*/
|
||||
public void onRecentsResumed() {
|
||||
if (!mPipManager.isPipShown()) {
|
||||
return;
|
||||
}
|
||||
mIsRecentsShown = true;
|
||||
mIsPipFocusedInRecent = true;
|
||||
mPipManager.resizePinnedStack(STATE_PIP_RECENTS_FOCUSED);
|
||||
// Overlay view will be added after the resize animation ends, if any.
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when Recents is paused.
|
||||
* PIPed activity will be resized accordingly and overlay will hide available buttons.
|
||||
*/
|
||||
public void onRecentsPaused() {
|
||||
mIsRecentsShown = false;
|
||||
mIsPipFocusedInRecent = false;
|
||||
removePipRecentsOverlayView();
|
||||
|
||||
if (mPipManager.isPipShown()) {
|
||||
mPipManager.resizePinnedStack(STATE_PIP_OVERLAY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if recents is shown.
|
||||
*/
|
||||
boolean isRecentsShown() {
|
||||
return mIsRecentsShown;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user