| /* |
| * 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.pip.phone; |
| |
| import android.content.Context; |
| import android.graphics.PixelFormat; |
| import android.graphics.Point; |
| import android.graphics.PointF; |
| import android.graphics.Rect; |
| import android.graphics.drawable.Drawable; |
| import android.view.Gravity; |
| import android.view.LayoutInflater; |
| import android.view.View; |
| import android.view.View.OnLayoutChangeListener; |
| import android.view.ViewGroup; |
| import android.view.WindowManager; |
| import android.view.WindowManager.LayoutParams; |
| import android.widget.FrameLayout; |
| |
| import com.android.systemui.Interpolators; |
| import com.android.systemui.R; |
| import com.android.systemui.recents.misc.SystemServicesProxy; |
| |
| public class PipDismissViewController { |
| |
| // This delay controls how long to wait before we show the target when the user first moves |
| // the PIP, to prevent the target from animating if the user just wants to fling the PIP |
| private static final int SHOW_TARGET_DELAY = 100; |
| private static final int SHOW_TARGET_DURATION = 350; |
| private static final int HIDE_TARGET_DURATION = 225; |
| |
| private Context mContext; |
| private WindowManager mWindowManager; |
| private View mDismissView; |
| |
| public PipDismissViewController(Context context) { |
| mContext = context; |
| mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); |
| } |
| |
| /** |
| * Creates the dismiss target for showing via {@link #showDismissTarget()}. |
| */ |
| public void createDismissTarget() { |
| if (mDismissView == null) { |
| // Determine sizes for the view |
| final Rect stableInsets = new Rect(); |
| SystemServicesProxy.getInstance(mContext).getStableInsets(stableInsets); |
| final Point windowSize = new Point(); |
| mWindowManager.getDefaultDisplay().getRealSize(windowSize); |
| final int gradientHeight = mContext.getResources().getDimensionPixelSize( |
| R.dimen.pip_dismiss_gradient_height); |
| final int bottomMargin = mContext.getResources().getDimensionPixelSize( |
| R.dimen.pip_dismiss_text_bottom_margin); |
| |
| // Create a new view for the dismiss target |
| LayoutInflater inflater = LayoutInflater.from(mContext); |
| mDismissView = inflater.inflate(R.layout.pip_dismiss_view, null); |
| mDismissView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE); |
| mDismissView.forceHasOverlappingRendering(false); |
| |
| // Set the gradient background |
| Drawable gradient = mContext.getResources().getDrawable(R.drawable.pip_dismiss_scrim); |
| gradient.setAlpha((int) (255 * 0.85f)); |
| mDismissView.setBackground(gradient); |
| |
| // Adjust bottom margins of the text |
| View text = mDismissView.findViewById(R.id.pip_dismiss_text); |
| FrameLayout.LayoutParams tlp = (FrameLayout.LayoutParams) text.getLayoutParams(); |
| tlp.bottomMargin = stableInsets.bottom + bottomMargin; |
| |
| // Add the target to the window |
| LayoutParams lp = new LayoutParams( |
| LayoutParams.MATCH_PARENT, gradientHeight, |
| 0, windowSize.y - gradientHeight, |
| LayoutParams.TYPE_NAVIGATION_BAR_PANEL, |
| LayoutParams.FLAG_LAYOUT_IN_SCREEN |
| | LayoutParams.FLAG_NOT_TOUCHABLE |
| | LayoutParams.FLAG_NOT_FOCUSABLE, |
| PixelFormat.TRANSLUCENT); |
| lp.setTitle("pip-dismiss-overlay"); |
| lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; |
| lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; |
| mWindowManager.addView(mDismissView, lp); |
| } |
| mDismissView.animate().cancel(); |
| } |
| |
| /** |
| * Shows the dismiss target. |
| */ |
| public void showDismissTarget() { |
| mDismissView.animate() |
| .alpha(1f) |
| .setInterpolator(Interpolators.LINEAR) |
| .setStartDelay(SHOW_TARGET_DELAY) |
| .setDuration(SHOW_TARGET_DURATION) |
| .start(); |
| } |
| |
| /** |
| * Hides and destroys the dismiss target. |
| */ |
| public void destroyDismissTarget() { |
| if (mDismissView != null) { |
| mDismissView.animate() |
| .alpha(0f) |
| .setInterpolator(Interpolators.LINEAR) |
| .setStartDelay(0) |
| .setDuration(HIDE_TARGET_DURATION) |
| .withEndAction(new Runnable() { |
| @Override |
| public void run() { |
| mWindowManager.removeViewImmediate(mDismissView); |
| mDismissView = null; |
| } |
| }) |
| .start(); |
| } |
| } |
| } |