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.
*/
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.launcher"
android:sharedUserId="android.uid.shared">
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.launcher"
android:sharedUserId="android.uid.shared">
<permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="normal"
android:label="@string/permlab_install_shortcut"
android:description="@string/permdesc_install_shortcut"/>
<permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="normal"
android:label="@string/permlab_uninstall_shortcut"
android:description="@string/permdesc_uninstall_shortcut"/>
<permission
android:name="com.android.launcher.permission.INSTALL_SHORTCUT"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="normal"
android:label="@string/permlab_install_shortcut"
android:description="@string/permdesc_install_shortcut" />
<permission
android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
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.EXPAND_STATUS_BAR"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.VIBRATE" />
<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
android:name="LauncherApplication"
android:process="android.process.acore"
android:label="@string/application_name"
android:icon="@drawable/ic_launcher_home">
<activity android:name="Launcher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:theme="@style/Theme"
android:configChanges="mcc|mnc">
<activity
android:name="Launcher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:theme="@style/Theme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME"/>
@ -60,7 +78,8 @@
</intent-filter>
</activity>
<activity android:name="WallpaperChooser"
<activity
android:name="WallpaperChooser"
android:label="@string/pick_wallpaper"
android:icon="@drawable/ic_launcher_gallery">
<intent-filter>
@ -70,21 +89,34 @@
</activity>
<!-- 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"
android:permission="com.android.launcher.permission.INSTALL_SHORTCUT">
<!-- Intent received used to install shortcuts from other applications -->
<receiver
android:name=".InstallShortcutReceiver"
android:permission="com.android.launcher.permission.INSTALL_SHORTCUT">
<intent-filter>
<action android:name="com.android.launcher.action.INSTALL_SHORTCUT" />
</intent-filter>
</receiver>
<receiver android:name=".UninstallShortcutReceiver"
android:permission="com.android.launcher.permission.UNINSTALL_SHORTCUT">
<!-- Intent received used to uninstall shortcuts from other applications -->
<receiver
android:name=".UninstallShortcutReceiver"
android:permission="com.android.launcher.permission.UNINSTALL_SHORTCUT">
<intent-filter>
<action android:name="com.android.launcher.action.UNINSTALL_SHORTCUT" />
</intent-filter>
</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>
</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"
android:id="@+id/name"
android:layout_width="fill_parent"
android:layout_height="88dip"
android:paddingTop="6dip"
android:paddingBottom="3dip"
android:paddingTop="5dip"
android:paddingBottom="2dip"
android:drawablePadding="0dip"
android:textSize="13dip"
android:maxLines="2"
android:ellipsize="end"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:textColor="@color/bright_text_dark_focused"
android:gravity="top|center_horizontal" />

View File

@ -16,6 +16,7 @@
<com.android.launcher.DragLayer
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"
android:id="@+id/drag_layer"
@ -30,9 +31,9 @@
launcher:defaultScreen="1">
<include layout="@layout/workspace_screen" />
<include layout="@layout/workspace_screen" />
<include layout="@layout/workspace_screen" />
<include android:id="@+id/cell1" layout="@layout/workspace_screen" />
<include android:id="@+id/cell2" layout="@layout/workspace_screen" />
<include android:id="@+id/cell3" layout="@layout/workspace_screen" />
</com.android.launcher.Workspace>
@ -42,19 +43,24 @@
android:layout_height="fill_parent"
android:orientation="horizontal"
android:bottomOffset="7px"
android:handle="@+id/all_apps"
android:content="@+id/content">
<ImageView
androidprv:bottomOffset="7px"
androidprv:handle="@+id/all_apps"
androidprv:content="@+id/content">
<com.android.launcher.HandleView
android:id="@id/all_apps"
android:layout_width="56dip"
android:layout_height="fill_parent"
android:background="@drawable/handle"
android:focusable="true"
android:clickable="true"
android:scaleType="center"
android:src="@drawable/handle_icon"
android:background="@drawable/handle"
android:layout_height="fill_parent"
android:layout_width="56dip" />
launcher:direction="vertical" />
<com.android.launcher.AllAppsGridView
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"
android:id="@+id/name"
android:layout_width="fill_parent"
android:layout_height="88dip"
android:paddingTop="6dip"
android:paddingBottom="3dip"
android:paddingTop="5dip"
android:paddingBottom="2dip"
android:drawablePadding="0dip"
android:textSize="13dip"
android:maxLines="2"
android:ellipsize="end"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:textColor="@color/bright_text_dark_focused"
android:gravity="top|center_horizontal" />

View File

@ -16,6 +16,7 @@
<com.android.launcher.DragLayer
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"
android:id="@+id/drag_layer"
@ -30,9 +31,9 @@
launcher:defaultScreen="1">
<include layout="@layout/workspace_screen" />
<include layout="@layout/workspace_screen" />
<include layout="@layout/workspace_screen" />
<include android:id="@+id/cell1" layout="@layout/workspace_screen" />
<include android:id="@+id/cell2" layout="@layout/workspace_screen" />
<include android:id="@+id/cell3" layout="@layout/workspace_screen" />
</com.android.launcher.Workspace>
@ -41,20 +42,25 @@
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:topOffset="5px"
android:bottomOffset="7px"
android:handle="@+id/all_apps"
android:content="@+id/content">
androidprv:topOffset="5px"
androidprv:bottomOffset="7px"
androidprv:handle="@+id/all_apps"
androidprv:content="@+id/content">
<ImageView
<com.android.launcher.HandleView
android:id="@id/all_apps"
android:layout_width="fill_parent"
android:layout_height="56dip"
android:background="@drawable/handle"
android:focusable="true"
android:clickable="true"
android:scaleType="center"
android:src="@drawable/handle_icon"
android:background="@drawable/handle"
android:layout_width="fill_parent"
android:layout_height="56dip" />
launcher:direction="horizontal" />
<com.android.launcher.AllAppsGridView
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:focusableInTouchMode="false"
android:singleLine="true"
android:selectAllOnFocus="true"
android:completionThreshold="1"
/>
<Button
android:id="@+id/go"
android:layout_marginLeft="4dip"
<ImageButton android:id="@+id/search_go_btn"
android:layout_marginLeft="1dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/go"/>
android:src="@android:drawable/ic_btn_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>
<!-- 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
the workspace in XML files. -->
<declare-styleable name="Workspace">
@ -49,12 +59,14 @@
a DeleteZone view in XML files. -->
<declare-styleable name="DeleteZone">
<!-- Orientation of the delete zone. -->
<attr name="direction">
<!-- Vertical delete zone. -->
<enum name="vertical" value="0" />
<!-- Horizontal delete zone. This is the default value. -->
<enum name="horizontal" value="1" />
</attr>
<attr name="direction" />
</declare-styleable>
<!-- HandleView specific attributes. These attributes are used to customize
a HandleView view in XML files. -->
<declare-styleable name="HandleView">
<!-- Orientation of the handle. -->
<attr name="direction" />
</declare-styleable>
</resources>

View File

@ -19,52 +19,66 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- General -->
<skip />
<!-- Application name -->
<string name="application_name">Home</string>
<!-- Default folder name -->
<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 -->
<string name="chooser_wallpaper">Select wallpaper from</string>
<!-- Button label on Wallpaper Gallery screen; user selects this button to set a specific wallpaper -->
<string name="wallpaper_instructions">Set wallpaper</string>
<!-- Option in "Select wallpaper from" dialog box -->
<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>
<!-- Folders -->
<skip />
<!-- 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 -->
<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>
<!-- Buttons in Rename folder dialog box -->
<string name="cancel_action">Cancel</string>
<!-- Shortcuts -->
<skip />
<!-- Title of dialog box -->
<string name="menu_item_add_item">Add to Home</string>
<!-- Options in "Add to Home" dialog box: -->
<string name="menu_item_add_item">Add to Home screen</string>
<!-- Options in "Add to Home" dialog box; Title of the group containing the list of all apps -->
<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_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>
<!-- 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>
<!-- Options in "Add to Home" dialog box; Name of the Folder widget-->
<string name="add_folder">Folder</string>
<!-- Options in "Add to Home" dialog box; Name of the Clock widget-->
<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>
<!-- Options in "Add to Home" dialog box; Name of the Google Search widget-->
<string name="add_search">Search</string>
<!-- 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>
<!-- Menus items: -->
<skip />
<!-- Verb, menu item used to add an item on the desktop -->
<string name="menu_add">Add</string>
<!-- Noun, menu item used to set the desktop's wallpaper -->
<string name="menu_wallpaper">Wallpaper</string>
<!-- Verb, menu item used to initiate a Google Search -->
<string name="menu_search">Search</string>
<!-- Noun, menu item used to bring down the notifications shade -->
<string name="menu_notifications">Notifications</string>
<!-- Noun, menu item used to show the system settings -->
<string name="menu_settings">Settings</string>
<!-- Permissions: -->
@ -74,9 +88,18 @@
<string name="permlab_uninstall_shortcut">uninstall shortcuts</string>
<string name="permdesc_uninstall_shortcut">Allows an application to remove
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: -->
<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>
</resources>

View File

@ -26,7 +26,7 @@
<style name="WorkspaceIcon">
<item name="android:textSize">13dip</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:shadowRadius">2.0</item>
<item name="android:textColor">#FFF</item>

View File

@ -28,6 +28,7 @@ import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.BaseExpandableListAdapter;
import android.graphics.drawable.Drawable;
import android.provider.LiveFolders;
import java.util.ArrayList;
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_SHORTCUTS = 1;
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 mCreateLiveFolderIntent;
private Intent mSetWallpaperIntent;
private final LayoutInflater mInflater;
private Launcher mLauncher;
@ -52,7 +55,7 @@ public final class AddAdapter extends BaseExpandableListAdapter {
* Abstract class representing one thing that can be added
*/
public abstract class AddAction implements Runnable {
private final Context mContext;
protected final Context mContext;
AddAction(Context context) {
mContext = context;
@ -110,8 +113,9 @@ public final class AddAdapter extends BaseExpandableListAdapter {
mLabel = info.activityInfo.name;
}
}
if (mIcon == null) {
mIcon = info.loadIcon(pm);
mIcon = Utilities.createIconThumbnail(info.loadIcon(pm), mContext);
}
text.setText(mLabel);
@ -126,12 +130,32 @@ public final class AddAdapter extends BaseExpandableListAdapter {
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
*/
public class CreateFolderAction extends AddAction {
private Drawable mIcon;
CreateFolderAction(Context context) {
super(context);
}
@ -140,8 +164,8 @@ public final class AddAdapter extends BaseExpandableListAdapter {
public void bindView(View view) {
TextView text = (TextView) view;
text.setText(R.string.add_folder);
text.setCompoundDrawablesWithIntrinsicBounds(getIcon(R.drawable.ic_launcher_folder),
null, null, null);
if (mIcon == null) mIcon = getIcon(R.drawable.ic_launcher_folder);
text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
}
public void run() {
@ -175,6 +199,8 @@ public final class AddAdapter extends BaseExpandableListAdapter {
* Class representing an action that will add a PhotoFrame
*/
public class CreatePhotoFrameAction extends AddAction {
private Drawable mIcon;
CreatePhotoFrameAction(Context context) {
super(context);
}
@ -183,8 +209,8 @@ public final class AddAdapter extends BaseExpandableListAdapter {
public void bindView(View view) {
TextView text = (TextView) view;
text.setText(R.string.add_photo_frame);
Drawable icon = getIcon(R.drawable.ic_launcher_gallery);
text.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
if (mIcon == null) mIcon = getIcon(R.drawable.ic_launcher_gallery);
text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
}
public void run() {
@ -197,6 +223,8 @@ public final class AddAdapter extends BaseExpandableListAdapter {
* Class representing an action that will add a Search widget
*/
public class CreateSearchAction extends AddAction {
private Drawable mIcon;
CreateSearchAction(Context context) {
super(context);
}
@ -205,8 +233,8 @@ public final class AddAdapter extends BaseExpandableListAdapter {
public void bindView(View view) {
TextView text = (TextView) view;
text.setText(R.string.add_search);
Drawable icon = getIcon(R.drawable.ic_search_gadget);
text.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
if (mIcon == null) mIcon = getIcon(R.drawable.ic_search_gadget);
text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
}
public void run() {
@ -296,22 +324,27 @@ public final class AddAdapter extends BaseExpandableListAdapter {
mCreateShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
mCreateShortcutIntent.setComponent(null);
mCreateLiveFolderIntent = new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER);
mCreateLiveFolderIntent.setComponent(null);
mSetWallpaperIntent = new Intent(Intent.ACTION_SET_WALLPAPER);
mSetWallpaperIntent.setComponent(null);
mLauncher = launcher;
mInflater = (LayoutInflater) launcher.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mGroups = new Group[forFolder ? 2 : 4];
mGroups = new Group[forFolder ? 2 : 5];
final Group[] groups = mGroups;
groups[GROUP_APPLICATIONS] = new ApplicationsGroup(mLauncher,
mLauncher.getString(R.string.group_applications));
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) {
groups[GROUP_WALLPAPERS] = new Group(mLauncher.getString(R.string.group_wallpapers));
groups[GROUP_SHORTCUTS].add(new CreateFolderAction(launcher));
groups[GROUP_WIDGETS] = new Group(mLauncher.getString(R.string.group_widgets));
final Group widgets = groups[GROUP_WIDGETS];
widgets.add(new CreateClockAction(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);
if (list != null && list.size() > 0) {
int count = list.size();

View File

@ -20,9 +20,7 @@ import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import com.android.internal.provider.Settings;
/**
* Represents a launchable application. An application is made of a name (or title),
@ -63,7 +61,7 @@ class ApplicationInfo extends ItemInfo {
Intent.ShortcutIconResource iconResource;
ApplicationInfo() {
itemType = Settings.Favorites.ITEM_TYPE_SHORTCUT;
itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
}
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.
* 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 launchFlags the launch flags
@ -92,7 +90,7 @@ class ApplicationInfo extends ItemInfo {
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setComponent(className);
intent.setFlags(launchFlags);
itemType = Settings.Favorites.ITEM_TYPE_APPLICATION;
itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
}
@Override
@ -100,20 +98,22 @@ class ApplicationInfo extends ItemInfo {
super.onAddToDatabase(values);
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;
values.put(Settings.Favorites.INTENT, uri);
values.put(LauncherSettings.Favorites.INTENT, uri);
if (customIcon) {
values.put(Settings.Favorites.ICON_TYPE, Settings.Favorites.ICON_TYPE_BITMAP);
Bitmap bitmap = ((BitmapDrawable) icon).getBitmap();
values.put(LauncherSettings.Favorites.ICON_TYPE,
LauncherSettings.Favorites.ICON_TYPE_BITMAP);
Bitmap bitmap = ((FastBitmapDrawable) icon).getBitmap();
writeBitmap(values, bitmap);
} 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) {
values.put(Settings.Favorites.ICON_PACKAGE, iconResource.packageName);
values.put(Settings.Favorites.ICON_RESOURCE, iconResource.resourceName);
values.put(LauncherSettings.Favorites.ICON_PACKAGE, iconResource.packageName);
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.Paint;
import android.graphics.RectF;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.Layout;
/**
@ -38,6 +38,9 @@ public class BubbleTextView extends TextView {
private final RectF mRect = new RectF();
private Paint mPaint;
private boolean mBackgroundSizeChanged;
private Drawable mBackground;
public BubbleTextView(Context context) {
super(context);
init();
@ -55,13 +58,57 @@ public class BubbleTextView extends TextView {
private void init() {
setFocusable(true);
mBackground = getBackground();
setBackgroundDrawable(null);
mBackground.setCallback(this);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(getContext().getResources().getColor(R.color.bubble_dark_background));
}
@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 RectF rect = mRect;
final int left = getCompoundPaddingLeft();
@ -69,10 +116,10 @@ public class BubbleTextView extends TextView {
rect.set(left + layout.getLineLeft(0) - PADDING_H,
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);
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;
}
@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
public void requestChildFocus(View child, View focused) {
super.requestChildFocus(child, focused);

View File

@ -20,7 +20,6 @@ import android.widget.ImageView;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import com.android.internal.provider.Settings;
import android.view.View;
import android.view.animation.TranslateAnimation;
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 ANIMATION_DURATION = 200;
private final int[] mLocation = new int[2];
private Launcher mLauncher;
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,
Object dragInfo) {
final ItemInfo item = (ItemInfo) dragInfo;
// Accept anything except items in the all apps folder
return item.container != ItemInfo.NO_ID;
return true;
}
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
final ItemInfo item = (ItemInfo) dragInfo;
if (item.container == -1) return;
final LauncherModel model = Launcher.getModel();
if (item.container == Settings.Favorites.CONTAINER_DESKTOP) {
if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
model.removeDesktopItem(item);
} else {
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) {
final ItemInfo item = (ItemInfo) info;
if (item != null && item.container != ItemInfo.NO_ID) {
if (item != null) {
mTrashMode = true;
createAnimations();
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.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.AbsListView;
import android.widget.ListAdapter;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
@ -34,7 +34,7 @@ import android.widget.AdapterView.OnItemLongClickListener;
public class Folder extends LinearLayout implements DragSource, OnItemLongClickListener,
OnItemClickListener, OnClickListener, View.OnLongClickListener {
protected GridView mContent;
protected AbsListView mContent;
protected DragController mDragger;
protected Launcher mLauncher;
@ -64,7 +64,7 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
protected void onFinishInflate() {
super.onFinishInflate();
mContent = (GridView) findViewById(R.id.content);
mContent = (AbsListView) findViewById(R.id.content);
mContent.setOnItemClickListener(this);
mContent.setOnItemLongClickListener(this);
@ -83,7 +83,9 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
}
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) {
@ -120,7 +122,7 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
*
* @param adapter The list of applications to display in the folder.
*/
void setContentAdapter(ArrayAdapter<ApplicationInfo> adapter) {
void setContentAdapter(ListAdapter adapter) {
mContent.setAdapter(adapter);
}
@ -145,4 +147,9 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
final Workspace workspace = mLauncher.getWorkspace();
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.res.Resources;
import android.graphics.drawable.Drawable;
import com.android.internal.provider.Settings;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.ViewGroup;
@ -65,8 +64,8 @@ public class FolderIcon extends BubbleTextView implements DropTarget {
Object dragInfo) {
final ItemInfo item = (ItemInfo) dragInfo;
final int itemType = item.itemType;
return (itemType == Settings.Favorites.ITEM_TYPE_APPLICATION ||
itemType == Settings.Favorites.ITEM_TYPE_SHORTCUT)
return (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT)
&& item.container != mInfo.id;
}

View File

@ -26,4 +26,9 @@ class FolderInfo extends ItemInfo {
* Whether this folder has been 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.ContentResolver;
import android.database.Cursor;
import com.android.internal.provider.Settings;
public class InstallShortcutReceiver extends BroadcastReceiver {
private final int[] mCoordinates = new int[2];
@ -29,6 +28,15 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent data) {
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)) {
CellLayout.CellInfo cell = new CellLayout.CellInfo();
cell.cellX = mCoordinates[0];
@ -48,7 +56,11 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
if (duplicate || !LauncherModel.shortcutExists(context, name, intent)) {
Launcher.addShortcut(context, data, cell, true);
}
return true;
}
return false;
}
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];
final ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(Settings.Favorites.CONTENT_URI,
new String[] { "cellX", "cellY", "spanX", "spanY" }, "screen=?",
Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
new String[] { LauncherSettings.Favorites.CELLX, LauncherSettings.Favorites.CELLY,
LauncherSettings.Favorites.SPANX, LauncherSettings.Favorites.SPANY },
LauncherSettings.Favorites.SCREEN + "=?",
new String[] { String.valueOf(screen) }, null);
final int cellXIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLX);
final int cellYIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLY);
final int spanXIndex = c.getColumnIndexOrThrow(Settings.Favorites.SPANX);
final int spanYIndex = c.getColumnIndexOrThrow(Settings.Favorites.SPANY);
final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
try {
while (c.moveToNext()) {

View File

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

View File

@ -29,16 +29,15 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@ -46,15 +45,12 @@ import android.os.IBinder;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Contacts;
import android.provider.*;
import android.telephony.PhoneNumberUtils;
import android.text.Selection;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.method.TextKeyListener;
import android.util.Config;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
@ -66,14 +62,15 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.View.OnLongClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.GridView;
import android.app.IWallpaperService;
import com.android.internal.provider.Settings;
import com.android.internal.widget.SlidingDrawer;
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 DEBUG_USER_INTERFACE = false;
private static final String USE_OPENGL_BY_DEFAULT = "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 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_CHOOSE_PHOTO = 2;
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 int SCREEN_COUNT = 3;
static final int DEFAULT_SCREN = 1;
static final int NUMBER_CELLS_X = 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;
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
private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";
// Type: boolean
@ -165,19 +159,15 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private final BroadcastReceiver mApplicationsReceiver = new ApplicationsIntentReceiver();
private final ContentObserver mObserver = new FavoritesChangeObserver();
private final Handler mHandler = new Handler();
private LayoutInflater mInflater;
private SensorManager mSensorManager;
private SensorHandler mSensorHandler;
private DragLayer mDragLayer;
private Workspace mWorkspace;
private CellLayout.CellInfo mAddItemCellInfo;
private CellLayout.CellInfo mMenuAddInfo;
private final int[] mCellCoordinates = new int[2];
private UserFolderInfo mFolderInfo;
private FolderInfo mFolderInfo;
private SlidingDrawer mDrawer;
private TransitionDrawable mHandleIcon;
@ -192,11 +182,10 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private boolean mRestoring;
private boolean mWaitingForResult;
private boolean mLocaleChanged;
@Override
protected void onCreate(Bundle savedInstanceState) {
dalvik.system.VMRuntime.getRuntime().setMinimumHeapSize(4 * 1024 * 1024);
super.onCreate(savedInstanceState);
mInflater = getLayoutInflater();
@ -204,11 +193,9 @@ public final class Launcher extends Activity implements View.OnClickListener, On
android.os.Debug.startMethodTracing("/sdcard/launcher");
}
checkForLocaleChange();
setWallpaperDimension();
enableSensors();
enableOpenGL();
if (sModel == null) {
sModel = new LauncherModel();
}
@ -234,6 +221,30 @@ public final class Launcher extends Activity implements View.OnClickListener, On
mDefaultKeySsb = new SpannableStringBuilder();
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() {
synchronized (sLock) {
@ -248,19 +259,11 @@ public final class Launcher extends Activity implements View.OnClickListener, On
}
private void startLoaders() {
sModel.loadApplications(true, this);
sModel.loadUserItems(true, this);
sModel.loadApplications(true, this, mLocaleChanged);
sModel.loadUserItems(!mLocaleChanged, this, mLocaleChanged);
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() {
IBinder binder = ServiceManager.getService(WALLPAPER_SERVICE);
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
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && mAddItemCellInfo != null) {
@ -315,6 +293,9 @@ public final class Launcher extends Activity implements View.OnClickListener, On
case REQUEST_UPDATE_PHOTO:
completeUpdatePhotoFrame(data, mAddItemCellInfo);
break;
case REQUEST_CREATE_LIVE_FOLDER:
completeAddLiveFolder(data, mAddItemCellInfo, !mDesktopLocked);
break;
}
}
mWaitingForResult = false;
@ -327,19 +308,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On
if (mRestoring) {
startLoaders();
}
if (mSensorManager != null) {
mSensorManager.registerListener(mSensorHandler, SensorManager.SENSOR_ACCELEROMETER);
}
}
@Override
protected void onStop() {
if (mSensorManager != null) {
mSensorManager.unregisterListener(mSensorHandler);
}
super.onStop();
}
@Override
@ -347,6 +315,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
boolean handled = super.onKeyUp(keyCode, event);
if (keyCode == KeyEvent.KEYCODE_SEARCH) {
handled = mWorkspace.snapToSearch();
if (handled) closeDrawer(true);
}
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 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.setCrossFadeEnabled(true);
@ -577,7 +547,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
Intent.ShortcutIconResource iconResource = null;
if (bitmap != null) {
icon = new BitmapDrawable(Utilities.createBitmapThumbnail(bitmap, context));
icon = new FastBitmapDrawable(Utilities.createBitmapThumbnail(bitmap, context));
filtered = true;
customIcon = true;
} else {
@ -608,7 +578,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
info.customIcon = customIcon;
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);
return info;
}
@ -630,7 +600,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
final int[] xy = mCellCoordinates;
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);
if (!mRestoring) {
@ -746,6 +716,12 @@ public final class Launcher extends Activity implements View.OnClickListener, On
mWorkspace.moveToDefaultScreen();
}
closeDrawer();
View v = getWindow().peekDecorView();
if (v != null && v.getWindowToken() != null) {
InputMethodManager imm = (InputMethodManager)getSystemService(
INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken());
}
} else {
closeDrawer(false);
}
@ -817,6 +793,16 @@ public final class Launcher extends Activity implements View.OnClickListener, On
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
public boolean onCreateOptionsMenu(Menu menu) {
if (mDesktopLocked) return false;
@ -893,6 +879,10 @@ public final class Launcher extends Activity implements View.OnClickListener, On
startActivityForResult(intent, REQUEST_CREATE_SHORTCUT);
}
void addLiveFolder(Intent intent) {
startActivityForResult(intent, REQUEST_CREATE_LIVE_FOLDER);
}
void addFolder() {
UserFolderInfo folderInfo = new UserFolderInfo();
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;
// Update the model
LauncherModel.addItemToDatabase(this, folderInfo, Settings.Favorites.CONTAINER_DESKTOP,
LauncherModel.addItemToDatabase(this, folderInfo, LauncherSettings.Favorites.CONTAINER_DESKTOP,
mWorkspace.getCurrentScreen(), cellX, cellY, false);
sModel.addDesktopItem(folderInfo);
sModel.addUserFolder(folderInfo);
sModel.addFolder(folderInfo);
// Create the view
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);
}
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() {
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;
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);
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() {
ContentResolver resolver = getContentResolver();
resolver.registerContentObserver(Settings.Favorites.CONTENT_URI, true, mObserver);
resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true, mObserver);
}
@Override
@ -1059,7 +1111,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private void onFavoritesChanged() {
mDesktopLocked = true;
mDrawer.lock();
sModel.loadUserItems(false, this);
sModel.loadUserItems(false, this, false);
}
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);
if (userFolders != null) {
for (long folderId : userFolders) {
final UserFolderInfo info = sModel.findFolderById(folderId);
final FolderInfo info = sModel.findFolderById(folderId);
if (info != null) {
openUserFolder(info);
openFolder(info);
}
}
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++) {
final ItemInfo item = shortcuts.get(i);
switch (item.itemType) {
case Settings.Favorites.ITEM_TYPE_APPLICATION:
case Settings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
final View shortcut = createShortcut((ApplicationInfo) item);
workspace.addInScreen(shortcut, item.screen, item.cellX, item.cellY, 1, 1,
!mDesktopLocked);
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,
(ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentScreen()),
((UserFolderInfo) item));
workspace.addInScreen(newFolder, item.screen, item.cellX, item.cellY, 1, 1,
!mDesktopLocked);
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:
final Widget widget = (Widget)item;
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();
View v = inflater.inflate(widget.layoutResource,
(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);
}
return v;
@ -1169,8 +1229,8 @@ public final class Launcher extends Activity implements View.OnClickListener, On
// Open shortcut
final Intent intent = ((ApplicationInfo) tag).intent;
startActivitySafely(intent);
} else if (tag instanceof UserFolderInfo) {
handleFolderClick((UserFolderInfo) tag);
} else if (tag instanceof FolderInfo) {
handleFolderClick((FolderInfo) tag);
}
}
@ -1188,7 +1248,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
// Close any open folder
closeFolder();
// Open the requested folder
openUserFolder(folderInfo);
openFolder(folderInfo);
} else {
// Find the open folder...
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
closeFolder();
// 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 played.
*
* @param tag The UserFolderInfo describing the folder to open.
* @param folderInfo The FolderInfo describing the folder to open.
*/
private void openUserFolder(Object tag) {
UserFolder openFolder = UserFolder.fromXml(this);
private void openFolder(FolderInfo folderInfo) {
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.setLauncher(this);
UserFolderInfo folderInfo = (UserFolderInfo) tag;
openFolder.bind(folderInfo);
folderInfo.opened = true;
@ -1299,6 +1367,10 @@ public final class Launcher extends Activity implements View.OnClickListener, On
return mWorkspace;
}
GridView getApplicationsGrid() {
return mAllAppsGrid;
}
@Override
protected Dialog onCreateDialog(int 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;
mWaitingForResult = true;
showDialog(DIALOG_RENAME_FOLDER);
@ -1384,16 +1456,17 @@ public final class Launcher extends Activity implements View.OnClickListener, On
if (mDesktopLocked) {
mDrawer.lock();
sModel.loadUserItems(false, Launcher.this);
sModel.loadUserItems(false, Launcher.this, false);
} else {
final FolderIcon folderIcon = (FolderIcon) mWorkspace.getViewForTag(mFolderInfo);
final FolderIcon folderIcon = (FolderIcon)
mWorkspace.getViewForTag(mFolderInfo);
if (folderIcon != null) {
folderIcon.setText(name);
getWorkspace().requestLayout();
} else {
mDesktopLocked = true;
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());
}
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 {
public FavoritesChangeObserver() {
super(mHandler);
super(new Handler());
}
@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.
*/

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.drawable.BitmapDrawable;
import android.net.Uri;
import com.android.internal.provider.Settings;
import android.util.Log;
import java.util.ArrayList;
@ -40,6 +39,7 @@ import java.util.List;
import java.util.Comparator;
import java.lang.ref.WeakReference;
import java.text.Collator;
import java.net.URISyntaxException;
/**
* 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 ArrayList<ItemInfo> mDesktopItems;
private HashMap<Long, UserFolderInfo> mUserFolders;
private HashMap<Long, FolderInfo> mFolders;
private ArrayList<ApplicationInfo> mApplications;
private ApplicationsAdapter mApplicationsAdapter;
@ -81,13 +81,13 @@ public class LauncherModel {
/**
* Loads the list of installed applications in mApplications.
*/
void loadApplications(boolean isLaunching, Launcher launcher) {
if (isLaunching && mApplicationsLoaded) {
void loadApplications(boolean isLaunching, Launcher launcher, boolean localeChanged) {
if (isLaunching && mApplicationsLoaded && !localeChanged) {
mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications);
return;
}
if (mApplicationsAdapter == null || isLaunching) {
if (mApplicationsAdapter == null || isLaunching || localeChanged) {
mApplicationsAdapter = new ApplicationsAdapter(launcher,
mApplications = new ArrayList<ApplicationInfo>(DEFAULT_APPLICATIONS_NUMBER));
}
@ -164,7 +164,7 @@ public class LauncherModel {
action.sort(new Comparator<ApplicationInfo>() {
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.
* 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) {
// We have already loaded our data from the DB
launcher.onDesktopItemsLoaded();
@ -240,19 +240,88 @@ public class LauncherModel {
}
mDesktopItemsLoaded = false;
mDesktopItemsLoader = new DesktopItemsLoader(launcher);
mDesktopItemsLoader = new DesktopItemsLoader(launcher, localeChanged);
mDesktopLoader = new Thread(mDesktopItemsLoader, "Desktop Items Loader");
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 volatile boolean mStopped;
private volatile boolean mRunning;
private final WeakReference<Launcher> mLauncher;
private boolean mLocaleChanged;
DesktopItemsLoader(Launcher launcher) {
DesktopItemsLoader(Launcher launcher, boolean localeChanged) {
mLauncher = new WeakReference<Launcher>(launcher);
mLocaleChanged = localeChanged;
}
void stop() {
@ -267,54 +336,61 @@ public class LauncherModel {
mRunning = true;
final Launcher launcher = mLauncher.get();
final ContentResolver contentResolver = launcher.getContentResolver();
final PackageManager manager = launcher.getPackageManager();
if (mLocaleChanged) {
updateShortcutLabels(contentResolver, manager);
}
mDesktopItems = new ArrayList<ItemInfo>();
mUserFolders = new HashMap<Long, UserFolderInfo>();
mFolders = new HashMap<Long, FolderInfo>();
final ArrayList<ItemInfo> desktopItems = mDesktopItems;
final Cursor c = launcher.getContentResolver().query(Settings.Favorites.CONTENT_URI,
null, null, null, null);
final Cursor c = contentResolver.query(
LauncherSettings.Favorites.CONTENT_URI, null, null, null, null);
try {
final int idIndex = c.getColumnIndexOrThrow(Settings.Favorites.ID);
final int intentIndex = c.getColumnIndexOrThrow(Settings.Favorites.INTENT);
final int titleIndex = c.getColumnIndexOrThrow(Settings.Favorites.TITLE);
final int iconTypeIndex = c.getColumnIndexOrThrow(Settings.Favorites.ICON_TYPE);
final int iconIndex = c.getColumnIndexOrThrow(Settings.Favorites.ICON);
final int iconPackageIndex = c.getColumnIndexOrThrow(Settings.Favorites.ICON_PACKAGE);
final int iconResourceIndex = c.getColumnIndexOrThrow(Settings.Favorites.ICON_RESOURCE);
final int containerIndex = c.getColumnIndexOrThrow(Settings.Favorites.CONTAINER);
final int itemTypeIndex = c.getColumnIndexOrThrow(Settings.Favorites.ITEM_TYPE);
final int screenIndex = c.getColumnIndexOrThrow(Settings.Favorites.SCREEN);
final int cellXIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLX);
final int cellYIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLY);
final PackageManager manager = launcher.getPackageManager();
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);
ApplicationInfo info;
String intentDescription;
Widget widgetInfo = null;
int container;
long id;
Intent intent;
final HashMap<Long, UserFolderInfo> userFolders = mUserFolders;
final HashMap<Long, FolderInfo> folders = mFolders;
while (!mStopped && c.moveToNext()) {
try {
int itemType = c.getInt(itemTypeIndex);
switch (itemType) {
case Settings.Favorites.ITEM_TYPE_APPLICATION:
case Settings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
intentDescription = c.getString(intentIndex);
Intent intent;
try {
intent = Intent.getIntent(intentDescription);
} catch (java.net.URISyntaxException e) {
continue;
}
if (itemType == Settings.Favorites.ITEM_TYPE_APPLICATION) {
if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
info = getApplicationInfo(manager, intent);
} else {
info = getApplicationInfoShortcut(c, launcher, iconTypeIndex,
@ -338,22 +414,22 @@ public class LauncherModel {
info.cellY = c.getInt(cellYIndex);
switch (container) {
case Settings.Favorites.CONTAINER_DESKTOP:
case LauncherSettings.Favorites.CONTAINER_DESKTOP:
desktopItems.add(info);
break;
default:
// Item is in a user folder
UserFolderInfo folderInfo =
findOrMakeFolder(userFolders, container);
findOrMakeUserFolder(folders, container);
folderInfo.add(info);
break;
}
}
break;
case Settings.Favorites.ITEM_TYPE_USER_FOLDER:
case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
long id = c.getLong(idIndex);
UserFolderInfo folderInfo = findOrMakeFolder(userFolders, id);
id = c.getLong(idIndex);
UserFolderInfo folderInfo = findOrMakeUserFolder(folders, id);
folderInfo.title = c.getString(titleIndex);
@ -365,24 +441,57 @@ public class LauncherModel {
folderInfo.cellY = c.getInt(cellYIndex);
switch (container) {
case Settings.Favorites.CONTAINER_DESKTOP:
desktopItems.add(folderInfo);
break;
default:
case LauncherSettings.Favorites.CONTAINER_DESKTOP:
desktopItems.add(folderInfo);
break;
}
break;
case Settings.Favorites.ITEM_TYPE_WIDGET_CLOCK:
case Settings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
case Settings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME:
case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
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) {
case Settings.Favorites.ITEM_TYPE_WIDGET_CLOCK:
case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK:
widgetInfo = Widget.makeClock();
break;
case Settings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
widgetInfo = Widget.makeSearch();
break;
case Settings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME:
case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME:
widgetInfo = Widget.makePhotoFrame();
byte[] data = c.getBlob(iconIndex);
if (data != null) {
@ -394,7 +503,7 @@ public class LauncherModel {
if (widgetInfo != null) {
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 "
+ "!= CONTAINER_DESKTOP -- ignoring!");
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.
*
@ -439,28 +575,42 @@ public class LauncherModel {
*
* @return A UserFolderInfo if the folder exists or null otherwise.
*/
UserFolderInfo findFolderById(long id) {
return mUserFolders.get(id);
FolderInfo findFolderById(long id) {
return mFolders.get(id);
}
void addUserFolder(UserFolderInfo info) {
mUserFolders.put(info.id, info);
void addFolder(FolderInfo info) {
mFolders.put(info.id, info);
}
/**
* Return an existing UserFolderInfo object if we have encountered this ID previously, or make a
* new one.
*/
private UserFolderInfo findOrMakeFolder(HashMap<Long, UserFolderInfo> userFolders, long id) {
UserFolderInfo folderInfo;
private UserFolderInfo findOrMakeUserFolder(HashMap<Long, FolderInfo> folders, long id) {
// See if a placeholder was created for us already
folderInfo = userFolders.get(id);
if (folderInfo == null) {
FolderInfo folderInfo = folders.get(id);
if (folderInfo == null || !(folderInfo instanceof UserFolderInfo)) {
// No placeholder -- create a new instance
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++) {
ItemInfo item = desktopItems.get(i);
switch (item.itemType) {
case Settings.Favorites.ITEM_TYPE_APPLICATION:
case Settings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
((ApplicationInfo)item).icon.setCallback(null);
}
}
@ -562,7 +712,7 @@ public class LauncherModel {
if (info.title == null) {
info.title = "";
}
info.itemType = Settings.Favorites.ITEM_TYPE_APPLICATION;
info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
return info;
}
@ -573,11 +723,11 @@ public class LauncherModel {
int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex) {
final ApplicationInfo info = new ApplicationInfo();
info.itemType = Settings.Favorites.ITEM_TYPE_SHORTCUT;
info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
int iconType = c.getInt(iconTypeIndex);
switch (iconType) {
case Settings.Favorites.ICON_TYPE_RESOURCE:
case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
String packageName = c.getString(iconPackageIndex);
String resourceName = c.getString(iconResourceIndex);
PackageManager packageManager = launcher.getPackageManager();
@ -593,10 +743,11 @@ public class LauncherModel {
info.iconResource.resourceName = resourceName;
info.customIcon = false;
break;
case Settings.Favorites.ICON_TYPE_BITMAP:
case LauncherSettings.Favorites.ICON_TYPE_BITMAP:
byte[] data = c.getBlob(iconIndex);
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.customIcon = true;
break;
@ -621,7 +772,7 @@ public class LauncherModel {
* @param 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 ContentResolver cr = context.getContentResolver();
values.put(Settings.Favorites.CONTAINER, item.container);
values.put(Settings.Favorites.CELLX, item.cellX);
values.put(Settings.Favorites.CELLY, item.cellY);
values.put(Settings.Favorites.SCREEN, item.screen);
values.put(LauncherSettings.Favorites.CONTAINER, item.container);
values.put(LauncherSettings.Favorites.CELLX, item.cellX);
values.put(LauncherSettings.Favorites.CELLY, item.cellY);
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) {
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.toURI() }, null);
boolean result = false;
@ -678,21 +829,32 @@ public class LauncherModel {
return result;
}
UserFolderInfo getFolderById(Context context, long id) {
FolderInfo getFolderById(Context context, long id) {
final ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(Settings.Favorites.CONTENT_URI, null, "_id=? and itemType=?",
new String[] { String.valueOf(id),
String.valueOf(Settings.Favorites.ITEM_TYPE_USER_FOLDER) }, null);
Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null,
"_id=? and itemType=? or itemType=?",
new String[] { String.valueOf(id),
String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER),
String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER) }, null);
try {
if (c.moveToFirst()) {
final int titleIndex = c.getColumnIndexOrThrow(Settings.Favorites.TITLE);
final int containerIndex = c.getColumnIndexOrThrow(Settings.Favorites.CONTAINER);
final int screenIndex = c.getColumnIndexOrThrow(Settings.Favorites.SCREEN);
final int cellXIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLX);
final int cellYIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLY);
final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
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.id = id;
@ -712,18 +874,18 @@ public class LauncherModel {
static Widget getPhotoFrameInfo(Context context, int screen, int cellX, int cellY) {
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=?",
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 {
if (c.moveToFirst()) {
final int idIndex = c.getColumnIndexOrThrow(Settings.Favorites.ID);
final int containerIndex = c.getColumnIndexOrThrow(Settings.Favorites.CONTAINER);
final int screenIndex = c.getColumnIndexOrThrow(Settings.Favorites.SCREEN);
final int cellXIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLX);
final int cellYIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLY);
final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ID);
final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
Widget widgetInfo = Widget.makePhotoFrame();
widgetInfo.id = c.getLong(idIndex);
@ -757,8 +919,8 @@ public class LauncherModel {
item.onAddToDatabase(values);
Uri result = cr.insert(notify ? Settings.Favorites.CONTENT_URI :
Settings.Favorites.CONTENT_URI_NO_NOTIFICATION, values);
Uri result = cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI :
LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values);
if (result != null) {
item.id = Integer.parseInt(result.getPathSegments().get(1));
@ -774,7 +936,7 @@ public class LauncherModel {
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) {
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) {
final ContentResolver cr = context.getContentResolver();
cr.delete(Settings.Favorites.getContentUri(info.id, false), null, null);
cr.delete(Settings.Favorites.CONTENT_URI, Settings.Favorites.CONTAINER + "=" + info.id,
cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null);
cr.delete(LauncherSettings.Favorites.CONTENT_URI, LauncherSettings.Favorites.CONTAINER + "=" + info.id,
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;
import java.util.List;
import android.app.ISearchManager;
import android.app.SearchManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.database.Cursor;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
@ -43,9 +49,9 @@ import android.view.View.OnKeyListener;
import android.view.View.OnLongClickListener;
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.Filter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SimpleCursorAdapter;
@ -59,7 +65,7 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
private final String TAG = "SearchGadget";
private AutoCompleteTextView mSearchText;
private Button mGoButton;
private ImageButton mGoButton;
private OnLongClickListener mLongClickListener;
// Support for suggestions
@ -69,12 +75,14 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
private Uri mSuggestionData = null;
private String mSuggestionQuery = null;
private int mItemSelected = -1;
private Rect mTempRect = new Rect();
/**
* Used to inflate the Workspace from XML.
*
* @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) {
super(context, attrs);
@ -84,7 +92,9 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
* Implements OnClickListener (for button)
*/
public void onClick(View v) {
query();
if (v == mGoButton) {
query();
}
}
private void query() {
@ -92,7 +102,9 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
if (TextUtils.getTrimmedLength(mSearchText.getText()) == 0) {
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.addTextChangedListener(this);
mGoButton = (Button) findViewById(R.id.go);
mGoButton = (ImageButton) findViewById(R.id.search_go_btn);
mGoButton.setOnClickListener(this);
mGoButton.setOnKeyListener(this);
@ -296,8 +308,8 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
// attach the suggestions adapter
mSuggestionsAdapter = new SuggestionsAdapter(mContext,
com.android.internal.R.layout.search_dropdown_item_1line, null,
SuggestionsAdapter.ONE_LINE_FROM, SuggestionsAdapter.ONE_LINE_TO, mSearchable);
com.android.internal.R.layout.search_dropdown_item_2line, null,
SuggestionsAdapter.TWO_LINE_FROM, SuggestionsAdapter.TWO_LINE_TO, mSearchable);
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.
* 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 {
public final static String[] ONE_LINE_FROM = { SearchManager.SUGGEST_COLUMN_TEXT_1 };
public final static int[] ONE_LINE_TO = { com.android.internal.R.id.text1 };
public final static String[] TWO_LINE_FROM = {SearchManager.SUGGEST_COLUMN_TEXT_1,
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";

View File

@ -21,11 +21,10 @@ import android.content.Context;
import android.content.Intent;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import java.net.URISyntaxException;
import com.android.internal.provider.Settings;
public class UninstallShortcutReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent data) {
Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
@ -34,18 +33,23 @@ public class UninstallShortcutReceiver extends BroadcastReceiver {
if (intent != null && name != null) {
final ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(Settings.Favorites.CONTENT_URI,
new String[] { "_id", "intent" }, "title=?", new String[]{ name }, null);
Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
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 idIndex = c.getColumnIndexOrThrow(Settings.Favorites._ID);
final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID);
boolean changed = false;
try {
while (c.moveToNext()) {
try {
if (intent.filterEquals(Intent.getIntent(c.getString(intentIndex)))) {
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) {
break;
}
@ -58,7 +62,7 @@ public class UninstallShortcutReceiver extends BroadcastReceiver {
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;
import android.content.Context;
import com.android.internal.provider.Settings;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@ -31,8 +30,8 @@ public class UserFolder extends Folder implements DropTarget {
Object dragInfo) {
final ItemInfo item = (ItemInfo) dragInfo;
final int itemType = item.itemType;
return (itemType == Settings.Favorites.ITEM_TYPE_APPLICATION ||
itemType == Settings.Favorites.ITEM_TYPE_SHORTCUT) && item.container != mInfo.id;
return (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
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) {
@ -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) {
}
@Override
public boolean onLongClick(View v) {
mLauncher.closeFolder(this);
mLauncher.showRenameDialog((UserFolderInfo) mInfo);
return true;
}
@Override
public void onDropCompleted(View target, boolean success) {
if (success) {
@ -68,10 +60,9 @@ public class UserFolder extends Folder implements DropTarget {
}
}
void bind(UserFolderInfo info) {
mInfo = info;
setContentAdapter(new ApplicationsAdapter(mContext, info.contents));
mCloseButton.setText(info.title);
void bind(FolderInfo info) {
super.bind(info);
setContentAdapter(new ApplicationsAdapter(mContext, ((UserFolderInfo) info).contents));
}
// When the folder opens, we need to refresh the GridView's selection by

View File

@ -17,7 +17,6 @@
package com.android.launcher;
import android.content.ContentValues;
import com.android.internal.provider.Settings;
import java.util.ArrayList;
@ -25,18 +24,13 @@ import java.util.ArrayList;
* Represents a folder containing shortcuts or apps.
*/
class UserFolderInfo extends FolderInfo {
/**
* The application name.
*/
CharSequence title;
/**
* The apps and shortcuts
*/
ArrayList<ApplicationInfo> contents = new ArrayList<ApplicationInfo>();
UserFolderInfo() {
itemType = Settings.Favorites.ITEM_TYPE_USER_FOLDER;
itemType = LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER;
}
/**
@ -60,6 +54,6 @@ class UserFolderInfo extends FolderInfo {
@Override
void onAddToDatabase(ContentValues 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.PaintDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.Canvas;
@ -97,30 +96,46 @@ final class Utilities {
painter.setIntrinsicHeight(height);
}
if (width > 0 && height > 0 && (width < iconWidth || height < iconHeight)) {
final float ratio = (float) iconWidth / iconHeight;
if (width > 0 && height > 0) {
if (width < iconWidth || height < iconHeight) {
final float ratio = (float) iconWidth / iconHeight;
if (iconWidth > iconHeight) {
height = (int) (width / ratio);
} else if (iconHeight > iconWidth) {
width = (int) (height * ratio);
if (iconWidth > iconHeight) {
height = (int) (width / ratio);
} else if (iconHeight > iconWidth) {
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;

View File

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

View File

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

View File

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