Port recent apps from tablet to phone
- wire up to long press on home - remove unused recents activity - remove duplicate recents resources in -large directories (using -sw600dp instead) - fix issue with zoom/scale translation when recents was brought up Change-Id: I45538ccaff49b46ac3659c4828f9e2b0cd075241
@@ -35,5 +35,6 @@ oneway interface IStatusBar
|
||||
void setImeWindowStatus(in IBinder token, int vis, int backDisposition);
|
||||
void setHardKeyboardStatus(boolean available, boolean enabled);
|
||||
void userActivity();
|
||||
void toggleRecentApps();
|
||||
}
|
||||
|
||||
|
||||
@@ -47,4 +47,5 @@ interface IStatusBarService
|
||||
void setSystemUiVisibility(int vis);
|
||||
void setHardKeyboardEnabled(boolean enabled);
|
||||
void userActivity();
|
||||
void toggleRecentApps();
|
||||
}
|
||||
|
||||
@@ -389,9 +389,11 @@
|
||||
<!-- Control the behavior when the user long presses the power button.
|
||||
0 - Nothing
|
||||
1 - Recent apps dialog
|
||||
2 - Recent apps activity in SystemUI
|
||||
2 - Recent apps view in SystemUI
|
||||
This needs to match the constants in
|
||||
policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
|
||||
-->
|
||||
<integer name="config_longPressOnHomeBehavior">1</integer>
|
||||
<integer name="config_longPressOnHomeBehavior">2</integer>
|
||||
|
||||
<!-- Array of light sensor LUX values to define our levels for auto backlight brightness support.
|
||||
The N entries of this array define N + 1 zones as follows:
|
||||
|
||||
@@ -33,13 +33,6 @@
|
||||
android:excludeFromRecents="true">
|
||||
</activity>
|
||||
|
||||
<activity android:name=".recent.RecentApplicationsActivity"
|
||||
android:theme="@android:style/Theme.NoTitleBar"
|
||||
android:excludeFromRecents="true"
|
||||
android:launchMode="singleInstance"
|
||||
android:exported="true">
|
||||
</activity>
|
||||
|
||||
<!-- started from UsbDeviceSettingsManager -->
|
||||
<activity android:name=".usb.UsbConfirmActivity"
|
||||
android:exported="true"
|
||||
|
||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 114 B |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
@@ -39,8 +39,8 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@id/app_thumbnail"
|
||||
android:layout_alignTop="@id/app_thumbnail"
|
||||
android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_border_width"
|
||||
android:layout_marginTop="@dimen/status_bar_recents_thumbnail_border_height"
|
||||
android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
|
||||
android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
|
||||
android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width"
|
||||
android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height"
|
||||
android:adjustViewBounds="true"
|
||||
@@ -56,7 +56,7 @@
|
||||
android:layout_alignLeft="@id/app_thumbnail"
|
||||
android:layout_below="@id/app_thumbnail"
|
||||
android:layout_marginTop="@dimen/status_bar_recents_text_description_padding"
|
||||
android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_border_width"
|
||||
android:layout_marginLeft="@dimen/recents_thumbnail_bg_padding_left"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="marquee"
|
||||
/>
|
||||
@@ -71,7 +71,7 @@
|
||||
android:layout_alignLeft="@id/app_thumbnail"
|
||||
android:layout_below="@id/app_label"
|
||||
android:layout_marginTop="@dimen/status_bar_recents_text_description_padding"
|
||||
android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_border_width"
|
||||
android:layout_marginLeft="@dimen/recents_thumbnail_bg_padding_left"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="marquee"
|
||||
/>
|
||||
|
||||
@@ -27,10 +27,9 @@
|
||||
<FrameLayout
|
||||
android:id="@+id/recents_bg_protect"
|
||||
android:background="@drawable/recents_bg_protect_tile"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:paddingBottom="@*android:dimen/status_bar_height"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false">
|
||||
|
||||
@@ -36,53 +36,52 @@
|
||||
<ImageView android:id="@+id/app_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginLeft="131dip"
|
||||
android:layout_marginTop="13dip"
|
||||
android:layout_alignLeft="@id/app_thumbnail"
|
||||
android:layout_alignTop="@id/app_thumbnail"
|
||||
android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
|
||||
android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
|
||||
android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width"
|
||||
android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height"
|
||||
android:adjustViewBounds="true"
|
||||
/>
|
||||
|
||||
<View android:id="@+id/recents_callout_line"
|
||||
android:layout_width="97dip"
|
||||
android:layout_height="1dip"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginTop="61dip"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_toLeftOf="@id/app_thumbnail"
|
||||
android:layout_marginRight="3dip"
|
||||
android:background="@drawable/recents_callout_line"
|
||||
/>
|
||||
|
||||
<TextView android:id="@+id/app_label"
|
||||
android:layout_width="97dip"
|
||||
android:layout_width="@dimen/status_bar_recents_app_label_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/status_bar_recents_app_description_text_size"
|
||||
android:textSize="@dimen/status_bar_recents_app_label_text_size"
|
||||
android:fadingEdge="horizontal"
|
||||
android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
|
||||
android:scrollHorizontally="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_marginTop="32dip"
|
||||
android:layout_alignTop="@id/app_icon"
|
||||
android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="marquee"
|
||||
/>
|
||||
|
||||
<View android:id="@+id/recents_callout_line"
|
||||
android:layout_width="@dimen/status_bar_recents_app_label_width"
|
||||
android:layout_height="1dip"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
|
||||
android:layout_toLeftOf="@id/app_thumbnail"
|
||||
android:layout_below="@id/app_label"
|
||||
android:layout_marginRight="3dip"
|
||||
android:layout_marginTop="3dip"
|
||||
android:background="@drawable/recents_callout_line"
|
||||
/>
|
||||
|
||||
<TextView android:id="@+id/app_description"
|
||||
android:layout_width="97dip"
|
||||
android:layout_width="@dimen/status_bar_recents_app_label_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/status_bar_recents_app_description_text_size"
|
||||
android:fadingEdge="horizontal"
|
||||
android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
|
||||
android:scrollHorizontally="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_marginTop="61dip"
|
||||
android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
|
||||
android:layout_below="@id/recents_callout_line"
|
||||
android:layout_marginTop="3dip"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="marquee"
|
||||
/>
|
||||
@@ -22,12 +22,12 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/recents_root"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="wrap_content">
|
||||
android:layout_width="match_parent">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/recents_bg_protect"
|
||||
android:background="@drawable/recents_bg_protect_tile"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:paddingBottom="@*android:dimen/status_bar_height"
|
||||
@@ -35,9 +35,9 @@
|
||||
android:clipChildren="false">
|
||||
|
||||
<LinearLayout android:id="@+id/recents_glow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="-49dip"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@drawable/recents_blue_glow"
|
||||
android:orientation="horizontal"
|
||||
@@ -47,7 +47,7 @@
|
||||
<com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container"
|
||||
android:layout_width="@dimen/status_bar_recents_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/status_bar_recents_right_glow_margin"
|
||||
android:layout_marginRight="0dp"
|
||||
android:divider="@null"
|
||||
android:stackFromBottom="true"
|
||||
android:fadingEdge="vertical"
|
||||
@@ -36,53 +36,53 @@
|
||||
<ImageView android:id="@+id/app_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginLeft="131dip"
|
||||
android:layout_marginTop="13dip"
|
||||
android:layout_alignLeft="@id/app_thumbnail"
|
||||
android:layout_alignTop="@id/app_thumbnail"
|
||||
android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
|
||||
android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
|
||||
android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width"
|
||||
android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height"
|
||||
android:adjustViewBounds="true"
|
||||
/>
|
||||
|
||||
<View android:id="@+id/recents_callout_line"
|
||||
android:layout_width="97dip"
|
||||
android:layout_height="1dip"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginTop="61dip"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_toLeftOf="@id/app_thumbnail"
|
||||
android:layout_marginRight="3dip"
|
||||
android:background="@drawable/recents_callout_line"
|
||||
/>
|
||||
|
||||
<TextView android:id="@+id/app_label"
|
||||
android:layout_width="97dip"
|
||||
android:layout_width="@dimen/status_bar_recents_app_label_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/status_bar_recents_app_description_text_size"
|
||||
android:textSize="@dimen/status_bar_recents_app_label_text_size"
|
||||
android:fadingEdge="horizontal"
|
||||
android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
|
||||
android:scrollHorizontally="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
|
||||
android:layout_marginTop="32dip"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="marquee"
|
||||
/>
|
||||
|
||||
<View android:id="@+id/recents_callout_line"
|
||||
android:layout_width="@dimen/status_bar_recents_app_label_width"
|
||||
android:layout_height="1dip"
|
||||
android:layout_below="@id/app_label"
|
||||
android:layout_marginTop="3dip"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
|
||||
android:layout_toLeftOf="@id/app_thumbnail"
|
||||
android:layout_marginRight="3dip"
|
||||
android:background="@drawable/recents_callout_line"
|
||||
/>
|
||||
|
||||
<TextView android:id="@+id/app_description"
|
||||
android:layout_width="97dip"
|
||||
android:layout_width="@dimen/status_bar_recents_app_label_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/status_bar_recents_app_description_text_size"
|
||||
android:fadingEdge="horizontal"
|
||||
android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
|
||||
android:scrollHorizontally="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_marginTop="61dip"
|
||||
android:layout_below="@id/recents_callout_line"
|
||||
android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
|
||||
android:layout_marginTop="3dip"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="marquee"
|
||||
/>
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2008, 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="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Title -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="#80FFFFFF"
|
||||
android:textStyle="bold"
|
||||
android:singleLine="true"
|
||||
android:text="@string/recent_tasks_title"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<!-- This is only intended to be visible when carousel is invisible -->
|
||||
<TextView
|
||||
android:id="@+id/no_applications_message"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:text="@string/recent_tasks_empty"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<com.android.systemui.recent.RecentApplicationsCarouselView
|
||||
android:id="@+id/carousel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1">
|
||||
</com.android.systemui.recent.RecentApplicationsCarouselView>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2008, 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="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Application Title -->
|
||||
<TextView android:id="@+id/app_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:singleLine="true"/>
|
||||
|
||||
<!-- Application Details -->
|
||||
<TextView
|
||||
android:id="@+id/app_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
</LinearLayout>
|
||||
24
packages/SystemUI/res/values-hdpi/dimens.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
* Copyright (c) 2011, 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.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
<!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg -->
|
||||
<dimen name="recents_thumbnail_bg_padding_left">6px</dimen>
|
||||
<dimen name="recents_thumbnail_bg_padding_top">7px</dimen>
|
||||
<dimen name="recents_thumbnail_bg_padding_right">6px</dimen>
|
||||
<dimen name="recents_thumbnail_bg_padding_bottom">6px</dimen>
|
||||
</resources>
|
||||
@@ -23,15 +23,17 @@
|
||||
<!-- Width of a recent app view, including all content -->
|
||||
<dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen>
|
||||
<!-- How far the thumbnail for a recent app appears from left edge -->
|
||||
<dimen name="status_bar_recents_thumbnail_left_margin">0dp</dimen>
|
||||
<dimen name="status_bar_recents_thumbnail_left_margin">8dp</dimen>
|
||||
<!-- How far the thumbnail for a recent app appears from top edge -->
|
||||
<dimen name="status_bar_recents_thumbnail_top_margin">12dp</dimen>
|
||||
<!-- Width of scrollable area in recents -->
|
||||
<dimen name="status_bar_recents_width">128dp</dimen>
|
||||
<!-- Thumbnail border width -->
|
||||
<dimen name="status_bar_recents_thumbnail_border_width">8dp</dimen>
|
||||
<!-- Thumbnail border height -->
|
||||
<dimen name="status_bar_recents_thumbnail_border_height">12dp</dimen>
|
||||
<!-- Padding for text descriptions -->
|
||||
<dimen name="status_bar_recents_text_description_padding">8dp</dimen>
|
||||
<!-- Width of application label text -->
|
||||
<dimen name="status_bar_recents_app_label_width">97dip</dimen>
|
||||
<!-- Left margin of application label text -->
|
||||
<dimen name="status_bar_recents_app_label_left_margin">16dip</dimen>
|
||||
<!-- Margin between recents container and glow on the right -->
|
||||
<dimen name="status_bar_recents_right_glow_margin">0dip</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -22,32 +22,6 @@
|
||||
<dimen name="status_bar_panel_bottom_offset">36dp</dimen>
|
||||
<!-- gap on either side of status bar notification icons -->
|
||||
<dimen name="status_bar_icon_padding">8dp</dimen>
|
||||
|
||||
<!-- Recent Applications parameters -->
|
||||
<!-- Width of a recent app view, including all content -->
|
||||
<dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen>
|
||||
<!-- How far the thumbnail for a recent app appears from left edge -->
|
||||
<dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen>
|
||||
<!-- Upper width limit for application icon -->
|
||||
<dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen>
|
||||
<!-- Upper height limit for application icon -->
|
||||
<dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen>
|
||||
<!-- Width of scrollable area in recents -->
|
||||
<dimen name="status_bar_recents_width">356dp</dimen>
|
||||
<!-- Thumbnail border width -->
|
||||
<dimen name="status_bar_recents_thumbnail_border_width">12dp</dimen>
|
||||
<!-- Thumbnail border height -->
|
||||
<dimen name="status_bar_recents_thumbnail_border_height">12dp</dimen>
|
||||
<!-- Padding for text descriptions -->
|
||||
<dimen name="status_bar_recents_text_description_padding">8dp</dimen>
|
||||
<!-- Size of application label text -->
|
||||
<dimen name="status_bar_recents_app_label_text_size">18dip</dimen>
|
||||
<!-- Size of application description text -->
|
||||
<dimen name="status_bar_recents_app_description_text_size">18dip</dimen>
|
||||
<!-- Size of fading edge for scroll effect -->
|
||||
<dimen name="status_bar_recents_fading_edge_length">20dip</dimen>
|
||||
<!-- Margin between recents container and glow on the right -->
|
||||
<dimen name="status_bar_recents_right_glow_margin">100dip</dimen>
|
||||
</resources>
|
||||
|
||||
|
||||
|
||||
24
packages/SystemUI/res/values-mdpi/dimens.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
* Copyright (c) 2011, 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.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
<!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg -->
|
||||
<dimen name="recents_thumbnail_bg_padding_left">6px</dimen>
|
||||
<dimen name="recents_thumbnail_bg_padding_top">7px</dimen>
|
||||
<dimen name="recents_thumbnail_bg_padding_right">6px</dimen>
|
||||
<dimen name="recents_thumbnail_bg_padding_bottom">6px</dimen>
|
||||
</resources>
|
||||
34
packages/SystemUI/res/values-port/dimens.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
* Copyright (c) 2006, 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.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
<!-- Recent Applications parameters -->
|
||||
<!-- Width of a recent app view, including all content -->
|
||||
<dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen>
|
||||
<!-- How far the thumbnail for a recent app appears from left edge -->
|
||||
<dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen>
|
||||
<!-- Width of scrollable area in recents -->
|
||||
<dimen name="status_bar_recents_width">356dp</dimen>
|
||||
<!-- Padding for text descriptions -->
|
||||
<dimen name="status_bar_recents_text_description_padding">8dp</dimen>
|
||||
<!-- Width of application label text -->
|
||||
<dimen name="status_bar_recents_app_label_width">97dip</dimen>
|
||||
<!-- Left margin of application label text -->
|
||||
<dimen name="status_bar_recents_app_label_left_margin">16dip</dimen>
|
||||
<!-- Margin between recents container and glow on the right -->
|
||||
<dimen name="status_bar_recents_right_glow_margin">100dip</dimen>
|
||||
</resources>
|
||||
@@ -28,4 +28,40 @@
|
||||
<dimen name="notification_panel_min_height">770dp</dimen>
|
||||
<!-- Bottom margin (from display edge) for status bar panels -->
|
||||
<dimen name="panel_float">56dp</dimen>
|
||||
|
||||
<!-- Recent Applications parameters -->
|
||||
<!-- Width of a recent app view, including all content -->
|
||||
<dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen>
|
||||
<!-- How far the thumbnail for a recent app appears from left edge -->
|
||||
<dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen>
|
||||
<!-- Upper width limit for application icon -->
|
||||
<dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen>
|
||||
<!-- Upper height limit for application icon -->
|
||||
<dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen>
|
||||
<!-- Width of scrollable area in recents -->
|
||||
<dimen name="status_bar_recents_width">356dp</dimen>
|
||||
<!-- Padding for text descriptions -->
|
||||
<dimen name="status_bar_recents_text_description_padding">8dp</dimen>
|
||||
<!-- Size of application label text -->
|
||||
<dimen name="status_bar_recents_app_label_text_size">18dip</dimen>
|
||||
<!-- Size of application description text -->
|
||||
<dimen name="status_bar_recents_app_description_text_size">18dip</dimen>
|
||||
<!-- Width of application label text -->
|
||||
<dimen name="status_bar_recents_app_label_width">97dip</dimen>
|
||||
<!-- Left margin for application label -->
|
||||
<dimen name="status_bar_recents_app_label_left_margin">16dip</dimen>
|
||||
<!-- Size of fading edge for scroll effect -->
|
||||
<dimen name="status_bar_recents_fading_edge_length">20dip</dimen>
|
||||
<!-- Margin between recents container and glow on the right -->
|
||||
<dimen name="status_bar_recents_right_glow_margin">100dip</dimen>
|
||||
|
||||
<!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg -->
|
||||
<dimen name="recents_thumbnail_bg_padding_left">15px</dimen>
|
||||
<dimen name="recents_thumbnail_bg_padding_top">8px</dimen>
|
||||
<dimen name="recents_thumbnail_bg_padding_right">12px</dimen>
|
||||
<dimen name="recents_thumbnail_bg_padding_bottom">8px</dimen>
|
||||
|
||||
<!-- Where to place the app icon over the thumbnail -->
|
||||
<dimen name="status_bar_recents_app_icon_left_margin">13dp</dimen>
|
||||
<dimen name="status_bar_recents_app_icon_top_margin">13dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -20,22 +20,14 @@
|
||||
<dimen name="status_bar_edge_ignore">5dp</dimen>
|
||||
|
||||
<!-- Recent Applications parameters -->
|
||||
<!-- Width of a recent app view, including all content -->
|
||||
<dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen>
|
||||
<!-- How far the thumbnail for a recent app appears from left edge -->
|
||||
<dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen>
|
||||
<!-- Upper width limit for application icon -->
|
||||
<dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen>
|
||||
<!-- Upper height limit for application icon -->
|
||||
<dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen>
|
||||
<!-- Width of scrollable area in recents -->
|
||||
<dimen name="status_bar_recents_width">356dp</dimen>
|
||||
<!-- Thumbnail border width -->
|
||||
<dimen name="status_bar_recents_thumbnail_border_width">12dp</dimen>
|
||||
<!-- Thumbnail border height -->
|
||||
<dimen name="status_bar_recents_thumbnail_border_height">12dp</dimen>
|
||||
<!-- Padding for text descriptions -->
|
||||
<dimen name="status_bar_recents_text_description_padding">8dp</dimen>
|
||||
<!-- Where to place the app icon over the thumbnail -->
|
||||
<dimen name="status_bar_recents_app_icon_left_margin">13dp</dimen>
|
||||
<dimen name="status_bar_recents_app_icon_top_margin">13dp</dimen>
|
||||
|
||||
<!-- Size of application label text -->
|
||||
<dimen name="status_bar_recents_app_label_text_size">18dip</dimen>
|
||||
<!-- Size of application description text -->
|
||||
|
||||
@@ -36,14 +36,16 @@ import android.view.View;
|
||||
View mScrimView;
|
||||
View mContentView;
|
||||
AnimatorSet mContentAnim;
|
||||
Animator.AnimatorListener mListener;
|
||||
|
||||
// the panel will start to appear this many px from the end
|
||||
final int HYPERSPACE_OFFRAMP = 200;
|
||||
|
||||
public Choreographer(View root, View scrim, View content) {
|
||||
public Choreographer(View root, View scrim, View content, Animator.AnimatorListener listener) {
|
||||
mRootView = root;
|
||||
mScrimView = scrim;
|
||||
mContentView = content;
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
void createAnimation(boolean appearing) {
|
||||
@@ -86,6 +88,9 @@ import android.view.View;
|
||||
.with(posAnim);
|
||||
mContentAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION);
|
||||
mContentAnim.addListener(this);
|
||||
if (mListener != null) {
|
||||
mContentAnim.addListener(mListener);
|
||||
}
|
||||
}
|
||||
|
||||
void startAnimation(boolean appearing) {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.android.systemui.recent;
|
||||
|
||||
import com.android.systemui.recent.RecentsPanelView.ActvityDescriptionAdapter;
|
||||
import com.android.systemui.recent.RecentsPanelView.ActivityDescriptionAdapter;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.Animator.AnimatorListener;
|
||||
@@ -49,7 +49,7 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
|
||||
private static final float THRESHHOLD = 50;
|
||||
private static final boolean DEBUG_INVALIDATE = false;
|
||||
private LinearLayout mLinearLayout;
|
||||
private ActvityDescriptionAdapter mAdapter;
|
||||
private ActivityDescriptionAdapter mAdapter;
|
||||
private RecentsCallback mCallback;
|
||||
protected int mLastScrollPosition;
|
||||
private View mCurrentView;
|
||||
@@ -273,7 +273,7 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
|
||||
}
|
||||
}
|
||||
|
||||
public void setAdapter(ActvityDescriptionAdapter adapter) {
|
||||
public void setAdapter(ActivityDescriptionAdapter adapter) {
|
||||
mAdapter = adapter;
|
||||
mAdapter.registerDataSetObserver(new DataSetObserver() {
|
||||
public void onChanged() {
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.systemui.recent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.LayoutTransition;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
@@ -52,27 +53,33 @@ import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.StatusBar;
|
||||
import com.android.systemui.statusbar.phone.PhoneStatusBar;
|
||||
import com.android.systemui.statusbar.tablet.StatusBarPanel;
|
||||
import com.android.systemui.statusbar.tablet.TabletStatusBar;
|
||||
|
||||
public class RecentsPanelView extends RelativeLayout
|
||||
implements OnItemClickListener, RecentsCallback, StatusBarPanel {
|
||||
private static final int GLOW_PADDING = 15;
|
||||
implements OnItemClickListener, RecentsCallback, StatusBarPanel, Animator.AnimatorListener {
|
||||
static final String TAG = "RecentsListView";
|
||||
static final boolean DEBUG = TabletStatusBar.DEBUG;
|
||||
static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG;
|
||||
private static final int DISPLAY_TASKS = 20;
|
||||
private static final int MAX_TASKS = DISPLAY_TASKS + 1; // allow extra for non-apps
|
||||
private TabletStatusBar mBar;
|
||||
private StatusBar mBar;
|
||||
private ArrayList<ActivityDescription> mActivityDescriptions;
|
||||
private int mIconDpi;
|
||||
private View mRecentsScrim;
|
||||
private View mRecentsGlowView;
|
||||
private View mRecentsContainer;
|
||||
private Bitmap mGlowBitmap;
|
||||
// TODO: add these widgets attributes to the layout file
|
||||
private int mGlowBitmapPaddingLeftPx;
|
||||
private int mGlowBitmapPaddingTopPx;
|
||||
private int mGlowBitmapPaddingRightPx;
|
||||
private int mGlowBitmapPaddingBottomPx;
|
||||
private boolean mShowing;
|
||||
private Choreographer mChoreo;
|
||||
private View mRecentsDismissButton;
|
||||
private ActvityDescriptionAdapter mListAdapter;
|
||||
private ActivityDescriptionAdapter mListAdapter;
|
||||
|
||||
/* package */ final static class ActivityDescription {
|
||||
int taskId; // application task id for curating apps
|
||||
@@ -108,10 +115,10 @@ public class RecentsPanelView extends RelativeLayout
|
||||
ActivityDescription activityDescription;
|
||||
}
|
||||
|
||||
/* package */ final class ActvityDescriptionAdapter extends BaseAdapter {
|
||||
/* package */ final class ActivityDescriptionAdapter extends BaseAdapter {
|
||||
private LayoutInflater mInflater;
|
||||
|
||||
public ActvityDescriptionAdapter(Context context) {
|
||||
public ActivityDescriptionAdapter(Context context) {
|
||||
mInflater = LayoutInflater.from(context);
|
||||
}
|
||||
|
||||
@@ -183,6 +190,26 @@ public class RecentsPanelView extends RelativeLayout
|
||||
}
|
||||
}
|
||||
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
}
|
||||
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (mShowing) {
|
||||
final LayoutTransition transitioner = new LayoutTransition();
|
||||
((ViewGroup)mRecentsContainer).setLayoutTransition(transitioner);
|
||||
createCustomAnimations(transitioner);
|
||||
} else {
|
||||
((ViewGroup)mRecentsContainer).setLayoutTransition(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
}
|
||||
|
||||
public void onAnimationStart(Animator animation) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* We need to be aligned at the bottom. LinearLayout can't do this, so instead,
|
||||
* let LinearLayout do all the hard work, and then shift everything down to the bottom.
|
||||
@@ -201,7 +228,7 @@ public class RecentsPanelView extends RelativeLayout
|
||||
return mShowing;
|
||||
}
|
||||
|
||||
public void setBar(TabletStatusBar bar) {
|
||||
public void setBar(StatusBar bar) {
|
||||
mBar = bar;
|
||||
}
|
||||
|
||||
@@ -217,7 +244,16 @@ public class RecentsPanelView extends RelativeLayout
|
||||
& Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE;
|
||||
|
||||
mIconDpi = xlarge ? DisplayMetrics.DENSITY_HIGH : res.getDisplayMetrics().densityDpi;
|
||||
|
||||
mGlowBitmap = BitmapFactory.decodeResource(res, R.drawable.recents_thumbnail_bg);
|
||||
mGlowBitmapPaddingLeftPx =
|
||||
res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_left);
|
||||
mGlowBitmapPaddingTopPx =
|
||||
res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_top);
|
||||
mGlowBitmapPaddingRightPx =
|
||||
res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_right);
|
||||
mGlowBitmapPaddingBottomPx =
|
||||
res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -225,7 +261,7 @@ public class RecentsPanelView extends RelativeLayout
|
||||
super.onFinishInflate();
|
||||
mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
mRecentsContainer = findViewById(R.id.recents_container);
|
||||
mListAdapter = new ActvityDescriptionAdapter(mContext);
|
||||
mListAdapter = new ActivityDescriptionAdapter(mContext);
|
||||
if (mRecentsContainer instanceof RecentsListView) {
|
||||
RecentsListView listView = (RecentsListView) mRecentsContainer;
|
||||
listView.setAdapter(mListAdapter);
|
||||
@@ -246,13 +282,10 @@ public class RecentsPanelView extends RelativeLayout
|
||||
throw new IllegalArgumentException("missing RecentsListView/RecentsScrollView");
|
||||
}
|
||||
|
||||
final LayoutTransition transitioner = new LayoutTransition();
|
||||
((ViewGroup)mRecentsContainer).setLayoutTransition(transitioner);
|
||||
createCustomAnimations(transitioner);
|
||||
|
||||
mRecentsGlowView = findViewById(R.id.recents_glow);
|
||||
mRecentsScrim = (View) findViewById(R.id.recents_bg_protect);
|
||||
mChoreo = new Choreographer(this, mRecentsScrim, mRecentsGlowView);
|
||||
mChoreo = new Choreographer(this, mRecentsScrim, mRecentsGlowView, this);
|
||||
mRecentsDismissButton = findViewById(R.id.recents_dismiss_button);
|
||||
mRecentsDismissButton.setOnClickListener(new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
@@ -402,10 +435,9 @@ public class RecentsPanelView extends RelativeLayout
|
||||
Log.v(TAG, "Source thumb: " + srcWidth + "x" + srcHeight);
|
||||
canvas.drawBitmap(thumbnail,
|
||||
new Rect(0, 0, srcWidth-1, srcHeight-1),
|
||||
new RectF(GLOW_PADDING,
|
||||
GLOW_PADDING - 7.0f,
|
||||
outBitmap.getWidth() - GLOW_PADDING + 3.0f,
|
||||
outBitmap.getHeight() - GLOW_PADDING + 7.0f), paint);
|
||||
new RectF(mGlowBitmapPaddingLeftPx, mGlowBitmapPaddingTopPx,
|
||||
outBitmap.getWidth() - mGlowBitmapPaddingRightPx,
|
||||
outBitmap.getHeight() - mGlowBitmapPaddingBottomPx), paint);
|
||||
}
|
||||
return outBitmap;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.android.systemui.recent;
|
||||
|
||||
import com.android.systemui.recent.RecentsPanelView.ActvityDescriptionAdapter;
|
||||
import com.android.systemui.recent.RecentsPanelView.ActivityDescriptionAdapter;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.Animator.AnimatorListener;
|
||||
@@ -49,7 +49,7 @@ public class RecentsVerticalScrollView extends ScrollView
|
||||
private static final float THRESHHOLD = 50;
|
||||
private static final boolean DEBUG_INVALIDATE = false;
|
||||
private LinearLayout mLinearLayout;
|
||||
private ActvityDescriptionAdapter mAdapter;
|
||||
private ActivityDescriptionAdapter mAdapter;
|
||||
private RecentsCallback mCallback;
|
||||
protected int mLastScrollPosition;
|
||||
private View mCurrentView;
|
||||
@@ -275,7 +275,7 @@ public class RecentsVerticalScrollView extends ScrollView
|
||||
}
|
||||
}
|
||||
|
||||
public void setAdapter(ActvityDescriptionAdapter adapter) {
|
||||
public void setAdapter(ActivityDescriptionAdapter adapter) {
|
||||
mAdapter = adapter;
|
||||
mAdapter.registerDataSetObserver(new DataSetObserver() {
|
||||
public void onChanged() {
|
||||
|
||||
@@ -1,532 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.carousel;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
import com.android.ex.carousel.CarouselView;
|
||||
import com.android.ex.carousel.CarouselViewHelper;
|
||||
import com.android.ex.carousel.CarouselRS.CarouselCallback;
|
||||
import com.android.ex.carousel.CarouselViewHelper.DetailTextureParameters;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.app.IActivityManager;
|
||||
import android.app.IThumbnailReceiver;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PaintFlagsDrawFilter;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Bitmap.Config;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.View.MeasureSpec;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class RecentApplicationsActivity extends Activity {
|
||||
private static final String TAG = "RecentApplicationsActivity";
|
||||
private static boolean DBG = false;
|
||||
private static final int CARD_SLOTS = 56;
|
||||
private static final int VISIBLE_SLOTS = 7;
|
||||
private static final int MAX_TASKS = VISIBLE_SLOTS * 2;
|
||||
|
||||
// TODO: these should be configurable
|
||||
private static final int DETAIL_TEXTURE_MAX_WIDTH = 200;
|
||||
private static final int DETAIL_TEXTURE_MAX_HEIGHT = 80;
|
||||
private static final int TEXTURE_WIDTH = 256;
|
||||
private static final int TEXTURE_HEIGHT = 256;
|
||||
|
||||
private ActivityManager mActivityManager;
|
||||
private List<RunningTaskInfo> mRunningTaskList;
|
||||
private boolean mPortraitMode = true;
|
||||
private ArrayList<ActivityDescription> mActivityDescriptions
|
||||
= new ArrayList<ActivityDescription>();
|
||||
private CarouselView mCarouselView;
|
||||
private LocalCarouselViewHelper mHelper;
|
||||
private View mNoRecentsView;
|
||||
private Bitmap mLoadingBitmap;
|
||||
private Bitmap mRecentOverlay;
|
||||
private boolean mHidden = false;
|
||||
private boolean mHiding = false;
|
||||
private DetailInfo mDetailInfo;
|
||||
|
||||
/**
|
||||
* This class is a container for all items associated with the DetailView we'll
|
||||
* be drawing to a bitmap and sending to Carousel.
|
||||
*
|
||||
*/
|
||||
static final class DetailInfo {
|
||||
public DetailInfo(View _view, TextView _title, TextView _desc) {
|
||||
view = _view;
|
||||
title = _title;
|
||||
description = _desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws view into the given bitmap, if provided
|
||||
* @param bitmap
|
||||
*/
|
||||
public Bitmap draw(Bitmap bitmap) {
|
||||
resizeView(view, DETAIL_TEXTURE_MAX_WIDTH, DETAIL_TEXTURE_MAX_HEIGHT);
|
||||
int desiredWidth = view.getWidth();
|
||||
int desiredHeight = view.getHeight();
|
||||
if (bitmap == null || desiredWidth != bitmap.getWidth()
|
||||
|| desiredHeight != bitmap.getHeight()) {
|
||||
bitmap = Bitmap.createBitmap(desiredWidth, desiredHeight, Config.ARGB_8888);
|
||||
}
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
view.draw(canvas);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a layout pass on the given view.
|
||||
*/
|
||||
private void resizeView(View view, int maxWidth, int maxHeight) {
|
||||
int widthSpec = MeasureSpec.getMode(MeasureSpec.AT_MOST)
|
||||
| MeasureSpec.getSize(maxWidth);
|
||||
int heightSpec = MeasureSpec.getMode(MeasureSpec.AT_MOST)
|
||||
| MeasureSpec.getSize(maxHeight);
|
||||
view.measure(widthSpec, heightSpec);
|
||||
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
|
||||
Log.v(TAG, "RESIZED VIEW: " + view.getWidth() + ", " + view.getHeight());
|
||||
}
|
||||
|
||||
public View view;
|
||||
public TextView title;
|
||||
public TextView description;
|
||||
}
|
||||
|
||||
static class ActivityDescription {
|
||||
int id;
|
||||
Bitmap thumbnail; // generated by Activity.onCreateThumbnail()
|
||||
Drawable icon; // application package icon
|
||||
String label; // application package label
|
||||
CharSequence description; // generated by Activity.onCreateDescription()
|
||||
Intent intent; // launch intent for application
|
||||
Matrix matrix; // arbitrary rotation matrix to correct orientation
|
||||
int position; // position in list
|
||||
|
||||
public ActivityDescription(Bitmap _thumbnail,
|
||||
Drawable _icon, String _label, String _desc, int _id, int _pos)
|
||||
{
|
||||
thumbnail = _thumbnail;
|
||||
icon = _icon;
|
||||
label = _label;
|
||||
description = _desc;
|
||||
id = _id;
|
||||
position = _pos;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
icon = null;
|
||||
thumbnail = null;
|
||||
label = null;
|
||||
description = null;
|
||||
intent = null;
|
||||
matrix = null;
|
||||
id = -1;
|
||||
position = -1;
|
||||
}
|
||||
};
|
||||
|
||||
private ActivityDescription findActivityDescription(int id) {
|
||||
for (int i = 0; i < mActivityDescriptions.size(); i++) {
|
||||
ActivityDescription item = mActivityDescriptions.get(i);
|
||||
if (item != null && item.id == id) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class LocalCarouselViewHelper extends CarouselViewHelper {
|
||||
private DetailTextureParameters mDetailParams = new DetailTextureParameters(10.0f, 20.0f);
|
||||
|
||||
public LocalCarouselViewHelper(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DetailTextureParameters getDetailTextureParameters(int id) {
|
||||
return mDetailParams;
|
||||
}
|
||||
|
||||
public void onCardSelected(int n) {
|
||||
if (n < mActivityDescriptions.size()) {
|
||||
ActivityDescription item = mActivityDescriptions.get(n);
|
||||
if (item.id >= 0) {
|
||||
// This is an active task; it should just go to the foreground.
|
||||
final ActivityManager am = (ActivityManager)
|
||||
getSystemService(Context.ACTIVITY_SERVICE);
|
||||
am.moveTaskToFront(item.id, ActivityManager.MOVE_TASK_WITH_HOME);
|
||||
} else if (item.intent != null) {
|
||||
// prepare a launch intent and send it
|
||||
item.intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
|
||||
| Intent.FLAG_ACTIVITY_TASK_ON_HOME);
|
||||
try {
|
||||
if (DBG) Log.v(TAG, "Starting intent " + item.intent);
|
||||
startActivity(item.intent);
|
||||
overridePendingTransition(R.anim.recent_app_enter, R.anim.recent_app_leave);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
if (DBG) Log.w("Recent", "Unable to launch recent task", e);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap getTexture(final int id) {
|
||||
if (DBG) Log.v(TAG, "onRequestTexture(" + id + ")");
|
||||
ActivityDescription info;
|
||||
synchronized(mActivityDescriptions) {
|
||||
info = mActivityDescriptions.get(id);
|
||||
}
|
||||
Bitmap bitmap = null;
|
||||
if (info != null) {
|
||||
bitmap = compositeBitmap(info);
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap getDetailTexture(int n) {
|
||||
Bitmap bitmap = null;
|
||||
if (n < mActivityDescriptions.size()) {
|
||||
ActivityDescription item = mActivityDescriptions.get(n);
|
||||
mDetailInfo.title.setText(item.label);
|
||||
mDetailInfo.description.setText(item.description);
|
||||
bitmap = mDetailInfo.draw(null);
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
};
|
||||
|
||||
private Bitmap compositeBitmap(ActivityDescription info) {
|
||||
final int targetWidth = TEXTURE_WIDTH;
|
||||
final int targetHeight = TEXTURE_HEIGHT;
|
||||
final int border = 3; // inset along the edge for thumnnail content
|
||||
final int overlap = 1; // how many pixels of overlap between border and thumbnail
|
||||
final Resources res = getResources();
|
||||
if (mRecentOverlay == null) {
|
||||
mRecentOverlay = BitmapFactory.decodeResource(res, R.drawable.recent_overlay);
|
||||
}
|
||||
|
||||
// Create a bitmap of the proper size/format and set the canvas to draw to it
|
||||
final Bitmap result = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888);
|
||||
final Canvas canvas = new Canvas(result);
|
||||
canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, Paint.FILTER_BITMAP_FLAG));
|
||||
Paint paint = new Paint();
|
||||
paint.setFilterBitmap(false);
|
||||
|
||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
|
||||
canvas.save();
|
||||
if (info.thumbnail != null) {
|
||||
// Draw the thumbnail
|
||||
int sourceWidth = targetWidth - 2 * (border - overlap);
|
||||
int sourceHeight = targetHeight - 2 * (border - overlap);
|
||||
final float scaleX = (float) sourceWidth / info.thumbnail.getWidth();
|
||||
final float scaleY = (float) sourceHeight / info.thumbnail.getHeight();
|
||||
canvas.translate(border * 0.5f, border * 0.5f);
|
||||
canvas.scale(scaleX, scaleY);
|
||||
canvas.drawBitmap(info.thumbnail, 0, 0, paint);
|
||||
} else {
|
||||
// Draw the Loading bitmap placeholder, TODO: Remove when RS handles blending
|
||||
final float scaleX = (float) targetWidth / mLoadingBitmap.getWidth();
|
||||
final float scaleY = (float) targetHeight / mLoadingBitmap.getHeight();
|
||||
canvas.scale(scaleX, scaleY);
|
||||
canvas.drawBitmap(mLoadingBitmap, 0, 0, paint);
|
||||
}
|
||||
canvas.restore();
|
||||
|
||||
// Draw overlay
|
||||
canvas.save();
|
||||
final float scaleOverlayX = (float) targetWidth / mRecentOverlay.getWidth();
|
||||
final float scaleOverlayY = (float) targetHeight / mRecentOverlay.getHeight();
|
||||
canvas.scale(scaleOverlayX, scaleOverlayY);
|
||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD));
|
||||
canvas.drawBitmap(mRecentOverlay, 0, 0, paint);
|
||||
canvas.restore();
|
||||
|
||||
// Draw icon
|
||||
if (info.icon != null) {
|
||||
canvas.save();
|
||||
info.icon.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private final IThumbnailReceiver mThumbnailReceiver = new IThumbnailReceiver.Stub() {
|
||||
|
||||
public void finished() throws RemoteException {
|
||||
|
||||
}
|
||||
|
||||
public void newThumbnail(final int id, final Bitmap bitmap, CharSequence description)
|
||||
throws RemoteException {
|
||||
int w = bitmap.getWidth();
|
||||
int h = bitmap.getHeight();
|
||||
if (DBG) Log.v(TAG, "New thumbnail for id=" + id + ", dimensions=" + w + "x" + h
|
||||
+ " description '" + description + "'");
|
||||
ActivityDescription info = findActivityDescription(id);
|
||||
if (info != null) {
|
||||
info.thumbnail = bitmap;
|
||||
info.description = description;
|
||||
final int thumbWidth = bitmap.getWidth();
|
||||
final int thumbHeight = bitmap.getHeight();
|
||||
if ((mPortraitMode && thumbWidth > thumbHeight)
|
||||
|| (!mPortraitMode && thumbWidth < thumbHeight)) {
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2);
|
||||
info.matrix = matrix;
|
||||
} else {
|
||||
info.matrix = null;
|
||||
}
|
||||
// Force Carousel to request new textures for this item.
|
||||
mCarouselView.setTextureForItem(info.position, null);
|
||||
mCarouselView.setDetailTextureForItem(info.position, 0, 0, 0, 0, null);
|
||||
} else {
|
||||
if (DBG) Log.v(TAG, "Can't find view for id " + id);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* We never really finish() RecentApplicationsActivity, since we don't want to
|
||||
* get destroyed and pay the start-up cost to restart it.
|
||||
*/
|
||||
@Override
|
||||
public void finish() {
|
||||
moveTaskToBack(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
mHidden = !mHidden;
|
||||
if (mHidden) {
|
||||
mHiding = true;
|
||||
moveTaskToBack(true);
|
||||
} else {
|
||||
mHiding = false;
|
||||
}
|
||||
super.onNewIntent(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
final Resources res = getResources();
|
||||
final View decorView = getWindow().getDecorView();
|
||||
|
||||
getWindow().getDecorView().setBackgroundColor(0x80000000);
|
||||
|
||||
if (mCarouselView == null) {
|
||||
long t = System.currentTimeMillis();
|
||||
setContentView(R.layout.recent_apps_activity);
|
||||
long elapsed = System.currentTimeMillis() - t;
|
||||
Log.v(TAG, "Recents layout took " + elapsed + "ms to load");
|
||||
mLoadingBitmap = BitmapFactory.decodeResource(res, R.drawable.recent_rez_border);
|
||||
mCarouselView = (CarouselView)findViewById(R.id.carousel);
|
||||
mHelper = new LocalCarouselViewHelper(this);
|
||||
mHelper.setCarouselView(mCarouselView);
|
||||
|
||||
mCarouselView.setSlotCount(CARD_SLOTS);
|
||||
mCarouselView.setVisibleSlots(VISIBLE_SLOTS);
|
||||
mCarouselView.createCards(0);
|
||||
mCarouselView.setStartAngle((float) -(2.0f*Math.PI * 5 / CARD_SLOTS));
|
||||
mCarouselView.setDefaultBitmap(mLoadingBitmap);
|
||||
mCarouselView.setLoadingBitmap(mLoadingBitmap);
|
||||
mCarouselView.setRezInCardCount(3.0f);
|
||||
mCarouselView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
|
||||
|
||||
mNoRecentsView = (View) findViewById(R.id.no_applications_message);
|
||||
|
||||
mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||
mPortraitMode = decorView.getHeight() > decorView.getWidth();
|
||||
|
||||
// Load detail view which will be used to render text
|
||||
View detail = getLayoutInflater().inflate(R.layout.recents_detail_view, null);
|
||||
TextView title = (TextView) detail.findViewById(R.id.app_title);
|
||||
TextView description = (TextView) detail.findViewById(R.id.app_description);
|
||||
mDetailInfo = new DetailInfo(detail, title, description);
|
||||
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
mPortraitMode = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT;
|
||||
if (DBG) Log.v(TAG, "CONFIG CHANGE, mPortraitMode = " + mPortraitMode);
|
||||
refresh();
|
||||
}
|
||||
|
||||
void updateRunningTasks() {
|
||||
mRunningTaskList = mActivityManager.getRunningTasks(MAX_TASKS,
|
||||
0, mThumbnailReceiver);
|
||||
if (DBG) Log.v(TAG, "Portrait: " + mPortraitMode);
|
||||
for (RunningTaskInfo r : mRunningTaskList) {
|
||||
if (r.thumbnail != null) {
|
||||
int thumbWidth = r.thumbnail.getWidth();
|
||||
int thumbHeight = r.thumbnail.getHeight();
|
||||
if (DBG) Log.v(TAG, "Got thumbnail " + thumbWidth + "x" + thumbHeight);
|
||||
ActivityDescription desc = findActivityDescription(r.id);
|
||||
if (desc != null) {
|
||||
desc.thumbnail = r.thumbnail;
|
||||
desc.description = r.description;
|
||||
if ((mPortraitMode && thumbWidth > thumbHeight)
|
||||
|| (!mPortraitMode && thumbWidth < thumbHeight)) {
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2);
|
||||
desc.matrix = matrix;
|
||||
}
|
||||
} else {
|
||||
if (DBG) Log.v(TAG, "Couldn't find ActivityDesc for id=" + r.id);
|
||||
}
|
||||
} else {
|
||||
if (DBG) Log.v(TAG, "*** RUNNING THUMBNAIL WAS NULL ***");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRecentTasks() {
|
||||
final PackageManager pm = getPackageManager();
|
||||
final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||
|
||||
final List<ActivityManager.RecentTaskInfo> recentTasks =
|
||||
am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
|
||||
|
||||
ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
|
||||
.resolveActivityInfo(pm, 0);
|
||||
|
||||
// IconUtilities iconUtilities = new IconUtilities(this); // FIXME
|
||||
|
||||
int numTasks = recentTasks.size();
|
||||
mActivityDescriptions.clear();
|
||||
for (int i = 0, index = 0; i < numTasks && (index < MAX_TASKS); ++i) {
|
||||
final ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(i);
|
||||
|
||||
Intent intent = new Intent(recentInfo.baseIntent);
|
||||
if (recentInfo.origActivity != null) {
|
||||
intent.setComponent(recentInfo.origActivity);
|
||||
}
|
||||
|
||||
// Skip the current home activity.
|
||||
if (homeInfo != null
|
||||
&& homeInfo.packageName.equals(intent.getComponent().getPackageName())
|
||||
&& homeInfo.name.equals(intent.getComponent().getClassName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
|
||||
| Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
|
||||
if (resolveInfo != null) {
|
||||
final ActivityInfo info = resolveInfo.activityInfo;
|
||||
final String title = info.loadLabel(pm).toString();
|
||||
Drawable icon = info.loadIcon(pm);
|
||||
|
||||
int id = recentTasks.get(i).id;
|
||||
if (id != -1 && title != null && title.length() > 0 && icon != null) {
|
||||
// icon = null; FIXME: iconUtilities.createIconDrawable(icon);
|
||||
ActivityDescription item = new ActivityDescription(
|
||||
null, icon, title, null, id, index);
|
||||
item.intent = intent;
|
||||
mActivityDescriptions.add(item);
|
||||
if (DBG) Log.v(TAG, "Added item[" + index
|
||||
+ "], id=" + item.id
|
||||
+ ", title=" + item.label);
|
||||
++index;
|
||||
} else {
|
||||
if (DBG) Log.v(TAG, "SKIPPING item " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final Runnable mRefreshRunnable = new Runnable() {
|
||||
public void run() {
|
||||
updateRecentTasks();
|
||||
updateRunningTasks();
|
||||
showCarousel(mActivityDescriptions.size() > 0);
|
||||
}
|
||||
};
|
||||
|
||||
private void showCarousel(boolean show) {
|
||||
if (show) {
|
||||
mCarouselView.createCards(mActivityDescriptions.size());
|
||||
for (int i = 1; i < mActivityDescriptions.size(); i++) {
|
||||
// Force Carousel to update textures. Note we don't do this for the first item,
|
||||
// since it will be updated when mThumbnailReceiver returns a thumbnail.
|
||||
// TODO: only do this for apps that have changed.
|
||||
mCarouselView.setTextureForItem(i, null);
|
||||
mCarouselView.setDetailTextureForItem(i, 0, 0, 0, 0, null);
|
||||
}
|
||||
// Make carousel visible
|
||||
mNoRecentsView.setVisibility(View.GONE);
|
||||
mCarouselView.setVisibility(View.VISIBLE);
|
||||
mCarouselView.createCards(mActivityDescriptions.size());
|
||||
} else {
|
||||
// show "No Recent Tasks"
|
||||
mNoRecentsView.setVisibility(View.VISIBLE);
|
||||
mCarouselView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
if (!mHiding && mCarouselView != null) {
|
||||
// Don't update the view now. Instead, post a request so it happens next time
|
||||
// we reach the looper after a delay. This way we can fold multiple refreshes
|
||||
// into just the latest.
|
||||
mCarouselView.removeCallbacks(mRefreshRunnable);
|
||||
mCarouselView.postDelayed(mRefreshRunnable, 50);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.carousel;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.ex.carousel.CarouselView;
|
||||
import com.android.systemui.R;
|
||||
|
||||
public class RecentApplicationsCarouselView extends CarouselView {
|
||||
|
||||
public RecentApplicationsCarouselView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public RecentApplicationsCarouselView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public Info getRenderScriptInfo() {
|
||||
return new Info(R.raw.carousel);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -61,6 +61,7 @@ public class CommandQueue extends IStatusBar.Stub {
|
||||
private static final int MSG_SET_HARD_KEYBOARD_STATUS = 10 << MSG_SHIFT;
|
||||
|
||||
private static final int MSG_USER_ACTIVITY = 11 << MSG_SHIFT;
|
||||
private static final int MSG_TOGGLE_RECENT_APPS = 12 << MSG_SHIFT;
|
||||
|
||||
private StatusBarIconList mList;
|
||||
private Callbacks mCallbacks;
|
||||
@@ -90,6 +91,7 @@ public class CommandQueue extends IStatusBar.Stub {
|
||||
public void setImeWindowStatus(IBinder token, int vis, int backDisposition);
|
||||
public void setHardKeyboardStatus(boolean available, boolean enabled);
|
||||
public void userActivity();
|
||||
public void toggleRecentApps();
|
||||
}
|
||||
|
||||
public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
|
||||
@@ -196,6 +198,13 @@ public class CommandQueue extends IStatusBar.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleRecentApps() {
|
||||
synchronized (mList) {
|
||||
mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS);
|
||||
mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
private final class H extends Handler {
|
||||
public void handleMessage(Message msg) {
|
||||
final int what = msg.what & MSG_MASK;
|
||||
@@ -265,6 +274,9 @@ public class CommandQueue extends IStatusBar.Stub {
|
||||
case MSG_USER_ACTIVITY:
|
||||
mCallbacks.userActivity();
|
||||
break;
|
||||
case MSG_TOGGLE_RECENT_APPS:
|
||||
mCallbacks.toggleRecentApps();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ public abstract class StatusBar extends SystemUI implements CommandQueue.Callbac
|
||||
protected abstract View makeStatusBarView();
|
||||
protected abstract int getStatusBarGravity();
|
||||
public abstract int getStatusBarHeight();
|
||||
public abstract void animateCollapse();
|
||||
|
||||
private DoNotDisturb mDoNotDisturb;
|
||||
|
||||
|
||||
@@ -28,10 +28,12 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.Handler;
|
||||
@@ -74,6 +76,7 @@ import com.android.internal.statusbar.StatusBarIconList;
|
||||
import com.android.internal.statusbar.StatusBarNotification;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.recent.RecentsPanelView;
|
||||
import com.android.systemui.statusbar.NotificationData;
|
||||
import com.android.systemui.statusbar.StatusBar;
|
||||
import com.android.systemui.statusbar.StatusBarIconView;
|
||||
@@ -83,6 +86,7 @@ import com.android.systemui.statusbar.policy.DateView;
|
||||
public class PhoneStatusBar extends StatusBar {
|
||||
static final String TAG = "PhoneStatusBar";
|
||||
static final boolean SPEW = false;
|
||||
public static final boolean DEBUG = false;
|
||||
|
||||
public static final String ACTION_STATUSBAR_START
|
||||
= "com.android.internal.policy.statusbar.START";
|
||||
@@ -94,6 +98,8 @@ public class PhoneStatusBar extends StatusBar {
|
||||
private static final int MSG_ANIMATE_REVEAL = 1001;
|
||||
private static final int MSG_SHOW_INTRUDER = 1002;
|
||||
private static final int MSG_HIDE_INTRUDER = 1003;
|
||||
private static final int MSG_OPEN_RECENTS_PANEL = 1020;
|
||||
private static final int MSG_CLOSE_RECENTS_PANEL = 1021;
|
||||
|
||||
// will likely move to a resource or other tunable param at some point
|
||||
private static final int INTRUDER_ALERT_DECAY_MS = 10000;
|
||||
@@ -160,6 +166,9 @@ public class PhoneStatusBar extends StatusBar {
|
||||
private View mTickerView;
|
||||
private boolean mTicking;
|
||||
|
||||
// Recent applications
|
||||
private RecentsPanelView mRecentsPanel;
|
||||
|
||||
// Tracking finger for opening/closing.
|
||||
int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
|
||||
boolean mTracking;
|
||||
@@ -296,6 +305,9 @@ public class PhoneStatusBar extends StatusBar {
|
||||
setAreThereNotifications();
|
||||
mDateView.setVisibility(View.INVISIBLE);
|
||||
|
||||
// Recents Panel
|
||||
initializeRecentsPanel();
|
||||
|
||||
// receive broadcasts
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
|
||||
@@ -306,6 +318,51 @@ public class PhoneStatusBar extends StatusBar {
|
||||
return sb;
|
||||
}
|
||||
|
||||
protected WindowManager.LayoutParams getRecentsLayoutParams() {
|
||||
boolean translucent = false;
|
||||
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
|
||||
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
|
||||
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
|
||||
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
|
||||
(translucent ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
|
||||
lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
|
||||
lp.setTitle("RecentsPanel");
|
||||
lp.windowAnimations = R.style.Animation_RecentPanel;
|
||||
lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
|
||||
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
|
||||
return lp;
|
||||
}
|
||||
|
||||
protected void initializeRecentsPanel() {
|
||||
// Recents Panel
|
||||
boolean visible = false;
|
||||
if (mRecentsPanel != null) {
|
||||
visible = mRecentsPanel.getVisibility() == View.VISIBLE;
|
||||
WindowManagerImpl.getDefault().removeView(mRecentsPanel);
|
||||
}
|
||||
mRecentsPanel = (RecentsPanelView) View.inflate(mContext,
|
||||
R.layout.status_bar_recent_panel, null);
|
||||
|
||||
mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL,
|
||||
mRecentsPanel));
|
||||
mRecentsPanel.setVisibility(View.GONE);
|
||||
WindowManager.LayoutParams lp = getRecentsLayoutParams();
|
||||
|
||||
WindowManagerImpl.getDefault().addView(mRecentsPanel, lp);
|
||||
mRecentsPanel.setBar(this);
|
||||
if (visible) {
|
||||
// need to set visibility to View.GONE earlier since that
|
||||
// triggers refreshing application list
|
||||
mRecentsPanel.setVisibility(View.VISIBLE);
|
||||
mRecentsPanel.show(true, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected int getStatusBarGravity() {
|
||||
return Gravity.TOP | Gravity.FILL_HORIZONTAL;
|
||||
}
|
||||
@@ -581,6 +638,12 @@ public class PhoneStatusBar extends StatusBar {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConfigurationChanged(Configuration newConfig) {
|
||||
initializeRecentsPanel();
|
||||
}
|
||||
|
||||
|
||||
View[] makeNotificationView(StatusBarNotification notification, ViewGroup parent) {
|
||||
Notification n = notification.notification;
|
||||
RemoteViews remoteViews = n.contentView;
|
||||
@@ -789,6 +852,21 @@ public class PhoneStatusBar extends StatusBar {
|
||||
case MSG_HIDE_INTRUDER:
|
||||
setIntruderAlertVisibility(false);
|
||||
break;
|
||||
case MSG_OPEN_RECENTS_PANEL:
|
||||
if (DEBUG) Slog.d(TAG, "opening recents panel");
|
||||
if (mRecentsPanel != null) {
|
||||
disable(StatusBarManager.DISABLE_BACK);
|
||||
mRecentsPanel.setVisibility(View.VISIBLE);
|
||||
mRecentsPanel.show(true, true);
|
||||
}
|
||||
break;
|
||||
case MSG_CLOSE_RECENTS_PANEL:
|
||||
if (DEBUG) Slog.d(TAG, "closing recents panel");
|
||||
if (mRecentsPanel != null && mRecentsPanel.isShowing()) {
|
||||
disable(StatusBarManager.DISABLE_NONE);
|
||||
mRecentsPanel.show(false, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -835,6 +913,10 @@ public class PhoneStatusBar extends StatusBar {
|
||||
}
|
||||
|
||||
public void animateCollapse() {
|
||||
animateCollapse(false);
|
||||
}
|
||||
|
||||
public void animateCollapse(boolean excludeRecents) {
|
||||
if (SPEW) {
|
||||
Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded
|
||||
+ " mExpandedVisible=" + mExpandedVisible
|
||||
@@ -844,6 +926,11 @@ public class PhoneStatusBar extends StatusBar {
|
||||
+ " mAnimVel=" + mAnimVel);
|
||||
}
|
||||
|
||||
if (!excludeRecents) {
|
||||
mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
|
||||
mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
|
||||
}
|
||||
|
||||
if (!mExpandedVisible) {
|
||||
return;
|
||||
}
|
||||
@@ -1557,6 +1644,13 @@ public class PhoneStatusBar extends StatusBar {
|
||||
} catch (RemoteException ex) { }
|
||||
}
|
||||
|
||||
public void toggleRecentApps() {
|
||||
int msg = (mRecentsPanel.getVisibility() == View.GONE)
|
||||
? MSG_OPEN_RECENTS_PANEL : MSG_CLOSE_RECENTS_PANEL;
|
||||
mHandler.removeMessages(msg);
|
||||
mHandler.sendEmptyMessage(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
|
||||
* This was added last-minute and is inconsistent with the way the rest of the notifications
|
||||
@@ -1625,7 +1719,14 @@ public class PhoneStatusBar extends StatusBar {
|
||||
String action = intent.getAction();
|
||||
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
|
||||
|| Intent.ACTION_SCREEN_OFF.equals(action)) {
|
||||
animateCollapse();
|
||||
boolean excludeRecents = false;
|
||||
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
|
||||
String reason = intent.getExtras().getString("reason");
|
||||
if (reason != null) {
|
||||
excludeRecents = reason.equals("recentapps");
|
||||
}
|
||||
}
|
||||
animateCollapse(excludeRecents);
|
||||
}
|
||||
else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
|
||||
repositionNavigationBar();
|
||||
@@ -1690,5 +1791,27 @@ public class PhoneStatusBar extends StatusBar {
|
||||
vibrate();
|
||||
}
|
||||
};
|
||||
|
||||
public class TouchOutsideListener implements View.OnTouchListener {
|
||||
private int mMsg;
|
||||
private RecentsPanelView mPanel;
|
||||
|
||||
public TouchOutsideListener(int msg, RecentsPanelView panel) {
|
||||
mMsg = msg;
|
||||
mPanel = panel;
|
||||
}
|
||||
|
||||
public boolean onTouch(View v, MotionEvent ev) {
|
||||
final int action = ev.getAction();
|
||||
if (action == MotionEvent.ACTION_OUTSIDE
|
||||
|| (action == MotionEvent.ACTION_DOWN
|
||||
&& !mPanel.isInContentArea((int)ev.getX(), (int)ev.getY()))) {
|
||||
mHandler.removeMessages(mMsg);
|
||||
mHandler.sendEmptyMessage(mMsg);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@ import com.android.systemui.statusbar.policy.LocationController;
|
||||
import com.android.systemui.statusbar.policy.NetworkController;
|
||||
import com.android.systemui.statusbar.policy.Prefs;
|
||||
import com.android.systemui.recent.RecentsPanelView;
|
||||
import com.android.systemui.recent.carousel.RecentApplicationsActivity;
|
||||
|
||||
public class TabletStatusBar extends StatusBar implements
|
||||
HeightReceiver.OnBarHeightChangedListener,
|
||||
@@ -1156,20 +1155,12 @@ public class TabletStatusBar extends StatusBar implements
|
||||
|
||||
public void onClickRecentButton() {
|
||||
if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled);
|
||||
if (mRecentsPanel == null) {
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(mContext, RecentApplicationsActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
|
||||
mContext.startActivity(intent);
|
||||
} else {
|
||||
if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
|
||||
int msg = (mRecentsPanel.getVisibility() == View.GONE)
|
||||
? MSG_OPEN_RECENTS_PANEL
|
||||
: MSG_CLOSE_RECENTS_PANEL;
|
||||
mHandler.removeMessages(msg);
|
||||
mHandler.sendEmptyMessage(msg);
|
||||
}
|
||||
if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
|
||||
int msg = (mRecentsPanel.getVisibility() == View.GONE)
|
||||
? MSG_OPEN_RECENTS_PANEL
|
||||
: MSG_CLOSE_RECENTS_PANEL;
|
||||
mHandler.removeMessages(msg);
|
||||
mHandler.sendEmptyMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1681,6 +1672,13 @@ public class TabletStatusBar extends StatusBar implements
|
||||
public void userActivity() {
|
||||
}
|
||||
|
||||
public void toggleRecentApps() {
|
||||
int msg = (mRecentsPanel.getVisibility() == View.GONE)
|
||||
? MSG_OPEN_RECENTS_PANEL : MSG_CLOSE_RECENTS_PANEL;
|
||||
mHandler.removeMessages(msg);
|
||||
mHandler.sendEmptyMessage(msg);
|
||||
}
|
||||
|
||||
public class TouchOutsideListener implements View.OnTouchListener {
|
||||
private int mMsg;
|
||||
private StatusBarPanel mPanel;
|
||||
|
||||
@@ -149,10 +149,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
static final int LONG_PRESS_POWER_NOTHING = 0;
|
||||
static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
|
||||
static final int LONG_PRESS_POWER_SHUT_OFF = 2;
|
||||
|
||||
|
||||
// These need to match the documentation/constant in
|
||||
// core/res/res/values/config.xml
|
||||
static final int LONG_PRESS_HOME_NOTHING = 0;
|
||||
static final int LONG_PRESS_HOME_RECENT_DIALOG = 1;
|
||||
static final int LONG_PRESS_HOME_RECENT_ACTIVITY = 2;
|
||||
static final int LONG_PRESS_HOME_RECENT_SYSTEM_UI = 2;
|
||||
|
||||
// wallpaper is at the bottom, though the window manager may move it.
|
||||
static final int WALLPAPER_LAYER = 2;
|
||||
@@ -623,7 +625,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
mLongPressOnHomeBehavior
|
||||
= mContext.getResources().getInteger(R.integer.config_longPressOnHomeBehavior);
|
||||
if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING ||
|
||||
mLongPressOnHomeBehavior > LONG_PRESS_HOME_RECENT_ACTIVITY) {
|
||||
mLongPressOnHomeBehavior > LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
|
||||
mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
|
||||
}
|
||||
}
|
||||
@@ -639,17 +641,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
|
||||
if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
|
||||
showOrHideRecentAppsDialog(0, true /*dismissIfShown*/);
|
||||
} else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_ACTIVITY) {
|
||||
} else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
|
||||
try {
|
||||
Intent intent = new Intent();
|
||||
intent.setClassName("com.android.systemui",
|
||||
"com.android.systemui.recent.RecentApplicationsActivity");
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
|
||||
mContext.startActivity(intent);
|
||||
return;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Log.e(TAG, "Failed to launch RecentAppsIntent", e);
|
||||
mStatusBarService.toggleRecentApps();
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "RemoteException when showing recent apps", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,6 +345,15 @@ public class StatusBarManagerService extends IStatusBarService.Stub
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toggleRecentApps() {
|
||||
if (mBar != null) {
|
||||
try {
|
||||
mBar.toggleRecentApps();
|
||||
} catch (RemoteException ex) {}
|
||||
}
|
||||
}
|
||||
|
||||
private void enforceStatusBar() {
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR,
|
||||
"StatusBarManagerService");
|
||||
|
||||