Code drop from //branches/cupcake/...@124589

This commit is contained in:
The Android Open Source Project 2008-12-17 18:05:58 -08:00
parent c8f00b61c6
commit d097a1880f
47 changed files with 2521 additions and 453 deletions

View File

@ -17,41 +17,59 @@
** limitations under the License. ** limitations under the License.
*/ */
--> -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest
package="com.android.launcher" xmlns:android="http://schemas.android.com/apk/res/android"
android:sharedUserId="android.uid.shared"> package="com.android.launcher"
android:sharedUserId="android.uid.shared">
<permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" <permission
android:permissionGroup="android.permission-group.SYSTEM_TOOLS" android:name="com.android.launcher.permission.INSTALL_SHORTCUT"
android:protectionLevel="normal" android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:label="@string/permlab_install_shortcut" android:protectionLevel="normal"
android:description="@string/permdesc_install_shortcut"/> android:label="@string/permlab_install_shortcut"
<permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" android:description="@string/permdesc_install_shortcut" />
android:permissionGroup="android.permission-group.SYSTEM_TOOLS" <permission
android:protectionLevel="normal" android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"
android:label="@string/permlab_uninstall_shortcut" android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:description="@string/permdesc_uninstall_shortcut"/> android:protectionLevel="normal"
android:label="@string/permlab_uninstall_shortcut"
android:description="@string/permdesc_uninstall_shortcut"/>
<permission
android:name="com.android.launcher.permission.READ_SETTINGS"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="normal"
android:label="@string/permlab_read_settings"
android:description="@string/permdesc_read_settings"/>
<permission
android:name="com.android.launcher.permission.WRITE_SETTINGS"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="normal"
android:label="@string/permlab_write_settings"
android:description="@string/permdesc_write_settings"/>
<uses-permission android:name="android.permission.CALL_PHONE"/> <uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/> <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<uses-permission android:name="android.permission.GET_TASKS"/> <uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.SET_WALLPAPER" /> <uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" /> <uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
<uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"/> <uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS" />
<application <application
android:name="LauncherApplication"
android:process="android.process.acore" android:process="android.process.acore"
android:label="@string/application_name" android:label="@string/application_name"
android:icon="@drawable/ic_launcher_home"> android:icon="@drawable/ic_launcher_home">
<activity android:name="Launcher" <activity
android:launchMode="singleTask" android:name="Launcher"
android:clearTaskOnLaunch="true" android:launchMode="singleTask"
android:stateNotNeeded="true" android:clearTaskOnLaunch="true"
android:theme="@style/Theme" android:stateNotNeeded="true"
android:configChanges="mcc|mnc"> android:theme="@style/Theme">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME"/> <category android:name="android.intent.category.HOME"/>
@ -60,7 +78,8 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name="WallpaperChooser" <activity
android:name="WallpaperChooser"
android:label="@string/pick_wallpaper" android:label="@string/pick_wallpaper"
android:icon="@drawable/ic_launcher_gallery"> android:icon="@drawable/ic_launcher_gallery">
<intent-filter> <intent-filter>
@ -70,21 +89,34 @@
</activity> </activity>
<!-- Enable system-default search mode for any activity in Home --> <!-- Enable system-default search mode for any activity in Home -->
<meta-data android:name="android.app.default_searchable" android:value="*" /> <meta-data
android:name="android.app.default_searchable"
android:value="*" />
<receiver android:name=".InstallShortcutReceiver" <!-- Intent received used to install shortcuts from other applications -->
android:permission="com.android.launcher.permission.INSTALL_SHORTCUT"> <receiver
android:name=".InstallShortcutReceiver"
android:permission="com.android.launcher.permission.INSTALL_SHORTCUT">
<intent-filter> <intent-filter>
<action android:name="com.android.launcher.action.INSTALL_SHORTCUT" /> <action android:name="com.android.launcher.action.INSTALL_SHORTCUT" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".UninstallShortcutReceiver" <!-- Intent received used to uninstall shortcuts from other applications -->
android:permission="com.android.launcher.permission.UNINSTALL_SHORTCUT"> <receiver
android:name=".UninstallShortcutReceiver"
android:permission="com.android.launcher.permission.UNINSTALL_SHORTCUT">
<intent-filter> <intent-filter>
<action android:name="com.android.launcher.action.UNINSTALL_SHORTCUT" /> <action android:name="com.android.launcher.action.UNINSTALL_SHORTCUT" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<!-- The settings provider contains Home's data, like the workspace favorites -->
<provider
android:name="LauncherProvider"
android:authorities="com.android.launcher.settings"
android:writePermission="com.android.launcher.permission.WRITE_SETTINGS"
android:readPermission="com.android.launcher.permission.READ_SETTINGS" />
</application> </application>
</manifest> </manifest>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -15,15 +15,17 @@
--> -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android" <TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/name"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="88dip" android:layout_height="88dip"
android:paddingTop="6dip" android:paddingTop="5dip"
android:paddingBottom="3dip" android:paddingBottom="2dip"
android:drawablePadding="0dip" android:drawablePadding="0dip"
android:textSize="13dip" android:textSize="13dip"
android:maxLines="2" android:maxLines="2"
android:ellipsize="end" android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:textColor="@color/bright_text_dark_focused" android:textColor="@color/bright_text_dark_focused"
android:gravity="top|center_horizontal" /> android:gravity="top|center_horizontal" />

View File

@ -16,6 +16,7 @@
<com.android.launcher.DragLayer <com.android.launcher.DragLayer
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher" xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
android:id="@+id/drag_layer" android:id="@+id/drag_layer"
@ -30,9 +31,9 @@
launcher:defaultScreen="1"> launcher:defaultScreen="1">
<include layout="@layout/workspace_screen" /> <include android:id="@+id/cell1" layout="@layout/workspace_screen" />
<include layout="@layout/workspace_screen" /> <include android:id="@+id/cell2" layout="@layout/workspace_screen" />
<include layout="@layout/workspace_screen" /> <include android:id="@+id/cell3" layout="@layout/workspace_screen" />
</com.android.launcher.Workspace> </com.android.launcher.Workspace>
@ -42,19 +43,24 @@
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:orientation="horizontal" android:orientation="horizontal"
android:bottomOffset="7px" androidprv:bottomOffset="7px"
android:handle="@+id/all_apps" androidprv:handle="@+id/all_apps"
android:content="@+id/content"> androidprv:content="@+id/content">
<ImageView <com.android.launcher.HandleView
android:id="@id/all_apps" android:id="@id/all_apps"
android:layout_width="56dip"
android:layout_height="fill_parent"
android:background="@drawable/handle"
android:focusable="true" android:focusable="true"
android:clickable="true" android:clickable="true"
android:scaleType="center" android:scaleType="center"
android:src="@drawable/handle_icon" android:src="@drawable/handle_icon"
android:background="@drawable/handle"
android:layout_height="fill_parent" launcher:direction="vertical" />
android:layout_width="56dip" />
<com.android.launcher.AllAppsGridView <com.android.launcher.AllAppsGridView
android:id="@id/content" android:id="@id/content"

View File

@ -0,0 +1,49 @@
<?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.
*/
-->
<com.android.launcher.LiveFolder xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical">
<Button
android:id="@+id/close"
android:background="@drawable/box_launcher_top"
android:gravity="left|center_vertical"
android:textSize="14sp"
android:textColor="#404040"
android:textStyle="bold"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<GridView
android:id="@id/content"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:background="@drawable/box_launcher_bottom"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarStyle="insideInset"
android:drawSelectorOnTop="false"
android:listSelector="@drawable/grid_selector"
android:verticalSpacing="10dip"
android:numColumns="5" />
</com.android.launcher.LiveFolder>

View File

@ -0,0 +1,21 @@
<?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.
*/
-->
<com.android.launcher.LiveFolderIcon xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/WorkspaceIcon.Landscape" />

View File

@ -15,15 +15,17 @@
--> -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android" <TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/name"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="88dip" android:layout_height="88dip"
android:paddingTop="6dip" android:paddingTop="5dip"
android:paddingBottom="3dip" android:paddingBottom="2dip"
android:drawablePadding="0dip" android:drawablePadding="0dip"
android:textSize="13dip" android:textSize="13dip"
android:maxLines="2" android:maxLines="2"
android:ellipsize="end" android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:textColor="@color/bright_text_dark_focused" android:textColor="@color/bright_text_dark_focused"
android:gravity="top|center_horizontal" /> android:gravity="top|center_horizontal" />

View File

@ -16,6 +16,7 @@
<com.android.launcher.DragLayer <com.android.launcher.DragLayer
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher" xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
android:id="@+id/drag_layer" android:id="@+id/drag_layer"
@ -30,9 +31,9 @@
launcher:defaultScreen="1"> launcher:defaultScreen="1">
<include layout="@layout/workspace_screen" /> <include android:id="@+id/cell1" layout="@layout/workspace_screen" />
<include layout="@layout/workspace_screen" /> <include android:id="@+id/cell2" layout="@layout/workspace_screen" />
<include layout="@layout/workspace_screen" /> <include android:id="@+id/cell3" layout="@layout/workspace_screen" />
</com.android.launcher.Workspace> </com.android.launcher.Workspace>
@ -41,20 +42,25 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:topOffset="5px" androidprv:topOffset="5px"
android:bottomOffset="7px" androidprv:bottomOffset="7px"
android:handle="@+id/all_apps" androidprv:handle="@+id/all_apps"
android:content="@+id/content"> androidprv:content="@+id/content">
<ImageView <com.android.launcher.HandleView
android:id="@id/all_apps" android:id="@id/all_apps"
android:layout_width="fill_parent"
android:layout_height="56dip"
android:background="@drawable/handle"
android:focusable="true" android:focusable="true"
android:clickable="true" android:clickable="true"
android:scaleType="center" android:scaleType="center"
android:src="@drawable/handle_icon" android:src="@drawable/handle_icon"
android:background="@drawable/handle"
android:layout_width="fill_parent" launcher:direction="horizontal" />
android:layout_height="56dip" />
<com.android.launcher.AllAppsGridView <com.android.launcher.AllAppsGridView
android:id="@id/content" android:id="@id/content"

View File

@ -0,0 +1,49 @@
<?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.
*/
-->
<com.android.launcher.LiveFolder xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical">
<Button
android:id="@+id/close"
android:background="@drawable/box_launcher_top"
android:gravity="left|center_vertical"
android:textSize="14sp"
android:textColor="#404040"
android:textStyle="bold"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<GridView
android:id="@id/content"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:background="@drawable/box_launcher_bottom"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarStyle="insideInset"
android:drawSelectorOnTop="false"
android:listSelector="@drawable/grid_selector"
android:verticalSpacing="10dip"
android:numColumns="4" />
</com.android.launcher.LiveFolder>

View File

@ -0,0 +1,21 @@
<?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.
*/
-->
<com.android.launcher.LiveFolderIcon xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/WorkspaceIcon.Portrait" />

View File

@ -0,0 +1,70 @@
<?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.
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingLeft="10dip"
android:orientation="horizontal">
<ImageView android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:scaleType="center" />
<LinearLayout
android:layout_width="0dip"
android:layout_weight="1.0"
android:layout_height="fill_parent"
android:paddingLeft="8dip"
android:paddingRight="8dip"
android:orientation="vertical"
android:gravity="center_vertical">
<TextView android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/name"
android:layout_alignLeft="@id/name"
android:singleLine="true"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,42 @@
<?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.
*/
-->
<com.android.launcher.LiveFolder xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical">
<Button
android:id="@+id/close"
android:background="@drawable/box_launcher_top"
android:gravity="left|center_vertical"
android:textSize="14sp"
android:textColor="#404040"
android:textStyle="bold"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<ListView
android:id="@id/content"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:cacheColorHint="#00000000"
android:background="@drawable/box_launcher_bottom" />
</com.android.launcher.LiveFolder>

View File

@ -34,15 +34,15 @@
android:hint="@string/search_hint" android:hint="@string/search_hint"
android:focusableInTouchMode="false" android:focusableInTouchMode="false"
android:singleLine="true" android:singleLine="true"
android:selectAllOnFocus="true"
android:completionThreshold="1" android:completionThreshold="1"
/> />
<Button <ImageButton android:id="@+id/search_go_btn"
android:id="@+id/go" android:layout_marginLeft="1dip"
android:layout_marginLeft="4dip"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/go"/> android:src="@android:drawable/ic_btn_search"
/>
</com.android.launcher.Search> </com.android.launcher.Search>

46
res/values-de/strings.xml Normal file
View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="application_name">"Startseite"</string>
<string name="folder_name">"Ordner"</string>
<string name="chooser_wallpaper">"Hintergrund auswählen"</string>
<string name="wallpaper_instructions">"Hintergrund festlegen"</string>
<string name="pick_wallpaper">"Galerie"</string>
<string name="activity_not_found">"Anwendung ist nicht auf dem Telefon installiert."</string>
<!-- no translation found for rename_folder_label (5646236631298452787) -->
<skip />
<string name="rename_folder_title">"Ordner umbenennen"</string>
<string name="rename_action">"OK"</string>
<string name="cancel_action">"Abbrechen"</string>
<!-- no translation found for menu_item_add_item (6233177331075781114) -->
<skip />
<string name="group_applications">"Anwendung"</string>
<string name="group_shortcuts">"Verknüpfung"</string>
<!-- no translation found for group_live_folders (3057578584715591220) -->
<skip />
<string name="group_widgets">"Widget"</string>
<string name="group_wallpapers">"Hintergrund"</string>
<string name="add_folder">"Ordner"</string>
<string name="add_clock">"Uhr"</string>
<string name="add_photo_frame">"Bildrahmen"</string>
<string name="add_search">"Suchen"</string>
<string name="out_of_space">"Auf der Startseite ist kein Platz mehr vorhanden."</string>
<string name="menu_add">"Hinzufügen"</string>
<string name="menu_wallpaper">"Hintergrund"</string>
<string name="menu_search">"Suchen"</string>
<string name="menu_notifications">"Benachrichtigungen"</string>
<string name="menu_settings">"Einstellungen"</string>
<string name="permlab_install_shortcut">"Verknüpfungen installieren"</string>
<string name="permdesc_install_shortcut">"Ermöglicht einer Anwendung das Hinzufügen von Verknüpfungen ohne Eingriff des Benutzers."</string>
<string name="permlab_uninstall_shortcut">"Verknüpfungen deinstallieren"</string>
<string name="permdesc_uninstall_shortcut">"Ermöglicht einer Anwendung das Entfernen von Verknüpfungen ohne Eingriff des Benutzers."</string>
<!-- no translation found for permlab_read_settings (3452408290738106747) -->
<skip />
<!-- no translation found for permdesc_read_settings (8377434937176025492) -->
<skip />
<!-- no translation found for permlab_write_settings (1360567537236705628) -->
<skip />
<!-- no translation found for permdesc_write_settings (1098648778383349818) -->
<skip />
<string name="search_hint">"Google-Suche"</string>
</resources>

46
res/values-ja/strings.xml Normal file
View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="application_name">"ホーム"</string>
<string name="folder_name">"フォルダ"</string>
<string name="chooser_wallpaper">"壁紙を選択"</string>
<string name="wallpaper_instructions">"壁紙に設定"</string>
<string name="pick_wallpaper">"壁紙ギャラリー"</string>
<string name="activity_not_found">"アプリケーションがインストールされていません。"</string>
<!-- no translation found for rename_folder_label (5646236631298452787) -->
<skip />
<string name="rename_folder_title">"フォルダ名を変更"</string>
<string name="rename_action">"OK"</string>
<string name="cancel_action">"キャンセル"</string>
<!-- no translation found for menu_item_add_item (6233177331075781114) -->
<skip />
<string name="group_applications">"アプリケーション"</string>
<string name="group_shortcuts">"ショートカット"</string>
<!-- no translation found for group_live_folders (3057578584715591220) -->
<skip />
<string name="group_widgets">"ウィジェット"</string>
<string name="group_wallpapers">"壁紙"</string>
<string name="add_folder">"フォルダ"</string>
<string name="add_clock">"時計"</string>
<string name="add_photo_frame">"写真フレーム"</string>
<string name="add_search">"検索"</string>
<string name="out_of_space">"このホーム画面には空きスペースがありません。"</string>
<string name="menu_add">"追加"</string>
<string name="menu_wallpaper">"壁紙"</string>
<string name="menu_search">"検索"</string>
<string name="menu_notifications">"通知"</string>
<string name="menu_settings">"設定"</string>
<string name="permlab_install_shortcut">"ショートカットのインストール"</string>
<string name="permdesc_install_shortcut">"ユーザー操作なしで、ショートカットをアプリケーションで追加できるようにします。"</string>
<string name="permlab_uninstall_shortcut">"ショートカットのアンインストール"</string>
<string name="permdesc_uninstall_shortcut">"ユーザー操作なしで、ショートカットをアプリケーションで削除できるようにします。"</string>
<!-- no translation found for permlab_read_settings (3452408290738106747) -->
<skip />
<!-- no translation found for permdesc_read_settings (8377434937176025492) -->
<skip />
<!-- no translation found for permlab_write_settings (1360567537236705628) -->
<skip />
<!-- no translation found for permdesc_write_settings (1098648778383349818) -->
<skip />
<string name="search_hint">"Google検索"</string>
</resources>

View File

@ -17,6 +17,16 @@
--> -->
<resources> <resources>
<!-- Orientation of a widget. -->
<attr name="direction">
<!-- Vertical widget. -->
<enum name="vertical" value="0" />
<!-- Horizontal widget. -->
<enum name="horizontal" value="1" />
</attr>
<skip />
<!-- Workspace specific attributes. These attributes are used to customize <!-- Workspace specific attributes. These attributes are used to customize
the workspace in XML files. --> the workspace in XML files. -->
<declare-styleable name="Workspace"> <declare-styleable name="Workspace">
@ -49,12 +59,14 @@
a DeleteZone view in XML files. --> a DeleteZone view in XML files. -->
<declare-styleable name="DeleteZone"> <declare-styleable name="DeleteZone">
<!-- Orientation of the delete zone. --> <!-- Orientation of the delete zone. -->
<attr name="direction"> <attr name="direction" />
<!-- Vertical delete zone. --> </declare-styleable>
<enum name="vertical" value="0" />
<!-- Horizontal delete zone. This is the default value. --> <!-- HandleView specific attributes. These attributes are used to customize
<enum name="horizontal" value="1" /> a HandleView view in XML files. -->
</attr> <declare-styleable name="HandleView">
<!-- Orientation of the handle. -->
<attr name="direction" />
</declare-styleable> </declare-styleable>
</resources> </resources>

View File

@ -19,52 +19,66 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- General --> <!-- General -->
<skip />
<!-- Application name --> <!-- Application name -->
<string name="application_name">Home</string> <string name="application_name">Home</string>
<!-- Default folder name --> <!-- Default folder name -->
<string name="folder_name">Folder</string> <string name="folder_name">Folder</string>
<!-- Unused string -->
<string name="all_apps_folder_name">Applications</string>
<!-- Unused string -->
<string name="delete_name">Delete</string>
<!-- Title of dialog that appears after user selects Wallpaper from menu --> <!-- Title of dialog that appears after user selects Wallpaper from menu -->
<string name="chooser_wallpaper">Select wallpaper from</string> <string name="chooser_wallpaper">Select wallpaper from</string>
<!-- Button label on Wallpaper Gallery screen; user selects this button to set a specific wallpaper --> <!-- Button label on Wallpaper Gallery screen; user selects this button to set a specific wallpaper -->
<string name="wallpaper_instructions">Set wallpaper</string> <string name="wallpaper_instructions">Set wallpaper</string>
<!-- Option in "Select wallpaper from" dialog box --> <!-- Option in "Select wallpaper from" dialog box -->
<string name="pick_wallpaper">Wallpaper gallery</string> <string name="pick_wallpaper">Wallpaper gallery</string>
<!--Displayed when user selects a shortcut for an app that was uninstalled --> <!-- Displayed when user selects a shortcut for an app that was uninstalled -->
<string name="activity_not_found">Application is not installed on your phone.</string> <string name="activity_not_found">Application is not installed on your phone.</string>
<!-- Folders --> <!-- Folders -->
<skip />
<!-- Label of Folder name field in Rename folder dialog box --> <!-- Label of Folder name field in Rename folder dialog box -->
<string name="rename_folder_label">Folder name:</string> <string name="rename_folder_label">Folder name</string>
<!-- Title of dialog box --> <!-- Title of dialog box -->
<string name="rename_folder_title">Rename folder</string> <string name="rename_folder_title">Rename folder</string>
<!-- Buttons in Rename folder dialog box: --> <!-- Buttons in Rename folder dialog box -->
<string name="rename_action">OK</string> <string name="rename_action">OK</string>
<!-- Buttons in Rename folder dialog box -->
<string name="cancel_action">Cancel</string> <string name="cancel_action">Cancel</string>
<!-- Shortcuts --> <!-- Shortcuts -->
<skip />
<!-- Title of dialog box --> <!-- Title of dialog box -->
<string name="menu_item_add_item">Add to Home</string> <string name="menu_item_add_item">Add to Home screen</string>
<!-- Options in "Add to Home" dialog box: --> <!-- Options in "Add to Home" dialog box; Title of the group containing the list of all apps -->
<string name="group_applications">Application</string> <string name="group_applications">Application</string>
<!-- Options in "Add to Home" dialog box; Title of the group containing the list of all shortcuts -->
<string name="group_shortcuts">Shortcut</string> <string name="group_shortcuts">Shortcut</string>
<string name="group_live_folders">Live folder</string>
<!-- Options in "Add to Home" dialog box; Title of the group containing the list of all widgets -->
<string name="group_widgets">Widget</string> <string name="group_widgets">Widget</string>
<!-- Options in "Add to Home" dialog box; Title of the group containing the list of apps that can set the wallpaper-->
<string name="group_wallpapers">Wallpaper</string> <string name="group_wallpapers">Wallpaper</string>
<!-- Options in "Add to Home" dialog box; Name of the Folder widget-->
<string name="add_folder">Folder</string> <string name="add_folder">Folder</string>
<!-- Options in "Add to Home" dialog box; Name of the Clock widget-->
<string name="add_clock">Clock</string> <string name="add_clock">Clock</string>
<!-- Options in "Add to Home" dialog box; Name of the Picture frame widget-->
<string name="add_photo_frame">Picture frame</string> <string name="add_photo_frame">Picture frame</string>
<!-- Options in "Add to Home" dialog box; Name of the Google Search widget-->
<string name="add_search">Search</string> <string name="add_search">Search</string>
<!-- Error message when user has filled a home screen, possibly not used --> <!-- Error message when user has filled a home screen, possibly not used -->
<string name="out_of_space">No more room on this Home screen.</string> <string name="out_of_space">No more room on this Home screen.</string>
<!-- Menus items: --> <!-- Menus items: -->
<skip />
<!-- Verb, menu item used to add an item on the desktop -->
<string name="menu_add">Add</string> <string name="menu_add">Add</string>
<!-- Noun, menu item used to set the desktop's wallpaper -->
<string name="menu_wallpaper">Wallpaper</string> <string name="menu_wallpaper">Wallpaper</string>
<!-- Verb, menu item used to initiate a Google Search -->
<string name="menu_search">Search</string> <string name="menu_search">Search</string>
<!-- Noun, menu item used to bring down the notifications shade -->
<string name="menu_notifications">Notifications</string> <string name="menu_notifications">Notifications</string>
<!-- Noun, menu item used to show the system settings -->
<string name="menu_settings">Settings</string> <string name="menu_settings">Settings</string>
<!-- Permissions: --> <!-- Permissions: -->
@ -74,9 +88,18 @@
<string name="permlab_uninstall_shortcut">uninstall shortcuts</string> <string name="permlab_uninstall_shortcut">uninstall shortcuts</string>
<string name="permdesc_uninstall_shortcut">Allows an application to remove <string name="permdesc_uninstall_shortcut">Allows an application to remove
shortcuts without user intervention.</string> shortcuts without user intervention.</string>
<string name="permlab_read_settings">read Home settings and shortcuts</string>
<string name="permdesc_read_settings">Allows an application to read the settings and
shortcuts in Home.</string>
<string name="permlab_write_settings">write Home settings and shortcuts</string>
<string name="permdesc_write_settings">Allows an application to change the settings and
shortcuts in Home.</string>
<!-- Widgets: --> <!-- Widgets: -->
<string name="go">Search</string> <skip />
<!-- This is the hint text shown in the search widget, before text is entered.
This translation SHOULD MATCH the string "search_hint" which is found in
GoogleSearch/res/values/strings.xml -->
<string name="search_hint">Google Search</string> <string name="search_hint">Google Search</string>
</resources> </resources>

View File

@ -26,7 +26,7 @@
<style name="WorkspaceIcon"> <style name="WorkspaceIcon">
<item name="android:textSize">13dip</item> <item name="android:textSize">13dip</item>
<item name="android:singleLine">true</item> <item name="android:singleLine">true</item>
<item name="android:ellipsize">end</item> <item name="android:ellipsize">marquee</item>
<item name="android:shadowColor">#FF000000</item> <item name="android:shadowColor">#FF000000</item>
<item name="android:shadowRadius">2.0</item> <item name="android:shadowRadius">2.0</item>
<item name="android:textColor">#FFF</item> <item name="android:textColor">#FFF</item>

View File

@ -28,6 +28,7 @@ import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import android.widget.BaseExpandableListAdapter; import android.widget.BaseExpandableListAdapter;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.provider.LiveFolders;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -40,9 +41,11 @@ public final class AddAdapter extends BaseExpandableListAdapter {
private static final int GROUP_APPLICATIONS = 0; private static final int GROUP_APPLICATIONS = 0;
private static final int GROUP_SHORTCUTS = 1; private static final int GROUP_SHORTCUTS = 1;
private static final int GROUP_WIDGETS = 2; private static final int GROUP_WIDGETS = 2;
private static final int GROUP_WALLPAPERS = 3; private static final int GROUP_LIVE_FOLDERS = 3;
private static final int GROUP_WALLPAPERS = 4;
private final Intent mCreateShortcutIntent; private final Intent mCreateShortcutIntent;
private final Intent mCreateLiveFolderIntent;
private Intent mSetWallpaperIntent; private Intent mSetWallpaperIntent;
private final LayoutInflater mInflater; private final LayoutInflater mInflater;
private Launcher mLauncher; private Launcher mLauncher;
@ -52,7 +55,7 @@ public final class AddAdapter extends BaseExpandableListAdapter {
* Abstract class representing one thing that can be added * Abstract class representing one thing that can be added
*/ */
public abstract class AddAction implements Runnable { public abstract class AddAction implements Runnable {
private final Context mContext; protected final Context mContext;
AddAction(Context context) { AddAction(Context context) {
mContext = context; mContext = context;
@ -110,8 +113,9 @@ public final class AddAdapter extends BaseExpandableListAdapter {
mLabel = info.activityInfo.name; mLabel = info.activityInfo.name;
} }
} }
if (mIcon == null) { if (mIcon == null) {
mIcon = info.loadIcon(pm); mIcon = Utilities.createIconThumbnail(info.loadIcon(pm), mContext);
} }
text.setText(mLabel); text.setText(mLabel);
@ -126,12 +130,32 @@ public final class AddAdapter extends BaseExpandableListAdapter {
mLauncher.addShortcut(intent); mLauncher.addShortcut(intent);
} }
} }
/**
* Class representing an action that will create a specific type
* of live folder
*/
public class CreateLiveFolderAction extends CreateShortcutAction {
CreateLiveFolderAction(Context context, ResolveInfo info) {
super(context, info);
}
@Override
public void run() {
Intent intent = new Intent(mCreateLiveFolderIntent);
ActivityInfo activityInfo = mInfo.activityInfo;
intent.setComponent(new ComponentName(activityInfo.applicationInfo.packageName,
activityInfo.name));
mLauncher.addLiveFolder(intent);
}
}
/** /**
* Class representing an action that will add a folder * Class representing an action that will add a folder
*/ */
public class CreateFolderAction extends AddAction { public class CreateFolderAction extends AddAction {
private Drawable mIcon;
CreateFolderAction(Context context) { CreateFolderAction(Context context) {
super(context); super(context);
} }
@ -140,8 +164,8 @@ public final class AddAdapter extends BaseExpandableListAdapter {
public void bindView(View view) { public void bindView(View view) {
TextView text = (TextView) view; TextView text = (TextView) view;
text.setText(R.string.add_folder); text.setText(R.string.add_folder);
text.setCompoundDrawablesWithIntrinsicBounds(getIcon(R.drawable.ic_launcher_folder), if (mIcon == null) mIcon = getIcon(R.drawable.ic_launcher_folder);
null, null, null); text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
} }
public void run() { public void run() {
@ -175,6 +199,8 @@ public final class AddAdapter extends BaseExpandableListAdapter {
* Class representing an action that will add a PhotoFrame * Class representing an action that will add a PhotoFrame
*/ */
public class CreatePhotoFrameAction extends AddAction { public class CreatePhotoFrameAction extends AddAction {
private Drawable mIcon;
CreatePhotoFrameAction(Context context) { CreatePhotoFrameAction(Context context) {
super(context); super(context);
} }
@ -183,8 +209,8 @@ public final class AddAdapter extends BaseExpandableListAdapter {
public void bindView(View view) { public void bindView(View view) {
TextView text = (TextView) view; TextView text = (TextView) view;
text.setText(R.string.add_photo_frame); text.setText(R.string.add_photo_frame);
Drawable icon = getIcon(R.drawable.ic_launcher_gallery); if (mIcon == null) mIcon = getIcon(R.drawable.ic_launcher_gallery);
text.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null); text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
} }
public void run() { public void run() {
@ -197,6 +223,8 @@ public final class AddAdapter extends BaseExpandableListAdapter {
* Class representing an action that will add a Search widget * Class representing an action that will add a Search widget
*/ */
public class CreateSearchAction extends AddAction { public class CreateSearchAction extends AddAction {
private Drawable mIcon;
CreateSearchAction(Context context) { CreateSearchAction(Context context) {
super(context); super(context);
} }
@ -205,8 +233,8 @@ public final class AddAdapter extends BaseExpandableListAdapter {
public void bindView(View view) { public void bindView(View view) {
TextView text = (TextView) view; TextView text = (TextView) view;
text.setText(R.string.add_search); text.setText(R.string.add_search);
Drawable icon = getIcon(R.drawable.ic_search_gadget); if (mIcon == null) mIcon = getIcon(R.drawable.ic_search_gadget);
text.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null); text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
} }
public void run() { public void run() {
@ -296,22 +324,27 @@ public final class AddAdapter extends BaseExpandableListAdapter {
mCreateShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT); mCreateShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
mCreateShortcutIntent.setComponent(null); mCreateShortcutIntent.setComponent(null);
mCreateLiveFolderIntent = new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER);
mCreateLiveFolderIntent.setComponent(null);
mSetWallpaperIntent = new Intent(Intent.ACTION_SET_WALLPAPER); mSetWallpaperIntent = new Intent(Intent.ACTION_SET_WALLPAPER);
mSetWallpaperIntent.setComponent(null); mSetWallpaperIntent.setComponent(null);
mLauncher = launcher; mLauncher = launcher;
mInflater = (LayoutInflater) launcher.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mInflater = (LayoutInflater) launcher.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mGroups = new Group[forFolder ? 2 : 4]; mGroups = new Group[forFolder ? 2 : 5];
final Group[] groups = mGroups; final Group[] groups = mGroups;
groups[GROUP_APPLICATIONS] = new ApplicationsGroup(mLauncher, groups[GROUP_APPLICATIONS] = new ApplicationsGroup(mLauncher,
mLauncher.getString(R.string.group_applications)); mLauncher.getString(R.string.group_applications));
groups[GROUP_SHORTCUTS] = new Group(mLauncher.getString(R.string.group_shortcuts)); groups[GROUP_SHORTCUTS] = new Group(mLauncher.getString(R.string.group_shortcuts));
groups[GROUP_LIVE_FOLDERS] = new Group(mLauncher.getString(R.string.group_live_folders));
if (!forFolder) { if (!forFolder) {
groups[GROUP_WALLPAPERS] = new Group(mLauncher.getString(R.string.group_wallpapers)); groups[GROUP_WALLPAPERS] = new Group(mLauncher.getString(R.string.group_wallpapers));
groups[GROUP_SHORTCUTS].add(new CreateFolderAction(launcher)); groups[GROUP_SHORTCUTS].add(new CreateFolderAction(launcher));
groups[GROUP_WIDGETS] = new Group(mLauncher.getString(R.string.group_widgets)); groups[GROUP_WIDGETS] = new Group(mLauncher.getString(R.string.group_widgets));
final Group widgets = groups[GROUP_WIDGETS]; final Group widgets = groups[GROUP_WIDGETS];
widgets.add(new CreateClockAction(launcher)); widgets.add(new CreateClockAction(launcher));
widgets.add(new CreatePhotoFrameAction(launcher)); widgets.add(new CreatePhotoFrameAction(launcher));
@ -330,6 +363,16 @@ public final class AddAdapter extends BaseExpandableListAdapter {
} }
} }
list = findTargetsForIntent(mCreateLiveFolderIntent, packageManager);
if (list != null && list.size() > 0) {
int count = list.size();
final Group shortcuts = groups[GROUP_LIVE_FOLDERS];
for (int i = 0; i < count; i++) {
ResolveInfo resolveInfo = list.get(i);
shortcuts.add(new CreateLiveFolderAction(launcher, resolveInfo));
}
}
list = findTargetsForIntent(mSetWallpaperIntent, packageManager); list = findTargetsForIntent(mSetWallpaperIntent, packageManager);
if (list != null && list.size() > 0) { if (list != null && list.size() > 0) {
int count = list.size(); int count = list.size();

View File

@ -20,9 +20,7 @@ import android.content.ComponentName;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import com.android.internal.provider.Settings;
/** /**
* Represents a launchable application. An application is made of a name (or title), * Represents a launchable application. An application is made of a name (or title),
@ -63,7 +61,7 @@ class ApplicationInfo extends ItemInfo {
Intent.ShortcutIconResource iconResource; Intent.ShortcutIconResource iconResource;
ApplicationInfo() { ApplicationInfo() {
itemType = Settings.Favorites.ITEM_TYPE_SHORTCUT; itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
} }
public ApplicationInfo(ApplicationInfo info) { public ApplicationInfo(ApplicationInfo info) {
@ -82,7 +80,7 @@ class ApplicationInfo extends ItemInfo {
/** /**
* Creates the application intent based on a component name and various launch flags. * Creates the application intent based on a component name and various launch flags.
* Sets {@link #itemType} to {@link Settings.Favorites#ITEM_TYPE_APPLICATION}. * Sets {@link #itemType} to {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION}.
* *
* @param className the class name of the component representing the intent * @param className the class name of the component representing the intent
* @param launchFlags the launch flags * @param launchFlags the launch flags
@ -92,7 +90,7 @@ class ApplicationInfo extends ItemInfo {
intent.addCategory(Intent.CATEGORY_LAUNCHER); intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setComponent(className); intent.setComponent(className);
intent.setFlags(launchFlags); intent.setFlags(launchFlags);
itemType = Settings.Favorites.ITEM_TYPE_APPLICATION; itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
} }
@Override @Override
@ -100,20 +98,22 @@ class ApplicationInfo extends ItemInfo {
super.onAddToDatabase(values); super.onAddToDatabase(values);
String titleStr = title != null ? title.toString() : null; String titleStr = title != null ? title.toString() : null;
values.put(Settings.Favorites.TITLE, titleStr); values.put(LauncherSettings.Favorites.TITLE, titleStr);
String uri = intent != null ? intent.toURI() : null; String uri = intent != null ? intent.toURI() : null;
values.put(Settings.Favorites.INTENT, uri); values.put(LauncherSettings.Favorites.INTENT, uri);
if (customIcon) { if (customIcon) {
values.put(Settings.Favorites.ICON_TYPE, Settings.Favorites.ICON_TYPE_BITMAP); values.put(LauncherSettings.Favorites.ICON_TYPE,
Bitmap bitmap = ((BitmapDrawable) icon).getBitmap(); LauncherSettings.Favorites.ICON_TYPE_BITMAP);
Bitmap bitmap = ((FastBitmapDrawable) icon).getBitmap();
writeBitmap(values, bitmap); writeBitmap(values, bitmap);
} else { } else {
values.put(Settings.Favorites.ICON_TYPE, Settings.Favorites.ICON_TYPE_RESOURCE); values.put(LauncherSettings.Favorites.ICON_TYPE,
LauncherSettings.Favorites.ICON_TYPE_RESOURCE);
if (iconResource != null) { if (iconResource != null) {
values.put(Settings.Favorites.ICON_PACKAGE, iconResource.packageName); values.put(LauncherSettings.Favorites.ICON_PACKAGE, iconResource.packageName);
values.put(Settings.Favorites.ICON_RESOURCE, iconResource.resourceName); values.put(LauncherSettings.Favorites.ICON_RESOURCE, iconResource.resourceName);
} }
} }
} }

View File

@ -22,7 +22,7 @@ import android.util.AttributeSet;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.RectF; import android.graphics.RectF;
import android.graphics.Rect; import android.graphics.drawable.Drawable;
import android.text.Layout; import android.text.Layout;
/** /**
@ -38,6 +38,9 @@ public class BubbleTextView extends TextView {
private final RectF mRect = new RectF(); private final RectF mRect = new RectF();
private Paint mPaint; private Paint mPaint;
private boolean mBackgroundSizeChanged;
private Drawable mBackground;
public BubbleTextView(Context context) { public BubbleTextView(Context context) {
super(context); super(context);
init(); init();
@ -55,13 +58,57 @@ public class BubbleTextView extends TextView {
private void init() { private void init() {
setFocusable(true); setFocusable(true);
mBackground = getBackground();
setBackgroundDrawable(null);
mBackground.setCallback(this);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(getContext().getResources().getColor(R.color.bubble_dark_background)); mPaint.setColor(getContext().getResources().getColor(R.color.bubble_dark_background));
} }
@Override @Override
public void onDraw(Canvas canvas) { protected boolean setFrame(int left, int top, int right, int bottom) {
if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {
mBackgroundSizeChanged = true;
}
return super.setFrame(left, top, right, bottom);
}
@Override
protected boolean verifyDrawable(Drawable who) {
return who == mBackground || super.verifyDrawable(who);
}
@Override
protected void drawableStateChanged() {
Drawable d = mBackground;
if (d != null && d.isStateful()) {
d.setState(getDrawableState());
}
super.drawableStateChanged();
}
@Override
public void draw(Canvas canvas) {
final Drawable background = mBackground;
if (background != null) {
final int scrollX = mScrollX;
final int scrollY = mScrollY;
if (mBackgroundSizeChanged) {
background.setBounds(0, 0, mRight - mLeft, mBottom - mTop);
mBackgroundSizeChanged = false;
}
if ((scrollX | scrollY) == 0) {
background.draw(canvas);
} else {
canvas.translate(scrollX, scrollY);
background.draw(canvas);
canvas.translate(-scrollX, -scrollY);
}
}
final Layout layout = getLayout(); final Layout layout = getLayout();
final RectF rect = mRect; final RectF rect = mRect;
final int left = getCompoundPaddingLeft(); final int left = getCompoundPaddingLeft();
@ -69,10 +116,10 @@ public class BubbleTextView extends TextView {
rect.set(left + layout.getLineLeft(0) - PADDING_H, rect.set(left + layout.getLineLeft(0) - PADDING_H,
top + layout.getLineTop(0) - PADDING_V, top + layout.getLineTop(0) - PADDING_V,
left + layout.getLineRight(0) + PADDING_H, Math.min(left + layout.getLineRight(0) + PADDING_H, mScrollX + mRight - mLeft),
top + layout.getLineBottom(0) + PADDING_V); top + layout.getLineBottom(0) + PADDING_V);
canvas.drawRoundRect(rect, CORNER_RADIUS, CORNER_RADIUS, mPaint); canvas.drawRoundRect(rect, CORNER_RADIUS, CORNER_RADIUS, mPaint);
super.onDraw(canvas); super.draw(canvas);
} }
} }

View File

@ -104,6 +104,17 @@ public class CellLayout extends ViewGroup {
return mPortrait ? mLongAxisCells : mShortAxisCells; return mPortrait ? mLongAxisCells : mShortAxisCells;
} }
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
// Generate an id for each view, this assumes we have at most 256x256 cells
// per workspace screen
final LayoutParams cellParams = (LayoutParams) params;
child.setId(((getId() & 0xFF) << 16) |
(cellParams.cellX & 0xFF) << 8 | (cellParams.cellY & 0xFF));
super.addView(child, index, params);
}
@Override @Override
public void requestChildFocus(View child, View focused) { public void requestChildFocus(View child, View focused) {
super.requestChildFocus(child, focused); super.requestChildFocus(child, focused);

View File

@ -20,7 +20,6 @@ import android.widget.ImageView;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.util.AttributeSet; import android.util.AttributeSet;
import com.android.internal.provider.Settings;
import android.view.View; import android.view.View;
import android.view.animation.TranslateAnimation; import android.view.animation.TranslateAnimation;
import android.view.animation.Animation; import android.view.animation.Animation;
@ -35,6 +34,8 @@ public class DeleteZone extends ImageView implements DropTarget, DragController.
private static final int TRANSITION_DURATION = 250; private static final int TRANSITION_DURATION = 250;
private static final int ANIMATION_DURATION = 200; private static final int ANIMATION_DURATION = 200;
private final int[] mLocation = new int[2];
private Launcher mLauncher; private Launcher mLauncher;
private boolean mTrashMode; private boolean mTrashMode;
@ -74,15 +75,16 @@ public class DeleteZone extends ImageView implements DropTarget, DragController.
public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset, public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
Object dragInfo) { Object dragInfo) {
final ItemInfo item = (ItemInfo) dragInfo; return true;
// Accept anything except items in the all apps folder
return item.container != ItemInfo.NO_ID;
} }
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) { public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
final ItemInfo item = (ItemInfo) dragInfo; final ItemInfo item = (ItemInfo) dragInfo;
if (item.container == -1) return;
final LauncherModel model = Launcher.getModel(); final LauncherModel model = Launcher.getModel();
if (item.container == Settings.Favorites.CONTAINER_DESKTOP) { if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
model.removeDesktopItem(item); model.removeDesktopItem(item);
} else { } else {
if (source instanceof UserFolder) { if (source instanceof UserFolder) {
@ -115,7 +117,7 @@ public class DeleteZone extends ImageView implements DropTarget, DragController.
public void onDragStart(View v, DragSource source, Object info, int dragAction) { public void onDragStart(View v, DragSource source, Object info, int dragAction) {
final ItemInfo item = (ItemInfo) info; final ItemInfo item = (ItemInfo) info;
if (item != null && item.container != ItemInfo.NO_ID) { if (item != null) {
mTrashMode = true; mTrashMode = true;
createAnimations(); createAnimations();
final int[] location = mLocation; final int[] location = mLocation;

View File

@ -0,0 +1,73 @@
/*
* 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.
*/
package com.android.launcher;
import android.graphics.drawable.Drawable;
import android.graphics.PixelFormat;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
class FastBitmapDrawable extends Drawable {
private Bitmap mBitmap;
FastBitmapDrawable(Bitmap b) {
mBitmap = b;
}
@Override
public void draw(Canvas canvas) {
canvas.drawBitmap(mBitmap, 0.0f, 0.0f, null);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter cf) {
}
@Override
public int getIntrinsicWidth() {
return mBitmap.getWidth();
}
@Override
public int getIntrinsicHeight() {
return mBitmap.getHeight();
}
@Override
public int getMinimumWidth() {
return mBitmap.getWidth();
}
@Override
public int getMinimumHeight() {
return mBitmap.getHeight();
}
public Bitmap getBitmap() {
return mBitmap;
}
}

View File

@ -21,10 +21,10 @@ import android.util.AttributeSet;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.GridView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.AbsListView;
import android.widget.ListAdapter;
import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener; import android.widget.AdapterView.OnItemLongClickListener;
@ -34,7 +34,7 @@ import android.widget.AdapterView.OnItemLongClickListener;
public class Folder extends LinearLayout implements DragSource, OnItemLongClickListener, public class Folder extends LinearLayout implements DragSource, OnItemLongClickListener,
OnItemClickListener, OnClickListener, View.OnLongClickListener { OnItemClickListener, OnClickListener, View.OnLongClickListener {
protected GridView mContent; protected AbsListView mContent;
protected DragController mDragger; protected DragController mDragger;
protected Launcher mLauncher; protected Launcher mLauncher;
@ -64,7 +64,7 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
protected void onFinishInflate() { protected void onFinishInflate() {
super.onFinishInflate(); super.onFinishInflate();
mContent = (GridView) findViewById(R.id.content); mContent = (AbsListView) findViewById(R.id.content);
mContent.setOnItemClickListener(this); mContent.setOnItemClickListener(this);
mContent.setOnItemLongClickListener(this); mContent.setOnItemLongClickListener(this);
@ -83,7 +83,9 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
} }
public boolean onLongClick(View v) { public boolean onLongClick(View v) {
return false; mLauncher.closeFolder(this);
mLauncher.showRenameDialog(mInfo);
return true;
} }
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
@ -120,7 +122,7 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
* *
* @param adapter The list of applications to display in the folder. * @param adapter The list of applications to display in the folder.
*/ */
void setContentAdapter(ArrayAdapter<ApplicationInfo> adapter) { void setContentAdapter(ListAdapter adapter) {
mContent.setAdapter(adapter); mContent.setAdapter(adapter);
} }
@ -145,4 +147,9 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
final Workspace workspace = mLauncher.getWorkspace(); final Workspace workspace = mLauncher.getWorkspace();
workspace.getChildAt(workspace.getCurrentScreen()).requestFocus(); workspace.getChildAt(workspace.getCurrentScreen()).requestFocus();
} }
void bind(FolderInfo info) {
mInfo = info;
mCloseButton.setText(info.title);
}
} }

View File

@ -19,7 +19,6 @@ package com.android.launcher;
import android.content.Context; import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import com.android.internal.provider.Settings;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -65,8 +64,8 @@ public class FolderIcon extends BubbleTextView implements DropTarget {
Object dragInfo) { Object dragInfo) {
final ItemInfo item = (ItemInfo) dragInfo; final ItemInfo item = (ItemInfo) dragInfo;
final int itemType = item.itemType; final int itemType = item.itemType;
return (itemType == Settings.Favorites.ITEM_TYPE_APPLICATION || return (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
itemType == Settings.Favorites.ITEM_TYPE_SHORTCUT) itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT)
&& item.container != mInfo.id; && item.container != mInfo.id;
} }

View File

@ -26,4 +26,9 @@ class FolderInfo extends ItemInfo {
* Whether this folder has been opened * Whether this folder has been opened
*/ */
boolean opened; boolean opened;
/**
* The folder name.
*/
CharSequence title;
} }

View File

@ -0,0 +1,91 @@
/*
* 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.
*/
package com.android.launcher;
import android.widget.ImageView;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.KeyEvent;
public class HandleView extends ImageView {
private static final int ORIENTATION_HORIZONTAL = 1;
private Launcher mLauncher;
private int mOrientation = ORIENTATION_HORIZONTAL;
public HandleView(Context context) {
super(context);
}
public HandleView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public HandleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HandleView, defStyle, 0);
mOrientation = a.getInt(R.styleable.HandleView_direction, ORIENTATION_HORIZONTAL);
a.recycle();
}
@Override
public View focusSearch(int direction) {
View newFocus = super.focusSearch(direction);
if (newFocus == null) {
final Workspace workspace = mLauncher.getWorkspace();
workspace.dispatchUnhandledMove(null, direction);
return (mOrientation == ORIENTATION_HORIZONTAL && direction == FOCUS_DOWN) ?
this : workspace;
}
return newFocus;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
final boolean handled = super.onKeyDown(keyCode, event);
if (!handled && !mLauncher.isDrawerDown() && !isDirectionKey(keyCode)) {
return mLauncher.getApplicationsGrid().onKeyDown(keyCode, event);
}
return handled;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
final boolean handled = super.onKeyUp(keyCode, event);
if (!handled && !mLauncher.isDrawerDown() && !isDirectionKey(keyCode)) {
return mLauncher.getApplicationsGrid().onKeyUp(keyCode, event);
}
return handled;
}
private static boolean isDirectionKey(int keyCode) {
return keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_LEFT ||
keyCode == KeyEvent.KEYCODE_DPAD_RIGHT || keyCode == KeyEvent.KEYCODE_DPAD_UP;
}
void setLauncher(Launcher launcher) {
mLauncher = launcher;
}
}

View File

@ -21,7 +21,6 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.database.Cursor; import android.database.Cursor;
import com.android.internal.provider.Settings;
public class InstallShortcutReceiver extends BroadcastReceiver { public class InstallShortcutReceiver extends BroadcastReceiver {
private final int[] mCoordinates = new int[2]; private final int[] mCoordinates = new int[2];
@ -29,6 +28,15 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent data) { public void onReceive(Context context, Intent data) {
int screen = Launcher.getScreen(); int screen = Launcher.getScreen();
if (!installShortcut(context, data, screen)) {
// The target screen is full, let's try the other screens
for (int i = 0; i < Launcher.SCREEN_COUNT; i++) {
if (i != screen && installShortcut(context, data, i)) break;
}
}
}
private boolean installShortcut(Context context, Intent data, int screen) {
if (findEmptyCell(context, mCoordinates, screen)) { if (findEmptyCell(context, mCoordinates, screen)) {
CellLayout.CellInfo cell = new CellLayout.CellInfo(); CellLayout.CellInfo cell = new CellLayout.CellInfo();
cell.cellX = mCoordinates[0]; cell.cellX = mCoordinates[0];
@ -48,7 +56,11 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
if (duplicate || !LauncherModel.shortcutExists(context, name, intent)) { if (duplicate || !LauncherModel.shortcutExists(context, name, intent)) {
Launcher.addShortcut(context, data, cell, true); Launcher.addShortcut(context, data, cell, true);
} }
return true;
} }
return false;
} }
private static boolean findEmptyCell(Context context, int[] xy, int screen) { private static boolean findEmptyCell(Context context, int[] xy, int screen) {
@ -58,14 +70,16 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
boolean[][] occupied = new boolean[xCount][yCount]; boolean[][] occupied = new boolean[xCount][yCount];
final ContentResolver cr = context.getContentResolver(); final ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(Settings.Favorites.CONTENT_URI, Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
new String[] { "cellX", "cellY", "spanX", "spanY" }, "screen=?", new String[] { LauncherSettings.Favorites.CELLX, LauncherSettings.Favorites.CELLY,
LauncherSettings.Favorites.SPANX, LauncherSettings.Favorites.SPANY },
LauncherSettings.Favorites.SCREEN + "=?",
new String[] { String.valueOf(screen) }, null); new String[] { String.valueOf(screen) }, null);
final int cellXIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLX); final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
final int cellYIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLY); final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
final int spanXIndex = c.getColumnIndexOrThrow(Settings.Favorites.SPANX); final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
final int spanYIndex = c.getColumnIndexOrThrow(Settings.Favorites.SPANY); final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
try { try {
while (c.moveToNext()) { while (c.moveToNext()) {

View File

@ -21,10 +21,8 @@ import java.io.IOException;
import android.content.ContentValues; import android.content.ContentValues;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import com.android.internal.provider.Settings;
import android.util.Log; import android.util.Log;
/** /**
* Represents an item in the launcher. * Represents an item in the launcher.
*/ */
@ -38,18 +36,18 @@ class ItemInfo {
long id = NO_ID; long id = NO_ID;
/** /**
* One of {@link Settings.Favorites#ITEM_TYPE_APPLICATION}, * One of {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION},
* {@link Settings.Favorites#ITEM_TYPE_SHORTCUT}, * {@link LauncherSettings.Favorites#ITEM_TYPE_SHORTCUT},
* {@link Settings.Favorites#ITEM_TYPE_USER_FOLDER}, * {@link LauncherSettings.Favorites#ITEM_TYPE_USER_FOLDER},
* {@link Settings.Favorites#ITEM_TYPE_WIDGET_CLOCK}, * {@link LauncherSettings.Favorites#ITEM_TYPE_WIDGET_CLOCK},
* {@link Settings.Favorites#ITEM_TYPE_WIDGET_SEARCH} or * {@link LauncherSettings.Favorites#ITEM_TYPE_WIDGET_SEARCH} or
* {@link Settings.Favorites#ITEM_TYPE_WIDGET_PHOTO_FRAME}, * {@link LauncherSettings.Favorites#ITEM_TYPE_WIDGET_PHOTO_FRAME},
*/ */
int itemType; int itemType;
/** /**
* The id of the container that holds this item. For the desktop, this will be * The id of the container that holds this item. For the desktop, this will be
* {@link Settings.Favorites#CONTAINER_DESKTOP}. For the all applications folder it * {@link LauncherSettings.Favorites#CONTAINER_DESKTOP}. For the all applications folder it
* will be {@link #NO_ID} (since it is not stored in the settings DB). For user folders * will be {@link #NO_ID} (since it is not stored in the settings DB). For user folders
* it will be the id of the folder. * it will be the id of the folder.
*/ */
@ -100,13 +98,13 @@ class ItemInfo {
* @param values * @param values
*/ */
void onAddToDatabase(ContentValues values) { void onAddToDatabase(ContentValues values) {
values.put(Settings.Favorites.ITEM_TYPE, itemType); values.put(LauncherSettings.Favorites.ITEM_TYPE, itemType);
values.put(Settings.Favorites.CONTAINER, container); values.put(LauncherSettings.Favorites.CONTAINER, container);
values.put(Settings.Favorites.SCREEN, screen); values.put(LauncherSettings.Favorites.SCREEN, screen);
values.put(Settings.Favorites.CELLX, cellX); values.put(LauncherSettings.Favorites.CELLX, cellX);
values.put(Settings.Favorites.CELLY, cellY); values.put(LauncherSettings.Favorites.CELLY, cellY);
values.put(Settings.Favorites.SPANX, spanX); values.put(LauncherSettings.Favorites.SPANX, spanX);
values.put(Settings.Favorites.SPANY, spanY); values.put(LauncherSettings.Favorites.SPANY, spanY);
} }
static void writeBitmap(ContentValues values, Bitmap bitmap) { static void writeBitmap(ContentValues values, Bitmap bitmap) {
@ -120,7 +118,7 @@ class ItemInfo {
out.flush(); out.flush();
out.close(); out.close();
values.put(Settings.Favorites.ICON, out.toByteArray()); values.put(LauncherSettings.Favorites.ICON, out.toByteArray());
} catch (IOException e) { } catch (IOException e) {
Log.w("Favorite", "Could not write icon"); Log.w("Favorite", "Could not write icon");
} }

View File

@ -29,16 +29,15 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.Configuration;
import android.database.ContentObserver; import android.database.ContentObserver;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable; import android.graphics.drawable.TransitionDrawable;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
@ -46,15 +45,12 @@ import android.os.IBinder;
import android.os.Parcelable; import android.os.Parcelable;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.os.SystemClock; import android.provider.*;
import android.os.SystemProperties;
import android.provider.Contacts;
import android.telephony.PhoneNumberUtils; import android.telephony.PhoneNumberUtils;
import android.text.Selection; import android.text.Selection;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.method.TextKeyListener; import android.text.method.TextKeyListener;
import android.util.Config;
import android.util.Log; import android.util.Log;
import android.view.Display; import android.view.Display;
import android.view.Gravity; import android.view.Gravity;
@ -66,14 +62,15 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.View.OnLongClickListener; import android.view.View.OnLongClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ExpandableListView; import android.widget.ExpandableListView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import android.widget.GridView;
import android.app.IWallpaperService; import android.app.IWallpaperService;
import com.android.internal.provider.Settings;
import com.android.internal.widget.SlidingDrawer; import com.android.internal.widget.SlidingDrawer;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
@ -88,18 +85,8 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private static final boolean PROFILE_STARTUP = false; private static final boolean PROFILE_STARTUP = false;
private static final boolean DEBUG_USER_INTERFACE = false; private static final boolean DEBUG_USER_INTERFACE = false;
private static final String USE_OPENGL_BY_DEFAULT = "false";
private static final boolean REMOVE_SHORTCUT_ON_PACKAGE_REMOVE = false; private static final boolean REMOVE_SHORTCUT_ON_PACKAGE_REMOVE = false;
// Type: boolean
private static final String PROPERTY_USE_OPENGL = "launcher.opengl";
// Type: boolean
private static final String PROPERTY_USE_SENSORS = "launcher.sensors";
private static final boolean USE_OPENGL = true;
private static final boolean USE_SENSORS = false;
private static final int WALLPAPER_SCREENS_SPAN = 2; private static final int WALLPAPER_SCREENS_SPAN = 2;
private static final int MENU_GROUP_ADD = 1; private static final int MENU_GROUP_ADD = 1;
@ -112,9 +99,11 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private static final int REQUEST_CREATE_SHORTCUT = 1; private static final int REQUEST_CREATE_SHORTCUT = 1;
private static final int REQUEST_CHOOSE_PHOTO = 2; private static final int REQUEST_CHOOSE_PHOTO = 2;
private static final int REQUEST_UPDATE_PHOTO = 3; private static final int REQUEST_UPDATE_PHOTO = 3;
private static final int REQUEST_CREATE_LIVE_FOLDER = 4;
static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate"; static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";
static final int SCREEN_COUNT = 3;
static final int DEFAULT_SCREN = 1; static final int DEFAULT_SCREN = 1;
static final int NUMBER_CELLS_X = 4; static final int NUMBER_CELLS_X = 4;
static final int NUMBER_CELLS_Y = 4; static final int NUMBER_CELLS_Y = 4;
@ -122,6 +111,11 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private static final int DIALOG_CREATE_SHORTCUT = 1; private static final int DIALOG_CREATE_SHORTCUT = 1;
static final int DIALOG_RENAME_FOLDER = 2; static final int DIALOG_RENAME_FOLDER = 2;
private static final String PREFERENCES = "launcher";
private static final String KEY_LOCALE = "locale";
private static final String KEY_MCC = "mcc";
private static final String KEY_MNC = "mnc";
// Type: int // Type: int
private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen"; private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";
// Type: boolean // Type: boolean
@ -165,19 +159,15 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private final BroadcastReceiver mApplicationsReceiver = new ApplicationsIntentReceiver(); private final BroadcastReceiver mApplicationsReceiver = new ApplicationsIntentReceiver();
private final ContentObserver mObserver = new FavoritesChangeObserver(); private final ContentObserver mObserver = new FavoritesChangeObserver();
private final Handler mHandler = new Handler();
private LayoutInflater mInflater; private LayoutInflater mInflater;
private SensorManager mSensorManager;
private SensorHandler mSensorHandler;
private DragLayer mDragLayer; private DragLayer mDragLayer;
private Workspace mWorkspace; private Workspace mWorkspace;
private CellLayout.CellInfo mAddItemCellInfo; private CellLayout.CellInfo mAddItemCellInfo;
private CellLayout.CellInfo mMenuAddInfo; private CellLayout.CellInfo mMenuAddInfo;
private final int[] mCellCoordinates = new int[2]; private final int[] mCellCoordinates = new int[2];
private UserFolderInfo mFolderInfo; private FolderInfo mFolderInfo;
private SlidingDrawer mDrawer; private SlidingDrawer mDrawer;
private TransitionDrawable mHandleIcon; private TransitionDrawable mHandleIcon;
@ -192,11 +182,10 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private boolean mRestoring; private boolean mRestoring;
private boolean mWaitingForResult; private boolean mWaitingForResult;
private boolean mLocaleChanged;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
dalvik.system.VMRuntime.getRuntime().setMinimumHeapSize(4 * 1024 * 1024);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mInflater = getLayoutInflater(); mInflater = getLayoutInflater();
@ -204,11 +193,9 @@ public final class Launcher extends Activity implements View.OnClickListener, On
android.os.Debug.startMethodTracing("/sdcard/launcher"); android.os.Debug.startMethodTracing("/sdcard/launcher");
} }
checkForLocaleChange();
setWallpaperDimension(); setWallpaperDimension();
enableSensors();
enableOpenGL();
if (sModel == null) { if (sModel == null) {
sModel = new LauncherModel(); sModel = new LauncherModel();
} }
@ -234,6 +221,30 @@ public final class Launcher extends Activity implements View.OnClickListener, On
mDefaultKeySsb = new SpannableStringBuilder(); mDefaultKeySsb = new SpannableStringBuilder();
Selection.setSelection(mDefaultKeySsb, 0); Selection.setSelection(mDefaultKeySsb, 0);
} }
private void checkForLocaleChange() {
final SharedPreferences preferences = getSharedPreferences(PREFERENCES, MODE_PRIVATE);
final Configuration configuration = getResources().getConfiguration();
final String previousLocale = preferences.getString(KEY_LOCALE, null);
final String locale = configuration.locale.toString();
final int previousMcc = preferences.getInt(KEY_MCC, -1);
final int mcc = configuration.mcc;
final int previousMnc = preferences.getInt(KEY_MNC, -1);
final int mnc = configuration.mnc;
mLocaleChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMnc;
if (mLocaleChanged) {
final SharedPreferences.Editor editor = preferences.edit();
editor.putString(KEY_LOCALE, locale);
editor.putInt(KEY_MCC, mcc);
editor.putInt(KEY_MNC, mnc);
editor.commit();
}
}
static int getScreen() { static int getScreen() {
synchronized (sLock) { synchronized (sLock) {
@ -248,19 +259,11 @@ public final class Launcher extends Activity implements View.OnClickListener, On
} }
private void startLoaders() { private void startLoaders() {
sModel.loadApplications(true, this); sModel.loadApplications(true, this, mLocaleChanged);
sModel.loadUserItems(true, this); sModel.loadUserItems(!mLocaleChanged, this, mLocaleChanged);
mRestoring = false; mRestoring = false;
} }
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// When MMC/MNC changes, so can applications, so we reload them
sModel.loadApplications(false, Launcher.this);
}
private void setWallpaperDimension() { private void setWallpaperDimension() {
IBinder binder = ServiceManager.getService(WALLPAPER_SERVICE); IBinder binder = ServiceManager.getService(WALLPAPER_SERVICE);
IWallpaperService wallpaperService = IWallpaperService.Stub.asInterface(binder); IWallpaperService wallpaperService = IWallpaperService.Stub.asInterface(binder);
@ -277,31 +280,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On
} }
} }
private void enableSensors() {
//noinspection PointlessBooleanExpression,ConstantConditions
if (USE_SENSORS || "true".equals(SystemProperties.get(PROPERTY_USE_SENSORS, "false"))) {
if (Config.LOGD) {
Log.d(LOG_TAG, "Launcher activating sensors");
}
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mSensorHandler = new SensorHandler();
}
}
private void enableOpenGL() {
//noinspection PointlessBooleanExpression,ConstantConditions
if (USE_OPENGL && "true".equals(SystemProperties.get(PROPERTY_USE_OPENGL,
USE_OPENGL_BY_DEFAULT))) {
if (Config.LOGD) {
Log.d(LOG_TAG, "Launcher starting in OpenGL");
}
//requestWindowFeature(Window.FEATURE_OPENGL);
//sOpenGlEnabled = true;
} else {
sOpenGlEnabled = false;
}
}
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && mAddItemCellInfo != null) { if (resultCode == RESULT_OK && mAddItemCellInfo != null) {
@ -315,6 +293,9 @@ public final class Launcher extends Activity implements View.OnClickListener, On
case REQUEST_UPDATE_PHOTO: case REQUEST_UPDATE_PHOTO:
completeUpdatePhotoFrame(data, mAddItemCellInfo); completeUpdatePhotoFrame(data, mAddItemCellInfo);
break; break;
case REQUEST_CREATE_LIVE_FOLDER:
completeAddLiveFolder(data, mAddItemCellInfo, !mDesktopLocked);
break;
} }
} }
mWaitingForResult = false; mWaitingForResult = false;
@ -327,19 +308,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On
if (mRestoring) { if (mRestoring) {
startLoaders(); startLoaders();
} }
if (mSensorManager != null) {
mSensorManager.registerListener(mSensorHandler, SensorManager.SENSOR_ACCELEROMETER);
}
}
@Override
protected void onStop() {
if (mSensorManager != null) {
mSensorManager.unregisterListener(mSensorHandler);
}
super.onStop();
} }
@Override @Override
@ -347,6 +315,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
boolean handled = super.onKeyUp(keyCode, event); boolean handled = super.onKeyUp(keyCode, event);
if (keyCode == KeyEvent.KEYCODE_SEARCH) { if (keyCode == KeyEvent.KEYCODE_SEARCH) {
handled = mWorkspace.snapToSearch(); handled = mWorkspace.snapToSearch();
if (handled) closeDrawer(true);
} }
return handled; return handled;
} }
@ -455,7 +424,8 @@ public final class Launcher extends Activity implements View.OnClickListener, On
final DeleteZone deleteZone = (DeleteZone) dragLayer.findViewById(R.id.delete_zone); final DeleteZone deleteZone = (DeleteZone) dragLayer.findViewById(R.id.delete_zone);
final ImageView handleIcon = (ImageView) drawer.findViewById(R.id.all_apps); final HandleView handleIcon = (HandleView) drawer.findViewById(R.id.all_apps);
handleIcon.setLauncher(this);
mHandleIcon = (TransitionDrawable) handleIcon.getDrawable(); mHandleIcon = (TransitionDrawable) handleIcon.getDrawable();
mHandleIcon.setCrossFadeEnabled(true); mHandleIcon.setCrossFadeEnabled(true);
@ -577,7 +547,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
Intent.ShortcutIconResource iconResource = null; Intent.ShortcutIconResource iconResource = null;
if (bitmap != null) { if (bitmap != null) {
icon = new BitmapDrawable(Utilities.createBitmapThumbnail(bitmap, context)); icon = new FastBitmapDrawable(Utilities.createBitmapThumbnail(bitmap, context));
filtered = true; filtered = true;
customIcon = true; customIcon = true;
} else { } else {
@ -608,7 +578,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
info.customIcon = customIcon; info.customIcon = customIcon;
info.iconResource = iconResource; info.iconResource = iconResource;
LauncherModel.addItemToDatabase(context, info, Settings.Favorites.CONTAINER_DESKTOP, LauncherModel.addItemToDatabase(context, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
cellInfo.screen, cellInfo.cellX, cellInfo.cellY, notify); cellInfo.screen, cellInfo.cellX, cellInfo.cellY, notify);
return info; return info;
} }
@ -630,7 +600,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
final int[] xy = mCellCoordinates; final int[] xy = mCellCoordinates;
if (!findSlot(cellInfo, xy, info.spanX, info.spanY)) return; if (!findSlot(cellInfo, xy, info.spanX, info.spanY)) return;
LauncherModel.addItemToDatabase(this, info, Settings.Favorites.CONTAINER_DESKTOP, LauncherModel.addItemToDatabase(this, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
mWorkspace.getCurrentScreen(), xy[0], xy[1], false); mWorkspace.getCurrentScreen(), xy[0], xy[1], false);
if (!mRestoring) { if (!mRestoring) {
@ -746,6 +716,12 @@ public final class Launcher extends Activity implements View.OnClickListener, On
mWorkspace.moveToDefaultScreen(); mWorkspace.moveToDefaultScreen();
} }
closeDrawer(); closeDrawer();
View v = getWindow().peekDecorView();
if (v != null && v.getWindowToken() != null) {
InputMethodManager imm = (InputMethodManager)getSystemService(
INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken());
}
} else { } else {
closeDrawer(false); closeDrawer(false);
} }
@ -817,6 +793,16 @@ public final class Launcher extends Activity implements View.OnClickListener, On
super.startActivityForResult(intent, requestCode); super.startActivityForResult(intent, requestCode);
} }
@Override
public void startSearch(String initialQuery, boolean selectInitialQuery,
Bundle appSearchData, boolean globalSearch) {
if (appSearchData == null) {
appSearchData = new Bundle();
appSearchData.putString(SearchManager.SOURCE, "launcher-search");
}
super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
}
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
if (mDesktopLocked) return false; if (mDesktopLocked) return false;
@ -893,6 +879,10 @@ public final class Launcher extends Activity implements View.OnClickListener, On
startActivityForResult(intent, REQUEST_CREATE_SHORTCUT); startActivityForResult(intent, REQUEST_CREATE_SHORTCUT);
} }
void addLiveFolder(Intent intent) {
startActivityForResult(intent, REQUEST_CREATE_LIVE_FOLDER);
}
void addFolder() { void addFolder() {
UserFolderInfo folderInfo = new UserFolderInfo(); UserFolderInfo folderInfo = new UserFolderInfo();
folderInfo.title = getText(R.string.folder_name); folderInfo.title = getText(R.string.folder_name);
@ -900,10 +890,10 @@ public final class Launcher extends Activity implements View.OnClickListener, On
int cellY = mAddItemCellInfo.cellY; int cellY = mAddItemCellInfo.cellY;
// Update the model // Update the model
LauncherModel.addItemToDatabase(this, folderInfo, Settings.Favorites.CONTAINER_DESKTOP, LauncherModel.addItemToDatabase(this, folderInfo, LauncherSettings.Favorites.CONTAINER_DESKTOP,
mWorkspace.getCurrentScreen(), cellX, cellY, false); mWorkspace.getCurrentScreen(), cellX, cellY, false);
sModel.addDesktopItem(folderInfo); sModel.addDesktopItem(folderInfo);
sModel.addUserFolder(folderInfo); sModel.addFolder(folderInfo);
// Create the view // Create the view
FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this, FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,
@ -911,6 +901,68 @@ public final class Launcher extends Activity implements View.OnClickListener, On
mWorkspace.addInCurrentScreen(newFolder, cellX, cellY, 1, 1); mWorkspace.addInCurrentScreen(newFolder, cellX, cellY, 1, 1);
} }
private void completeAddLiveFolder(Intent data, CellLayout.CellInfo cellInfo,
boolean insertAtFirst) {
cellInfo.screen = mWorkspace.getCurrentScreen();
final LiveFolderInfo info = addLiveFolder(this, data, cellInfo, false);
if (!mRestoring) {
sModel.addDesktopItem(info);
final View view = LiveFolderIcon.fromXml(R.layout.live_folder_icon, this,
(ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentScreen()), info);
mWorkspace.addInCurrentScreen(view, cellInfo.cellX, cellInfo.cellY, 1, 1, insertAtFirst);
} else if (sModel.isDesktopLoaded()) {
sModel.addDesktopItem(info);
}
}
static LiveFolderInfo addLiveFolder(Context context, Intent data,
CellLayout.CellInfo cellInfo, boolean notify) {
Intent baseIntent = data.getParcelableExtra(LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT);
String name = data.getStringExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME);
Drawable icon = null;
boolean filtered = false;
Intent.ShortcutIconResource iconResource = null;
Parcelable extra = data.getParcelableExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON);
if (extra != null && extra instanceof Intent.ShortcutIconResource) {
try {
iconResource = (Intent.ShortcutIconResource) extra;
final PackageManager packageManager = context.getPackageManager();
Resources resources = packageManager.getResourcesForApplication(
iconResource.packageName);
final int id = resources.getIdentifier(iconResource.resourceName, null, null);
icon = resources.getDrawable(id);
} catch (Exception e) {
Log.w(LOG_TAG, "Could not load live folder icon: " + extra);
}
}
if (icon == null) {
icon = context.getResources().getDrawable(R.drawable.ic_launcher_folder);
}
final LiveFolderInfo info = new LiveFolderInfo();
info.icon = icon;
info.filtered = filtered;
info.title = name;
info.iconResource = iconResource;
info.uri = data.getData();
info.baseIntent = baseIntent;
info.displayMode = data.getIntExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE,
LiveFolders.DISPLAY_MODE_GRID);
LauncherModel.addItemToDatabase(context, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
cellInfo.screen, cellInfo.cellX, cellInfo.cellY, notify);
sModel.addFolder(info);
return info;
}
void getPhotoForPhotoFrame() { void getPhotoForPhotoFrame() {
startActivityForResult(createPhotoPickIntent(), REQUEST_CHOOSE_PHOTO); startActivityForResult(createPhotoPickIntent(), REQUEST_CHOOSE_PHOTO);
} }
@ -935,7 +987,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
if (!findSlot(cellInfo, xy, spanX, spanY)) return; if (!findSlot(cellInfo, xy, spanX, spanY)) return;
sModel.addDesktopItem(info); sModel.addDesktopItem(info);
LauncherModel.addItemToDatabase(this, info, Settings.Favorites.CONTAINER_DESKTOP, LauncherModel.addItemToDatabase(this, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
mWorkspace.getCurrentScreen(), xy[0], xy[1], false); mWorkspace.getCurrentScreen(), xy[0], xy[1], false);
final View view = mInflater.inflate(info.layoutResource, null); final View view = mInflater.inflate(info.layoutResource, null);
@ -999,7 +1051,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
*/ */
private void registerContentObservers() { private void registerContentObservers() {
ContentResolver resolver = getContentResolver(); ContentResolver resolver = getContentResolver();
resolver.registerContentObserver(Settings.Favorites.CONTENT_URI, true, mObserver); resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true, mObserver);
} }
@Override @Override
@ -1059,7 +1111,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private void onFavoritesChanged() { private void onFavoritesChanged() {
mDesktopLocked = true; mDesktopLocked = true;
mDrawer.lock(); mDrawer.lock();
sModel.loadUserItems(false, this); sModel.loadUserItems(false, this, false);
} }
void onDesktopItemsLoaded() { void onDesktopItemsLoaded() {
@ -1074,9 +1126,9 @@ public final class Launcher extends Activity implements View.OnClickListener, On
final long[] userFolders = mSavedState.getLongArray(RUNTIME_STATE_USER_FOLDERS); final long[] userFolders = mSavedState.getLongArray(RUNTIME_STATE_USER_FOLDERS);
if (userFolders != null) { if (userFolders != null) {
for (long folderId : userFolders) { for (long folderId : userFolders) {
final UserFolderInfo info = sModel.findFolderById(folderId); final FolderInfo info = sModel.findFolderById(folderId);
if (info != null) { if (info != null) {
openUserFolder(info); openFolder(info);
} }
} }
final Folder openFolder = mWorkspace.getOpenFolder(); final Folder openFolder = mWorkspace.getOpenFolder();
@ -1119,19 +1171,27 @@ public final class Launcher extends Activity implements View.OnClickListener, On
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
final ItemInfo item = shortcuts.get(i); final ItemInfo item = shortcuts.get(i);
switch (item.itemType) { switch (item.itemType) {
case Settings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case Settings.Favorites.ITEM_TYPE_SHORTCUT: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
final View shortcut = createShortcut((ApplicationInfo) item); final View shortcut = createShortcut((ApplicationInfo) item);
workspace.addInScreen(shortcut, item.screen, item.cellX, item.cellY, 1, 1, workspace.addInScreen(shortcut, item.screen, item.cellX, item.cellY, 1, 1,
!mDesktopLocked); !mDesktopLocked);
break; break;
case Settings.Favorites.ITEM_TYPE_USER_FOLDER: case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
final FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this, final FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,
(ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentScreen()), (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentScreen()),
((UserFolderInfo) item)); ((UserFolderInfo) item));
workspace.addInScreen(newFolder, item.screen, item.cellX, item.cellY, 1, 1, workspace.addInScreen(newFolder, item.screen, item.cellX, item.cellY, 1, 1,
!mDesktopLocked); !mDesktopLocked);
break; break;
case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
final FolderIcon newLiveFolder = LiveFolderIcon.fromXml(
R.layout.live_folder_icon, this,
(ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentScreen()),
((LiveFolderInfo) item));
workspace.addInScreen(newLiveFolder, item.screen, item.cellX, item.cellY, 1, 1,
!mDesktopLocked);
break;
default: default:
final Widget widget = (Widget)item; final Widget widget = (Widget)item;
final View view = createWidget(mInflater, widget); final View view = createWidget(mInflater, widget);
@ -1148,7 +1208,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
final int screen = workspace.getCurrentScreen(); final int screen = workspace.getCurrentScreen();
View v = inflater.inflate(widget.layoutResource, View v = inflater.inflate(widget.layoutResource,
(ViewGroup) workspace.getChildAt(screen), false); (ViewGroup) workspace.getChildAt(screen), false);
if (widget.itemType == Settings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME) { if (widget.itemType == LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME) {
((ImageView)v).setImageBitmap(widget.photo); ((ImageView)v).setImageBitmap(widget.photo);
} }
return v; return v;
@ -1169,8 +1229,8 @@ public final class Launcher extends Activity implements View.OnClickListener, On
// Open shortcut // Open shortcut
final Intent intent = ((ApplicationInfo) tag).intent; final Intent intent = ((ApplicationInfo) tag).intent;
startActivitySafely(intent); startActivitySafely(intent);
} else if (tag instanceof UserFolderInfo) { } else if (tag instanceof FolderInfo) {
handleFolderClick((UserFolderInfo) tag); handleFolderClick((FolderInfo) tag);
} }
} }
@ -1188,7 +1248,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
// Close any open folder // Close any open folder
closeFolder(); closeFolder();
// Open the requested folder // Open the requested folder
openUserFolder(folderInfo); openFolder(folderInfo);
} else { } else {
// Find the open folder... // Find the open folder...
Folder openFolder = mWorkspace.getFolderForTag(folderInfo); Folder openFolder = mWorkspace.getFolderForTag(folderInfo);
@ -1201,7 +1261,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
// Close any folder open on the current screen // Close any folder open on the current screen
closeFolder(); closeFolder();
// Pull the folder onto this screen // Pull the folder onto this screen
openUserFolder(folderInfo); openFolder(folderInfo);
} }
} }
} }
@ -1226,14 +1286,22 @@ public final class Launcher extends Activity implements View.OnClickListener, On
* is animated relative to the specified View. If the View is null, no animation * is animated relative to the specified View. If the View is null, no animation
* is played. * is played.
* *
* @param tag The UserFolderInfo describing the folder to open. * @param folderInfo The FolderInfo describing the folder to open.
*/ */
private void openUserFolder(Object tag) { private void openFolder(FolderInfo folderInfo) {
UserFolder openFolder = UserFolder.fromXml(this); Folder openFolder;
if (folderInfo instanceof UserFolderInfo) {
openFolder = UserFolder.fromXml(this);
} else if (folderInfo instanceof LiveFolderInfo) {
openFolder = com.android.launcher.LiveFolder.fromXml(this, folderInfo);
} else {
return;
}
openFolder.setDragger(mDragLayer); openFolder.setDragger(mDragLayer);
openFolder.setLauncher(this); openFolder.setLauncher(this);
UserFolderInfo folderInfo = (UserFolderInfo) tag;
openFolder.bind(folderInfo); openFolder.bind(folderInfo);
folderInfo.opened = true; folderInfo.opened = true;
@ -1299,6 +1367,10 @@ public final class Launcher extends Activity implements View.OnClickListener, On
return mWorkspace; return mWorkspace;
} }
GridView getApplicationsGrid() {
return mAllAppsGrid;
}
@Override @Override
protected Dialog onCreateDialog(int id) { protected Dialog onCreateDialog(int id) {
switch (id) { switch (id) {
@ -1327,7 +1399,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
} }
} }
void showRenameDialog(UserFolderInfo info) { void showRenameDialog(FolderInfo info) {
mFolderInfo = info; mFolderInfo = info;
mWaitingForResult = true; mWaitingForResult = true;
showDialog(DIALOG_RENAME_FOLDER); showDialog(DIALOG_RENAME_FOLDER);
@ -1384,16 +1456,17 @@ public final class Launcher extends Activity implements View.OnClickListener, On
if (mDesktopLocked) { if (mDesktopLocked) {
mDrawer.lock(); mDrawer.lock();
sModel.loadUserItems(false, Launcher.this); sModel.loadUserItems(false, Launcher.this, false);
} else { } else {
final FolderIcon folderIcon = (FolderIcon) mWorkspace.getViewForTag(mFolderInfo); final FolderIcon folderIcon = (FolderIcon)
mWorkspace.getViewForTag(mFolderInfo);
if (folderIcon != null) { if (folderIcon != null) {
folderIcon.setText(name); folderIcon.setText(name);
getWorkspace().requestLayout(); getWorkspace().requestLayout();
} else { } else {
mDesktopLocked = true; mDesktopLocked = true;
mDrawer.lock(); mDrawer.lock();
sModel.loadUserItems(false, Launcher.this); sModel.loadUserItems(false, Launcher.this, false);
} }
} }
} }
@ -1479,7 +1552,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
removeShortcutsForPackage(intent.getData().getSchemeSpecificPart()); removeShortcutsForPackage(intent.getData().getSchemeSpecificPart());
} }
removeDialog(DIALOG_CREATE_SHORTCUT); removeDialog(DIALOG_CREATE_SHORTCUT);
sModel.loadApplications(false, Launcher.this); sModel.loadApplications(false, Launcher.this, false);
} }
} }
@ -1488,7 +1561,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
*/ */
private class FavoritesChangeObserver extends ContentObserver { private class FavoritesChangeObserver extends ContentObserver {
public FavoritesChangeObserver() { public FavoritesChangeObserver() {
super(mHandler); super(new Handler());
} }
@Override @Override
@ -1497,34 +1570,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On
} }
} }
private class SensorHandler implements SensorListener {
private long mLastNegativeShake;
private long mLastPositiveShake;
public void onSensorChanged(int sensor, float[] values) {
if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
float shake = values[0];
if (shake <= -SensorManager.STANDARD_GRAVITY) {
mLastNegativeShake = SystemClock.uptimeMillis();
} else if (shake >= SensorManager.STANDARD_GRAVITY) {
mLastPositiveShake = SystemClock.uptimeMillis();
}
final long difference = mLastPositiveShake - mLastNegativeShake;
if (difference <= -80 && difference >= -180) {
mWorkspace.scrollLeft();
mLastNegativeShake = mLastPositiveShake = 0;
} else if (difference >= 80 && difference <= 180) {
mWorkspace.scrollRight();
mLastNegativeShake = mLastPositiveShake = 0;
}
}
}
public void onAccuracyChanged(int sensor, int accuracy) {
}
}
/** /**
* Receives intents from other applications to change the wallpaper. * Receives intents from other applications to change the wallpaper.
*/ */

View File

@ -0,0 +1,29 @@
/*
* 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.
*/
package com.android.launcher;
import android.app.Application;
import dalvik.system.VMRuntime;
public class LauncherApplication extends Application {
@Override
public void onCreate() {
VMRuntime.getRuntime().setMinimumHeapSize(4 * 1024 * 1024);
super.onCreate();
}
}

View File

@ -30,7 +30,6 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.net.Uri; import android.net.Uri;
import com.android.internal.provider.Settings;
import android.util.Log; import android.util.Log;
import java.util.ArrayList; import java.util.ArrayList;
@ -40,6 +39,7 @@ import java.util.List;
import java.util.Comparator; import java.util.Comparator;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.text.Collator; import java.text.Collator;
import java.net.URISyntaxException;
/** /**
* Maintains in-memory state of the Launcher. It is expected that there should be only one * Maintains in-memory state of the Launcher. It is expected that there should be only one
@ -58,7 +58,7 @@ public class LauncherModel {
private boolean mDesktopItemsLoaded; private boolean mDesktopItemsLoaded;
private ArrayList<ItemInfo> mDesktopItems; private ArrayList<ItemInfo> mDesktopItems;
private HashMap<Long, UserFolderInfo> mUserFolders; private HashMap<Long, FolderInfo> mFolders;
private ArrayList<ApplicationInfo> mApplications; private ArrayList<ApplicationInfo> mApplications;
private ApplicationsAdapter mApplicationsAdapter; private ApplicationsAdapter mApplicationsAdapter;
@ -81,13 +81,13 @@ public class LauncherModel {
/** /**
* Loads the list of installed applications in mApplications. * Loads the list of installed applications in mApplications.
*/ */
void loadApplications(boolean isLaunching, Launcher launcher) { void loadApplications(boolean isLaunching, Launcher launcher, boolean localeChanged) {
if (isLaunching && mApplicationsLoaded) { if (isLaunching && mApplicationsLoaded && !localeChanged) {
mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications); mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications);
return; return;
} }
if (mApplicationsAdapter == null || isLaunching) { if (mApplicationsAdapter == null || isLaunching || localeChanged) {
mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplicationsAdapter = new ApplicationsAdapter(launcher,
mApplications = new ArrayList<ApplicationInfo>(DEFAULT_APPLICATIONS_NUMBER)); mApplications = new ArrayList<ApplicationInfo>(DEFAULT_APPLICATIONS_NUMBER));
} }
@ -164,7 +164,7 @@ public class LauncherModel {
action.sort(new Comparator<ApplicationInfo>() { action.sort(new Comparator<ApplicationInfo>() {
public final int compare(ApplicationInfo a, ApplicationInfo b) { public final int compare(ApplicationInfo a, ApplicationInfo b) {
return sCollator.compare(a.title, b.title); return sCollator.compare(a.title.toString(), b.title.toString());
} }
}); });
@ -221,7 +221,7 @@ public class LauncherModel {
* Loads all of the items on the desktop, in folders, or in the dock. * Loads all of the items on the desktop, in folders, or in the dock.
* These can be apps, shortcuts or widgets * These can be apps, shortcuts or widgets
*/ */
void loadUserItems(boolean isLaunching, Launcher launcher) { void loadUserItems(boolean isLaunching, Launcher launcher, boolean localeChanged) {
if (isLaunching && mDesktopItems != null && mDesktopItemsLoaded) { if (isLaunching && mDesktopItems != null && mDesktopItemsLoaded) {
// We have already loaded our data from the DB // We have already loaded our data from the DB
launcher.onDesktopItemsLoaded(); launcher.onDesktopItemsLoaded();
@ -240,19 +240,88 @@ public class LauncherModel {
} }
mDesktopItemsLoaded = false; mDesktopItemsLoaded = false;
mDesktopItemsLoader = new DesktopItemsLoader(launcher); mDesktopItemsLoader = new DesktopItemsLoader(launcher, localeChanged);
mDesktopLoader = new Thread(mDesktopItemsLoader, "Desktop Items Loader"); mDesktopLoader = new Thread(mDesktopItemsLoader, "Desktop Items Loader");
mDesktopLoader.start(); mDesktopLoader.start();
} }
private static void updateShortcutLabels(ContentResolver resolver, PackageManager manager) {
final Cursor c = resolver.query(LauncherSettings.Favorites.CONTENT_URI,
new String[] { LauncherSettings.Favorites.ID, LauncherSettings.Favorites.TITLE,
LauncherSettings.Favorites.INTENT, LauncherSettings.Favorites.ITEM_TYPE },
null, null, null);
final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ID);
final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
// boolean changed = false;
try {
while (c.moveToNext()) {
try {
if (c.getInt(itemTypeIndex) != LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
continue;
}
final String intentUri = c.getString(intentIndex);
if (intentUri != null) {
final Intent shortcut = Intent.getIntent(intentUri);
if (Intent.ACTION_MAIN.equals(shortcut.getAction())) {
final ComponentName name = shortcut.getComponent();
if (name != null) {
final ActivityInfo activityInfo = manager.getActivityInfo(name, 0);
final String title = c.getString(titleIndex);
String label = getLabel(manager, activityInfo);
if (title == null || !title.equals(label)) {
final ContentValues values = new ContentValues();
values.put(LauncherSettings.Favorites.TITLE, label);
resolver.update(LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION,
values, "_id=?",
new String[] { String.valueOf(c.getLong(idIndex)) });
// changed = true;
}
}
}
}
} catch (URISyntaxException e) {
// Ignore
} catch (PackageManager.NameNotFoundException e) {
// Ignore
}
}
} finally {
c.close();
}
// if (changed) resolver.notifyChange(Settings.Favorites.CONTENT_URI, null);
}
private static String getLabel(PackageManager manager, ActivityInfo activityInfo) {
String label = activityInfo.loadLabel(manager).toString();
if (label == null) {
label = manager.getApplicationLabel(activityInfo.applicationInfo).toString();
if (label == null) {
label = activityInfo.name;
}
}
return label;
}
private class DesktopItemsLoader implements Runnable { private class DesktopItemsLoader implements Runnable {
private volatile boolean mStopped; private volatile boolean mStopped;
private volatile boolean mRunning; private volatile boolean mRunning;
private final WeakReference<Launcher> mLauncher; private final WeakReference<Launcher> mLauncher;
private boolean mLocaleChanged;
DesktopItemsLoader(Launcher launcher) { DesktopItemsLoader(Launcher launcher, boolean localeChanged) {
mLauncher = new WeakReference<Launcher>(launcher); mLauncher = new WeakReference<Launcher>(launcher);
mLocaleChanged = localeChanged;
} }
void stop() { void stop() {
@ -267,54 +336,61 @@ public class LauncherModel {
mRunning = true; mRunning = true;
final Launcher launcher = mLauncher.get(); final Launcher launcher = mLauncher.get();
final ContentResolver contentResolver = launcher.getContentResolver();
final PackageManager manager = launcher.getPackageManager();
if (mLocaleChanged) {
updateShortcutLabels(contentResolver, manager);
}
mDesktopItems = new ArrayList<ItemInfo>(); mDesktopItems = new ArrayList<ItemInfo>();
mUserFolders = new HashMap<Long, UserFolderInfo>(); mFolders = new HashMap<Long, FolderInfo>();
final ArrayList<ItemInfo> desktopItems = mDesktopItems; final ArrayList<ItemInfo> desktopItems = mDesktopItems;
final Cursor c = launcher.getContentResolver().query(Settings.Favorites.CONTENT_URI, final Cursor c = contentResolver.query(
null, null, null, null); LauncherSettings.Favorites.CONTENT_URI, null, null, null, null);
try { try {
final int idIndex = c.getColumnIndexOrThrow(Settings.Favorites.ID); final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ID);
final int intentIndex = c.getColumnIndexOrThrow(Settings.Favorites.INTENT); final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
final int titleIndex = c.getColumnIndexOrThrow(Settings.Favorites.TITLE); final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
final int iconTypeIndex = c.getColumnIndexOrThrow(Settings.Favorites.ICON_TYPE); final int iconTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_TYPE);
final int iconIndex = c.getColumnIndexOrThrow(Settings.Favorites.ICON); final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON);
final int iconPackageIndex = c.getColumnIndexOrThrow(Settings.Favorites.ICON_PACKAGE); final int iconPackageIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_PACKAGE);
final int iconResourceIndex = c.getColumnIndexOrThrow(Settings.Favorites.ICON_RESOURCE); final int iconResourceIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE);
final int containerIndex = c.getColumnIndexOrThrow(Settings.Favorites.CONTAINER); final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
final int itemTypeIndex = c.getColumnIndexOrThrow(Settings.Favorites.ITEM_TYPE); final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
final int screenIndex = c.getColumnIndexOrThrow(Settings.Favorites.SCREEN); final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
final int cellXIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLX); final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
final int cellYIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLY); final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
final PackageManager manager = launcher.getPackageManager(); final int displayModeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.DISPLAY_MODE);
ApplicationInfo info; ApplicationInfo info;
String intentDescription; String intentDescription;
Widget widgetInfo = null; Widget widgetInfo = null;
int container; int container;
long id;
Intent intent;
final HashMap<Long, UserFolderInfo> userFolders = mUserFolders; final HashMap<Long, FolderInfo> folders = mFolders;
while (!mStopped && c.moveToNext()) { while (!mStopped && c.moveToNext()) {
try { try {
int itemType = c.getInt(itemTypeIndex); int itemType = c.getInt(itemTypeIndex);
switch (itemType) { switch (itemType) {
case Settings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case Settings.Favorites.ITEM_TYPE_SHORTCUT: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
intentDescription = c.getString(intentIndex); intentDescription = c.getString(intentIndex);
Intent intent;
try { try {
intent = Intent.getIntent(intentDescription); intent = Intent.getIntent(intentDescription);
} catch (java.net.URISyntaxException e) { } catch (java.net.URISyntaxException e) {
continue; continue;
} }
if (itemType == Settings.Favorites.ITEM_TYPE_APPLICATION) { if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
info = getApplicationInfo(manager, intent); info = getApplicationInfo(manager, intent);
} else { } else {
info = getApplicationInfoShortcut(c, launcher, iconTypeIndex, info = getApplicationInfoShortcut(c, launcher, iconTypeIndex,
@ -338,22 +414,22 @@ public class LauncherModel {
info.cellY = c.getInt(cellYIndex); info.cellY = c.getInt(cellYIndex);
switch (container) { switch (container) {
case Settings.Favorites.CONTAINER_DESKTOP: case LauncherSettings.Favorites.CONTAINER_DESKTOP:
desktopItems.add(info); desktopItems.add(info);
break; break;
default: default:
// Item is in a user folder // Item is in a user folder
UserFolderInfo folderInfo = UserFolderInfo folderInfo =
findOrMakeFolder(userFolders, container); findOrMakeUserFolder(folders, container);
folderInfo.add(info); folderInfo.add(info);
break; break;
} }
} }
break; break;
case Settings.Favorites.ITEM_TYPE_USER_FOLDER: case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
long id = c.getLong(idIndex); id = c.getLong(idIndex);
UserFolderInfo folderInfo = findOrMakeFolder(userFolders, id); UserFolderInfo folderInfo = findOrMakeUserFolder(folders, id);
folderInfo.title = c.getString(titleIndex); folderInfo.title = c.getString(titleIndex);
@ -365,24 +441,57 @@ public class LauncherModel {
folderInfo.cellY = c.getInt(cellYIndex); folderInfo.cellY = c.getInt(cellYIndex);
switch (container) { switch (container) {
case Settings.Favorites.CONTAINER_DESKTOP: case LauncherSettings.Favorites.CONTAINER_DESKTOP:
desktopItems.add(folderInfo); desktopItems.add(folderInfo);
break; break;
default:
} }
break; break;
case Settings.Favorites.ITEM_TYPE_WIDGET_CLOCK: case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
case Settings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
case Settings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME: id = c.getLong(idIndex);
LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(folders, id);
intentDescription = c.getString(intentIndex);
intent = null;
if (intentDescription != null) {
try {
intent = Intent.getIntent(intentDescription);
} catch (java.net.URISyntaxException e) {
// Ignore, a live folder might not have a base intent
}
}
liveFolderInfo.title = c.getString(titleIndex);
liveFolderInfo.id = id;
container = c.getInt(containerIndex);
liveFolderInfo.container = container;
liveFolderInfo.screen = c.getInt(screenIndex);
liveFolderInfo.cellX = c.getInt(cellXIndex);
liveFolderInfo.cellY = c.getInt(cellYIndex);
liveFolderInfo.uri = Uri.parse(c.getString(uriIndex));
liveFolderInfo.baseIntent = intent;
liveFolderInfo.displayMode = c.getInt(displayModeIndex);
loadLiveFolderIcon(launcher, c, iconTypeIndex, iconPackageIndex,
iconResourceIndex, liveFolderInfo);
switch (container) {
case LauncherSettings.Favorites.CONTAINER_DESKTOP:
desktopItems.add(liveFolderInfo);
break;
}
break;
case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK:
case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME:
switch (itemType) { switch (itemType) {
case Settings.Favorites.ITEM_TYPE_WIDGET_CLOCK: case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK:
widgetInfo = Widget.makeClock(); widgetInfo = Widget.makeClock();
break; break;
case Settings.Favorites.ITEM_TYPE_WIDGET_SEARCH: case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
widgetInfo = Widget.makeSearch(); widgetInfo = Widget.makeSearch();
break; break;
case Settings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME: case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME:
widgetInfo = Widget.makePhotoFrame(); widgetInfo = Widget.makePhotoFrame();
byte[] data = c.getBlob(iconIndex); byte[] data = c.getBlob(iconIndex);
if (data != null) { if (data != null) {
@ -394,7 +503,7 @@ public class LauncherModel {
if (widgetInfo != null) { if (widgetInfo != null) {
container = c.getInt(containerIndex); container = c.getInt(containerIndex);
if (container != Settings.Favorites.CONTAINER_DESKTOP) { if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
Log.e(Launcher.LOG_TAG, "Widget found where container " Log.e(Launcher.LOG_TAG, "Widget found where container "
+ "!= CONTAINER_DESKTOP -- ignoring!"); + "!= CONTAINER_DESKTOP -- ignoring!");
continue; continue;
@ -432,6 +541,33 @@ public class LauncherModel {
} }
} }
private static void loadLiveFolderIcon(Launcher launcher, Cursor c, int iconTypeIndex,
int iconPackageIndex, int iconResourceIndex, LiveFolderInfo liveFolderInfo) {
int iconType = c.getInt(iconTypeIndex);
switch (iconType) {
case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
String packageName = c.getString(iconPackageIndex);
String resourceName = c.getString(iconResourceIndex);
PackageManager packageManager = launcher.getPackageManager();
try {
Resources resources = packageManager.getResourcesForApplication(packageName);
final int id = resources.getIdentifier(resourceName, null, null);
liveFolderInfo.icon = resources.getDrawable(id);
} catch (Exception e) {
liveFolderInfo.icon =
launcher.getResources().getDrawable(R.drawable.ic_launcher_folder);
}
liveFolderInfo.iconResource = new Intent.ShortcutIconResource();
liveFolderInfo.iconResource.packageName = packageName;
liveFolderInfo.iconResource.resourceName = resourceName;
break;
default:
liveFolderInfo.icon =
launcher.getResources().getDrawable(R.drawable.ic_launcher_folder);
}
}
/** /**
* Finds the user folder defined by the specified id. * Finds the user folder defined by the specified id.
* *
@ -439,28 +575,42 @@ public class LauncherModel {
* *
* @return A UserFolderInfo if the folder exists or null otherwise. * @return A UserFolderInfo if the folder exists or null otherwise.
*/ */
UserFolderInfo findFolderById(long id) { FolderInfo findFolderById(long id) {
return mUserFolders.get(id); return mFolders.get(id);
} }
void addUserFolder(UserFolderInfo info) { void addFolder(FolderInfo info) {
mUserFolders.put(info.id, info); mFolders.put(info.id, info);
} }
/** /**
* Return an existing UserFolderInfo object if we have encountered this ID previously, or make a * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a
* new one. * new one.
*/ */
private UserFolderInfo findOrMakeFolder(HashMap<Long, UserFolderInfo> userFolders, long id) { private UserFolderInfo findOrMakeUserFolder(HashMap<Long, FolderInfo> folders, long id) {
UserFolderInfo folderInfo;
// See if a placeholder was created for us already // See if a placeholder was created for us already
folderInfo = userFolders.get(id); FolderInfo folderInfo = folders.get(id);
if (folderInfo == null) { if (folderInfo == null || !(folderInfo instanceof UserFolderInfo)) {
// No placeholder -- create a new instance // No placeholder -- create a new instance
folderInfo = new UserFolderInfo(); folderInfo = new UserFolderInfo();
userFolders.put(id, folderInfo); folders.put(id, folderInfo);
} }
return folderInfo; return (UserFolderInfo) folderInfo;
}
/**
* Return an existing UserFolderInfo object if we have encountered this ID previously, or make a
* new one.
*/
private LiveFolderInfo findOrMakeLiveFolder(HashMap<Long, FolderInfo> folders, long id) {
// See if a placeholder was created for us already
FolderInfo folderInfo = folders.get(id);
if (folderInfo == null || !(folderInfo instanceof LiveFolderInfo)) {
// No placeholder -- create a new instance
folderInfo = new LiveFolderInfo();
folders.put(id, folderInfo);
}
return (LiveFolderInfo) folderInfo;
} }
/** /**
@ -483,8 +633,8 @@ public class LauncherModel {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
ItemInfo item = desktopItems.get(i); ItemInfo item = desktopItems.get(i);
switch (item.itemType) { switch (item.itemType) {
case Settings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case Settings.Favorites.ITEM_TYPE_SHORTCUT: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
((ApplicationInfo)item).icon.setCallback(null); ((ApplicationInfo)item).icon.setCallback(null);
} }
} }
@ -562,7 +712,7 @@ public class LauncherModel {
if (info.title == null) { if (info.title == null) {
info.title = ""; info.title = "";
} }
info.itemType = Settings.Favorites.ITEM_TYPE_APPLICATION; info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
return info; return info;
} }
@ -573,11 +723,11 @@ public class LauncherModel {
int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex) { int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex) {
final ApplicationInfo info = new ApplicationInfo(); final ApplicationInfo info = new ApplicationInfo();
info.itemType = Settings.Favorites.ITEM_TYPE_SHORTCUT; info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
int iconType = c.getInt(iconTypeIndex); int iconType = c.getInt(iconTypeIndex);
switch (iconType) { switch (iconType) {
case Settings.Favorites.ICON_TYPE_RESOURCE: case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
String packageName = c.getString(iconPackageIndex); String packageName = c.getString(iconPackageIndex);
String resourceName = c.getString(iconResourceIndex); String resourceName = c.getString(iconResourceIndex);
PackageManager packageManager = launcher.getPackageManager(); PackageManager packageManager = launcher.getPackageManager();
@ -593,10 +743,11 @@ public class LauncherModel {
info.iconResource.resourceName = resourceName; info.iconResource.resourceName = resourceName;
info.customIcon = false; info.customIcon = false;
break; break;
case Settings.Favorites.ICON_TYPE_BITMAP: case LauncherSettings.Favorites.ICON_TYPE_BITMAP:
byte[] data = c.getBlob(iconIndex); byte[] data = c.getBlob(iconIndex);
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
info.icon = new BitmapDrawable(Utilities.createBitmapThumbnail(bitmap, launcher)); info.icon = new FastBitmapDrawable(
Utilities.createBitmapThumbnail(bitmap, launcher));
info.filtered = true; info.filtered = true;
info.customIcon = true; info.customIcon = true;
break; break;
@ -621,7 +772,7 @@ public class LauncherModel {
* @param userFolderInfo * @param userFolderInfo
*/ */
void removeUserFolder(UserFolderInfo userFolderInfo) { void removeUserFolder(UserFolderInfo userFolderInfo) {
mUserFolders.remove(userFolderInfo.id); mFolders.remove(userFolderInfo.id);
} }
/** /**
@ -652,12 +803,12 @@ public class LauncherModel {
final ContentValues values = new ContentValues(); final ContentValues values = new ContentValues();
final ContentResolver cr = context.getContentResolver(); final ContentResolver cr = context.getContentResolver();
values.put(Settings.Favorites.CONTAINER, item.container); values.put(LauncherSettings.Favorites.CONTAINER, item.container);
values.put(Settings.Favorites.CELLX, item.cellX); values.put(LauncherSettings.Favorites.CELLX, item.cellX);
values.put(Settings.Favorites.CELLY, item.cellY); values.put(LauncherSettings.Favorites.CELLY, item.cellY);
values.put(Settings.Favorites.SCREEN, item.screen); values.put(LauncherSettings.Favorites.SCREEN, item.screen);
cr.update(Settings.Favorites.getContentUri(item.id, false), values, null, null); cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
} }
/** /**
@ -666,7 +817,7 @@ public class LauncherModel {
*/ */
static boolean shortcutExists(Context context, String title, Intent intent) { static boolean shortcutExists(Context context, String title, Intent intent) {
final ContentResolver cr = context.getContentResolver(); final ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(Settings.Favorites.CONTENT_URI, Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
new String[] { "title", "intent" }, "title=? and intent=?", new String[] { "title", "intent" }, "title=? and intent=?",
new String[] { title, intent.toURI() }, null); new String[] { title, intent.toURI() }, null);
boolean result = false; boolean result = false;
@ -678,21 +829,32 @@ public class LauncherModel {
return result; return result;
} }
UserFolderInfo getFolderById(Context context, long id) { FolderInfo getFolderById(Context context, long id) {
final ContentResolver cr = context.getContentResolver(); final ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(Settings.Favorites.CONTENT_URI, null, "_id=? and itemType=?", Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null,
new String[] { String.valueOf(id), "_id=? and itemType=? or itemType=?",
String.valueOf(Settings.Favorites.ITEM_TYPE_USER_FOLDER) }, null); new String[] { String.valueOf(id),
String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER),
String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER) }, null);
try { try {
if (c.moveToFirst()) { if (c.moveToFirst()) {
final int titleIndex = c.getColumnIndexOrThrow(Settings.Favorites.TITLE); final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
final int containerIndex = c.getColumnIndexOrThrow(Settings.Favorites.CONTAINER); final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
final int screenIndex = c.getColumnIndexOrThrow(Settings.Favorites.SCREEN); final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
final int cellXIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLX); final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
final int cellYIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLY); final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
UserFolderInfo folderInfo = findOrMakeFolder(mUserFolders, id); FolderInfo folderInfo = null;
switch (c.getInt(itemTypeIndex)) {
case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
folderInfo = findOrMakeUserFolder(mFolders, id);
break;
case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
folderInfo = findOrMakeLiveFolder(mFolders, id);
break;
}
folderInfo.title = c.getString(titleIndex); folderInfo.title = c.getString(titleIndex);
folderInfo.id = id; folderInfo.id = id;
@ -712,18 +874,18 @@ public class LauncherModel {
static Widget getPhotoFrameInfo(Context context, int screen, int cellX, int cellY) { static Widget getPhotoFrameInfo(Context context, int screen, int cellX, int cellY) {
final ContentResolver cr = context.getContentResolver(); final ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(Settings.Favorites.CONTENT_URI, Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
null, "screen=? and cellX=? and cellY=? and itemType=?", null, "screen=? and cellX=? and cellY=? and itemType=?",
new String[] { String.valueOf(screen), String.valueOf(cellX), String.valueOf(cellY), new String[] { String.valueOf(screen), String.valueOf(cellX), String.valueOf(cellY),
String.valueOf(Settings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME) }, null); String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME) }, null);
try { try {
if (c.moveToFirst()) { if (c.moveToFirst()) {
final int idIndex = c.getColumnIndexOrThrow(Settings.Favorites.ID); final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ID);
final int containerIndex = c.getColumnIndexOrThrow(Settings.Favorites.CONTAINER); final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
final int screenIndex = c.getColumnIndexOrThrow(Settings.Favorites.SCREEN); final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
final int cellXIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLX); final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
final int cellYIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLY); final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
Widget widgetInfo = Widget.makePhotoFrame(); Widget widgetInfo = Widget.makePhotoFrame();
widgetInfo.id = c.getLong(idIndex); widgetInfo.id = c.getLong(idIndex);
@ -757,8 +919,8 @@ public class LauncherModel {
item.onAddToDatabase(values); item.onAddToDatabase(values);
Uri result = cr.insert(notify ? Settings.Favorites.CONTENT_URI : Uri result = cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI :
Settings.Favorites.CONTENT_URI_NO_NOTIFICATION, values); LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values);
if (result != null) { if (result != null) {
item.id = Integer.parseInt(result.getPathSegments().get(1)); item.id = Integer.parseInt(result.getPathSegments().get(1));
@ -774,7 +936,7 @@ public class LauncherModel {
item.onAddToDatabase(values); item.onAddToDatabase(values);
cr.update(Settings.Favorites.getContentUri(item.id, false), values, null, null); cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
} }
/** /**
@ -785,7 +947,7 @@ public class LauncherModel {
static void deleteItemFromDatabase(Context context, ItemInfo item) { static void deleteItemFromDatabase(Context context, ItemInfo item) {
final ContentResolver cr = context.getContentResolver(); final ContentResolver cr = context.getContentResolver();
cr.delete(Settings.Favorites.getContentUri(item.id, false), null, null); cr.delete(LauncherSettings.Favorites.getContentUri(item.id, false), null, null);
} }
@ -795,8 +957,8 @@ public class LauncherModel {
static void deleteUserFolderContentsFromDatabase(Context context, UserFolderInfo info) { static void deleteUserFolderContentsFromDatabase(Context context, UserFolderInfo info) {
final ContentResolver cr = context.getContentResolver(); final ContentResolver cr = context.getContentResolver();
cr.delete(Settings.Favorites.getContentUri(info.id, false), null, null); cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null);
cr.delete(Settings.Favorites.CONTENT_URI, Settings.Favorites.CONTAINER + "=" + info.id, cr.delete(LauncherSettings.Favorites.CONTENT_URI, LauncherSettings.Favorites.CONTAINER + "=" + info.id,
null); null);
} }
} }

View File

@ -0,0 +1,435 @@
/*
* 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.
*/
package com.android.launcher;
import android.content.ContentProvider;
import android.content.Context;
import android.content.ContentValues;
import android.content.Intent;
import android.content.ComponentName;
import android.content.ContentUris;
import android.content.ContentResolver;
import android.content.pm.PackageManager;
import android.content.pm.ActivityInfo;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.database.Cursor;
import android.util.Log;
import android.util.Xml;
import android.net.Uri;
import android.text.TextUtils;
import android.os.*;
import android.provider.Settings;
import java.io.FileReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import com.android.internal.util.XmlUtils;
public class LauncherProvider extends ContentProvider {
private static final String LOG_TAG = "LauncherSettingsProvider";
private static final String DATABASE_NAME = "launcher.db";
private static final int DATABASE_VERSION = 1;
static final String AUTHORITY = "com.android.launcher.settings";
static final String TABLE_FAVORITES = "favorites";
static final String PARAMETER_NOTIFY = "notify";
private SQLiteOpenHelper mOpenHelper;
@Override
public boolean onCreate() {
mOpenHelper = new DatabaseHelper(getContext());
return true;
}
@Override
public String getType(Uri uri) {
SqlArguments args = new SqlArguments(uri, null, null);
if (TextUtils.isEmpty(args.where)) {
return "vnd.android.cursor.dir/" + args.table;
} else {
return "vnd.android.cursor.item/" + args.table;
}
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SqlArguments args = new SqlArguments(uri, selection, selectionArgs);
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(args.table);
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor result = qb.query(db, projection, args.where, args.args, null, null, sortOrder);
result.setNotificationUri(getContext().getContentResolver(), uri);
return result;
}
@Override
public Uri insert(Uri uri, ContentValues initialValues) {
SqlArguments args = new SqlArguments(uri);
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
final long rowId = db.insert(args.table, null, initialValues);
if (rowId <= 0) return null;
uri = ContentUris.withAppendedId(uri, rowId);
sendNotify(uri);
return uri;
}
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
SqlArguments args = new SqlArguments(uri);
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
try {
int numValues = values.length;
for (int i = 0; i < numValues; i++) {
if (db.insert(args.table, null, values[i]) < 0) return 0;
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
sendNotify(uri);
return values.length;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SqlArguments args = new SqlArguments(uri, selection, selectionArgs);
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count = db.delete(args.table, args.where, args.args);
if (count > 0) sendNotify(uri);
return count;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SqlArguments args = new SqlArguments(uri, selection, selectionArgs);
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count = db.update(args.table, values, args.where, args.args);
if (count > 0) sendNotify(uri);
return count;
}
private void sendNotify(Uri uri) {
String notify = uri.getQueryParameter(PARAMETER_NOTIFY);
if (notify == null || "true".equals(notify)) {
getContext().getContentResolver().notifyChange(uri, null);
}
}
private static class DatabaseHelper extends SQLiteOpenHelper {
/**
* Path to file containing default favorite packages, relative to ANDROID_ROOT.
*/
private static final String DEFAULT_FAVORITES_PATH = "etc/favorites.xml";
private static final String TAG_FAVORITES = "favorites";
private static final String TAG_FAVORITE = "favorite";
private static final String TAG_PACKAGE = "package";
private static final String TAG_CLASS = "class";
private static final String ATTRIBUTE_SCREEN = "screen";
private static final String ATTRIBUTE_X = "x";
private static final String ATTRIBUTE_Y = "y";
private final Context mContext;
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE favorites (" +
"_id INTEGER PRIMARY KEY," +
"title TEXT," +
"intent TEXT," +
"container INTEGER," +
"screen INTEGER," +
"cellX INTEGER," +
"cellY INTEGER," +
"spanX INTEGER," +
"spanY INTEGER," +
"itemType INTEGER," +
"isShortcut INTEGER," +
"iconType INTEGER," +
"iconPackage TEXT," +
"iconResource TEXT," +
"icon BLOB," +
"uri TEXT," +
"displayMode INTEGER" +
");");
if (!convertDatabase(db)) {
// Populate favorites table with initial favorites
loadFavorites(db, DEFAULT_FAVORITES_PATH);
}
}
private boolean convertDatabase(SQLiteDatabase db) {
boolean converted = false;
final Uri uri = Uri.parse("content://" + Settings.AUTHORITY +
"/favorites?notify=true");
final ContentResolver resolver = mContext.getContentResolver();
Cursor cursor = null;
try {
cursor = resolver.query(uri, null, null, null, null);
} catch (Exception e) {
// Ignore
}
// We already have a favorites database in the old provider
if (cursor != null && cursor.getCount() > 0) {
try {
converted = copyFromCursor(db, cursor) > 0;
} finally {
cursor.close();
}
if (converted) {
resolver.delete(uri, null, null);
}
}
return converted;
}
private int copyFromCursor(SQLiteDatabase db, Cursor c) {
final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ID);
final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
final int iconTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_TYPE);
final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON);
final int iconPackageIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_PACKAGE);
final int iconResourceIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE);
final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
final int displayModeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.DISPLAY_MODE);
ContentValues[] rows = new ContentValues[c.getCount()];
int i = 0;
while (c.moveToNext()) {
ContentValues values = new ContentValues(c.getColumnCount());
values.put(LauncherSettings.Favorites.ID, c.getLong(idIndex));
values.put(LauncherSettings.Favorites.INTENT, c.getString(intentIndex));
values.put(LauncherSettings.Favorites.TITLE, c.getString(titleIndex));
values.put(LauncherSettings.Favorites.ICON_TYPE, c.getInt(iconTypeIndex));
values.put(LauncherSettings.Favorites.ICON, c.getBlob(iconIndex));
values.put(LauncherSettings.Favorites.ICON_PACKAGE, c.getString(iconPackageIndex));
values.put(LauncherSettings.Favorites.ICON_RESOURCE, c.getString(iconResourceIndex));
values.put(LauncherSettings.Favorites.CONTAINER, c.getInt(containerIndex));
values.put(LauncherSettings.Favorites.ITEM_TYPE, c.getInt(itemTypeIndex));
values.put(LauncherSettings.Favorites.SCREEN, c.getInt(screenIndex));
values.put(LauncherSettings.Favorites.CELLX, c.getInt(cellXIndex));
values.put(LauncherSettings.Favorites.CELLY, c.getInt(cellYIndex));
values.put(LauncherSettings.Favorites.URI, c.getString(uriIndex));
values.put(LauncherSettings.Favorites.DISPLAY_MODE, c.getInt(displayModeIndex));
rows[i++] = values;
}
db.beginTransaction();
int total = 0;
try {
int numValues = rows.length;
for (i = 0; i < numValues; i++) {
if (db.insert(TABLE_FAVORITES, null, rows[i]) < 0) {
return 0;
} else {
total++;
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
return total;
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(LOG_TAG, "Upgrading database from version " + oldVersion + " to " +
newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_FAVORITES);
onCreate(db);
}
/**
* Loads the default set of favorite packages from an xml file.
*
* @param db The database to write the values into
* @param subPath The relative path from ANDROID_ROOT to the file to read
*/
private int loadFavorites(SQLiteDatabase db, String subPath) {
FileReader favReader;
// Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
final File favFile = new File(Environment.getRootDirectory(), subPath);
try {
favReader = new FileReader(favFile);
} catch (FileNotFoundException e) {
Log.e(LOG_TAG, "Couldn't find or open favorites file " + favFile);
return 0;
}
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
ContentValues values = new ContentValues();
PackageManager packageManager = mContext.getPackageManager();
ActivityInfo info;
int i = 0;
try {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(favReader);
XmlUtils.beginDocument(parser, TAG_FAVORITES);
while (true) {
XmlUtils.nextElement(parser);
String name = parser.getName();
if (!TAG_FAVORITE.equals(name)) {
break;
}
String pkg = parser.getAttributeValue(null, TAG_PACKAGE);
String cls = parser.getAttributeValue(null, TAG_CLASS);
try {
ComponentName cn = new ComponentName(pkg, cls);
info = packageManager.getActivityInfo(cn, 0);
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
values.put(LauncherSettings.Favorites.INTENT, intent.toURI());
values.put(LauncherSettings.Favorites.TITLE,
info.loadLabel(packageManager).toString());
values.put(LauncherSettings.Favorites.CONTAINER,
LauncherSettings.Favorites.CONTAINER_DESKTOP);
values.put(LauncherSettings.Favorites.ITEM_TYPE,
LauncherSettings.Favorites.ITEM_TYPE_APPLICATION);
values.put(LauncherSettings.Favorites.SCREEN,
parser.getAttributeValue(null, ATTRIBUTE_SCREEN));
values.put(LauncherSettings.Favorites.CELLX,
parser.getAttributeValue(null, ATTRIBUTE_X));
values.put(LauncherSettings.Favorites.CELLY,
parser.getAttributeValue(null, ATTRIBUTE_Y));
values.put(LauncherSettings.Favorites.SPANX, 1);
values.put(LauncherSettings.Favorites.SPANY, 1);
db.insert(TABLE_FAVORITES, null, values);
i++;
} catch (PackageManager.NameNotFoundException e) {
Log.w(LOG_TAG, "Unable to add favorite: " + pkg + "/" + cls, e);
}
}
} catch (XmlPullParserException e) {
Log.w(LOG_TAG, "Got exception parsing favorites.", e);
} catch (IOException e) {
Log.w(LOG_TAG, "Got exception parsing favorites.", e);
}
// Add a clock
values.clear();
values.put(LauncherSettings.Favorites.CONTAINER,
LauncherSettings.Favorites.CONTAINER_DESKTOP);
values.put(LauncherSettings.Favorites.ITEM_TYPE,
LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK);
values.put(LauncherSettings.Favorites.SCREEN, 1);
values.put(LauncherSettings.Favorites.CELLX, 1);
values.put(LauncherSettings.Favorites.CELLY, 0);
values.put(LauncherSettings.Favorites.SPANX, 2);
values.put(LauncherSettings.Favorites.SPANY, 2);
db.insert(TABLE_FAVORITES, null, values);
// Add a search box
values.clear();
values.put(LauncherSettings.Favorites.CONTAINER,
LauncherSettings.Favorites.CONTAINER_DESKTOP);
values.put(LauncherSettings.Favorites.ITEM_TYPE,
LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH);
values.put(LauncherSettings.Favorites.SCREEN, 2);
values.put(LauncherSettings.Favorites.CELLX, 0);
values.put(LauncherSettings.Favorites.CELLY, 0);
values.put(LauncherSettings.Favorites.SPANX, 4);
values.put(LauncherSettings.Favorites.SPANY, 1);
db.insert(TABLE_FAVORITES, null, values);
return i;
}
}
static class SqlArguments {
public final String table;
public final String where;
public final String[] args;
SqlArguments(Uri url, String where, String[] args) {
if (url.getPathSegments().size() == 1) {
this.table = url.getPathSegments().get(0);
this.where = where;
this.args = args;
} else if (url.getPathSegments().size() != 2) {
throw new IllegalArgumentException("Invalid URI: " + url);
} else if (!TextUtils.isEmpty(where)) {
throw new UnsupportedOperationException("WHERE clause not supported: " + url);
} else {
this.table = url.getPathSegments().get(0);
this.where = "_id=" + ContentUris.parseId(url);
this.args = null;
}
}
SqlArguments(Uri url) {
if (url.getPathSegments().size() == 1) {
table = url.getPathSegments().get(0);
where = null;
args = null;
} else {
throw new IllegalArgumentException("Invalid URI: " + url);
}
}
}
}

View File

@ -0,0 +1,222 @@
/*
* 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.
*/
package com.android.launcher;
import android.provider.BaseColumns;
import android.net.Uri;
/**
* Settings related utilities.
*/
class LauncherSettings {
/**
* Favorites.
*/
static final class Favorites implements BaseColumns {
/**
* The content:// style URL for this table
*/
static final Uri CONTENT_URI = Uri.parse("content://" +
LauncherProvider.AUTHORITY + "/" + LauncherProvider.TABLE_FAVORITES +
"?" + LauncherProvider.PARAMETER_NOTIFY + "=true");
/**
* The content:// style URL for this table. When this Uri is used, no notification is
* sent if the content changes.
*/
static final Uri CONTENT_URI_NO_NOTIFICATION = Uri.parse("content://" +
LauncherProvider.AUTHORITY + "/" + LauncherProvider.TABLE_FAVORITES +
"?" + LauncherProvider.PARAMETER_NOTIFY + "=false");
/**
* The content:// style URL for a given row, identified by its id.
*
* @param id The row id.
* @param notify True to send a notification is the content changes.
*
* @return The unique content URL for the specified row.
*/
static Uri getContentUri(long id, boolean notify) {
return Uri.parse("content://" + LauncherProvider.AUTHORITY +
"/" + LauncherProvider.TABLE_FAVORITES + "/" + id + "?" +
LauncherProvider.PARAMETER_NOTIFY + "=" + notify);
}
/**
* The row ID.
* <p>Type: INTEGER</p>
*/
static final String ID = "_id";
/**
* Descriptive name of the favorite that can be displayed to the user.
* <P>Type: TEXT</P>
*/
static final String TITLE = "title";
/**
* The Intent URL of the favorite, describing what it points to. This
* value is given to {@link android.content.Intent#getIntent} to create
* an Intent that can be launched.
* <P>Type: TEXT</P>
*/
static final String INTENT = "intent";
/**
* The container holding the favorite
* <P>Type: INTEGER</P>
*/
static final String CONTAINER = "container";
/**
* The icon is a resource identified by a package name and an integer id.
*/
static final int CONTAINER_DESKTOP = -100;
/**
* The screen holding the favorite (if container is CONTAINER_DESKTOP)
* <P>Type: INTEGER</P>
*/
static final String SCREEN = "screen";
/**
* The X coordinate of the cell holding the favorite
* (if container is CONTAINER_DESKTOP or CONTAINER_DOCK)
* <P>Type: INTEGER</P>
*/
static final String CELLX = "cellX";
/**
* The Y coordinate of the cell holding the favorite
* (if container is CONTAINER_DESKTOP)
* <P>Type: INTEGER</P>
*/
static final String CELLY = "cellY";
/**
* The X span of the cell holding the favorite
* <P>Type: INTEGER</P>
*/
static final String SPANX = "spanX";
/**
* The Y span of the cell holding the favorite
* <P>Type: INTEGER</P>
*/
static final String SPANY = "spanY";
/**
* The type of the favorite
*
* <P>Type: INTEGER</P>
*/
static final String ITEM_TYPE = "itemType";
/**
* The favorite is an application
*/
static final int ITEM_TYPE_APPLICATION = 0;
/**
* The favorite is an application created shortcut
*/
static final int ITEM_TYPE_SHORTCUT = 1;
/**
* The favorite is a user created folder
*/
static final int ITEM_TYPE_USER_FOLDER = 2;
/**
* The favorite is a live folder
*/
static final int ITEM_TYPE_LIVE_FOLDER = 3;
/**
* The favorite is a clock
*/
static final int ITEM_TYPE_WIDGET_CLOCK = 1000;
/**
* The favorite is a search widget
*/
static final int ITEM_TYPE_WIDGET_SEARCH = 1001;
/**
* The favorite is a photo frame
*/
static final int ITEM_TYPE_WIDGET_PHOTO_FRAME = 1002;
/**
* Indicates whether this favorite is an application-created shortcut or not.
* If the value is 0, the favorite is not an application-created shortcut, if the
* value is 1, it is an application-created shortcut.
* <P>Type: INTEGER</P>
*/
static final String IS_SHORTCUT = "isShortcut";
/**
* The icon type.
* <P>Type: INTEGER</P>
*/
static final String ICON_TYPE = "iconType";
/**
* The icon is a resource identified by a package name and an integer id.
*/
static final int ICON_TYPE_RESOURCE = 0;
/**
* The icon is a bitmap.
*/
static final int ICON_TYPE_BITMAP = 1;
/**
* The icon package name, if icon type is ICON_TYPE_RESOURCE.
* <P>Type: TEXT</P>
*/
static final String ICON_PACKAGE = "iconPackage";
/**
* The icon resource id, if icon type is ICON_TYPE_RESOURCE.
* <P>Type: TEXT</P>
*/
static final String ICON_RESOURCE = "iconResource";
/**
* The custom icon bitmap, if icon type is ICON_TYPE_BITMAP.
* <P>Type: BLOB</P>
*/
static final String ICON = "icon";
/**
* The URI associated with the favorite. It is used, for instance, by
* live folders to find the content provider.
* <P>Type: TEXT</P>
*/
static final String URI = "uri";
/**
* The display mode if the item is a live folder.
* <P>Type: INTEGER</P>
*
* @see android.provider.LiveFolders#DISPLAY_MODE_GRID
* @see android.provider.LiveFolders#DISPLAY_MODE_LIST
*/
static final String DISPLAY_MODE = "displayMode";
}
}

View File

@ -0,0 +1,83 @@
/*
* 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.
*/
package com.android.launcher;
import android.content.Context;
import android.content.Intent;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.net.Uri;
import android.provider.LiveFolders;
public class LiveFolder extends Folder {
public LiveFolder(Context context, AttributeSet attrs) {
super(context, attrs);
}
static LiveFolder fromXml(Context context, FolderInfo folderInfo) {
final int layout = isDisplayModeList(folderInfo) ?
R.layout.live_folder_list : R.layout.live_folder_grid;
return (LiveFolder) LayoutInflater.from(context).inflate(layout, null);
}
private static boolean isDisplayModeList(FolderInfo folderInfo) {
return ((LiveFolderInfo) folderInfo).displayMode ==
LiveFolders.DISPLAY_MODE_LIST;
}
@Override
public void onItemClick(AdapterView parent, View v, int position, long id) {
LiveFolderAdapter.ViewHolder holder = (LiveFolderAdapter.ViewHolder) v.getTag();
if (holder.useBaseIntent) {
final Intent baseIntent = ((LiveFolderInfo) mInfo).baseIntent;
if (baseIntent != null) {
final Intent intent = new Intent(baseIntent);
Uri uri = baseIntent.getData();
uri = uri.buildUpon().appendPath(Long.toString(holder.id)).build();
intent.setData(uri);
mLauncher.startActivitySafely(intent);
}
} else if (holder.intent != null) {
mLauncher.startActivitySafely(holder.intent);
}
}
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
return false;
}
void bind(FolderInfo info) {
super.bind(info);
setContentAdapter(new LiveFolderAdapter(mLauncher, (LiveFolderInfo) info));
}
@Override
void onOpen() {
super.onOpen();
requestFocus();
}
@Override
void onClose() {
super.onClose();
((LiveFolderAdapter) mContent.getAdapter()).cleanup();
}
}

View File

@ -0,0 +1,205 @@
/*
* 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.
*/
package com.android.launcher;
import android.widget.CursorAdapter;
import android.widget.TextView;
import android.widget.ImageView;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.content.pm.PackageManager;
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;
import android.database.Cursor;
import android.provider.LiveFolders;
import android.graphics.drawable.Drawable;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.lang.ref.SoftReference;
class LiveFolderAdapter extends CursorAdapter {
private boolean mIsList;
private LayoutInflater mInflater;
private final HashMap<String, Drawable> mIcons = new HashMap<String, Drawable>();
private final HashMap<Long, SoftReference<Drawable>> mCustomIcons =
new HashMap<Long, SoftReference<Drawable>>();
private final Launcher mLauncher;
LiveFolderAdapter(Launcher launcher, LiveFolderInfo info) {
super(launcher, query(launcher, info), true);
mIsList = info.displayMode == LiveFolders.DISPLAY_MODE_LIST;
mInflater = LayoutInflater.from(launcher);
mLauncher = launcher;
mLauncher.startManagingCursor(getCursor());
}
private static Cursor query(Context context, LiveFolderInfo info) {
return context.getContentResolver().query(info.uri, null, null, null, LiveFolders.NAME + " ASC");
}
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view;
final ViewHolder holder = new ViewHolder();
if (!mIsList) {
view = mInflater.inflate(R.layout.application_boxed, parent, false);
} else {
view = mInflater.inflate(R.layout.application_list, parent, false);
holder.description = (TextView) view.findViewById(R.id.description);
holder.icon = (ImageView) view.findViewById(R.id.icon);
}
holder.name = (TextView) view.findViewById(R.id.name);
holder.idIndex = cursor.getColumnIndexOrThrow(LiveFolders._ID);
holder.nameIndex = cursor.getColumnIndexOrThrow(LiveFolders.NAME);
holder.descriptionIndex = cursor.getColumnIndex(LiveFolders.DESCRIPTION);
holder.intentIndex = cursor.getColumnIndex(LiveFolders.INTENT);
holder.iconBitmapIndex = cursor.getColumnIndex(LiveFolders.ICON_BITMAP);
holder.iconResourceIndex = cursor.getColumnIndex(LiveFolders.ICON_RESOURCE);
holder.iconPackageIndex = cursor.getColumnIndex(LiveFolders.ICON_PACKAGE);
view.setTag(holder);
return view;
}
public void bindView(View view, Context context, Cursor cursor) {
final ViewHolder holder = (ViewHolder) view.getTag();
holder.id = cursor.getLong(holder.idIndex);
final Drawable icon = loadIcon(context, cursor, holder);
holder.name.setText(cursor.getString(holder.nameIndex));
if (!mIsList) {
holder.name.setCompoundDrawablesWithIntrinsicBounds(null, icon, null, null);
} else {
final boolean hasIcon = icon != null;
holder.icon.setVisibility(hasIcon ? View.VISIBLE : View.GONE);
if (hasIcon) holder.icon.setImageDrawable(icon);
if (holder.descriptionIndex != -1) {
final String description = cursor.getString(holder.descriptionIndex);
if (description != null) {
holder.description.setText(description);
holder.description.setVisibility(View.VISIBLE);
} else {
holder.description.setVisibility(View.GONE);
}
} else {
holder.description.setVisibility(View.GONE);
}
}
if (holder.intentIndex != -1) {
try {
holder.intent = Intent.getIntent(cursor.getString(holder.intentIndex));
} catch (URISyntaxException e) {
// Ignore
}
} else {
holder.useBaseIntent = true;
}
}
private Drawable loadIcon(Context context, Cursor cursor, ViewHolder holder) {
Drawable icon = null;
byte[] data = null;
if (holder.iconBitmapIndex != -1) {
data = cursor.getBlob(holder.iconBitmapIndex);
}
if (data != null) {
final SoftReference<Drawable> reference = mCustomIcons.get(holder.id);
if (reference != null) {
icon = reference.get();
}
if (icon == null) {
final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
icon = new FastBitmapDrawable(Utilities.createBitmapThumbnail(bitmap, mContext));
mCustomIcons.put(holder.id, new SoftReference<Drawable>(icon));
}
} else if (holder.iconResourceIndex != -1 && holder.iconPackageIndex != -1) {
final String resource = cursor.getString(holder.iconResourceIndex);
icon = mIcons.get(resource);
if (icon == null) {
try {
final PackageManager packageManager = context.getPackageManager();
Resources resources = packageManager.getResourcesForApplication(
cursor.getString(holder.iconPackageIndex));
final int id = resources.getIdentifier(resource,
null, null);
icon = Utilities.createIconThumbnail(resources.getDrawable(id), mContext);
mIcons.put(resource, icon);
} catch (Exception e) {
// Ignore
}
}
}
return icon;
}
void cleanup() {
for (Drawable icon : mIcons.values()) {
icon.setCallback(null);
}
mIcons.clear();
for (SoftReference<Drawable> icon : mCustomIcons.values()) {
final Drawable drawable = icon.get();
if (drawable != null) {
drawable.setCallback(null);
}
}
mCustomIcons.clear();
try {
getCursor().close();
} finally {
mLauncher.stopManagingCursor(getCursor());
}
}
static class ViewHolder {
TextView name;
TextView description;
ImageView icon;
Intent intent;
long id;
boolean useBaseIntent;
int idIndex;
int nameIndex;
int descriptionIndex = -1;
int intentIndex = -1;
int iconBitmapIndex = -1;
int iconResourceIndex = -1;
int iconPackageIndex = -1;
}
}

View File

@ -0,0 +1,76 @@
/*
* 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.
*/
package com.android.launcher;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.view.LayoutInflater;
import android.graphics.drawable.Drawable;
public class LiveFolderIcon extends FolderIcon {
public LiveFolderIcon(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LiveFolderIcon(Context context) {
super(context);
}
static LiveFolderIcon fromXml(int resId, Launcher launcher, ViewGroup group,
LiveFolderInfo folderInfo) {
LiveFolderIcon icon = (LiveFolderIcon)
LayoutInflater.from(launcher).inflate(resId, group, false);
final Resources resources = launcher.getResources();
Drawable d = folderInfo.icon;
if (d == null) {
resources.getDrawable(R.drawable.ic_launcher_folder);
d = Utilities.createIconThumbnail(d, launcher);
folderInfo.filtered = true;
}
icon.setCompoundDrawablesWithIntrinsicBounds(null, d, null, null);
icon.setText(folderInfo.title);
icon.setTag(folderInfo);
icon.setOnClickListener(launcher);
return icon;
}
@Override
public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
return false;
}
@Override
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
}
@Override
public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
}
@Override
public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
}
@Override
public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
}
}

View File

@ -0,0 +1,75 @@
/*
* 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.
*/
package com.android.launcher;
import android.content.ContentValues;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
class LiveFolderInfo extends FolderInfo {
/**
* The base intent, if it exists.
*/
Intent baseIntent;
/**
* The live folder's content uri.
*/
Uri uri;
/**
* The live folder's display type.
*/
int displayMode;
/**
* The live folder icon.
*/
Drawable icon;
/**
* When set to true, indicates that the icon has been resized.
*/
boolean filtered;
/**
* Reference to the live folder icon as an application's resource.
*/
Intent.ShortcutIconResource iconResource;
LiveFolderInfo() {
itemType = LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER;
}
@Override
void onAddToDatabase(ContentValues values) {
super.onAddToDatabase(values);
values.put(LauncherSettings.Favorites.TITLE, title.toString());
values.put(LauncherSettings.Favorites.URI, uri.toString());
if (baseIntent != null) {
values.put(LauncherSettings.Favorites.INTENT, baseIntent.toURI());
}
values.put(LauncherSettings.Favorites.ICON_TYPE, LauncherSettings.Favorites.ICON_TYPE_RESOURCE);
values.put(LauncherSettings.Favorites.DISPLAY_MODE, displayMode);
if (iconResource != null) {
values.put(LauncherSettings.Favorites.ICON_PACKAGE, iconResource.packageName);
values.put(LauncherSettings.Favorites.ICON_RESOURCE, iconResource.resourceName);
}
}
}

View File

@ -16,13 +16,19 @@
package com.android.launcher; package com.android.launcher;
import java.util.List;
import android.app.ISearchManager; import android.app.ISearchManager;
import android.app.SearchManager; import android.app.SearchManager;
import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.Resources.NotFoundException; import android.content.res.Resources.NotFoundException;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
@ -43,9 +49,9 @@ import android.view.View.OnKeyListener;
import android.view.View.OnLongClickListener; import android.view.View.OnLongClickListener;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AutoCompleteTextView; import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CursorAdapter; import android.widget.CursorAdapter;
import android.widget.Filter; import android.widget.Filter;
import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.SimpleCursorAdapter; import android.widget.SimpleCursorAdapter;
@ -59,7 +65,7 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
private final String TAG = "SearchGadget"; private final String TAG = "SearchGadget";
private AutoCompleteTextView mSearchText; private AutoCompleteTextView mSearchText;
private Button mGoButton; private ImageButton mGoButton;
private OnLongClickListener mLongClickListener; private OnLongClickListener mLongClickListener;
// Support for suggestions // Support for suggestions
@ -69,12 +75,14 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
private Uri mSuggestionData = null; private Uri mSuggestionData = null;
private String mSuggestionQuery = null; private String mSuggestionQuery = null;
private int mItemSelected = -1; private int mItemSelected = -1;
private Rect mTempRect = new Rect();
/** /**
* Used to inflate the Workspace from XML. * Used to inflate the Workspace from XML.
* *
* @param context The application's context. * @param context The application's context.
* @param attrs The attribtues set containing the Workspace's customization values. * @param attrs The attributes set containing the Workspace's customization values.
*/ */
public Search(Context context, AttributeSet attrs) { public Search(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
@ -84,7 +92,9 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
* Implements OnClickListener (for button) * Implements OnClickListener (for button)
*/ */
public void onClick(View v) { public void onClick(View v) {
query(); if (v == mGoButton) {
query();
}
} }
private void query() { private void query() {
@ -92,7 +102,9 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
if (TextUtils.getTrimmedLength(mSearchText.getText()) == 0) { if (TextUtils.getTrimmedLength(mSearchText.getText()) == 0) {
return; return;
} }
sendLaunchIntent(Intent.ACTION_SEARCH, null, query, null, 0, null, mSearchable); Bundle appData = new Bundle();
appData.putString(SearchManager.SOURCE, "launcher-widget");
sendLaunchIntent(Intent.ACTION_SEARCH, null, query, appData, 0, null, mSearchable);
} }
/** /**
@ -254,7 +266,7 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
mSearchText.setOnKeyListener(this); mSearchText.setOnKeyListener(this);
mSearchText.addTextChangedListener(this); mSearchText.addTextChangedListener(this);
mGoButton = (Button) findViewById(R.id.go); mGoButton = (ImageButton) findViewById(R.id.search_go_btn);
mGoButton.setOnClickListener(this); mGoButton.setOnClickListener(this);
mGoButton.setOnKeyListener(this); mGoButton.setOnKeyListener(this);
@ -296,8 +308,8 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
// attach the suggestions adapter // attach the suggestions adapter
mSuggestionsAdapter = new SuggestionsAdapter(mContext, mSuggestionsAdapter = new SuggestionsAdapter(mContext,
com.android.internal.R.layout.search_dropdown_item_1line, null, com.android.internal.R.layout.search_dropdown_item_2line, null,
SuggestionsAdapter.ONE_LINE_FROM, SuggestionsAdapter.ONE_LINE_TO, mSearchable); SuggestionsAdapter.TWO_LINE_FROM, SuggestionsAdapter.TWO_LINE_TO, mSearchable);
mSearchText.setAdapter(mSuggestionsAdapter); mSearchText.setAdapter(mSuggestionsAdapter);
} }
@ -432,10 +444,14 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
/** /**
* This class provides the filtering-based interface to suggestions providers. * This class provides the filtering-based interface to suggestions providers.
* It is hardwired in a couple of places to support GoogleSearch - for example, it supports
* two-line suggestions, but it does not support icons.
*/ */
private static class SuggestionsAdapter extends SimpleCursorAdapter { private static class SuggestionsAdapter extends SimpleCursorAdapter {
public final static String[] ONE_LINE_FROM = { SearchManager.SUGGEST_COLUMN_TEXT_1 }; public final static String[] TWO_LINE_FROM = {SearchManager.SUGGEST_COLUMN_TEXT_1,
public final static int[] ONE_LINE_TO = { com.android.internal.R.id.text1 }; SearchManager.SUGGEST_COLUMN_TEXT_2 };
public final static int[] TWO_LINE_TO = {com.android.internal.R.id.text1,
com.android.internal.R.id.text2};
private final String TAG = "SuggestionsAdapter"; private final String TAG = "SuggestionsAdapter";

View File

@ -21,11 +21,10 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import com.android.internal.provider.Settings;
public class UninstallShortcutReceiver extends BroadcastReceiver { public class UninstallShortcutReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent data) { public void onReceive(Context context, Intent data) {
Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
@ -34,18 +33,23 @@ public class UninstallShortcutReceiver extends BroadcastReceiver {
if (intent != null && name != null) { if (intent != null && name != null) {
final ContentResolver cr = context.getContentResolver(); final ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(Settings.Favorites.CONTENT_URI, Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
new String[] { "_id", "intent" }, "title=?", new String[]{ name }, null); new String[] { LauncherSettings.Favorites.ID, LauncherSettings.Favorites.INTENT },
LauncherSettings.Favorites.TITLE + "=?", new String[] { name }, null);
final int intentIndex = c.getColumnIndexOrThrow(Settings.Favorites.INTENT); final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
final int idIndex = c.getColumnIndexOrThrow(Settings.Favorites._ID); final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID);
boolean changed = false;
try { try {
while (c.moveToNext()) { while (c.moveToNext()) {
try { try {
if (intent.filterEquals(Intent.getIntent(c.getString(intentIndex)))) { if (intent.filterEquals(Intent.getIntent(c.getString(intentIndex)))) {
final long id = c.getLong(idIndex); final long id = c.getLong(idIndex);
cr.delete(Settings.Favorites.getContentUri(id, false), null, null); final Uri uri = LauncherSettings.Favorites.getContentUri(id, false);
cr.delete(uri, null, null);
changed = true;
if (!duplicate) { if (!duplicate) {
break; break;
} }
@ -58,7 +62,7 @@ public class UninstallShortcutReceiver extends BroadcastReceiver {
c.close(); c.close();
} }
cr.notifyChange(Settings.Favorites.CONTENT_URI, null); if (changed) cr.notifyChange(LauncherSettings.Favorites.CONTENT_URI, null);
} }
} }
} }

View File

@ -1,7 +1,6 @@
package com.android.launcher; package com.android.launcher;
import android.content.Context; import android.content.Context;
import com.android.internal.provider.Settings;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -31,8 +30,8 @@ public class UserFolder extends Folder implements DropTarget {
Object dragInfo) { Object dragInfo) {
final ItemInfo item = (ItemInfo) dragInfo; final ItemInfo item = (ItemInfo) dragInfo;
final int itemType = item.itemType; final int itemType = item.itemType;
return (itemType == Settings.Favorites.ITEM_TYPE_APPLICATION || return (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
itemType == Settings.Favorites.ITEM_TYPE_SHORTCUT) && item.container != mInfo.id; itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) && item.container != mInfo.id;
} }
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) { public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
@ -51,13 +50,6 @@ public class UserFolder extends Folder implements DropTarget {
public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) { public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
} }
@Override
public boolean onLongClick(View v) {
mLauncher.closeFolder(this);
mLauncher.showRenameDialog((UserFolderInfo) mInfo);
return true;
}
@Override @Override
public void onDropCompleted(View target, boolean success) { public void onDropCompleted(View target, boolean success) {
if (success) { if (success) {
@ -68,10 +60,9 @@ public class UserFolder extends Folder implements DropTarget {
} }
} }
void bind(UserFolderInfo info) { void bind(FolderInfo info) {
mInfo = info; super.bind(info);
setContentAdapter(new ApplicationsAdapter(mContext, info.contents)); setContentAdapter(new ApplicationsAdapter(mContext, ((UserFolderInfo) info).contents));
mCloseButton.setText(info.title);
} }
// When the folder opens, we need to refresh the GridView's selection by // When the folder opens, we need to refresh the GridView's selection by

View File

@ -17,7 +17,6 @@
package com.android.launcher; package com.android.launcher;
import android.content.ContentValues; import android.content.ContentValues;
import com.android.internal.provider.Settings;
import java.util.ArrayList; import java.util.ArrayList;
@ -25,18 +24,13 @@ import java.util.ArrayList;
* Represents a folder containing shortcuts or apps. * Represents a folder containing shortcuts or apps.
*/ */
class UserFolderInfo extends FolderInfo { class UserFolderInfo extends FolderInfo {
/**
* The application name.
*/
CharSequence title;
/** /**
* The apps and shortcuts * The apps and shortcuts
*/ */
ArrayList<ApplicationInfo> contents = new ArrayList<ApplicationInfo>(); ArrayList<ApplicationInfo> contents = new ArrayList<ApplicationInfo>();
UserFolderInfo() { UserFolderInfo() {
itemType = Settings.Favorites.ITEM_TYPE_USER_FOLDER; itemType = LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER;
} }
/** /**
@ -60,6 +54,6 @@ class UserFolderInfo extends FolderInfo {
@Override @Override
void onAddToDatabase(ContentValues values) { void onAddToDatabase(ContentValues values) {
super.onAddToDatabase(values); super.onAddToDatabase(values);
values.put(Settings.Favorites.TITLE, title.toString()); values.put(LauncherSettings.Favorites.TITLE, title.toString());
} }
} }

View File

@ -18,7 +18,6 @@ package com.android.launcher;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.PaintDrawable; import android.graphics.drawable.PaintDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.graphics.Canvas; import android.graphics.Canvas;
@ -97,30 +96,46 @@ final class Utilities {
painter.setIntrinsicHeight(height); painter.setIntrinsicHeight(height);
} }
if (width > 0 && height > 0 && (width < iconWidth || height < iconHeight)) { if (width > 0 && height > 0) {
final float ratio = (float) iconWidth / iconHeight; if (width < iconWidth || height < iconHeight) {
final float ratio = (float) iconWidth / iconHeight;
if (iconWidth > iconHeight) { if (iconWidth > iconHeight) {
height = (int) (width / ratio); height = (int) (width / ratio);
} else if (iconHeight > iconWidth) { } else if (iconHeight > iconWidth) {
width = (int) (height * ratio); width = (int) (height * ratio);
}
final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ?
Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c);
final Canvas canvas = sCanvas;
canvas.setBitmap(thumb);
// Copy the old bounds to restore them later
// If we were to do oldBounds = icon.getBounds(),
// the call to setBounds() that follows would
// change the same instance and we would lose the
// old bounds
sOldBounds.set(icon.getBounds());
final int x = (sIconWidth - width) / 2;
final int y = (sIconHeight - height) / 2;
icon.setBounds(x, y, x + width, y + height);
icon.draw(canvas);
icon.setBounds(sOldBounds);
icon = new FastBitmapDrawable(thumb);
} else if (iconWidth < width && iconHeight < height) {
final Bitmap.Config c = Bitmap.Config.ARGB_8888;
final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c);
final Canvas canvas = sCanvas;
canvas.setBitmap(thumb);
sOldBounds.set(icon.getBounds());
final int x = (width - iconWidth) / 2;
final int y = (height - iconHeight) / 2;
icon.setBounds(x, y, x + iconWidth, y + iconHeight);
icon.draw(canvas);
icon.setBounds(sOldBounds);
icon = new FastBitmapDrawable(thumb);
} }
final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ?
Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c);
final Canvas canvas = sCanvas;
canvas.setBitmap(thumb);
// Copy the old bounds to restore them later
// If we were to do oldBounds = icon.getBounds(),
// the call to setBounds() that follows would
// change the same instance and we would lose the
// old bounds
sOldBounds.set(icon.getBounds());
icon.setBounds((sIconWidth - width) / 2, (sIconHeight - height) / 2, width, height);
icon.draw(canvas);
icon.setBounds(sOldBounds);
icon = new BitmapDrawable(thumb);
} }
return icon; return icon;

View File

@ -102,6 +102,7 @@ public class WallpaperChooser extends Activity implements AdapterView.OnItemSele
mGallery = (Gallery) findViewById(R.id.gallery); mGallery = (Gallery) findViewById(R.id.gallery);
mGallery.setAdapter(new ImageAdapter(this)); mGallery.setAdapter(new ImageAdapter(this));
mGallery.setOnItemSelectedListener(this); mGallery.setOnItemSelectedListener(this);
mGallery.setCallbackDuringFling(false);
Button b = (Button) findViewById(R.id.set); Button b = (Button) findViewById(R.id.set);
b.setOnClickListener(this); b.setOnClickListener(this);

View File

@ -18,7 +18,6 @@ package com.android.launcher;
import android.content.ContentValues; import android.content.ContentValues;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import com.android.internal.provider.Settings;
/** /**
* Represents one instance of a Launcher widget (clock, search, photo frame). * Represents one instance of a Launcher widget (clock, search, photo frame).
@ -31,7 +30,7 @@ class Widget extends ItemInfo {
static Widget makeClock() { static Widget makeClock() {
Widget w = new Widget(); Widget w = new Widget();
w.itemType = Settings.Favorites.ITEM_TYPE_WIDGET_CLOCK; w.itemType = LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK;
w.spanX = 2; w.spanX = 2;
w.spanY = 2; w.spanY = 2;
w.layoutResource = R.layout.widget_clock; w.layoutResource = R.layout.widget_clock;
@ -40,7 +39,7 @@ class Widget extends ItemInfo {
static Widget makePhotoFrame() { static Widget makePhotoFrame() {
Widget w = new Widget(); Widget w = new Widget();
w.itemType = Settings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME; w.itemType = LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME;
w.spanX = 2; w.spanX = 2;
w.spanY = 2; w.spanY = 2;
w.layoutResource = R.layout.widget_photo_frame; w.layoutResource = R.layout.widget_photo_frame;
@ -49,7 +48,7 @@ class Widget extends ItemInfo {
static Widget makeSearch() { static Widget makeSearch() {
Widget w = new Widget(); Widget w = new Widget();
w.itemType = Settings.Favorites.ITEM_TYPE_WIDGET_SEARCH; w.itemType = LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH;
w.spanX = 4; w.spanX = 4;
w.spanY = 1; w.spanY = 1;
w.layoutResource = R.layout.widget_search; w.layoutResource = R.layout.widget_search;

View File

@ -34,8 +34,6 @@ import android.widget.Scroller;
import android.os.Parcelable; import android.os.Parcelable;
import android.os.Parcel; import android.os.Parcel;
import com.android.internal.provider.Settings;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
@ -249,7 +247,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
* @param currentScreen * @param currentScreen
*/ */
void setCurrentScreen(int currentScreen) { void setCurrentScreen(int currentScreen) {
mCurrentScreen = Math.max(0, Math.min(currentScreen, getChildCount())); mCurrentScreen = Math.max(0, Math.min(currentScreen, getChildCount() - 1));
scrollTo(mCurrentScreen * getWidth(), 0); scrollTo(mCurrentScreen * getWidth(), 0);
invalidate(); invalidate();
} }
@ -426,7 +424,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
mScrollY = mScroller.getCurrY(); mScrollY = mScroller.getCurrY();
postInvalidate(); postInvalidate();
} else if (mNextScreen != INVALID_SCREEN) { } else if (mNextScreen != INVALID_SCREEN) {
mCurrentScreen = mNextScreen; mCurrentScreen = Math.max(0, Math.min(mNextScreen, getChildCount() - 1));
Launcher.setScreen(mCurrentScreen); Launcher.setScreen(mCurrentScreen);
mNextScreen = INVALID_SCREEN; mNextScreen = INVALID_SCREEN;
clearChildrenCache(); clearChildrenCache();
@ -784,6 +782,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
void snapToScreen(int whichScreen) { void snapToScreen(int whichScreen) {
enableChildrenCache(); enableChildrenCache();
whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
boolean changingScreens = whichScreen != mCurrentScreen; boolean changingScreens = whichScreen != mCurrentScreen;
mNextScreen = whichScreen; mNextScreen = whichScreen;
@ -861,7 +860,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
final ItemInfo info = (ItemInfo)cell.getTag(); final ItemInfo info = (ItemInfo)cell.getTag();
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams(); CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
LauncherModel.moveItemInDatabase(mLauncher, info, LauncherModel.moveItemInDatabase(mLauncher, info,
Settings.Favorites.CONTAINER_DESKTOP, mCurrentScreen, lp.cellX, lp.cellY); LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentScreen, lp.cellX, lp.cellY);
} }
} }
} }
@ -885,8 +884,8 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
View view; View view;
switch (info.itemType) { switch (info.itemType) {
case Settings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case Settings.Favorites.ITEM_TYPE_SHORTCUT: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
if (info.container == NO_ID) { if (info.container == NO_ID) {
// Came from all apps -- make a copy // Came from all apps -- make a copy
info = new ApplicationInfo((ApplicationInfo) info); info = new ApplicationInfo((ApplicationInfo) info);
@ -894,7 +893,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
view = mLauncher.createShortcut(R.layout.application, cellLayout, view = mLauncher.createShortcut(R.layout.application, cellLayout,
(ApplicationInfo) info); (ApplicationInfo) info);
break; break;
case Settings.Favorites.ITEM_TYPE_USER_FOLDER: case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher, view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher,
(ViewGroup) getChildAt(mCurrentScreen), ((UserFolderInfo) info)); (ViewGroup) getChildAt(mCurrentScreen), ((UserFolderInfo) info));
break; break;
@ -910,7 +909,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
final LauncherModel model = Launcher.getModel(); final LauncherModel model = Launcher.getModel();
model.addDesktopItem(info); model.addDesktopItem(info);
LauncherModel.addOrMoveItemInDatabase(mLauncher, info, LauncherModel.addOrMoveItemInDatabase(mLauncher, info,
Settings.Favorites.CONTAINER_DESKTOP, mCurrentScreen, lp.cellX, lp.cellY); LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentScreen, lp.cellX, lp.cellY);
} }
public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset, public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,