diff options
23 files changed, 882 insertions, 208 deletions
diff --git a/core/res/res/layout/lock_to_app_checkbox.xml b/core/res/res/layout/lock_to_app_checkbox.xml deleted file mode 100644 index 890507b..0000000 --- a/core/res/res/layout/lock_to_app_checkbox.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* //device/apps/common/res/layout/alert_dialog.xml -** -** Copyright 2014, 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. -*/ ---> -<FrameLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingTop="15dip" - android:paddingBottom="0dip" - android:paddingStart="12dip" - android:paddingEnd="25dip" - > - - <CheckBox - android:id="@+id/lock_to_app_checkbox" - style="?android:attr/textAppearanceMedium" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> - -</FrameLayout> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 9e25ee2..fe87919 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4856,16 +4856,6 @@ <string name="lock_to_app_toast_accessible">To unpin this screen, touch and hold Overview.</string> <!-- Notify user that they are locked in lock-to-app mode --> <string name="lock_to_app_toast_locked">Screen is pinned. Unpinning isn\'t allowed by your organization.</string> - <!-- Lock-to-app dialog title. --> - <string name="lock_to_app_title">Use screen pinning?</string> - <!-- Lock-to-app dialog description. --> - <string name="lock_to_app_description">Screen pinning locks the display in a single view.\n\nTo unpin, touch and hold Back and Overview at the same time.</string> - <!-- Lock-to-app dialog description when in accessibility mode. --> - <string name="lock_to_app_description_accessible">Screen pinning locks the display in a single view.\n\nTo unpin, touch and hold Overview.</string> - <!-- Lock-to-app negative response. --> - <string name="lock_to_app_negative">NO, THANKS</string> - <!-- Lock-to-app positive response. --> - <string name="lock_to_app_positive">START</string> <!-- Starting lock-to-app indication. --> <string name="lock_to_app_start">Screen pinned</string> <!-- Exting lock-to-app indication. --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 5ab4078..24c24f8 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -668,13 +668,6 @@ <java-symbol type="string" name="lock_to_app_toast" /> <java-symbol type="string" name="lock_to_app_toast_accessible" /> <java-symbol type="string" name="lock_to_app_toast_locked" /> - <java-symbol type="string" name="lock_to_app_title" /> - <java-symbol type="string" name="lock_to_app_description" /> - <java-symbol type="string" name="lock_to_app_description_accessible" /> - <java-symbol type="string" name="lock_to_app_negative" /> - <java-symbol type="string" name="lock_to_app_positive" /> - <java-symbol type="layout" name="lock_to_app_checkbox" /> - <java-symbol type="id" name="lock_to_app_checkbox" /> <java-symbol type="string" name="lock_to_app_start" /> <java-symbol type="string" name="lock_to_app_exit" /> <java-symbol type="string" name="lock_to_app_unlock_pin" /> diff --git a/packages/SystemUI/res/drawable/screen_pinning_bg_circ.xml b/packages/SystemUI/res/drawable/screen_pinning_bg_circ.xml new file mode 100644 index 0000000..354b8bd --- /dev/null +++ b/packages/SystemUI/res/drawable/screen_pinning_bg_circ.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* + * Copyright 2014, 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" + android:shape="oval" > + + <solid android:color="@color/system_accent_color" /> + + <size + android:height="@dimen/screen_pinning_nav_highlight_size" + android:width="@dimen/screen_pinning_nav_highlight_size" /> + +</shape> diff --git a/packages/SystemUI/res/drawable/screen_pinning_light_bg_circ.xml b/packages/SystemUI/res/drawable/screen_pinning_light_bg_circ.xml new file mode 100644 index 0000000..9e83057 --- /dev/null +++ b/packages/SystemUI/res/drawable/screen_pinning_light_bg_circ.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* + * Copyright 2014, 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" + android:shape="oval" > + + <solid android:color="@color/screen_pinning_nav_icon_highlight_outer" /> + + <size + android:height="@dimen/screen_pinning_nav_highlight_outer_size" + android:width="@dimen/screen_pinning_nav_highlight_outer_size" /> + +</shape> diff --git a/packages/SystemUI/res/layout/screen_pinning_request.xml b/packages/SystemUI/res/layout/screen_pinning_request.xml new file mode 100644 index 0000000..fea45cc --- /dev/null +++ b/packages/SystemUI/res/layout/screen_pinning_request.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2014, 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" + android:layout_width="@dimen/screen_pinning_request_width" + android:layout_height="wrap_content" + android:gravity="bottom|center_horizontal" + android:layoutDirection="ltr" + android:orientation="vertical" > + + <include + android:layout_width="@dimen/screen_pinning_request_width" + android:layout_height="wrap_content" + layout="@layout/screen_pinning_request_text_area" /> + + <View + android:id="@+id/spacer" + android:layout_width="@dimen/screen_pinning_request_width" + android:layout_height="18dp" + android:background="@color/screen_pinning_request_bg" /> + + <include + android:layout_width="@dimen/screen_pinning_request_width" + android:layout_height="wrap_content" + layout="@layout/screen_pinning_request_buttons" /> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml b/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml new file mode 100644 index 0000000..224a0a0 --- /dev/null +++ b/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2014, 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. + */ +--> +<!-- + This layout matches the structure of navigation_bar.xml and will need + to be kept up to sync with changes there. + On sw600dp, dimensions are changed to be large enough such that the + empty views between the buttons is reduced to nothing, if (nav bar) + sw600dp layout is changed then this will likely have to be adjusted + and possibly need a sw600dp specific one. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/screen_pinning_buttons" + android:layout_width="match_parent" + android:layout_height="@dimen/screen_pinning_request_button_height" + android:background="@color/screen_pinning_request_bg" > + + <View + android:layout_width="@dimen/screen_pinning_request_side_width" + android:layout_height="match_parent" + android:layout_weight="0" + android:visibility="invisible" /> + + <FrameLayout + android:id="@+id/screen_pinning_back_group" + android:layout_width="@dimen/screen_pinning_request_button_width" + android:layout_height="@dimen/screen_pinning_request_button_height" + android:layout_weight="0" + android:paddingStart="@dimen/screen_pinning_request_frame_padding" + android:paddingEnd="@dimen/screen_pinning_request_frame_padding" > + + <ImageView + android:id="@+id/screen_pinning_back_bg_light" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:scaleType="matrix" + android:src="@drawable/screen_pinning_light_bg_circ" /> + + <ImageView + android:id="@+id/screen_pinning_back_bg" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingEnd="@dimen/screen_pinning_request_inner_padding" + android:paddingStart="@dimen/screen_pinning_request_inner_padding" + android:paddingTop="@dimen/screen_pinning_request_inner_padding" + android:scaleType="matrix" + android:src="@drawable/screen_pinning_bg_circ" /> + + <ImageView + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingEnd="@dimen/screen_pinning_request_nav_side_padding" + android:paddingStart="@dimen/screen_pinning_request_nav_side_padding" + android:paddingTop="@dimen/screen_pinning_request_nav_icon_padding" + android:scaleType="center" + android:src="@drawable/ic_sysbar_back" /> + </FrameLayout> + + <View + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_weight="1" + android:visibility="invisible" /> + + <FrameLayout + android:id="@+id/screen_pinning_home_group" + android:layout_width="@dimen/screen_pinning_request_button_width" + android:layout_height="@dimen/screen_pinning_request_button_height" + android:layout_weight="0" + android:paddingStart="@dimen/screen_pinning_request_frame_padding" + android:paddingEnd="@dimen/screen_pinning_request_frame_padding" > + + <ImageView + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingEnd="@dimen/screen_pinning_request_nav_side_padding" + android:paddingStart="@dimen/screen_pinning_request_nav_side_padding" + android:paddingTop="@dimen/screen_pinning_request_nav_icon_padding" + android:scaleType="center" + android:src="@drawable/ic_sysbar_home" /> + </FrameLayout> + + <View + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_weight="1" + android:visibility="invisible" /> + + <FrameLayout + android:id="@+id/screen_pinning_recents_group" + android:layout_width="@dimen/screen_pinning_request_button_width" + android:layout_height="@dimen/screen_pinning_request_button_height" + android:layout_weight="0" + android:paddingStart="@dimen/screen_pinning_request_frame_padding" + android:paddingEnd="@dimen/screen_pinning_request_frame_padding" > + + <ImageView + android:layout_width="match_parent" + android:layout_height="match_parent" + android:scaleType="matrix" + android:src="@drawable/screen_pinning_light_bg_circ" /> + + <ImageView + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingEnd="@dimen/screen_pinning_request_inner_padding" + android:paddingStart="@dimen/screen_pinning_request_inner_padding" + android:paddingTop="@dimen/screen_pinning_request_inner_padding" + android:scaleType="matrix" + android:src="@drawable/screen_pinning_bg_circ" /> + + <ImageView + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingEnd="@dimen/screen_pinning_request_nav_side_padding" + android:paddingStart="@dimen/screen_pinning_request_nav_side_padding" + android:paddingTop="@dimen/screen_pinning_request_nav_icon_padding" + android:scaleType="center" + android:src="@drawable/ic_sysbar_recent" /> + </FrameLayout> + + <View + android:layout_width="@dimen/screen_pinning_request_side_width" + android:layout_height="match_parent" + android:layout_weight="0" + android:visibility="invisible" /> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout/screen_pinning_request_buttons_land.xml b/packages/SystemUI/res/layout/screen_pinning_request_buttons_land.xml new file mode 100644 index 0000000..1e5193f --- /dev/null +++ b/packages/SystemUI/res/layout/screen_pinning_request_buttons_land.xml @@ -0,0 +1,135 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2014, 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. + */ +--> +<!-- Note all width/height dimensions are switched here to handle landspace + rather than duplicating them all. + This layout matches the structure of navigation_bar.xml (rot90) and + will need to be kept up to sync with changes there. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/screen_pinning_buttons" + android:layout_height="match_parent" + android:layout_width="@dimen/screen_pinning_request_button_height" + android:background="@color/screen_pinning_request_bg" + android:orientation="vertical" > + + <View + android:layout_height="@dimen/screen_pinning_request_side_width" + android:layout_width="match_parent" + android:layout_weight="0" + android:visibility="invisible" /> + + <FrameLayout + android:id="@+id/screen_pinning_recents_group" + android:layout_height="@dimen/screen_pinning_request_button_width" + android:layout_width="@dimen/screen_pinning_request_button_height" + android:layout_weight="0" > + + <ImageView + android:layout_height="match_parent" + android:layout_width="match_parent" + android:scaleType="matrix" + android:src="@drawable/screen_pinning_light_bg_circ" /> + + <ImageView + android:layout_height="match_parent" + android:layout_width="match_parent" + android:scaleType="matrix" + android:paddingLeft="@dimen/screen_pinning_request_inner_padding" + android:paddingTop="@dimen/screen_pinning_request_inner_padding" + android:paddingBottom="@dimen/screen_pinning_request_inner_padding" + android:src="@drawable/screen_pinning_bg_circ" /> + + <ImageView + android:layout_height="match_parent" + android:layout_width="match_parent" + android:scaleType="center" + android:paddingLeft="@dimen/screen_pinning_request_nav_icon_padding" + android:paddingTop="@dimen/screen_pinning_request_nav_side_padding" + android:paddingBottom="@dimen/screen_pinning_request_nav_side_padding" + android:src="@drawable/ic_sysbar_recent" /> + </FrameLayout> + + <View + android:layout_height="match_parent" + android:layout_width="match_parent" + android:layout_weight="1" + android:visibility="invisible" /> + + <FrameLayout + android:id="@+id/screen_pinning_home_group" + android:layout_height="@dimen/screen_pinning_request_button_width" + android:layout_width="@dimen/screen_pinning_request_button_height" + android:layout_weight="0" > + + <ImageView + android:layout_height="match_parent" + android:layout_width="match_parent" + android:scaleType="center" + android:paddingLeft="@dimen/screen_pinning_request_nav_icon_padding" + android:paddingTop="@dimen/screen_pinning_request_nav_side_padding" + android:paddingBottom="@dimen/screen_pinning_request_nav_side_padding" + android:src="@drawable/ic_sysbar_home" /> + </FrameLayout> + + <View + android:layout_height="match_parent" + android:layout_width="match_parent" + android:layout_weight="1" + android:visibility="invisible" /> + + <FrameLayout + android:id="@+id/screen_pinning_back_group" + android:layout_height="@dimen/screen_pinning_request_button_width" + android:layout_width="@dimen/screen_pinning_request_button_height" + android:layout_weight="0" > + + <ImageView + android:id="@+id/screen_pinning_back_bg_light" + android:layout_height="match_parent" + android:layout_width="match_parent" + android:scaleType="matrix" + android:src="@drawable/screen_pinning_light_bg_circ" /> + + <ImageView + android:id="@+id/screen_pinning_back_bg" + android:layout_height="match_parent" + android:layout_width="match_parent" + android:scaleType="matrix" + android:paddingLeft="@dimen/screen_pinning_request_inner_padding" + android:paddingTop="@dimen/screen_pinning_request_inner_padding" + android:paddingBottom="@dimen/screen_pinning_request_inner_padding" + android:src="@drawable/screen_pinning_bg_circ" /> + + <ImageView + android:layout_height="match_parent" + android:layout_width="match_parent" + android:scaleType="center" + android:paddingLeft="@dimen/screen_pinning_request_nav_icon_padding" + android:paddingTop="@dimen/screen_pinning_request_nav_side_padding" + android:paddingBottom="@dimen/screen_pinning_request_nav_side_padding" + android:src="@drawable/ic_sysbar_back" /> + </FrameLayout> + + <View + android:layout_height="@dimen/screen_pinning_request_side_width" + android:layout_width="match_parent" + android:layout_weight="0" + android:visibility="invisible" /> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout/screen_pinning_request_land_phone.xml b/packages/SystemUI/res/layout/screen_pinning_request_land_phone.xml new file mode 100644 index 0000000..e6c22d4 --- /dev/null +++ b/packages/SystemUI/res/layout/screen_pinning_request_land_phone.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2014, 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" + android:layout_height="@dimen/screen_pinning_request_width" + android:layout_width="wrap_content" + android:gravity="right|center_vertical" + android:orientation="horizontal" > + + <include + android:layout_width="360dp" + android:layout_height="@dimen/screen_pinning_request_width" + layout="@layout/screen_pinning_request_text_area" /> + + <include + android:layout_width="wrap_content" + android:layout_height="@dimen/screen_pinning_request_width" + layout="@layout/screen_pinning_request_buttons_land" /> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout/screen_pinning_request_text_area.xml b/packages/SystemUI/res/layout/screen_pinning_request_text_area.xml new file mode 100644 index 0000000..df957f4 --- /dev/null +++ b/packages/SystemUI/res/layout/screen_pinning_request_text_area.xml @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2014, 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. + */ +--> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/screen_pinning_text_area" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="@color/screen_pinning_request_bg" + android:gravity="center_vertical" > + + <TextView + android:id="@+id/screen_pinning_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingEnd="48dp" + android:paddingStart="48dp" + android:paddingTop="43dp" + android:text="@string/screen_pinning_title" + android:textColor="@color/screen_pinning_primary_text" + android:textSize="24sp" /> + + <TextView + android:id="@+id/screen_pinning_description" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/screen_pinning_title" + android:paddingEnd="48dp" + android:paddingStart="48dp" + android:paddingTop="12.6dp" + android:text="@string/screen_pinning_description" + android:textColor="@color/screen_pinning_primary_text" + android:textSize="16sp" /> + + <Button + android:id="@+id/screen_pinning_ok_button" + style="@android:style/Widget.Material.Button" + android:layout_width="wrap_content" + android:layout_height="36dp" + android:layout_alignParentEnd="true" + android:layout_below="@+id/screen_pinning_description" + android:layout_marginEnd="40dp" + android:layout_marginTop="18dp" + android:background="@null" + android:paddingEnd="8dp" + android:paddingStart="8dp" + android:text="@string/screen_pinning_positive" + android:textColor="@android:color/white" + android:textSize="14sp" /> + + <Button + android:id="@+id/screen_pinning_cancel_button" + style="@android:style/Widget.Material.Button" + android:layout_width="wrap_content" + android:layout_height="36dp" + android:layout_alignTop="@id/screen_pinning_ok_button" + android:layout_marginEnd="4dp" + android:layout_toStartOf="@id/screen_pinning_ok_button" + android:background="@null" + android:paddingEnd="8dp" + android:paddingStart="8dp" + android:text="@string/screen_pinning_negative" + android:textColor="@android:color/white" + android:textSize="14sp" /> + +</RelativeLayout> diff --git a/packages/SystemUI/res/values-sw400dp/dimens.xml b/packages/SystemUI/res/values-sw400dp/dimens.xml index 80e82c4..f19335b 100644 --- a/packages/SystemUI/res/values-sw400dp/dimens.xml +++ b/packages/SystemUI/res/values-sw400dp/dimens.xml @@ -23,5 +23,13 @@ navigation_extra_key_width --> <dimen name="navigation_side_padding">50dp</dimen> + <!-- Screen pinning request padding on side of icons + (makes the width match the nav bar)--> + <dimen name="screen_pinning_request_nav_side_padding">7dp</dimen> + <!-- Screen pinning request side views to match nav bar + navigation_side_padding - 3 / 2 * (screen_pinning_request_button_width + - navigation_key_width) --> + <dimen name="screen_pinning_request_side_width">44dp</dimen> + </resources> diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml index 2c22cef..3a62ad9 100644 --- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml @@ -29,4 +29,15 @@ <dimen name="keyguard_clock_notifications_margin_max">36dp</dimen> <dimen name="keyguard_indication_margin_bottom">80dp</dimen> + + <!-- Screen pinning request width (just a little bit bigger than the three buttons here --> + <dimen name="screen_pinning_request_width">490dp</dimen> + <!-- Screen pinning request bottom button circle widths --> + <dimen name="screen_pinning_request_button_width">162dp</dimen> + <!-- Screen pinning request, controls padding on bigger screens, bigger nav bar --> + <dimen name="screen_pinning_request_frame_padding">39dp</dimen> + <!-- Screen pinning request side views to match nav bar + In sw600dp we want the buttons centered so this fills the space, + (screen_pinning_request_width - 3 * screen_pinning_request_button_width) / 2 --> + <dimen name="screen_pinning_request_side_width">2dp</dimen> </resources> diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml index d3b5580..195fdb1 100644 --- a/packages/SystemUI/res/values-sw600dp/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp/dimens.xml @@ -87,4 +87,15 @@ <!-- Margin on the right side of the system icon group on Keyguard. --> <dimen name="system_icons_keyguard_padding_end">2dp</dimen> + + <!-- Screen pinning request width --> + <dimen name="screen_pinning_request_width">400dp</dimen> + <!-- Screen pinning request bottom button circle widths --> + <dimen name="screen_pinning_request_button_width">128dp</dimen> + <!-- Screen pinning request, controls padding on bigger screens, bigger nav bar --> + <dimen name="screen_pinning_request_frame_padding">22dp</dimen> + <!-- Screen pinning request side views to match nav bar + In sw600dp we want the buttons centered so this fills the space, + (screen_pinning_request_width - 3 * screen_pinning_request_button_width) / 2 --> + <dimen name="screen_pinning_request_side_width">8dp</dimen> </resources> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index 82dccd2..ea9d3c3 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -123,4 +123,10 @@ <!-- Shadow color for the furthest pixels around the fake shadow for recents. --> <color name="fake_shadow_end_color">#03000000</color> + + <!-- 25% deep teal 200 --> + <color name="screen_pinning_nav_icon_highlight_outer">#4080cbc4</color> + <!-- deep teal 500 --> + <color name="screen_pinning_request_bg">#ff009688</color> + <color name="screen_pinning_request_window_bg">#80000000</color> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 51ef0c3..0edf60f 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -520,4 +520,29 @@ <!-- Padding for signal cluster and battery icon when there are not icons in signal cluster --> <dimen name="no_signal_cluster_battery_padding">3dp</dimen> + + <!-- Screen pinning request width --> + <dimen name="screen_pinning_request_width">@dimen/match_parent</dimen> + <!-- Screen pinning request nav button circle heights --> + <dimen name="screen_pinning_request_button_height">66dp</dimen> + <!-- Screen pinning request nav button circle widths --> + <dimen name="screen_pinning_request_button_width">84dp</dimen> + <!-- Screen pinning request padding on top of inner circle --> + <dimen name="screen_pinning_request_inner_padding">14dp</dimen> + <!-- Screen pinning request padding on top of icons --> + <dimen name="screen_pinning_request_nav_icon_padding">18dp</dimen> + <!-- Screen pinning request padding on side of icons + (makes the width match the nav bar)--> + <dimen name="screen_pinning_request_nav_side_padding">7dp</dimen> + <!-- Screen pinning request side views to match nav bar + navigation_side_padding - 3 / 2 * (screen_pinning_request_button_width + - navigation_key_width) --> + <dimen name="screen_pinning_request_side_width">34dp</dimen> + <!-- Screen pinning request controls padding on bigger screens --> + <dimen name="screen_pinning_request_frame_padding">0dp</dimen> + <!-- Screen pinning inner nav bar circle size --> + <dimen name="screen_pinning_nav_highlight_size">56dp</dimen> + <!-- Screen pinning inner nav bar outer circle size --> + <dimen name="screen_pinning_nav_highlight_outer_size">84dp</dimen> + </resources> diff --git a/packages/SystemUI/res/values/internal.xml b/packages/SystemUI/res/values/internal.xml index 3b593d2..67685ee 100644 --- a/packages/SystemUI/res/values/internal.xml +++ b/packages/SystemUI/res/values/internal.xml @@ -17,5 +17,6 @@ <resources> <dimen name="status_bar_height">@*android:dimen/status_bar_height</dimen> <dimen name="navigation_bar_height">@*android:dimen/navigation_bar_height</dimen> + <color name="screen_pinning_primary_text">@*android:color/primary_text_default_material_light</color> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 7a0d655..d70f4e3 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -899,4 +899,16 @@ <!-- Accessibility string for current zen mode and selected exit condition. A template that simply concatenates existing mode string and the current condition description. [CHAR LIMIT=20] --> <string name="zen_mode_and_condition"><xliff:g id="zen_mode" example="Priority interruptions only">%1$s</xliff:g>. <xliff:g id="exit_condition" example="For one hour">%2$s</xliff:g></string> + + <!-- Screen pinning dialog title. --> + <string name="screen_pinning_title">Screen is pinned</string> + <!-- Screen pinning dialog description. --> + <string name="screen_pinning_description">This keeps it in view until you unpin. Touch and hold Back and Overview at the same time to unpin.</string> + <!-- Screen pinning dialog description when in accessibility mode. --> + <string name="screen_pinning_description_accessible">This keeps it in view until you unpin. Touch and hold Overview to unpin.</string> + <!-- Screen pinning positive response. --> + <string name="screen_pinning_positive">Got it</string> + <!-- Screen pinning negative response. --> + <string name="screen_pinning_negative">No thanks</string> + </resources> diff --git a/packages/SystemUI/src/com/android/systemui/recent/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recent/ScreenPinningRequest.java new file mode 100644 index 0000000..9e5c2c8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recent/ScreenPinningRequest.java @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2014 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.recent; + +import android.animation.ArgbEvaluator; +import android.animation.ValueAnimator; +import android.app.ActivityManager; +import android.app.ActivityManagerNative; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.res.Configuration; +import android.graphics.PixelFormat; +import android.graphics.drawable.ColorDrawable; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.accessibility.AccessibilityManager; +import android.view.animation.DecelerateInterpolator; +import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.android.systemui.R; +import com.android.systemui.recents.model.RecentsTaskLoader; + +import java.util.ArrayList; + +public class ScreenPinningRequest implements View.OnClickListener { + private final Context mContext; + + private final AccessibilityManager mAccessibilityService; + private final WindowManager mWindowManager; + + private RequestWindowView mRequestWindow; + + public ScreenPinningRequest(Context context) { + mContext = context; + mAccessibilityService = (AccessibilityManager) + mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); + mWindowManager = (WindowManager) + mContext.getSystemService(Context.WINDOW_SERVICE); + } + + public void clearPrompt() { + if (mRequestWindow != null) { + mWindowManager.removeView(mRequestWindow); + mRequestWindow = null; + } + } + + public void showPrompt(boolean allowCancel) { + clearPrompt(); + + mRequestWindow = new RequestWindowView(mContext, allowCancel); + + mRequestWindow.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE); + + // show the confirmation + WindowManager.LayoutParams lp = getWindowLayoutParams(); + mWindowManager.addView(mRequestWindow, lp); + } + + public void onConfigurationChanged() { + if (mRequestWindow != null) { + mRequestWindow.onConfigurationChanged(); + } + } + + private WindowManager.LayoutParams getWindowLayoutParams() { + final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, + 0 + | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED + , + PixelFormat.TRANSLUCENT); + lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; + lp.setTitle("ScreenPinningConfirmation"); + lp.gravity = Gravity.FILL; + return lp; + } + + @Override + public void onClick(View v) { + if (v.getId() == R.id.screen_pinning_ok_button || mRequestWindow == v) { + try { + ActivityManagerNative.getDefault().startLockTaskModeOnCurrent(); + } catch (RemoteException e) {} + } + clearPrompt(); + } + + public FrameLayout.LayoutParams getRequestLayoutParams(boolean isLandscape) { + return new FrameLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT, + isLandscape ? (Gravity.CENTER_VERTICAL | Gravity.RIGHT) + : (Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM)); + } + + private class RequestWindowView extends FrameLayout { + private static final int OFFSET_DP = 96; + + private final ColorDrawable mColor = new ColorDrawable(0); + private ValueAnimator mColorAnim; + private ViewGroup mLayout; + private boolean mShowCancel; + + public RequestWindowView(Context context, boolean showCancel) { + super(context); + setClickable(true); + setOnClickListener(ScreenPinningRequest.this); + setBackground(mColor); + mShowCancel = showCancel; + } + + @Override + public void onAttachedToWindow() { + DisplayMetrics metrics = new DisplayMetrics(); + mWindowManager.getDefaultDisplay().getMetrics(metrics); + float density = metrics.density; + boolean isLandscape = isLandscapePhone(mContext); + + inflateView(isLandscape); + int bgColor = mContext.getResources().getColor( + R.color.screen_pinning_request_window_bg); + if (ActivityManager.isHighEndGfx()) { + mLayout.setAlpha(0f); + if (isLandscape) { + mLayout.setTranslationX(OFFSET_DP * density); + } else { + mLayout.setTranslationY(OFFSET_DP * density); + } + mLayout.animate() + .alpha(1f) + .translationX(0) + .translationY(0) + .setDuration(300) + .setInterpolator(new DecelerateInterpolator()) + .start(); + + mColorAnim = ValueAnimator.ofObject(new ArgbEvaluator(), 0, bgColor); + mColorAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + final int c = (Integer) animation.getAnimatedValue(); + mColor.setColor(c); + } + }); + mColorAnim.setDuration(1000); + mColorAnim.start(); + } else { + mColor.setColor(bgColor); + } + + IntentFilter filter = new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED); + filter.addAction(Intent.ACTION_USER_SWITCHED); + filter.addAction(Intent.ACTION_SCREEN_OFF); + mContext.registerReceiver(mReceiver, filter); + } + + private boolean isLandscapePhone(Context context) { + Configuration config = mContext.getResources().getConfiguration(); + return config.orientation == Configuration.ORIENTATION_LANDSCAPE + && config.smallestScreenWidthDp < 600; + } + + private void inflateView(boolean isLandscape) { + // We only want this landscape orientation on <600dp, so rather than handle + // resource overlay for -land and -sw600dp-land, just inflate this + // other view for this single case. + mLayout = (ViewGroup) View.inflate(getContext(), isLandscape + ? R.layout.screen_pinning_request_land_phone : R.layout.screen_pinning_request, + null); + // Catch touches so they don't trigger cancel/activate, like outside does. + mLayout.setClickable(true); + // Status bar is always on the right. + mLayout.setLayoutDirection(View.LAYOUT_DIRECTION_LTR); + // Buttons and text do switch sides though. + View buttons = mLayout.findViewById(R.id.screen_pinning_buttons); + buttons.setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE); + mLayout.findViewById(R.id.screen_pinning_text_area) + .setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE); + swapChildrenIfRtlAndVertical(buttons); + + ((Button) mLayout.findViewById(R.id.screen_pinning_ok_button)) + .setOnClickListener(ScreenPinningRequest.this); + if (mShowCancel) { + ((Button) mLayout.findViewById(R.id.screen_pinning_cancel_button)) + .setOnClickListener(ScreenPinningRequest.this); + } else { + ((Button) mLayout.findViewById(R.id.screen_pinning_cancel_button)) + .setVisibility(View.INVISIBLE); + } + + final int description = mAccessibilityService.isEnabled() + ? R.string.screen_pinning_description_accessible + : R.string.screen_pinning_description; + ((TextView) mLayout.findViewById(R.id.screen_pinning_description)) + .setText(description); + final int backBgVisibility = + mAccessibilityService.isEnabled() ? View.INVISIBLE : View.VISIBLE; + mLayout.findViewById(R.id.screen_pinning_back_bg).setVisibility(backBgVisibility); + mLayout.findViewById(R.id.screen_pinning_back_bg_light).setVisibility(backBgVisibility); + + addView(mLayout, getRequestLayoutParams(isLandscape)); + } + + private void swapChildrenIfRtlAndVertical(View group) { + if (mContext.getResources().getConfiguration().getLayoutDirection() + != View.LAYOUT_DIRECTION_RTL) { + return; + } + LinearLayout linearLayout = (LinearLayout) group; + if (linearLayout.getOrientation() == LinearLayout.VERTICAL) { + int childCount = linearLayout.getChildCount(); + ArrayList<View> childList = new ArrayList<>(childCount); + for (int i = 0; i < childCount; i++) { + childList.add(linearLayout.getChildAt(i)); + } + linearLayout.removeAllViews(); + for (int i = childCount - 1; i >= 0; i--) { + linearLayout.addView(childList.get(i)); + } + } + } + + @Override + public void onDetachedFromWindow() { + mContext.unregisterReceiver(mReceiver); + } + + protected void onConfigurationChanged() { + removeAllViews(); + inflateView(isLandscapePhone(mContext)); + } + + private final Runnable mUpdateLayoutRunnable = new Runnable() { + @Override + public void run() { + if (mLayout != null && mLayout.getParent() != null) { + mLayout.setLayoutParams(getRequestLayoutParams(isLandscapePhone(mContext))); + } + } + }; + + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(Intent.ACTION_CONFIGURATION_CHANGED)) { + post(mUpdateLayoutRunnable); + } else if (intent.getAction().equals(Intent.ACTION_USER_SWITCHED) + || intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { + clearPrompt(); + } + } + }; + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index f8d981f..de95ae8 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -37,6 +37,7 @@ import android.view.KeyEvent; import android.view.View; import android.view.ViewStub; import android.widget.Toast; + import com.android.systemui.R; import com.android.systemui.recents.misc.DebugTrigger; import com.android.systemui.recents.misc.ReferenceCountedTrigger; @@ -50,6 +51,8 @@ import com.android.systemui.recents.views.DebugOverlayView; import com.android.systemui.recents.views.RecentsView; import com.android.systemui.recents.views.SystemBarScrimViews; import com.android.systemui.recents.views.ViewAnimation; +import com.android.systemui.statusbar.phone.PhoneStatusBar; +import com.android.systemui.SystemUIApplication; import java.lang.ref.WeakReference; import java.lang.reflect.InvocationTargetException; @@ -82,6 +85,8 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView // Runnables to finish the Recents activity FinishRecentsRunnable mFinishLaunchHomeRunnable; + private PhoneStatusBar mStatusBar; + /** * A common Runnable to finish Recents either by calling finish() (with a custom animation) or * launching Home with some ActivityOptions. Generally we always launch home when we exit @@ -430,6 +435,9 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView } }); } + + mStatusBar = ((SystemUIApplication) getApplication()) + .getComponent(PhoneStatusBar.class); } /** Inflates the debug overlay if debug mode is enabled. */ @@ -631,6 +639,13 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView mFinishLaunchHomeRunnable.run(); } + @Override + public void onScreenPinningRequest() { + if (mStatusBar != null) { + mStatusBar.showScreenPinningRequest(false); + } + } + /**** RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks Implementation ****/ @Override diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java index 646d701..51b3fb5 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -495,17 +495,6 @@ public class SystemServicesProxy { } /** - * Locks the current task. - */ - public void lockCurrentTask() { - if (mIam == null) return; - - try { - mIam.startLockTaskModeOnCurrent(); - } catch (RemoteException e) {} - } - - /** * Takes a screenshot of the current surface. */ public Bitmap takeScreenshot() { diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index 81ee839..6093584 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -31,6 +31,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.WindowInsets; import android.widget.FrameLayout; + import com.android.systemui.recents.Constants; import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.misc.SystemServicesProxy; @@ -54,6 +55,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV public void onTaskLaunchFailed(); public void onAllTaskViewsDismissed(); public void onExitToHomeAnimationTriggered(); + public void onScreenPinningRequest(); } RecentsConfiguration mConfig; @@ -461,7 +463,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV postDelayed(new Runnable() { @Override public void run() { - ssp.lockCurrentTask(); + mCb.onScreenPinningRequest(); } }, 350); mTriggered = true; @@ -485,7 +487,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV if (ssp.startActivityFromRecents(getContext(), task.key.id, task.activityLabel, launchOpts)) { if (launchOpts == null && lockToTask) { - ssp.lockCurrentTask(); + mCb.onScreenPinningRequest(); } } else { // Dismiss the task and return the user to home if we fail to diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 1485bde..820aadf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -123,6 +123,7 @@ import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.qs.QSPanel; +import com.android.systemui.recent.ScreenPinningRequest; import com.android.systemui.statusbar.ActivatableNotificationView; import com.android.systemui.statusbar.BackDropView; import com.android.systemui.statusbar.BaseStatusBar; @@ -356,6 +357,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, ? new GestureRecorder("/sdcard/statusbar_gestures.dat") : null; + private ScreenPinningRequest mScreenPinningRequest; + private int mNavigationIconHints = 0; // ensure quick settings is disabled until the current user makes it through the setup wizard @@ -597,6 +600,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, setControllerUsers(); notifyUserAboutHiddenNotifications(); + + mScreenPinningRequest = new ScreenPinningRequest(mContext); } // ================================================================================ @@ -3144,6 +3149,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, updateExpandedViewPos(EXPANDED_LEAVE_ALONE); updateShowSearchHoldoff(); updateRowStates(); + mScreenPinningRequest.onConfigurationChanged(); } @Override @@ -4038,7 +4044,16 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, @Override public void showScreenPinningRequest() { - // TODO: Show request. + if (mKeyguardMonitor.isShowing()) { + // Don't allow apps to trigger this from keyguard. + return; + } + // Show screen pinning request, since this comes from an app, show 'no thanks', button. + showScreenPinningRequest(true); + } + + public void showScreenPinningRequest(boolean allowCancel) { + mScreenPinningRequest.showPrompt(allowCancel); } public boolean hasActiveNotifications() { diff --git a/services/core/java/com/android/server/am/LockToAppRequestDialog.java b/services/core/java/com/android/server/am/LockToAppRequestDialog.java deleted file mode 100644 index 739fd0a..0000000 --- a/services/core/java/com/android/server/am/LockToAppRequestDialog.java +++ /dev/null @@ -1,141 +0,0 @@ - -package com.android.server.am; - -import android.app.AlertDialog; -import android.app.admin.DevicePolicyManager; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.res.Resources; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.provider.Settings; -import android.provider.Settings.SettingNotFoundException; -import android.util.Slog; -import android.view.WindowManager; -import android.view.accessibility.AccessibilityManager; -import android.widget.CheckBox; - -import com.android.internal.R; -import com.android.internal.widget.ILockSettings; -import com.android.internal.widget.LockPatternUtils; -import com.android.internal.widget.LockPatternUtilsCache; - -public class LockToAppRequestDialog implements OnClickListener { - private static final String TAG = "ActivityManager"; - - final private Context mContext; - final private ActivityManagerService mService; - - private AlertDialog mDialog; - private TaskRecord mRequestedTask; - - private CheckBox mCheckbox; - - private ILockSettings mLockSettingsService; - - private AccessibilityManager mAccessibilityService; - - public LockToAppRequestDialog(Context context, ActivityManagerService activityManagerService) { - mContext = context; - mAccessibilityService = (AccessibilityManager) - mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); - mService = activityManagerService; - } - - private ILockSettings getLockSettings() { - if (mLockSettingsService == null) { - mLockSettingsService = LockPatternUtilsCache.getInstance( - ILockSettings.Stub.asInterface(ServiceManager.getService("lock_settings"))); - } - return mLockSettingsService; - } - - private int getLockString(int userId) { - try { - int quality = (int) getLockSettings().getLong(LockPatternUtils.PASSWORD_TYPE_KEY, - DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId); - switch (quality) { - case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: - case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: - return R.string.lock_to_app_unlock_pin; - case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC: - case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: - case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: - return R.string.lock_to_app_unlock_password; - case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: - if (getLockSettings().getBoolean(Settings.Secure.LOCK_PATTERN_ENABLED, false, - userId)) { - return R.string.lock_to_app_unlock_pattern; - } - } - } catch (RemoteException e) { - } - return 0; - } - - public void clearPrompt() { - if (mDialog != null) { - mDialog.dismiss(); - mDialog = null; - } - } - - public void showLockTaskPrompt(TaskRecord task) { - clearPrompt(); - mRequestedTask = task; - final int unlockStringId = getLockString(task.userId); - - final Resources r = Resources.getSystem(); - final String description= r.getString(mAccessibilityService.isEnabled() - ? R.string.lock_to_app_description_accessible - : R.string.lock_to_app_description); - AlertDialog.Builder builder = new AlertDialog.Builder(mContext) - .setTitle(r.getString(R.string.lock_to_app_title)) - .setMessage(description) - .setPositiveButton(r.getString(R.string.lock_to_app_positive), this) - .setNegativeButton(r.getString(R.string.lock_to_app_negative), this); - if (unlockStringId != 0) { - builder.setView(R.layout.lock_to_app_checkbox); - } - mDialog = builder.create(); - - mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); - mDialog.getWindow().getAttributes().privateFlags |= - WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; - mDialog.show(); - - if (unlockStringId != 0) { - String unlockString = mContext.getString(unlockStringId); - mCheckbox = (CheckBox) mDialog.findViewById(R.id.lock_to_app_checkbox); - mCheckbox.setText(unlockString); - - // Remember state. - try { - boolean useLock = Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0; - mCheckbox.setChecked(useLock); - } catch (SettingNotFoundException e) { - } - } else { - mCheckbox = null; - } - } - - @Override - public void onClick(DialogInterface dialog, int which) { - if (DialogInterface.BUTTON_POSITIVE == which) { - Slog.d(TAG, "accept lock-to-app request"); - // Set whether to use the lock screen when exiting. - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, - mCheckbox != null && mCheckbox.isChecked() ? 1 : 0); - - // Start lock-to-app. - mService.startLockTaskMode(mRequestedTask); - } else { - Slog.d(TAG, "ignore lock-to-app request"); - } - } - -} |
