Merge "Changing long-press-on-workspace behaviour to show Applications & Widgets."
diff --git a/Android.mk b/Android.mk
index 89e626b..844f052 100644
--- a/Android.mk
+++ b/Android.mk
@@ -21,9 +21,10 @@
LOCAL_MODULE_TAGS := optional
-LOCAL_STATIC_JAVA_LIBRARIES := android-common
+LOCAL_STATIC_JAVA_LIBRARIES := android-common android-support-v13
-LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-renderscript-files-under, src)
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+
LOCAL_PACKAGE_NAME := Launcher2
LOCAL_CERTIFICATE := shared
@@ -34,4 +35,6 @@
include $(BUILD_PACKAGE)
+include $(call all-subdir-makefiles)
+
endif
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 5d0f323..5206896 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -67,7 +67,7 @@
android:process="@string/process"
android:label="@string/application_name"
android:icon="@drawable/ic_launcher_home"
- android:hardwareAccelerated="@bool/config_hardwareAccelerated"
+ android:hardwareAccelerated="true"
android:largeHeap="true">
<activity
@@ -100,6 +100,18 @@
android:resource="@xml/wallpaper_picker_preview" />
</activity>
+ <activity android:name="com.android.launcher2.RocketLauncher"
+ android:label="@string/dream_name"
+ android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
+ android:hardwareAccelerated="true"
+ >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.DREAM" />
+ </intent-filter>
+ </activity>
+
<!-- Intent received used to install shortcuts from other applications -->
<receiver
android:name="com.android.launcher2.InstallShortcutReceiver"
diff --git a/res/drawable-large-hdpi/divider_launcher_holo.9.png b/res/drawable-hdpi/divider_launcher_holo.9.png
similarity index 100%
rename from res/drawable-large-hdpi/divider_launcher_holo.9.png
rename to res/drawable-hdpi/divider_launcher_holo.9.png
Binary files differ
diff --git a/res/drawable-large-hdpi/ic_generic_search.png b/res/drawable-hdpi/ic_generic_search.png
similarity index 100%
rename from res/drawable-large-hdpi/ic_generic_search.png
rename to res/drawable-hdpi/ic_generic_search.png
Binary files differ
diff --git a/res/drawable-large-hdpi/ic_voice_search.png b/res/drawable-hdpi/ic_voice_search.png
similarity index 100%
rename from res/drawable-large-hdpi/ic_voice_search.png
rename to res/drawable-hdpi/ic_voice_search.png
Binary files differ
diff --git a/res/drawable-land-hdpi/divider_launcher_holo.9.png b/res/drawable-land-hdpi/divider_launcher_holo.9.png
new file mode 100644
index 0000000..f07f6c4
--- /dev/null
+++ b/res/drawable-land-hdpi/divider_launcher_holo.9.png
Binary files differ
diff --git a/res/drawable-land-mdpi/divider_launcher_holo.9.png b/res/drawable-land-mdpi/divider_launcher_holo.9.png
new file mode 100644
index 0000000..ae77340
--- /dev/null
+++ b/res/drawable-land-mdpi/divider_launcher_holo.9.png
Binary files differ
diff --git a/res/drawable-large-mdpi/divider_launcher_holo.9.png b/res/drawable-mdpi/divider_launcher_holo.9.png
similarity index 100%
rename from res/drawable-large-mdpi/divider_launcher_holo.9.png
rename to res/drawable-mdpi/divider_launcher_holo.9.png
Binary files differ
diff --git a/res/drawable-large-mdpi/ic_generic_search.png b/res/drawable-mdpi/ic_generic_search.png
similarity index 100%
rename from res/drawable-large-mdpi/ic_generic_search.png
rename to res/drawable-mdpi/ic_generic_search.png
Binary files differ
diff --git a/res/drawable-large-mdpi/ic_voice_search.png b/res/drawable-mdpi/ic_voice_search.png
similarity index 100%
rename from res/drawable-large-mdpi/ic_voice_search.png
rename to res/drawable-mdpi/ic_voice_search.png
Binary files differ
diff --git a/res/drawable/flying_icon_bg.xml b/res/drawable/flying_icon_bg.xml
new file mode 100644
index 0000000..affd975
--- /dev/null
+++ b/res/drawable/flying_icon_bg.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:drawable="@drawable/homescreen_small_green" />
+ <item android:drawable="@android:color/transparent" />
+</selector>
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index b2b2c9f..c8a82e6 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -41,6 +41,12 @@
</com.android.launcher2.Workspace>
+ <include layout="@layout/qsb_bar"
+ android:id="@+id/qsb_bar"
+ android:layout_width="@dimen/qsb_bar_height"
+ android:layout_height="match_parent"
+ android:layout_gravity="left" />
+
<include layout="@layout/apps_customize_pane"
android:id="@+id/apps_customize_pane"
android:layout_width="match_parent"
diff --git a/res/layout-land/workspace_screen.xml b/res/layout-land/workspace_screen.xml
index f2bac59..a9faf89 100644
--- a/res/layout-land/workspace_screen.xml
+++ b/res/layout-land/workspace_screen.xml
@@ -24,7 +24,7 @@
launcher:cellWidth="@dimen/workspace_cell_width"
launcher:cellHeight="@dimen/workspace_cell_height"
- launcher:xAxisStartPadding="48dip"
+ launcher:xAxisStartPadding="@dimen/qsb_bar_height"
launcher:xAxisEndPadding="0dip"
launcher:yAxisStartPadding="0dip"
launcher:yAxisEndPadding="0dip"/>
diff --git a/res/layout-large/customize_tab_widget_indicator.xml b/res/layout-large/customize_tab_widget_indicator.xml
new file mode 100644
index 0000000..186a342
--- /dev/null
+++ b/res/layout-large/customize_tab_widget_indicator.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<com.android.launcher2.AccessibleTabView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/CustomizeTabIndicator.Wide" />
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index c7bcbb0..f05f9b6 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -36,9 +36,14 @@
<include android:id="@+id/cell3" layout="@layout/workspace_screen" />
<include android:id="@+id/cell4" layout="@layout/workspace_screen" />
<include android:id="@+id/cell5" layout="@layout/workspace_screen" />
-
</com.android.launcher2.Workspace>
+ <include layout="@layout/qsb_bar"
+ android:id="@+id/qsb_bar"
+ android:layout_width="fill_parent"
+ android:layout_height="@dimen/qsb_bar_height"
+ android:layout_gravity="top" />
+
<include layout="@layout/apps_customize_pane"
android:id="@+id/apps_customize_pane"
android:layout_width="match_parent"
diff --git a/res/layout-port/workspace_screen.xml b/res/layout-port/workspace_screen.xml
index f400c40..7a6714f 100644
--- a/res/layout-port/workspace_screen.xml
+++ b/res/layout-port/workspace_screen.xml
@@ -24,7 +24,7 @@
launcher:cellWidth="@dimen/workspace_cell_width"
launcher:cellHeight="@dimen/workspace_cell_height"
- launcher:yAxisStartPadding="8dip"
+ launcher:yAxisStartPadding="@dimen/qsb_bar_height"
launcher:yAxisEndPadding="@dimen/button_bar_height"
launcher:xAxisStartPadding="0dip"
launcher:xAxisEndPadding="0dip" />
diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml
index 05884ef..e22ba12 100644
--- a/res/layout/apps_customize_pane.xml
+++ b/res/layout/apps_customize_pane.xml
@@ -20,7 +20,7 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@drawable/apps_customize_bg_gradient">
+ android:background="#FF000000">
<!-- The layout_width of the tab bar gets overriden to align the content
with the text in the tabs in AppsCustomizeTabHost. -->
<FrameLayout
diff --git a/res/layout/qsb_bar.xml b/res/layout/qsb_bar.xml
new file mode 100644
index 0000000..5469224
--- /dev/null
+++ b/res/layout/qsb_bar.xml
@@ -0,0 +1,70 @@
+<?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.
+-->
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
+ android:focusable="false">
+
+ <!-- Search buttons container -->
+ <LinearLayout
+ android:id="@+id/qsb_search_bar"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ style="@style/SearchBar">
+ <!-- Global search icon -->
+ <ImageView
+ style="@style/SearchButton"
+ android:id="@+id/search_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_generic_search"
+ android:background="@drawable/button_bg"
+ android:onClick="onClickSearchButton"
+ android:focusable="true"
+ android:clickable="true"
+ android:contentDescription="@string/accessibility_search_button" />
+
+ <ImageView
+ style="@style/SearchButtonDivider"
+ android:id="@+id/search_divider"
+ android:src="@drawable/divider_launcher_holo"
+ android:onClick="onClickSearchButton"
+ android:focusable="false"
+ android:clickable="true" />
+
+ <!-- Voice search icon -->
+ <ImageView
+ style="@style/SearchButton"
+ android:id="@+id/voice_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_voice_search"
+ android:background="@drawable/button_bg"
+ android:onClick="onClickVoiceButton"
+ android:focusable="true"
+ android:clickable="true"
+ android:contentDescription="@string/accessibility_voice_search_button" />
+ </LinearLayout>
+
+ <!-- Drag specific targets container -->
+ <LinearLayout
+ android:id="@+id/drag_target_bar"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#FF00FF00"
+ android:visibility="gone">
+ </LinearLayout>
+</FrameLayout>
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index b3d0b2e..13519e5 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -15,7 +15,11 @@
-->
<resources>
- <dimen name="workspace_cell_width">96dip</dimen>
+<!-- QSB -->
+ <dimen name="toolbar_button_vertical_padding">12dip</dimen>
+ <dimen name="toolbar_button_horizontal_padding">12dip</dimen>
+
+ <dimen name="workspace_cell_width">106dip</dimen>
<dimen name="workspace_cell_height">74dip</dimen>
<dimen name="folder_cell_width">100dip</dimen>
<dimen name="folder_cell_height">74dip</dimen>
diff --git a/res/values-land/styles.xml b/res/values-land/styles.xml
index 251c717..50aba09 100644
--- a/res/values-land/styles.xml
+++ b/res/values-land/styles.xml
@@ -18,6 +18,23 @@
-->
<resources>
+<!-- Search Bar -->
+ <style name="SearchBar">
+ <item name="android:orientation">vertical</item>
+ </style>
+ <style name="SearchButton">
+ <item name="android:layout_gravity">center_horizontal</item>
+ <item name="android:paddingTop">@dimen/toolbar_button_vertical_padding</item>
+ <item name="android:paddingBottom">@dimen/toolbar_button_vertical_padding</item>
+ <item name="android:paddingLeft">@dimen/toolbar_button_horizontal_padding</item>
+ <item name="android:paddingRight">@dimen/toolbar_button_horizontal_padding</item>
+ </style>
+ <style name="SearchButtonDivider">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_gravity">center_horizontal</item>
+ </style>
+
<style name="HotseatButton">
<item name="android:paddingTop">12dip</item>
<item name="android:paddingBottom">12dip</item>
diff --git a/res/values-large-port/styles.xml b/res/values-large-port/styles.xml
new file mode 100644
index 0000000..ba23a89
--- /dev/null
+++ b/res/values-large-port/styles.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 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.
+*/
+-->
+
+<resources>
+ <style name="CustomizeTabIndicator.Wide" parent="TabIndicator.Wide">
+ <item name="android:paddingLeft">20dp</item>
+ <item name="android:paddingRight">20dp</item>
+ <item name="android:paddingTop">12dp</item>
+ <item name="android:paddingBottom">16dp</item>
+ <item name="android:textSize">16sp</item>
+ </style>
+</resources>
diff --git a/res/values-large/dimens.xml b/res/values-large/dimens.xml
index 10836b9..fa660e5 100644
--- a/res/values-large/dimens.xml
+++ b/res/values-large/dimens.xml
@@ -62,9 +62,6 @@
<integer name="land_all_apps_view_cellCountX">7</integer>
<integer name="land_all_apps_view_cellCountY">5</integer>
- <dimen name="toolbar_button_vertical_padding">12dip</dimen>
- <dimen name="toolbar_button_horizontal_padding">16dip</dimen>
-
<!-- height & width of the drop rectangle for the trash icon -->
<dimen name="delete_zone_vertical_drag_padding">20dip</dimen>
<dimen name="delete_zone_horizontal_drag_padding">20dip</dimen>
diff --git a/res/values-large/styles.xml b/res/values-large/styles.xml
index bcbe038..ebb26f5 100644
--- a/res/values-large/styles.xml
+++ b/res/values-large/styles.xml
@@ -50,6 +50,9 @@
<item name="android:textSize">20sp</item>
</style>
+ <style name="CustomizeTabIndicator.Wide" parent="TabIndicator.Wide">
+ </style>
+
<style name="config_orientation">
<item name="@android:screenOrientation">unspecified</item>
</style>
diff --git a/res/values-xlarge/styles.xml b/res/values-xlarge/styles.xml
new file mode 100644
index 0000000..fdf2f19
--- /dev/null
+++ b/res/values-xlarge/styles.xml
@@ -0,0 +1,23 @@
+<?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>
+ <style name="CustomizeTabIndicator.Wide" parent="TabIndicator.Wide">
+ </style>
+</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 99b1240..9d159f9 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -15,6 +15,13 @@
-->
<resources>
+<!-- Workspace -->
+ <dimen name="qsb_bar_height">56dp</dimen>
+
+<!-- QSB -->
+ <dimen name="toolbar_button_vertical_padding">12dip</dimen>
+ <dimen name="toolbar_button_horizontal_padding">16dip</dimen>
+
<!-- AllApps/Customize/AppsCustomize -->
<!-- Size of icons in Workspace/AppsCustomize -->
<dimen name="app_icon_size">50dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 0b90353..32e649d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -248,4 +248,7 @@
<!-- Text to inform the user that they can't uninstall a system application -->
<string name="uninstall_system_app_text">This is a system application and cannot be uninstalled.</string>
+
+ <!-- Title of the Android Dreams (screensaver) module -->
+ <string name="dream_name">Rocket Launcher</string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index abe6ac4..c3e6ce9 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -68,6 +68,23 @@
<item name="android:layout_marginRight">10dip</item>
</style>
+ <style name="SearchBar">
+ <item name="android:orientation">horizontal</item>
+ </style>
+ <style name="SearchButton">
+ <item name="android:layout_gravity">center_vertical</item>
+ <item name="android:paddingTop">@dimen/toolbar_button_vertical_padding</item>
+ <item name="android:paddingBottom">@dimen/toolbar_button_vertical_padding</item>
+ <item name="android:paddingLeft">@dimen/toolbar_button_horizontal_padding</item>
+ <item name="android:paddingRight">@dimen/toolbar_button_horizontal_padding</item>
+ </style>
+ <style name="SearchButtonDivider">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">match_parent</item>
+ <item name="android:layout_gravity">center_vertical</item>
+ </style>
+
+
<style name="TabIndicator">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">match_parent</item>
@@ -85,13 +102,6 @@
<item name="android:shadowRadius">1.0</item>
</style>
- <style name="SearchButton" parent="@android:style/Widget.Button.Small">
- <item name="android:paddingTop">7dip</item>
- <item name="android:paddingBottom">9dip</item>
- <item name="android:paddingLeft">10dip</item>
- <item name="android:paddingRight">10dip</item>
- </style>
-
<style name="MarketButton">
<item name="android:paddingRight">20dp</item>
<item name="android:text">@string/market</item>
diff --git a/src/com/android/launcher2/CachedTextView.java b/src/com/android/launcher2/CachedTextView.java
index d0f6dd8..ac2cc3b 100644
--- a/src/com/android/launcher2/CachedTextView.java
+++ b/src/com/android/launcher2/CachedTextView.java
@@ -107,7 +107,7 @@
int width = (int) (textCacheRight - mTextCacheLeft + (2 * xCharWidth));
int height = (int) (textCacheBottom - mTextCacheTop);
- if (width != 0 && height != 0) {
+ if (width > 0 && height > 0) {
if (mCache != null) {
if (mCache.getWidth() != width || mCache.getHeight() != height) {
mCache.recycle();
diff --git a/src/com/android/launcher2/CustomizeTrayTabHost.java b/src/com/android/launcher2/CustomizeTrayTabHost.java
index 6306bda..c6a39b3 100644
--- a/src/com/android/launcher2/CustomizeTrayTabHost.java
+++ b/src/com/android/launcher2/CustomizeTrayTabHost.java
@@ -77,19 +77,23 @@
TextView tabView;
TabWidget tabWidget = (TabWidget) findViewById(com.android.internal.R.id.tabs);
- tabView = (TextView) mInflater.inflate(R.layout.tab_widget_indicator, tabWidget, false);
+ tabView = (TextView) mInflater.inflate(
+ R.layout.customize_tab_widget_indicator, tabWidget, false);
tabView.setText(mContext.getString(R.string.widgets_tab_label));
addTab(newTabSpec(WIDGETS_TAG)
.setIndicator(tabView).setContent(contentFactory));
- tabView = (TextView) mInflater.inflate(R.layout.tab_widget_indicator, tabWidget, false);
+ tabView = (TextView) mInflater.inflate(
+ R.layout.customize_tab_widget_indicator, tabWidget, false);
tabView.setText(mContext.getString(R.string.applications_tab_label));
addTab(newTabSpec(APPLICATIONS_TAG)
.setIndicator(tabView).setContent(contentFactory));
- tabView = (TextView) mInflater.inflate(R.layout.tab_widget_indicator, tabWidget, false);
+ tabView = (TextView) mInflater.inflate(
+ R.layout.customize_tab_widget_indicator, tabWidget, false);
tabView.setText(mContext.getString(R.string.wallpapers_tab_label));
addTab(newTabSpec(WALLPAPERS_TAG)
.setIndicator(tabView).setContent(contentFactory));
- tabView = (TextView) mInflater.inflate(R.layout.tab_widget_indicator, tabWidget, false);
+ tabView = (TextView) mInflater.inflate(
+ R.layout.customize_tab_widget_indicator, tabWidget, false);
tabView.setText(mContext.getString(R.string.shortcuts_tab_label));
addTab(newTabSpec(SHORTCUTS_TAG)
.setIndicator(tabView).setContent(contentFactory));
diff --git a/src/com/android/launcher2/IconCache.java b/src/com/android/launcher2/IconCache.java
index 7e37afe..5c07cfb 100644
--- a/src/com/android/launcher2/IconCache.java
+++ b/src/com/android/launcher2/IconCache.java
@@ -24,6 +24,7 @@
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
+import android.util.Pair;
import android.util.DisplayMetrics;
import java.util.HashMap;
@@ -187,4 +188,16 @@
}
return entry;
}
+
+ public HashMap<ComponentName,Bitmap> getAllIcons() {
+ synchronized (mCache) {
+ HashMap<ComponentName,Bitmap> set = new HashMap<ComponentName,Bitmap>();
+ int i = 0;
+ for (ComponentName cn : mCache.keySet()) {
+ final CacheEntry e = mCache.get(cn);
+ set.put(cn, e.icon);
+ }
+ return set;
+ }
+ }
}
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index f8d3411..5cf8e9c 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -3152,22 +3152,34 @@
}
private void updateGlobalSearchIcon() {
- if (LauncherApplication.isScreenLarge()) {
- final View searchButton = findViewById(R.id.search_button);
- final View searchDivider = findViewById(R.id.search_divider);
+ final ImageView searchButton = (ImageView) findViewById(R.id.search_button);
+ final View searchDivider = findViewById(R.id.search_divider);
- final SearchManager searchManager =
- (SearchManager) getSystemService(Context.SEARCH_SERVICE);
- ComponentName activityName = searchManager.getGlobalSearchActivity();
- if (activityName != null) {
+ final SearchManager searchManager =
+ (SearchManager) getSystemService(Context.SEARCH_SERVICE);
+ ComponentName activityName = searchManager.getGlobalSearchActivity();
+ if (activityName != null) {
+ // In landscape mode on the Phone UI, we only have enough space to show the magnifying
+ // glass icon
+ boolean iconLoaded = false;
+ if (!LauncherApplication.isScreenLarge()) {
+ // TODO-APPS_CUSTOMIZE: Remove when the QSB fixes itself?
+ int orientation = getResources().getConfiguration().orientation;
+ if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ searchButton.setImageResource(R.drawable.ic_generic_search);
+ iconLoaded = true;
+ sGlobalSearchIcon = null;
+ }
+ }
+ if (!iconLoaded) {
sGlobalSearchIcon = updateButtonWithIconFromExternalActivity(
R.id.search_button, activityName, R.drawable.ic_generic_search);
- searchButton.setVisibility(View.VISIBLE);
- searchDivider.setVisibility(View.VISIBLE);
- } else {
- searchButton.setVisibility(View.GONE);
- searchDivider.setVisibility(View.GONE);
}
+ searchButton.setVisibility(View.VISIBLE);
+ searchDivider.setVisibility(View.VISIBLE);
+ } else {
+ searchButton.setVisibility(View.GONE);
+ searchDivider.setVisibility(View.GONE);
}
}
@@ -3176,21 +3188,19 @@
}
private void updateVoiceSearchIcon() {
- if (LauncherApplication.isScreenLarge()) {
- final View searchDivider = findViewById(R.id.search_divider);
- final View voiceButton = findViewById(R.id.voice_button);
+ final View searchDivider = findViewById(R.id.search_divider);
+ final View voiceButton = findViewById(R.id.voice_button);
- Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
- ComponentName activityName = intent.resolveActivity(getPackageManager());
- if (activityName != null) {
- sVoiceSearchIcon = updateButtonWithIconFromExternalActivity(
- R.id.voice_button, activityName, R.drawable.ic_voice_search);
- searchDivider.setVisibility(View.VISIBLE);
- voiceButton.setVisibility(View.VISIBLE);
- } else {
- searchDivider.setVisibility(View.GONE);
- voiceButton.setVisibility(View.GONE);
- }
+ Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
+ ComponentName activityName = intent.resolveActivity(getPackageManager());
+ if (activityName != null) {
+ sVoiceSearchIcon = updateButtonWithIconFromExternalActivity(
+ R.id.voice_button, activityName, R.drawable.ic_voice_search);
+ searchDivider.setVisibility(View.VISIBLE);
+ voiceButton.setVisibility(View.VISIBLE);
+ } else {
+ searchDivider.setVisibility(View.GONE);
+ voiceButton.setVisibility(View.GONE);
}
}
diff --git a/src/com/android/launcher2/RocketLauncher.java b/src/com/android/launcher2/RocketLauncher.java
new file mode 100644
index 0000000..1c6510f
--- /dev/null
+++ b/src/com/android/launcher2/RocketLauncher.java
@@ -0,0 +1,426 @@
+/*);
+ * 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.
+ */
+
+// TODO:
+// background stellar matter:
+// - add some slow horizontal parallax motion, or perhaps veeeeery gradual outward drift
+
+package com.android.launcher2;
+
+import android.animation.AnimatorSet;
+import android.animation.PropertyValuesHolder;
+import android.animation.ObjectAnimator;
+import android.animation.TimeAnimator;
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.support.v13.dreams.BasicDream;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Pair;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import java.util.HashMap;
+import java.util.Random;
+
+import com.android.launcher.R;
+
+public class RocketLauncher extends BasicDream {
+ public static final boolean ROCKET_LAUNCHER = true;
+
+ public static class Board extends FrameLayout
+ {
+ public static final boolean FIXED_STARS = true;
+ public static final boolean FLYING_STARS = true;
+ public static final int NUM_ICONS = 20;
+
+ public static final float MANEUVERING_THRUST_SCALE = 0.1f; // tenth speed
+ private boolean mManeuveringThrusters = false;
+ private float mSpeedScale = 1.0f;
+
+ public static final int LAUNCH_ZOOM_TIME = 400; // ms
+
+ HashMap<ComponentName, Bitmap> mIcons;
+ ComponentName[] mComponentNames;
+
+ static Random sRNG = new Random();
+
+ static float lerp(float a, float b, float f) {
+ return (b-a)*f + a;
+ }
+
+ static float randfrange(float a, float b) {
+ return lerp(a, b, sRNG.nextFloat());
+ }
+
+ static int randsign() {
+ return sRNG.nextBoolean() ? 1 : -1;
+ }
+
+ static <E> E pick(E[] array) {
+ if (array.length == 0) return null;
+ return array[sRNG.nextInt(array.length)];
+ }
+
+ public class FlyingIcon extends ImageView {
+ public static final float VMAX = 1000.0f;
+ public static final float VMIN = 100.0f;
+ public static final float ANGULAR_VMAX = 45f;
+ public static final float ANGULAR_VMIN = 0f;
+ public static final float SCALE_MIN = 0.5f;
+ public static final float SCALE_MAX = 4f;
+
+ public float v, vr;
+
+ public final float[] hsv = new float[3];
+
+ public float angle, anglex, angley;
+ public float fuse;
+ public float dist;
+ public float endscale;
+ public float boardCenterX, boardCenterY;
+
+ public ComponentName component;
+
+ public FlyingIcon(Context context, AttributeSet as) {
+ super(context, as);
+ setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+ setBackgroundResource(R.drawable.flying_icon_bg);
+ //android.util.Log.d("RocketLauncher", "ctor: " + this);
+ hsv[1] = 1f;
+ hsv[2] = 1f;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (!mManeuveringThrusters || component == null) {
+ return false;
+ }
+ if (getAlpha() < 0.5f) {
+ setPressed(false);
+ return false;
+ }
+
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ setPressed(true);
+ Board.this.resetWarpTimer();
+ break;
+ case MotionEvent.ACTION_MOVE:
+ final Rect hit = new Rect();
+ final Point offset = new Point();
+ getGlobalVisibleRect(hit, offset);
+ final int globx = (int) event.getX() + offset.x;
+ final int globy = (int) event.getY() + offset.y;
+ setPressed(hit.contains(globx, globy));
+ Board.this.resetWarpTimer();
+ break;
+ case MotionEvent.ACTION_UP:
+ if (isPressed()) {
+ setPressed(false);
+ postDelayed(new Runnable() {
+ public void run() {
+ try {
+ getContext().startActivity(new Intent(Intent.ACTION_MAIN)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .setComponent(component));
+ } catch (android.content.ActivityNotFoundException e) {
+ } catch (SecurityException e) {
+ }
+ }
+ }, LAUNCH_ZOOM_TIME);
+ endscale = 0;
+ AnimatorSet s = new AnimatorSet();
+ s.playTogether(
+ ObjectAnimator.ofFloat(this, "scaleX", 15f),
+ ObjectAnimator.ofFloat(this, "scaleY", 15f),
+ ObjectAnimator.ofFloat(this, "alpha", 0f)
+ );
+
+ // make sure things are still moving until the very last instant the
+ // activity is visible
+ s.setDuration((int)(LAUNCH_ZOOM_TIME * 1.25));
+ s.setInterpolator(new android.view.animation.AccelerateInterpolator(3));
+ s.start();
+ }
+ break;
+ }
+ return true;
+ }
+
+ public String toString() {
+ return String.format("<'%s' @ (%.1f, %.1f) v=%.1f a=%.1f dist/fuse=%.1f/%.1f>",
+ "icon", getX(), getY(), v, angle, dist, fuse);
+ }
+
+ public void randomizeIcon() {
+ component = pick(mComponentNames);
+ setImageBitmap(mIcons.get(component));
+ }
+
+ public void randomize() {
+ v = randfrange(VMIN, VMAX);
+ angle = randfrange(0, 360f);
+ anglex = (float) Math.sin(angle / 180. * Math.PI);
+ angley = (float) Math.cos(angle / 180. * Math.PI);
+ vr = randfrange(ANGULAR_VMIN, ANGULAR_VMAX) * randsign();
+ endscale = randfrange(SCALE_MIN, SCALE_MAX);
+
+ randomizeIcon();
+ }
+ public void reset() {
+ randomize();
+ boardCenterX = (Board.this.getWidth() - getWidth()) / 2;
+ boardCenterY = (Board.this.getHeight() - getHeight()) / 2;
+ setX(boardCenterX);
+ setY(boardCenterY);
+ fuse = (float) Math.max(boardCenterX, boardCenterY);
+ setRotation(180-angle);
+ setScaleX(0f);
+ setScaleY(0f);
+ dist = 0;
+ setAlpha(0f);
+ }
+ public void update(float dt) {
+ dist += v * dt;
+ setX(getX() + anglex * v * dt);
+ setY(getY() + angley * v * dt);
+ //setRotation(getRotation() + vr * dt);
+ if (endscale > 0) {
+ float scale = lerp(0, endscale, (float) Math.sqrt(dist / fuse));
+ setScaleX(scale * lerp(1f, 0.75f, (float) Math.pow((v-VMIN)/(VMAX-VMIN),3)));
+ setScaleY(scale * lerp(1f, 1.5f, (float) Math.pow((v-VMIN)/(VMAX-VMIN),3)));
+ final float q1 = fuse*0.15f;
+ final float q4 = fuse*0.75f;
+ if (dist < q1) {
+ setAlpha((float) Math.sqrt(dist/q1));
+ } else if (dist > q4) {
+ setAlpha((dist >= fuse) ? 0f : (1f-(float)Math.pow((dist-q4)/(fuse-q4),2)));
+ } else {
+ setAlpha(1f);
+ }
+ }
+ }
+ }
+
+ public class FlyingStar extends FlyingIcon {
+ public FlyingStar(Context context, AttributeSet as) {
+ super(context, as);
+ }
+ public void randomizeIcon() {
+ setImageResource(R.drawable.widget_resize_handle_bottom);
+ }
+ public void randomize() {
+ super.randomize();
+ v = randfrange(VMAX*0.75f, VMAX*2f); // fasticate
+ endscale = randfrange(1f, 2f); // ensmallen
+ }
+ }
+
+ TimeAnimator mAnim;
+
+ public Board(Context context, AttributeSet as) {
+ super(context, as);
+
+ setBackgroundColor(0xFF000000);
+
+ LauncherApplication app = (LauncherApplication)context.getApplicationContext();
+ mIcons = app.getIconCache().getAllIcons();
+ mComponentNames = new ComponentName[mIcons.size()];
+ mComponentNames = mIcons.keySet().toArray(mComponentNames);
+ }
+
+ private void reset() {
+ removeAllViews();
+
+ final ViewGroup.LayoutParams wrap = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ if (FIXED_STARS) {
+ for(int i=0; i<20; i++) {
+ ImageView fixedStar = new ImageView(getContext(), null);
+ fixedStar.setImageResource(R.drawable.widget_resize_handle_bottom);
+ final float s = randfrange(0.25f, 0.75f);
+ fixedStar.setScaleX(s);
+ fixedStar.setScaleY(s);
+ fixedStar.setAlpha(0.75f);
+ addView(fixedStar, wrap);
+ fixedStar.setX(randfrange(0, getWidth()));
+ fixedStar.setY(randfrange(0, getHeight()));
+ }
+ }
+
+ for(int i=0; i<NUM_ICONS*2; i++) {
+ FlyingIcon nv = (FLYING_STARS && (i < NUM_ICONS))
+ ? new FlyingStar(getContext(), null)
+ : new FlyingIcon(getContext(), null);
+ addView(nv, wrap);
+ nv.reset();
+ }
+
+ mAnim = new TimeAnimator();
+ mAnim.setTimeListener(new TimeAnimator.TimeListener() {
+ public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
+ // setRotation(totalTime * 0.01f); // not as cool as you would think
+
+ final int START_ZOOM_TIME = 3000;
+ if (totalTime < START_ZOOM_TIME) {
+ final float x = totalTime/(float)START_ZOOM_TIME;
+ final float s = 1f-(float)Math.pow(x-1, 4);
+ setScaleX(s); setScaleY(s);
+ } else {
+ setScaleX(1.0f); setScaleY(1.0f);
+ }
+
+ if (mManeuveringThrusters) {
+ if (mSpeedScale > MANEUVERING_THRUST_SCALE) {
+ mSpeedScale -= (2*deltaTime/1000f);
+ }
+ if (mSpeedScale < MANEUVERING_THRUST_SCALE) {
+ mSpeedScale = MANEUVERING_THRUST_SCALE;
+ }
+ } else {
+ if (mSpeedScale < 1.0f) {
+ mSpeedScale += (deltaTime/1000f);
+ }
+ if (mSpeedScale > 1.0f) {
+ mSpeedScale = 1.0f;
+ }
+ }
+
+ for (int i=0; i<getChildCount(); i++) {
+ View v = getChildAt(i);
+ if (!(v instanceof FlyingIcon)) continue;
+ FlyingIcon nv = (FlyingIcon) v;
+ nv.update(deltaTime / 1000f * mSpeedScale);
+ final float scaledWidth = nv.getWidth() * nv.getScaleX();
+ final float scaledHeight = nv.getHeight() * nv.getScaleY();
+ if ( nv.getX() + scaledWidth < 0
+ || nv.getX() - scaledWidth > getWidth()
+ || nv.getY() + scaledHeight < 0
+ || nv.getY() - scaledHeight > getHeight())
+ {
+ nv.reset();
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
+
+ reset();
+ mAnim.start();
+ }
+
+ protected void onSizeChanged (int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w,h,oldw,oldh);
+ mAnim.cancel();
+ reset();
+ mAnim.start();
+ }
+
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mAnim.cancel();
+ }
+
+ @Override
+ public boolean isOpaque() {
+ return true;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent e) {
+ // we want to eat touch events ourselves if we're in warp speed
+ return (!(ROCKET_LAUNCHER && mManeuveringThrusters));
+ }
+
+ final Runnable mEngageWarp = new Runnable() {
+ @Override
+ public void run() {
+ mManeuveringThrusters = false;
+ }
+ };
+ public void resetWarpTimer() {
+ final Handler h = getHandler();
+ h.removeCallbacks(mEngageWarp);
+ h.postDelayed(mEngageWarp, 5000);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (!ROCKET_LAUNCHER) {
+ return true;
+ }
+
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ if (!mManeuveringThrusters) {
+ mManeuveringThrusters = true;
+ resetWarpTimer();
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+
+ DisplayMetrics metrics = new DisplayMetrics();
+ getWindowManager().getDefaultDisplay().getMetrics(metrics);
+ final int longside = metrics.widthPixels > metrics.heightPixels
+ ? metrics.widthPixels : metrics.heightPixels;
+
+ Board b = new Board(this, null);
+ setContentView(b, new ViewGroup.LayoutParams(longside, longside));
+ b.setX((metrics.widthPixels - longside) / 2);
+ b.setY((metrics.heightPixels - longside) / 2);
+ }
+
+ @Override
+ public void onUserInteraction() {
+ if (!ROCKET_LAUNCHER) {
+ finish();
+ }
+ }
+}
diff --git a/tests/Android.mk b/tests/Android.mk
new file mode 100644
index 0000000..84e9559
--- /dev/null
+++ b/tests/Android.mk
@@ -0,0 +1,15 @@
+# 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.
+#
+include $(call all-subdir-makefiles)
diff --git a/tests/stress/Android.mk b/tests/stress/Android.mk
new file mode 100644
index 0000000..da22bb9
--- /dev/null
+++ b/tests/stress/Android.mk
@@ -0,0 +1,33 @@
+# 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.
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := LauncherRotationStressTest
+
+LOCAL_CERTIFICATE := shared
+
+LOCAL_INSTRUMENTATION_FOR := Launcher2
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/tests/stress/AndroidManifest.xml b/tests/stress/AndroidManifest.xml
new file mode 100644
index 0000000..ce5dbe4
--- /dev/null
+++ b/tests/stress/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="2.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.launcher.stress.launcherrotation">
+
+ <uses-sdk android:minSdkVersion="8" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.launcher"
+ android:label="Rotation stress test using Launcher2">
+ </instrumentation>
+</manifest>
diff --git a/tests/stress/src/com/android/launcher2/stress/LauncherRotationStressTest.java b/tests/stress/src/com/android/launcher2/stress/LauncherRotationStressTest.java
new file mode 100644
index 0000000..3d787f2
--- /dev/null
+++ b/tests/stress/src/com/android/launcher2/stress/LauncherRotationStressTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+package com.android.launcher2.stress;
+
+
+import com.android.launcher2.Launcher;
+
+import android.content.pm.ActivityInfo;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.TimedTest;
+import android.util.Log;
+
+/**
+ * Run rotation stress test using Launcher2 for 50 iterations.
+ */
+public class LauncherRotationStressTest extends ActivityInstrumentationTestCase2<Launcher> {
+
+ private static final int NUM_ITERATIONS = 50;
+ private static final String LOG_TAG = "LauncherRotationStressTest";
+
+ public LauncherRotationStressTest() {
+ super(Launcher.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @TimedTest(includeDetailedStats=true)
+ public void testLauncherRotationStress() throws Exception {
+ Launcher launcher = getActivity();
+ for (int i = 0; i < NUM_ITERATIONS; i++) {
+ Log.i(LOG_TAG, "Starting LauncherRotationStressTest " + (i + 1) + " of " +
+ NUM_ITERATIONS);
+ getInstrumentation().waitForIdleSync();
+ SystemClock.sleep(500);
+ launcher.setRequestedOrientation(
+ ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ getInstrumentation().waitForIdleSync();
+ SystemClock.sleep(500);
+ launcher.setRequestedOrientation(
+ ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ Log.i(LOG_TAG, "Finished LauncherRotationStressTest " + (i + 1) + " of " +
+ NUM_ITERATIONS);
+ }
+ }
+}