Merge "Controls UI - Basic impl"

This commit is contained in:
Matt Pietal
2020-01-27 17:49:56 +00:00
committed by Android (Google) Code Review
33 changed files with 1060 additions and 26 deletions

View File

@@ -0,0 +1,7 @@
package android.service.controls;
/** @hide */
interface TokenProvider {
void setAuthToken(String token);
String getAccountName();
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:color="@color/control_default_background" />
<item android:color="@color/GM2_yellow_50" />
</selector>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:color="@color/control_default_foreground" />
<item android:color="@color/GM2_orange_900" />
</selector>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:color="@color/control_default_background" />
<item android:color="@color/GM2_blue_50" />
</selector>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:color="@color/control_default_foreground" />
<item android:color="@color/GM2_blue_700" />
</selector>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:color="@color/control_default_foreground" />
<item android:color="@color/GM2_blue_700" />
</selector>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright 2020, 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.
*/
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="?android:attr/colorBackgroundFloating"/>
<corners android:radius="@dimen/control_corner_radius" />
</shape>
</item>
<item
android:id="@+id/clip_layer">
<clip
android:clipOrientation="horizontal"
android:drawable="@drawable/control_layer"/>
</item>
</layer-list>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright 2020, 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.
*/
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/transparent"/>
<corners android:radius="@dimen/control_corner_radius" />
</shape>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright 2020, 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.
*/
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:width="1dp" android:color="?android:attr/colorBackgroundFloating"/>
<corners android:radius="@dimen/control_corner_radius" />
</shape>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M18,9h-5v2h5m3,-6h-8v2h8m-9,11.97c0.62,-0.83 1,-1.85 1,-2.97 0,-1.63 -0.79,-3.09 -2,-4V6c0,-1.66 -1.34,-3 -3,-3S5,4.34 5,6v6c-1.21,0.91 -2,2.37 -2,4 0,1.12 0.38,2.14 1,2.97V19h0.02c0.91,1.21 2.35,2 3.98,2s3.06,-0.79 3.98,-2H12v-0.03zM6.2,13.6L7,13V6c0,-0.55 0.45,-1 1,-1s1,0.45 1,1v7l0.8,0.6c0.75,0.57 1.2,1.46 1.2,2.4H5c0,-0.94 0.45,-1.84 1.2,-2.4z"/>
</vector>

View File

@@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M9,21v-1h6v1c0,0.55 -0.45,1 -1,1h-4c-0.55,0 -1,-0.45 -1,-1z"/>
<group>
<clip-path android:pathData="M0,0h24v24H0z M 0,0"/>
</group>
<path
android:fillColor="#FF000000"
android:pathData="M12,2c-1.89,0 -3.6,0.75 -4.86,1.97l1.41,1.41C9.45,4.53 10.67,4 12,4c2.76,0 5,2.24 5,5 0,1.28 -0.5,2.5 -1.36,3.42l-0.02,0.02 1.41,1.41C18.25,12.6 19,10.89 19,9c0,-3.86 -3.14,-7 -7,-7z"
android:fillType="evenOdd"/>
<path
android:fillColor="#FF000000"
android:pathData="M2.92,2.29L1.65,3.57l3.59,3.59C5.09,7.75 5,8.36 5,9c0,2.38 1.19,4.47 3,5.74V17c0,0.55 0.45,1 1,1h6c0.3,0 0.57,-0.13 0.75,-0.34L20.09,22l1.27,-1.27L2.92,2.29zM10,16v-2.3l-0.85,-0.6C7.8,12.16 7,10.63 7,9v-0.08L14.09,16H10z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM9,6c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v2L9,8L9,6zM18,20L6,20L6,10h12v10zM12,17c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2z"/>
</vector>

View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6h2c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM18,20L6,20L6,10h12v10z"/>
<path
android:fillColor="#FF000000"
android:pathData="M12,15m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
</vector>

View File

@@ -0,0 +1,24 @@
<!--
Copyright (C) 2020 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M16,9v4.66l-3.5,3.51V19h-1v-1.83L8,13.65V9h8m0,-6h-2v4h-4V3H8v4h-0.01C6.9,6.99 6,7.89 6,8.98v5.52L9.5,18v3h5v-3l3.5,-3.51V9c0,-1.1 -0.9,-2 -2,-2V3z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M21.19,21.19L2.81,2.81 1.39,4.22l4.63,4.63L6,14.5 9.5,18v3h5v-3l0.34,-0.34 4.94,4.94 1.41,-1.41zM12.5,17.17L12.5,19h-1v-1.83L8,13.65v-2.83l5.42,5.42 -0.92,0.93zM11.83,9L8,5.17L8,3h2v4h4L14,3h2v4c1.1,0 2,0.9 2,2v5.49l-0.34,0.34L16,13.17L16,9h-4.17z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M11,2h2v10h-2zM18.37,5.64l-1.41,1.41c2.73,2.73 2.72,7.16 -0.01,9.89 -2.73,2.73 -7.17,2.73 -9.89,0.01 -2.73,-2.73 -2.74,-7.18 -0.01,-9.91l-1.41,-1.4c-3.51,3.51 -3.51,9.21 0.01,12.73 3.51,3.51 9.21,3.51 12.72,-0.01 3.51,-3.51 3.51,-9.2 0,-12.72z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M19,9h-8.02C10.06,7.79 8.63,7 7,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5c1.63,0 3.06,-0.79 3.98,-2H19c1.66,0 3,-1.34 3,-3S20.66,9 19,9zM19,13h-7.1c0.07,-0.32 0.1,-0.66 0.1,-1s-0.04,-0.68 -0.1,-1H19c0.55,0 1,0.45 1,1S19.55,13 19,13z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M4,16c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3zM4,20c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1 1,0.45 1,1 -0.45,1 -1,1zM23,20v2h-7v-2h2.49L12.01,4.59C11.6,3.63 10.66,3 9.61,3 8.17,3 7,4.17 7,5.61L7,9h2c2.21,0 4,1.79 4,4v9L7.99,22c0.44,-0.58 0.76,-1.26 0.91,-2L11,20v-7c0,-1.1 -0.9,-2 -2,-2L4,11v3c-0.71,0 -1.39,0.15 -2,0.42L2,9h3L5,5.61C5,3.07 7.07,1 9.61,1c1.86,0 3.53,1.11 4.25,2.82L20.66,20L23,20z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M18,10.48L18,6c0,-1.1 -0.9,-2 -2,-2L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2v-4.48l4,3.98v-11l-4,3.98zM16,9.69L16,18L4,18L4,6h12v3.69z"/>
</vector>

View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 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.
-->
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="@dimen/control_height"
android:padding="@dimen/control_padding"
android:clickable="true"
android:focusable="true"
android:layout_marginLeft="3dp"
android:layout_marginRight="3dp"
android:background="@drawable/control_background">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/control_status_normal"
android:textColor="?android:attr/textColorPrimary"
android:fontFamily="@*android:string/config_bodyFontFamily"
android:paddingLeft="3dp"
app:layout_constraintBottom_toBottomOf="@+id/icon"
app:layout_constraintStart_toEndOf="@+id/icon" />
<TextView
android:id="@+id/status_extra"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/control_status_normal"
android:textColor="?android:attr/textColorPrimary"
android:fontFamily="@*android:string/config_bodyFontFamily"
android:paddingLeft="3dp"
app:layout_constraintBottom_toBottomOf="@+id/icon"
app:layout_constraintStart_toEndOf="@+id/status" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="?android:attr/textColorPrimary"
android:fontFamily="@*android:string/config_headlineFontFamily"
app:layout_constraintBottom_toTopOf="@+id/subtitle"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/icon" />
<TextView
android:id="@+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="?android:attr/textColorSecondary"
android:fontFamily="@*android:string/config_headlineFontFamily"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,18 @@
<merge
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/controls_title"
android:text="@string/quick_controls_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:gravity="center"
android:textSize="25dp"
android:paddingTop="40dp"
android:paddingBottom="40dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:textColor="?android:attr/textColorPrimary"
android:fontFamily="@*android:string/config_headlineFontFamily"
android:background="@drawable/control_no_favorites_background"/>
</merge>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 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"
orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/control_spacing" />

View File

@@ -0,0 +1,35 @@
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="@string/quick_controls_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:gravity="center"
android:textSize="25dp"
android:textColor="?android:attr/textColorPrimary"
android:fontFamily="@*android:string/config_headlineFontFamily"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<ImageView
android:id="@+id/controls_more"
android:src="@drawable/ic_more_vert"
android:layout_width="34dp"
android:layout_height="24dp"
android:layout_marginEnd="10dp"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:id="@+id/global_actions_controls_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</merge>

View File

@@ -111,20 +111,7 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/global_actions_panel">
<TextView
android:text="Home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:gravity="center"
android:textSize="25dp"
android:textColor="?android:attr/textColorPrimary"
android:fontFamily="@*android:string/config_headlineFontFamily" />
<LinearLayout
android:id="@+id/global_actions_controls_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

View File

@@ -200,18 +200,28 @@
<color name="GM2_grey_800">#3C4043</color>
<color name="GM2_grey_900">#202124</color>
<color name="GM2_red_50">#FCE8E6</color>
<color name="GM2_red_300">#F28B82</color>
<color name="GM2_red_500">#B71C1C</color>
<color name="GM2_red_700">#C5221F</color>
<color name="GM2_blue_50">#E8F0FE</color>
<color name="GM2_blue_200">#AECBFA</color>
<color name="GM2_blue_300">#8AB4F8</color>
<color name="GM2_blue_500">#FF4285F4</color>
<color name="GM2_blue_600">#1A73E8</color>
<color name="GM2_blue_700">#1967D2</color>
<color name="GM2_yellow_50">#FEF7E0</color>
<color name="GM2_yellow_500">#FFFBBC04</color>
<color name="GM2_green_500">#FF34A853</color>
<color name="GM2_blue_500">#FF4285F4</color>
<color name="GM2_orange_900">#B06000</color>
<color name="magnification_border_color">#FF9900</color>
<!-- controls -->
<color name="control_default_foreground">?android:attr/textColorPrimary</color>
<color name="control_default_background">?android:attr/colorBackgroundFloating</color>
</resources>

View File

@@ -1181,5 +1181,12 @@
<dimen name="magnifier_up_down_controls_width">45dp</dimen>
<dimen name="magnifier_up_down_controls_height">40dp</dimen>
<!-- Home Controls -->
<dimen name="control_spacing">5dp</dimen>
<dimen name="control_corner_radius">15dp</dimen>
<dimen name="control_height">100dp</dimen>
<dimen name="control_padding">15dp</dimen>
<dimen name="control_status_normal">12dp</dimen>
<dimen name="control_status_expanded">18dp</dimen>
<dimen name="app_icon_size">32dp</dimen>
</resources>

View File

@@ -2546,4 +2546,7 @@
<string name="magnification_window_title">Magnification Window</string>
<!-- Title for Magnification Controls Window [CHAR LIMIT=NONE] -->
<string name="magnification_controls_title">Magnification Window Controls</string>
<!-- Quick Controls strings [CHAR LIMIT=30] -->
<string name="quick_controls_title">Quick Controls</string>
</resources>

View File

@@ -0,0 +1,400 @@
/*
* Copyright (C) 2020 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.controls.ui
import android.content.Context
import android.graphics.drawable.ClipDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.Icon
import android.graphics.drawable.LayerDrawable
import android.service.controls.Control
import android.service.controls.DeviceTypes
import android.service.controls.actions.BooleanAction
import android.service.controls.actions.ControlAction
import android.service.controls.actions.FloatAction
import android.service.controls.templates.ControlTemplate
import android.service.controls.templates.RangeTemplate
import android.service.controls.templates.ToggleRangeTemplate
import android.service.controls.templates.ToggleTemplate
import android.util.TypedValue
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.R
private const val MIN_LEVEL = 0
private const val MAX_LEVEL = 10000
class ControlViewHolder(
val layout: ViewGroup,
val controlsController: ControlsController
) {
val icon: ImageView = layout.requireViewById(R.id.icon)
val status: TextView = layout.requireViewById(R.id.status)
val statusExtra: TextView = layout.requireViewById(R.id.status_extra)
val title: TextView = layout.requireViewById(R.id.title)
val subtitle: TextView = layout.requireViewById(R.id.subtitle)
val context: Context = layout.getContext()
val clipLayer: ClipDrawable
val gd: GradientDrawable
lateinit var cws: ControlWithState
init {
val ld = layout.getBackground() as LayerDrawable
ld.mutate()
clipLayer = ld.findDrawableByLayerId(R.id.clip_layer) as ClipDrawable
gd = clipLayer.getDrawable() as GradientDrawable
}
fun bindData(cws: ControlWithState) {
this.cws = cws
val (status, template) = cws.control?.let {
title.setText(it.getTitle())
subtitle.setText(it.getSubtitle())
Pair(it.getStatus(), it.getControlTemplate())
} ?: run {
title.setText(cws.ci.controlTitle)
subtitle.setText("")
Pair(Control.STATUS_UNKNOWN, ControlTemplate.NO_TEMPLATE)
}
findBehavior(status, template).apply(this, cws)
}
fun action(action: ControlAction) {
controlsController.action(cws.ci, action)
}
private fun findBehavior(status: Int, template: ControlTemplate): Behavior {
return when {
status == Control.STATUS_UNKNOWN -> UnknownBehavior()
template is ToggleTemplate -> ToggleTemplateBehavior()
template is ToggleRangeTemplate -> ToggleRangeTemplateBehavior()
else -> {
object : Behavior {
override fun apply(cvh: ControlViewHolder, cws: ControlWithState) {
cvh.status.setText(cws.control?.getStatusText())
cvh.applyRenderInfo(findRenderInfo(cws.ci.deviceType, false))
}
}
}
}
}
internal fun applyRenderInfo(ri: RenderInfo) {
val fg = context.getResources().getColorStateList(ri.foreground, context.getTheme())
val bg = context.getResources().getColorStateList(ri.background, context.getTheme())
status.setTextColor(fg)
statusExtra.setTextColor(fg)
icon.setImageIcon(Icon.createWithResource(context, ri.iconResourceId))
icon.setImageTintList(fg)
gd.setColor(bg)
}
fun setEnabled(enabled: Boolean) {
status.setEnabled(enabled)
icon.setEnabled(enabled)
}
}
private interface Behavior {
fun apply(cvh: ControlViewHolder, cws: ControlWithState)
fun findRenderInfo(deviceType: Int, isActive: Boolean): RenderInfo =
deviceRenderMap.getOrDefault(deviceType, unknownDeviceMap).getValue(isActive)
}
private class UnknownBehavior : Behavior {
override fun apply(cvh: ControlViewHolder, cws: ControlWithState) {
cvh.status.setText("Loading...")
cvh.applyRenderInfo(findRenderInfo(cws.ci.deviceType, false))
}
}
private class ToggleRangeTemplateBehavior : Behavior {
lateinit var clipLayer: Drawable
lateinit var template: ToggleRangeTemplate
lateinit var control: Control
lateinit var cvh: ControlViewHolder
lateinit var rangeTemplate: RangeTemplate
lateinit var statusExtra: TextView
lateinit var status: TextView
lateinit var context: Context
override fun apply(cvh: ControlViewHolder, cws: ControlWithState) {
this.control = cws.control!!
this.cvh = cvh
statusExtra = cvh.statusExtra
status = cvh.status
status.setText(control.getStatusText())
context = status.getContext()
cvh.layout.setOnTouchListener(ToggleRangeTouchListener())
val ld = cvh.layout.getBackground() as LayerDrawable
clipLayer = ld.findDrawableByLayerId(R.id.clip_layer)
template = control.getControlTemplate() as ToggleRangeTemplate
rangeTemplate = template.getRange()
val checked = template.isChecked()
val deviceType = control.getDeviceType()
updateRange((rangeTemplate.getCurrentValue() / 100.0f), checked)
cvh.setEnabled(checked)
cvh.applyRenderInfo(findRenderInfo(deviceType, checked))
}
fun toggle() {
cvh.action(BooleanAction(template.getTemplateId(), !template.isChecked()))
val nextLevel = if (template.isChecked()) MIN_LEVEL else MAX_LEVEL
clipLayer.setLevel(nextLevel)
}
fun beginUpdateRange() {
status.setVisibility(View.GONE)
statusExtra.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources()
.getDimensionPixelSize(R.dimen.control_status_expanded).toFloat())
}
fun updateRange(f: Float, checked: Boolean) {
clipLayer.setLevel(if (checked) (MAX_LEVEL * f).toInt() else MIN_LEVEL)
if (checked && f < 100.0f && f > 0.0f) {
statusExtra.setText("" + (f * 100.0).toInt() + "%")
statusExtra.setVisibility(View.VISIBLE)
} else {
statusExtra.setText("")
statusExtra.setVisibility(View.GONE)
}
}
fun endUpdateRange(f: Float) {
statusExtra.setText(" - " + (f * 100.0).toInt() + "%")
val newValue = rangeTemplate.getMinValue() +
(f * (rangeTemplate.getMaxValue() - rangeTemplate.getMinValue()))
statusExtra.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources()
.getDimensionPixelSize(R.dimen.control_status_normal).toFloat())
status.setVisibility(View.VISIBLE)
cvh.action(FloatAction(rangeTemplate.getTemplateId(), findNearestStep(newValue)))
}
fun findNearestStep(value: Float): Float {
var minDiff = 1000f
var f = rangeTemplate.getMinValue()
while (f <= rangeTemplate.getMaxValue()) {
val currentDiff = Math.abs(value - f)
if (currentDiff < minDiff) {
minDiff = currentDiff
} else {
return f - rangeTemplate.getStepValue()
}
f += rangeTemplate.getStepValue()
}
return rangeTemplate.getMaxValue()
}
inner class ToggleRangeTouchListener() : View.OnTouchListener {
private var initialTouchX: Float = 0.0f
private var initialTouchY: Float = 0.0f
private var isDragging: Boolean = false
private val minDragDiff = 20
override fun onTouch(v: View, e: MotionEvent): Boolean {
when (e.getActionMasked()) {
MotionEvent.ACTION_DOWN -> setupTouch(e)
MotionEvent.ACTION_MOVE -> detectDrag(v, e)
MotionEvent.ACTION_UP -> endTouch(v, e)
}
return true
}
private fun setupTouch(e: MotionEvent) {
initialTouchX = e.getX()
initialTouchY = e.getY()
}
private fun detectDrag(v: View, e: MotionEvent) {
val xDiff = Math.abs(e.getX() - initialTouchX)
val yDiff = Math.abs(e.getY() - initialTouchY)
if (xDiff < minDragDiff) {
isDragging = false
} else {
if (!isDragging) {
this@ToggleRangeTemplateBehavior.beginUpdateRange()
}
v.getParent().requestDisallowInterceptTouchEvent(true)
isDragging = true
if (yDiff > xDiff) {
endTouch(v, e)
} else {
val percent = Math.max(0.0f, Math.min(1.0f, e.getX() / v.getWidth()))
this@ToggleRangeTemplateBehavior.updateRange(percent, true)
}
}
}
private fun endTouch(v: View, e: MotionEvent) {
if (!isDragging) {
this@ToggleRangeTemplateBehavior.toggle()
} else {
val percent = Math.max(0.0f, Math.min(1.0f, e.getX() / v.getWidth()))
this@ToggleRangeTemplateBehavior.endUpdateRange(percent)
}
initialTouchX = 0.0f
initialTouchY = 0.0f
isDragging = false
}
}
}
private class ToggleTemplateBehavior : Behavior {
lateinit var clipLayer: Drawable
lateinit var template: ToggleTemplate
lateinit var control: Control
lateinit var cvh: ControlViewHolder
lateinit var context: Context
lateinit var status: TextView
override fun apply(cvh: ControlViewHolder, cws: ControlWithState) {
this.control = cws.control!!
this.cvh = cvh
status = cvh.status
status.setText(control.getStatusText())
cvh.layout.setOnClickListener(View.OnClickListener() { toggle() })
val ld = cvh.layout.getBackground() as LayerDrawable
clipLayer = ld.findDrawableByLayerId(R.id.clip_layer)
template = control.getControlTemplate() as ToggleTemplate
val checked = template.isChecked()
val deviceType = control.getDeviceType()
clipLayer.setLevel(if (checked) MAX_LEVEL else MIN_LEVEL)
cvh.setEnabled(checked)
cvh.applyRenderInfo(findRenderInfo(deviceType, checked))
}
fun toggle() {
cvh.action(BooleanAction(template.getTemplateId(), !template.isChecked()))
val nextLevel = if (template.isChecked()) MIN_LEVEL else MAX_LEVEL
clipLayer.setLevel(nextLevel)
}
}
internal data class RenderInfo(val iconResourceId: Int, val foreground: Int, val background: Int)
private val unknownDeviceMap = mapOf(
false to RenderInfo(
R.drawable.ic_light_off_gm2_24px,
R.color.unknown_foreground,
R.color.unknown_foreground),
true to RenderInfo(
R.drawable.ic_lightbulb_outline_gm2_24px,
R.color.unknown_foreground,
R.color.unknown_foreground)
)
private val deviceRenderMap = mapOf<Int, Map<Boolean, RenderInfo>>(
DeviceTypes.TYPE_UNKNOWN to unknownDeviceMap,
DeviceTypes.TYPE_LIGHT to mapOf(
false to RenderInfo(
R.drawable.ic_light_off_gm2_24px,
R.color.light_foreground,
R.color.light_background),
true to RenderInfo(
R.drawable.ic_lightbulb_outline_gm2_24px,
R.color.light_foreground,
R.color.light_background)
),
DeviceTypes.TYPE_THERMOSTAT to mapOf(
false to RenderInfo(
R.drawable.ic_device_thermostat_gm2_24px,
R.color.light_foreground,
R.color.light_background),
true to RenderInfo(
R.drawable.ic_device_thermostat_gm2_24px,
R.color.light_foreground,
R.color.light_background)
),
DeviceTypes.TYPE_CAMERA to mapOf(
false to RenderInfo(
R.drawable.ic_videocam_gm2_24px,
R.color.light_foreground,
R.color.light_background),
true to RenderInfo(
R.drawable.ic_videocam_gm2_24px,
R.color.light_foreground,
R.color.light_background)
),
DeviceTypes.TYPE_LOCK to mapOf(
false to RenderInfo(
R.drawable.ic_lock_open_gm2_24px,
R.color.lock_foreground,
R.color.lock_background),
true to RenderInfo(
R.drawable.ic_lock_gm2_24px,
R.color.lock_foreground,
R.color.lock_background)
),
DeviceTypes.TYPE_SWITCH to mapOf(
false to RenderInfo(
R.drawable.ic_switches_gm2_24px,
R.color.lock_foreground,
R.color.lock_background),
true to RenderInfo(
R.drawable.ic_switches_gm2_24px,
R.color.lock_foreground,
R.color.lock_background)
),
DeviceTypes.TYPE_OUTLET to mapOf(
false to RenderInfo(
R.drawable.ic_power_off_gm2_24px,
R.color.lock_foreground,
R.color.lock_background),
true to RenderInfo(
R.drawable.ic_power_gm2_24px,
R.color.lock_foreground,
R.color.lock_background)
)
)

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2020 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.controls.ui
import android.service.controls.Control
import com.android.systemui.controls.controller.ControlInfo
/**
* A container for:
* <ul>
* <li>ControlInfo - Basic cached info about a Control
* <li>Control - Actual Control parcelable received directly from
* the participating application
* </ul>
*/
data class ControlWithState(val ci: ControlInfo, val control: Control?)

View File

@@ -19,12 +19,15 @@ package com.android.systemui.controls.ui
import android.content.ComponentName
import android.service.controls.Control
import android.service.controls.actions.ControlAction
import android.view.ViewGroup
interface ControlsUiController {
fun show(parent: ViewGroup)
fun hide()
fun onRefreshState(componentName: ComponentName, controls: List<Control>)
fun onActionResponse(
componentName: ComponentName,
controlId: String,
@ControlAction.ResponseResult response: Int
)
}
}

View File

@@ -16,19 +16,204 @@
package com.android.systemui.controls.ui
import android.accounts.Account
import android.accounts.AccountManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.IBinder
import android.service.controls.Control
import android.service.controls.TokenProvider
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.controls.controller.ControlInfo
import com.android.systemui.controls.management.ControlsProviderSelectorActivity
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.R
import dagger.Lazy
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Singleton
private const val TAG = "ControlsUi"
// TEMP CODE for MOCK
private const val TOKEN = "https://www.googleapis.com/auth/assistant"
private const val SCOPE = "oauth2:" + TOKEN
private var tokenProviderConnection: TokenProviderConnection? = null
class TokenProviderConnection(val cc: ControlsController, val context: Context)
: ServiceConnection {
private var mTokenProvider: TokenProvider? = null
override fun onServiceConnected(cName: ComponentName, binder: IBinder) {
Thread({
Log.i(TAG, "TokenProviderConnection connected")
mTokenProvider = TokenProvider.Stub.asInterface(binder)
val mLastAccountName = mTokenProvider?.getAccountName()
if (mLastAccountName == null || mLastAccountName.isEmpty()) {
Log.e(TAG, "NO ACCOUNT IS SET. Open HomeMock app")
} else {
mTokenProvider?.setAuthToken(getAuthToken(mLastAccountName))
cc.subscribeToFavorites()
}
}, "TokenProviderThread").start()
}
override fun onServiceDisconnected(cName: ComponentName) {
mTokenProvider = null
}
fun getAuthToken(accountName: String): String? {
val am = AccountManager.get(context)
val accounts = am.getAccountsByType("com.google")
if (accounts == null || accounts.size == 0) {
Log.w(TAG, "No com.google accounts found")
return null
}
var account: Account? = null
for (a in accounts) {
if (a.name.equals(accountName)) {
account = a
break
}
}
if (account == null) {
account = accounts[0]
}
try {
return am.blockingGetAuthToken(account!!, SCOPE, true)
} catch (e: Throwable) {
Log.e(TAG, "Error getting auth token", e)
return null
}
}
}
@Singleton
class ControlsUiControllerImpl @Inject constructor() : ControlsUiController {
class ControlsUiControllerImpl @Inject constructor (
val controlsController: Lazy<ControlsController>,
val context: Context,
@Main val uiExecutor: Executor
) : ControlsUiController {
private lateinit var controlInfos: List<ControlInfo>
private val controlsById = mutableMapOf<Pair<ComponentName, String>, ControlWithState>()
private val controlViewsById = mutableMapOf<String, ControlViewHolder>()
private lateinit var parent: ViewGroup
override fun show(parent: ViewGroup) {
Log.d(TAG, "show()")
this.parent = parent
controlInfos = controlsController.get().getFavoriteControls()
controlInfos.map {
ControlWithState(it, null)
}.associateByTo(controlsById) { Pair(it.ci.component, it.ci.controlId) }
if (controlInfos.isEmpty()) {
showInitialSetupView()
} else {
showControlsView()
}
// Temp code to pass auth
tokenProviderConnection = TokenProviderConnection(controlsController.get(), context)
val serviceIntent = Intent()
serviceIntent.setComponent(ComponentName("com.android.systemui.home.mock",
"com.android.systemui.home.mock.AuthService"))
context.bindService(serviceIntent, tokenProviderConnection!!, Context.BIND_AUTO_CREATE)
}
private fun showInitialSetupView() {
val inflater = LayoutInflater.from(context)
inflater.inflate(R.layout.controls_no_favorites, parent, true)
val textView = parent.requireViewById(R.id.controls_title) as TextView
textView.setOnClickListener {
val i = Intent()
i.setComponent(ComponentName(context, ControlsProviderSelectorActivity::class.java))
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
context.startActivity(i)
}
}
private fun showControlsView() {
val inflater = LayoutInflater.from(context)
inflater.inflate(R.layout.controls_with_favorites, parent, true)
val listView = parent.requireViewById(R.id.global_actions_controls_list) as ViewGroup
var lastRow: ViewGroup = createRow(inflater, listView)
controlInfos.forEach {
Log.d(TAG, "favorited control id: " + it.controlId)
if (lastRow.getChildCount() == 2) {
lastRow = createRow(inflater, listView)
}
val item = inflater.inflate(
R.layout.controls_base_item, lastRow, false) as ViewGroup
lastRow.addView(item)
val cvh = ControlViewHolder(item, controlsController.get())
cvh.bindData(controlsById.get(Pair(it.component, it.controlId))!!)
controlViewsById.put(it.controlId, cvh)
}
val moreImageView = parent.requireViewById(R.id.controls_more) as View
moreImageView.setOnClickListener {
val i = Intent()
i.setComponent(ComponentName(context, ControlsProviderSelectorActivity::class.java))
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
context.startActivity(i)
}
}
override fun hide() {
Log.d(TAG, "hide()")
controlsController.get().unsubscribe()
context.unbindService(tokenProviderConnection)
tokenProviderConnection = null
parent.removeAllViews()
controlsById.clear()
controlViewsById.clear()
}
override fun onRefreshState(componentName: ComponentName, controls: List<Control>) {
TODO("not implemented")
Log.d(TAG, "onRefreshState()")
controls.forEach { c ->
controlsById.get(Pair(componentName, c.getControlId()))?.let {
Log.d(TAG, "onRefreshState() for id: " + c.getControlId())
val cws = ControlWithState(it.ci, c)
controlsById.put(Pair(componentName, c.getControlId()), cws)
uiExecutor.execute {
controlViewsById.get(c.getControlId())?.bindData(cws)
}
}
}
}
override fun onActionResponse(componentName: ComponentName, controlId: String, response: Int) {
Log.d(TAG, "onActionResponse()")
TODO("not implemented")
}
}
private fun createRow(inflater: LayoutInflater, parent: ViewGroup): ViewGroup {
val row = inflater.inflate(R.layout.controls_row, parent, false) as ViewGroup
parent.addView(row)
return row
}
}

View File

@@ -93,12 +93,13 @@ import com.android.systemui.MultiListLayout;
import com.android.systemui.MultiListLayout.MultiListAdapter;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.controls.ui.ControlsUiController;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
import com.android.systemui.plugins.GlobalActionsPanelPlugin;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
import com.android.systemui.statusbar.BlurUtils;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -183,6 +184,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
private final IStatusBarService mStatusBarService;
private final NotificationShadeWindowController mNotificationShadeWindowController;
private GlobalActionsPanelPlugin mPanelPlugin;
private ControlsUiController mControlsUiController;
/**
* @param context everything needs a context :(
@@ -200,7 +202,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
TelecomManager telecomManager, MetricsLogger metricsLogger,
BlurUtils blurUtils, SysuiColorExtractor colorExtractor,
IStatusBarService statusBarService,
NotificationShadeWindowController notificationShadeWindowController) {
NotificationShadeWindowController notificationShadeWindowController,
ControlsUiController controlsUiController) {
mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
mWindowManagerFuncs = windowManagerFuncs;
mAudioManager = audioManager;
@@ -220,6 +223,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
mSysuiColorExtractor = colorExtractor;
mStatusBarService = statusBarService;
mNotificationShadeWindowController = notificationShadeWindowController;
mControlsUiController = controlsUiController;
// receive broadcasts
IntentFilter filter = new IntentFilter();
@@ -455,9 +459,12 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
mKeyguardManager.isDeviceLocked())
: null;
boolean showControls = !mKeyguardManager.isDeviceLocked() && isControlsEnabled(mContext);
ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, panelViewController,
mBlurUtils, mSysuiColorExtractor, mStatusBarService,
mNotificationShadeWindowController, isControlsEnabled(mContext));
mNotificationShadeWindowController,
showControls ? mControlsUiController : null);
dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
dialog.setKeyguardShowing(mKeyguardShowing);
@@ -1543,13 +1550,15 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
private boolean mHadTopUi;
private final NotificationShadeWindowController mNotificationShadeWindowController;
private final BlurUtils mBlurUtils;
private final boolean mControlsEnabled;
private ControlsUiController mControlsUiController;
private ViewGroup mControlsView;
ActionsDialog(Context context, MyAdapter adapter,
GlobalActionsPanelPlugin.PanelViewController plugin, BlurUtils blurUtils,
SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService,
NotificationShadeWindowController notificationShadeWindowController,
boolean controlsEnabled) {
ControlsUiController controlsUiController) {
super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
mContext = context;
mAdapter = adapter;
@@ -1557,7 +1566,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
mColorExtractor = sysuiColorExtractor;
mStatusBarService = statusBarService;
mNotificationShadeWindowController = notificationShadeWindowController;
mControlsEnabled = controlsEnabled;
mControlsUiController = controlsUiController;
// Window initialization
Window window = getWindow();
@@ -1639,6 +1648,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
private void initializeLayout() {
setContentView(getGlobalActionsLayoutId(mContext));
fixNavBarClipping();
mControlsView = findViewById(com.android.systemui.R.id.global_actions_controls);
mGlobalActionsLayout = findViewById(com.android.systemui.R.id.global_actions_view);
mGlobalActionsLayout.setOutsideTouchListener(view -> dismiss());
((View) mGlobalActionsLayout.getParent()).setOnClickListener(view -> dismiss());
@@ -1674,7 +1684,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
private int getGlobalActionsLayoutId(Context context) {
if (mControlsEnabled) {
if (mControlsUiController != null) {
return com.android.systemui.R.layout.global_actions_grid_v2;
}
@@ -1758,6 +1768,9 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
mBlurUtils.radiusForRatio(animatedValue));
})
.start();
if (mControlsUiController != null) {
mControlsUiController.show(mControlsView);
}
}
@Override
@@ -1766,6 +1779,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
return;
}
mShowing = false;
if (mControlsUiController != null) mControlsUiController.hide();
mGlobalActionsLayout.setTranslationX(0);
mGlobalActionsLayout.setTranslationY(0);
mGlobalActionsLayout.setAlpha(1);