1/*
2 * Copyright (C) 2016 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
17package com.android.systemui.pip.phone;
18
19import android.content.Context;
20import android.graphics.PixelFormat;
21import android.graphics.Point;
22import android.graphics.PointF;
23import android.graphics.Rect;
24import android.graphics.drawable.Drawable;
25import android.view.Gravity;
26import android.view.LayoutInflater;
27import android.view.View;
28import android.view.View.OnLayoutChangeListener;
29import android.view.ViewGroup;
30import android.view.WindowManager;
31import android.view.WindowManager.LayoutParams;
32import android.widget.FrameLayout;
33
34import com.android.systemui.Interpolators;
35import com.android.systemui.R;
36import com.android.systemui.recents.misc.SystemServicesProxy;
37
38public class PipDismissViewController {
39
40    // This delay controls how long to wait before we show the target when the user first moves
41    // the PIP, to prevent the target from animating if the user just wants to fling the PIP
42    private static final int SHOW_TARGET_DELAY = 100;
43    private static final int SHOW_TARGET_DURATION = 350;
44    private static final int HIDE_TARGET_DURATION = 225;
45
46    private Context mContext;
47    private WindowManager mWindowManager;
48    private View mDismissView;
49
50    public PipDismissViewController(Context context) {
51        mContext = context;
52        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
53    }
54
55    /**
56     * Creates the dismiss target for showing via {@link #showDismissTarget()}.
57     */
58    public void createDismissTarget() {
59        if (mDismissView == null) {
60            // Determine sizes for the view
61            final Rect stableInsets = new Rect();
62            SystemServicesProxy.getInstance(mContext).getStableInsets(stableInsets);
63            final Point windowSize = new Point();
64            mWindowManager.getDefaultDisplay().getRealSize(windowSize);
65            final int gradientHeight = mContext.getResources().getDimensionPixelSize(
66                    R.dimen.pip_dismiss_gradient_height);
67            final int bottomMargin = mContext.getResources().getDimensionPixelSize(
68                    R.dimen.pip_dismiss_text_bottom_margin);
69
70            // Create a new view for the dismiss target
71            LayoutInflater inflater = LayoutInflater.from(mContext);
72            mDismissView = inflater.inflate(R.layout.pip_dismiss_view, null);
73            mDismissView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
74            mDismissView.forceHasOverlappingRendering(false);
75
76            // Set the gradient background
77            Drawable gradient = mContext.getResources().getDrawable(R.drawable.pip_dismiss_scrim);
78            gradient.setAlpha((int) (255 * 0.85f));
79            mDismissView.setBackground(gradient);
80
81            // Adjust bottom margins of the text
82            View text = mDismissView.findViewById(R.id.pip_dismiss_text);
83            FrameLayout.LayoutParams tlp = (FrameLayout.LayoutParams) text.getLayoutParams();
84            tlp.bottomMargin = stableInsets.bottom + bottomMargin;
85
86            // Add the target to the window
87            LayoutParams lp =  new LayoutParams(
88                    LayoutParams.MATCH_PARENT, gradientHeight,
89                    0, windowSize.y - gradientHeight,
90                    LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
91                    LayoutParams.FLAG_LAYOUT_IN_SCREEN
92                            | LayoutParams.FLAG_NOT_TOUCHABLE
93                            | LayoutParams.FLAG_NOT_FOCUSABLE
94                            | LayoutParams.FLAG_HARDWARE_ACCELERATED,
95                    PixelFormat.TRANSLUCENT);
96            lp.setTitle("pip-dismiss-overlay");
97            lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
98            lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
99            mWindowManager.addView(mDismissView, lp);
100        }
101        mDismissView.animate().cancel();
102    }
103
104    /**
105     * Shows the dismiss target.
106     */
107    public void showDismissTarget() {
108        mDismissView.animate()
109                .alpha(1f)
110                .setInterpolator(Interpolators.LINEAR)
111                .setStartDelay(SHOW_TARGET_DELAY)
112                .setDuration(SHOW_TARGET_DURATION)
113                .start();
114    }
115
116    /**
117     * Hides and destroys the dismiss target.
118     */
119    public void destroyDismissTarget() {
120        if (mDismissView != null) {
121            mDismissView.animate()
122                    .alpha(0f)
123                    .setInterpolator(Interpolators.LINEAR)
124                    .setStartDelay(0)
125                    .setDuration(HIDE_TARGET_DURATION)
126                    .withEndAction(new Runnable() {
127                        @Override
128                        public void run() {
129                            mWindowManager.removeViewImmediate(mDismissView);
130                            mDismissView = null;
131                        }
132                    })
133                    .start();
134        }
135    }
136}
137