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.android.wm.shell.unfold;
18 
19 import static android.graphics.Color.blue;
20 import static android.graphics.Color.green;
21 import static android.graphics.Color.red;
22 
23 import android.annotation.ColorRes;
24 import android.annotation.NonNull;
25 import android.content.Context;
26 import android.view.SurfaceControl;
27 
28 import com.android.wm.shell.R;
29 
30 /**
31  * Controls background color layer for the unfold animations
32  */
33 public class UnfoldBackgroundController {
34 
35     private static final int BACKGROUND_LAYER_Z_INDEX = -1;
36     private final float[] mBackgroundColor;
37     private final float[] mSplitScreenBackgroundColor;
38     private float[] mBackgroundColorSet;
39     private SurfaceControl mBackgroundLayer;
40     private boolean mSplitScreenVisible = false;
41 
UnfoldBackgroundController(@onNull Context context)42     public UnfoldBackgroundController(@NonNull Context context) {
43         mBackgroundColor = getRGBColorFromId(context, R.color.unfold_background);
44         mSplitScreenBackgroundColor = getRGBColorFromId(context, R.color.split_divider_background);
45     }
46 
47     /**
48      * Ensures that unfold animation background color layer is present,
49      * @param transaction where we should add the background if it is not added
50      */
ensureBackground(@onNull SurfaceControl.Transaction transaction)51     public void ensureBackground(@NonNull SurfaceControl.Transaction transaction) {
52         float[] expectedColor = getCurrentBackgroundColor();
53         if (mBackgroundLayer != null) {
54             if (mBackgroundColorSet != expectedColor) {
55                 transaction.setColor(mBackgroundLayer, expectedColor);
56                 mBackgroundColorSet = expectedColor;
57             }
58             return;
59         }
60 
61         SurfaceControl.Builder colorLayerBuilder = new SurfaceControl.Builder()
62                 .setName("app-unfold-background")
63                 .setCallsite("AppUnfoldTransitionController")
64                 .setColorLayer();
65         mBackgroundLayer = colorLayerBuilder.build();
66 
67         transaction
68                 .setColor(mBackgroundLayer, expectedColor)
69                 .show(mBackgroundLayer)
70                 .setLayer(mBackgroundLayer, BACKGROUND_LAYER_Z_INDEX);
71         mBackgroundColorSet = expectedColor;
72     }
73 
74     /**
75      * Ensures that the background is not visible
76      * @param transaction as part of which the removal will happen if needed
77      */
removeBackground(@onNull SurfaceControl.Transaction transaction)78     public void removeBackground(@NonNull SurfaceControl.Transaction transaction) {
79         if (mBackgroundLayer == null) return;
80         if (mBackgroundLayer.isValid()) {
81             transaction.remove(mBackgroundLayer);
82         }
83         mBackgroundLayer = null;
84     }
85 
86     /**
87      * Expected to be called whenever split screen visibility changes.
88      *
89      * @param visible True when split screen is visible
90      */
onSplitVisibilityChanged(boolean visible)91     public void onSplitVisibilityChanged(boolean visible) {
92         mSplitScreenVisible = visible;
93     }
94 
getCurrentBackgroundColor()95     private float[] getCurrentBackgroundColor() {
96         if (mSplitScreenVisible) {
97             return mSplitScreenBackgroundColor;
98         } else {
99             return mBackgroundColor;
100         }
101     }
102 
getRGBColorFromId(Context context, @ColorRes int id)103     private float[] getRGBColorFromId(Context context, @ColorRes int id) {
104         int colorInt = context.getResources().getColor(id);
105         return new float[]{
106                 (float) red(colorInt) / 255.0F,
107                 (float) green(colorInt) / 255.0F,
108                 (float) blue(colorInt) / 255.0F
109         };
110     }
111 }
112