blob: 9c456eecc1acd29ff35aa15b498f0fd27b2cb9b0 [file] [log] [blame]
Heemin Seogd9af2982020-01-09 16:24:57 -08001/*
2 * Copyright (C) 2020 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
Abhijoy Saha84590ea2020-01-14 12:31:00 -080017package com.android.systemui.window;
Heemin Seogd9af2982020-01-09 16:24:57 -080018
19import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
20
21import android.content.Context;
22import android.content.res.Resources;
23import android.graphics.PixelFormat;
24import android.graphics.Point;
25import android.os.Binder;
26import android.view.Gravity;
27import android.view.LayoutInflater;
28import android.view.ViewGroup;
29import android.view.WindowManager;
30
31import com.android.systemui.R;
32import com.android.systemui.dagger.qualifiers.Main;
33import com.android.systemui.statusbar.policy.ConfigurationController;
34
35import javax.inject.Inject;
36import javax.inject.Singleton;
37
38/**
39 * Controls the expansion state of the primary window which will contain all of the fullscreen sysui
40 * behavior. This window still has a collapsed state in order to watch for swipe events to expand
41 * this window for the notification panel.
42 */
43@Singleton
Abhijoy Saha84590ea2020-01-14 12:31:00 -080044public class SystemUIOverlayWindowController implements
Heemin Seogd9af2982020-01-09 16:24:57 -080045 ConfigurationController.ConfigurationListener {
46
47 private final Context mContext;
48 private final Resources mResources;
49 private final WindowManager mWindowManager;
50
51 private final int mStatusBarHeight;
52 private final int mNavBarHeight;
53 private final int mDisplayHeight;
54 private ViewGroup mBaseLayout;
55 private WindowManager.LayoutParams mLp;
56 private WindowManager.LayoutParams mLpChanged;
Heemin Seog17134e22020-01-10 10:54:05 -080057 private boolean mIsAttached = false;
Heemin Seogd9af2982020-01-09 16:24:57 -080058
59 @Inject
Abhijoy Saha84590ea2020-01-14 12:31:00 -080060 public SystemUIOverlayWindowController(
Heemin Seogd9af2982020-01-09 16:24:57 -080061 Context context,
62 @Main Resources resources,
63 WindowManager windowManager,
64 ConfigurationController configurationController
65 ) {
66 mContext = context;
67 mResources = resources;
68 mWindowManager = windowManager;
69
70 Point display = new Point();
71 mWindowManager.getDefaultDisplay().getSize(display);
72 mDisplayHeight = display.y;
73
74 mStatusBarHeight = mResources.getDimensionPixelSize(
75 com.android.internal.R.dimen.status_bar_height);
76 mNavBarHeight = mResources.getDimensionPixelSize(R.dimen.navigation_bar_height);
77
78 mLpChanged = new WindowManager.LayoutParams();
79 mBaseLayout = (ViewGroup) LayoutInflater.from(context)
Abhijoy Saha84590ea2020-01-14 12:31:00 -080080 .inflate(R.layout.sysui_overlay_window, /* root= */ null, false);
Heemin Seogd9af2982020-01-09 16:24:57 -080081
82 configurationController.addCallback(this);
83 }
84
85 /** Returns the base view of the primary window. */
86 public ViewGroup getBaseLayout() {
87 return mBaseLayout;
88 }
89
Heemin Seog17134e22020-01-10 10:54:05 -080090 /** Returns {@code true} if the window is already attached. */
91 public boolean isAttached() {
92 return mIsAttached;
93 }
94
Heemin Seogd9af2982020-01-09 16:24:57 -080095 /** Attaches the window to the window manager. */
96 public void attach() {
Heemin Seog17134e22020-01-10 10:54:05 -080097 if (mIsAttached) {
98 return;
99 }
100 mIsAttached = true;
Heemin Seogd9af2982020-01-09 16:24:57 -0800101 // Now that the status bar window encompasses the sliding panel and its
102 // translucent backdrop, the entire thing is made TRANSLUCENT and is
103 // hardware-accelerated.
104 mLp = new WindowManager.LayoutParams(
105 ViewGroup.LayoutParams.MATCH_PARENT,
106 mStatusBarHeight,
107 WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL,
108 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
109 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
110 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Heemin Seog17134e22020-01-10 10:54:05 -0800111 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
112 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
Heemin Seogd9af2982020-01-09 16:24:57 -0800113 PixelFormat.TRANSLUCENT);
114 mLp.token = new Binder();
115 mLp.gravity = Gravity.TOP;
Tiger Huang52724442020-01-20 21:38:42 +0800116 mLp.setFitInsetsTypes(/* types= */ 0);
Heemin Seogd9af2982020-01-09 16:24:57 -0800117 mLp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
Abhijoy Saha84590ea2020-01-14 12:31:00 -0800118 mLp.setTitle("SystemUIOverlayWindow");
Heemin Seogd9af2982020-01-09 16:24:57 -0800119 mLp.packageName = mContext.getPackageName();
120 mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
121
122 mWindowManager.addView(mBaseLayout, mLp);
123 mLpChanged.copyFrom(mLp);
124 }
125
126 /** Sets the window to the expanded state. */
127 public void setWindowExpanded(boolean expanded) {
128 if (expanded) {
129 // TODO: Update this so that the windowing type gets the full height of the display
130 // when we use MATCH_PARENT.
131 mLpChanged.height = mDisplayHeight + mNavBarHeight;
Heemin Seog17134e22020-01-10 10:54:05 -0800132 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
Heemin Seogd9af2982020-01-09 16:24:57 -0800133 } else {
134 mLpChanged.height = mStatusBarHeight;
Heemin Seog17134e22020-01-10 10:54:05 -0800135 // TODO: Allow touches to go through to the status bar to handle notification panel.
136 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
Heemin Seogd9af2982020-01-09 16:24:57 -0800137 }
138 updateWindow();
139 }
140
141 /** Returns {@code true} if the window is expanded */
142 public boolean isWindowExpanded() {
143 return mLp.height != mStatusBarHeight;
144 }
145
146 private void updateWindow() {
147 if (mLp != null && mLp.copyFrom(mLpChanged) != 0) {
Heemin Seog17134e22020-01-10 10:54:05 -0800148 if (isAttached()) {
149 mWindowManager.updateViewLayout(mBaseLayout, mLp);
150 }
Heemin Seogd9af2982020-01-09 16:24:57 -0800151 }
152 }
153}