Merge commit 'korg/cupcake'
|
@ -71,6 +71,7 @@
|
|||
android:clearTaskOnLaunch="true"
|
||||
android:stateNotNeeded="true"
|
||||
android:theme="@style/Theme"
|
||||
android:screenOrientation="nosensor"
|
||||
android:windowSoftInputMode="stateUnspecified|adjustPan">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 859 B |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 651 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 954 B After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 982 B |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 646 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 958 B After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 962 B After Width: | Height: | Size: 833 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 196 B |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 419 B |
Before Width: | Height: | Size: 6.6 KiB |
|
@ -66,7 +66,7 @@
|
|||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
|
||||
launcher:texture="@drawable/texture_brushed_steel"
|
||||
launcher:texture="@drawable/pattern_carbon_fiber_dark"
|
||||
|
||||
android:scrollbarStyle="outsideInset"
|
||||
android:drawSelectorOnTop="false"
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
|
||||
launcher:texture="@drawable/texture_brushed_steel"
|
||||
launcher:texture="@drawable/pattern_carbon_fiber_dark"
|
||||
|
||||
android:scrollbarStyle="outsideInset"
|
||||
android:drawSelectorOnTop="false"
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2008, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/title"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="?android:attr/listPreferredItemHeight"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:textAppearance="?android:attr/textAppearanceLargeInverse"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingRight="15dip"
|
||||
android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft" />
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2008, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_marginTop="5dip"
|
||||
android:cacheColorHint="@null"
|
||||
android:divider="@android:drawable/divider_horizontal_bright"
|
||||
android:scrollbars="vertical" />
|
|
@ -1,30 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2008, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/title"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:textAppearance="?android:attr/textAppearanceLargeInverse"
|
||||
android:gravity="center_vertical"
|
||||
android:drawablePadding="14dip"
|
||||
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
|
||||
android:paddingRight="15dip" />
|
||||
|
||||
|
|
@ -19,11 +19,13 @@
|
|||
android:layout_height="fill_parent"
|
||||
android:orientation="horizontal"
|
||||
android:background="@drawable/search_bg"
|
||||
android:gravity="center_vertical">
|
||||
android:gravity="center_vertical"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="3dip"
|
||||
android:src="@drawable/google_logo" />
|
||||
|
||||
<com.android.launcher.SearchAutoCompleteTextView
|
||||
|
@ -31,6 +33,7 @@
|
|||
android:layout_width="0dip"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="1dip"
|
||||
android:hint="@string/search_hint"
|
||||
android:focusableInTouchMode="false"
|
||||
android:singleLine="true"
|
||||
|
@ -38,16 +41,18 @@
|
|||
android:completionThreshold="1"
|
||||
android:inputType="textAutoComplete"
|
||||
android:imeOptions="actionSearch"
|
||||
android:lines="1"
|
||||
/>
|
||||
|
||||
<ImageButton android:id="@+id/search_go_btn"
|
||||
android:layout_marginLeft="1dip"
|
||||
android:layout_marginLeft="4dip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@*android:drawable/ic_btn_search"
|
||||
/>
|
||||
|
||||
<ImageButton android:id="@+id/search_voice_btn"
|
||||
android:layout_marginLeft="2dip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@android:drawable/ic_btn_speak_now"
|
||||
|
|
|
@ -54,6 +54,5 @@
|
|||
<string name="permlab_write_settings">"zápis nastavení a odkazů plochy"</string>
|
||||
<string name="permdesc_write_settings">"Povoluje aplikaci změnit nastavení a odkazy plochy."</string>
|
||||
<string name="search_hint">"Vyhledávání Google"</string>
|
||||
<!-- no translation found for gadget_error_text (8359351016167075858) -->
|
||||
<skip />
|
||||
<string name="gadget_error_text">"Problém s načtením widgetu"</string>
|
||||
</resources>
|
||||
|
|
|
@ -54,6 +54,5 @@
|
|||
<string name="permlab_write_settings">"Einstellungen und Shortcuts für Startseite schreiben"</string>
|
||||
<string name="permdesc_write_settings">"Ermöglicht einer Anwendung, die Einstellungen und Shortcuts auf der Startseite zu ändern."</string>
|
||||
<string name="search_hint">"Google-Suche"</string>
|
||||
<!-- no translation found for gadget_error_text (8359351016167075858) -->
|
||||
<skip />
|
||||
<string name="gadget_error_text">"Problem beim Laden des Widgets"</string>
|
||||
</resources>
|
||||
|
|
|
@ -54,6 +54,5 @@
|
|||
<string name="permlab_write_settings">"escribir información de accesos directos y de configuración de la página principal"</string>
|
||||
<string name="permdesc_write_settings">"Permite que una aplicación modifique la configuración y los accesos directos de la página principal."</string>
|
||||
<string name="search_hint">"Búsqueda de Google"</string>
|
||||
<!-- no translation found for gadget_error_text (8359351016167075858) -->
|
||||
<skip />
|
||||
<string name="gadget_error_text">"Problema al cargar el widget"</string>
|
||||
</resources>
|
||||
|
|
|
@ -54,6 +54,5 @@
|
|||
<string name="permlab_write_settings">"Enregistrer les paramètres de la page d\'accueil et des raccourcis"</string>
|
||||
<string name="permdesc_write_settings">"Permet à une application de modifier les paramètres et les raccourcis de la page d\'accueil."</string>
|
||||
<string name="search_hint">"Recherche Google"</string>
|
||||
<!-- no translation found for gadget_error_text (8359351016167075858) -->
|
||||
<skip />
|
||||
<string name="gadget_error_text">"Problème lors du chargement du widget"</string>
|
||||
</resources>
|
||||
|
|
|
@ -54,6 +54,5 @@
|
|||
<string name="permlab_write_settings">"creare impostazioni e scorciatoie in Home"</string>
|
||||
<string name="permdesc_write_settings">"Consente a un\'applicazione di modificare le impostazioni e le scorciatoie in Home."</string>
|
||||
<string name="search_hint">"Ricerca Google"</string>
|
||||
<!-- no translation found for gadget_error_text (8359351016167075858) -->
|
||||
<skip />
|
||||
<string name="gadget_error_text">"Errore durante il caricamento del widget"</string>
|
||||
</resources>
|
||||
|
|
|
@ -26,20 +26,27 @@
|
|||
<string name="rename_action">"OK"</string>
|
||||
<string name="cancel_action">"キャンセル"</string>
|
||||
<string name="menu_item_add_item">"ホーム画面に追加"</string>
|
||||
<string name="group_applications">"アプリケーション"</string>
|
||||
<string name="group_shortcuts">"ショートカット"</string>
|
||||
<!-- no translation found for group_applications (4118484163419674240) -->
|
||||
<skip />
|
||||
<!-- no translation found for group_shortcuts (9133529424900391877) -->
|
||||
<skip />
|
||||
<string name="group_search">"検索"</string>
|
||||
<string name="group_folder">"フォルダ"</string>
|
||||
<string name="group_live_folders">"ライブフォルダ"</string>
|
||||
<string name="group_widgets">"ウィジェット"</string>
|
||||
<string name="group_wallpapers">"壁紙"</string>
|
||||
<!-- no translation found for group_folder (5143593791798929193) -->
|
||||
<skip />
|
||||
<!-- no translation found for group_live_folders (2664945399140647217) -->
|
||||
<skip />
|
||||
<!-- no translation found for group_widgets (6704978494073105844) -->
|
||||
<skip />
|
||||
<!-- no translation found for group_wallpapers (1568191644272224858) -->
|
||||
<skip />
|
||||
<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="title_select_shortcut">"ショートカットを選択"</string>
|
||||
<string name="title_select_live_folder">"ライブフォルダを選択"</string>
|
||||
<!-- no translation found for title_select_live_folder (3753447798805166749) -->
|
||||
<skip />
|
||||
<string name="menu_add">"追加"</string>
|
||||
<string name="menu_wallpaper">"壁紙"</string>
|
||||
<string name="menu_search">"検索"</string>
|
||||
|
@ -54,6 +61,5 @@
|
|||
<string name="permlab_write_settings">"ホームの設定とショートカットの書き込み"</string>
|
||||
<string name="permdesc_write_settings">"ホームの設定とショートカットの変更をアプリケーションに許可します。"</string>
|
||||
<string name="search_hint">"Google検索"</string>
|
||||
<!-- no translation found for gadget_error_text (8359351016167075858) -->
|
||||
<skip />
|
||||
<string name="gadget_error_text">"ウィジェットを表示できません"</string>
|
||||
</resources>
|
||||
|
|
|
@ -54,6 +54,5 @@
|
|||
<string name="permlab_write_settings">"홈 설정 및 바로가기 쓰기"</string>
|
||||
<string name="permdesc_write_settings">"응용프로그램이 홈에 있는 설정 및 바로가기를 변경할 수 있습니다."</string>
|
||||
<string name="search_hint">"Google 검색"</string>
|
||||
<!-- no translation found for gadget_error_text (8359351016167075858) -->
|
||||
<skip />
|
||||
<string name="gadget_error_text">"위젯을 로드하는 중 문제가 발생했습니다."</string>
|
||||
</resources>
|
||||
|
|
|
@ -54,6 +54,5 @@
|
|||
<string name="permlab_write_settings">"skrive skrivebordsinnstillinger og -snarveier"</string>
|
||||
<string name="permdesc_write_settings">"Lar applikasjonen endre innstillinger og snarveier på skrivebordet."</string>
|
||||
<string name="search_hint">"Google-søk"</string>
|
||||
<!-- no translation found for gadget_error_text (8359351016167075858) -->
|
||||
<skip />
|
||||
<string name="gadget_error_text">"Problem under lasting av gadget"</string>
|
||||
</resources>
|
||||
|
|
|
@ -54,6 +54,5 @@
|
|||
<string name="permlab_write_settings">"instellingen en snelkoppelingen voor de startpagina schrijven"</string>
|
||||
<string name="permdesc_write_settings">"Hiermee kan een toepassing de instellingen en snelkoppelingen op de startpagina wijzigen."</string>
|
||||
<string name="search_hint">"Google Zoeken"</string>
|
||||
<!-- no translation found for gadget_error_text (8359351016167075858) -->
|
||||
<skip />
|
||||
<string name="gadget_error_text">"Probleem bij het laden van widget"</string>
|
||||
</resources>
|
||||
|
|
|
@ -54,6 +54,5 @@
|
|||
<string name="permlab_write_settings">"zapisywanie ustawień i skrótów strony głównej"</string>
|
||||
<string name="permdesc_write_settings">"Umożliwia aplikacji zmianę ustawień i skrótów strony głównej."</string>
|
||||
<string name="search_hint">"Szukaj w Google"</string>
|
||||
<!-- no translation found for gadget_error_text (8359351016167075858) -->
|
||||
<skip />
|
||||
<string name="gadget_error_text">"Problem podczas ładowania widżetu"</string>
|
||||
</resources>
|
||||
|
|
|
@ -54,6 +54,5 @@
|
|||
<string name="permlab_write_settings">"записывать ярлыки и настройки главного экрана"</string>
|
||||
<string name="permdesc_write_settings">"Позволяет приложению изменять настройки и ярлыки на главном экране."</string>
|
||||
<string name="search_hint">"Поиск Google"</string>
|
||||
<!-- no translation found for gadget_error_text (8359351016167075858) -->
|
||||
<skip />
|
||||
<string name="gadget_error_text">"Не удалось загрузить виджет"</string>
|
||||
</resources>
|
||||
|
|
|
@ -54,6 +54,5 @@
|
|||
<string name="permlab_write_settings">"写入“主页”设置和快捷键"</string>
|
||||
<string name="permdesc_write_settings">"允许应用程序更改“主页”中的设置和快捷键。"</string>
|
||||
<string name="search_hint">"Google 搜索"</string>
|
||||
<!-- no translation found for gadget_error_text (8359351016167075858) -->
|
||||
<skip />
|
||||
<string name="gadget_error_text">"载入窗口小部件时出现问题"</string>
|
||||
</resources>
|
||||
|
|
|
@ -54,6 +54,5 @@
|
|||
<string name="permlab_write_settings">"寫入首頁設定和捷徑"</string>
|
||||
<string name="permdesc_write_settings">"允許應用程式變更首頁中的設定和捷徑。"</string>
|
||||
<string name="search_hint">"Google 搜尋"</string>
|
||||
<!-- no translation found for gadget_error_text (8359351016167075858) -->
|
||||
<skip />
|
||||
<string name="gadget_error_text">"載入小工具時發生問題"</string>
|
||||
</resources>
|
||||
|
|
|
@ -76,4 +76,12 @@
|
|||
<attr name="texture" format="reference" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- XML attributes used by default_workspace.xml -->
|
||||
<declare-styleable name="Favorite">
|
||||
<attr name="className" format="string" />
|
||||
<attr name="packageName" format="string" />
|
||||
<attr name="screen" format="string" />
|
||||
<attr name="x" format="string" />
|
||||
<attr name="y" format="string" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
|
|
|
@ -49,19 +49,19 @@
|
|||
<!-- Title of 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>
|
||||
<string name="group_applications">Applications</string>
|
||||
<!-- Options in "Add to Home" dialog box; Title of the group containing the list of all shortcuts -->
|
||||
<string name="group_shortcuts">Shortcut</string>
|
||||
<string name="group_shortcuts">Shortcuts</string>
|
||||
<!-- Options in "Add to Home" dialog box; Title of the search gadget -->
|
||||
<string name="group_search">Search</string>
|
||||
<!-- Options in "Add to Home" dialog box; Title of the folder gadget -->
|
||||
<string name="group_folder">Folder</string>
|
||||
<string name="group_folder">New folder</string>
|
||||
<!-- Options in "Add to Home" dialog box; Title of the group containing the list of all live folders -->
|
||||
<string name="group_live_folders">Live folder</string>
|
||||
<string name="group_live_folders">Folders</string>
|
||||
<!-- Options in "Add to Home" dialog box; Title of the group containing the list of all widgets/gadgets -->
|
||||
<string name="group_widgets">Widget</string>
|
||||
<string name="group_widgets">Widgets</string>
|
||||
<!-- Options in "Add to Home" dialog box; Title of the group containing the list of apps that can set the wallpaper-->
|
||||
<string name="group_wallpapers">Wallpaper</string>
|
||||
<string name="group_wallpapers">Wallpapers</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-->
|
||||
|
@ -76,7 +76,7 @@
|
|||
<!-- Title of dialog when user is selecting shortcut to add to homescreen -->
|
||||
<string name="title_select_shortcut">Select shortcut</string>
|
||||
<!-- Title of dialog when user is selecting live folder to add to homescreen -->
|
||||
<string name="title_select_live_folder">Select live folder</string>
|
||||
<string name="title_select_live_folder">Select folder</string>
|
||||
|
||||
<!-- Menus items: -->
|
||||
<skip />
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2009 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.
|
||||
-->
|
||||
|
||||
<favorites xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher">
|
||||
|
||||
<clock
|
||||
launcher:screen="1"
|
||||
launcher:x="1"
|
||||
launcher:y="0" />
|
||||
|
||||
<search
|
||||
launcher:screen="2"
|
||||
launcher:x="0"
|
||||
launcher:y="0" />
|
||||
|
||||
<favorite
|
||||
launcher:packageName="com.android.contacts"
|
||||
launcher:className="com.android.contacts.DialtactsActivity"
|
||||
launcher:screen="1"
|
||||
launcher:x="0"
|
||||
launcher:y="3" />
|
||||
|
||||
<favorite
|
||||
launcher:packageName="com.android.contacts"
|
||||
launcher:className="com.android.contacts.DialtactsContactsEntryActivity"
|
||||
launcher:screen="1"
|
||||
launcher:x="1"
|
||||
launcher:y="3" />
|
||||
|
||||
<favorite
|
||||
launcher:packageName="com.android.browser"
|
||||
launcher:className="com.android.browser.BrowserActivity"
|
||||
launcher:screen="1"
|
||||
launcher:x="2"
|
||||
launcher:y="3" />
|
||||
|
||||
<favorite
|
||||
launcher:packageName="com.google.android.apps.maps"
|
||||
launcher:className="com.google.android.maps.MapsActivity"
|
||||
launcher:screen="1"
|
||||
launcher:x="3"
|
||||
launcher:y="3" />
|
||||
|
||||
<favorite
|
||||
launcher:packageName="com.android.mms"
|
||||
launcher:className="com.android.mms.ui.ConversationList"
|
||||
launcher:screen="1"
|
||||
launcher:x="0"
|
||||
launcher:y="2" />
|
||||
|
||||
<favorite
|
||||
launcher:packageName="com.android.vending"
|
||||
launcher:className="com.android.vending.AssetBrowserActivity"
|
||||
launcher:screen="1"
|
||||
launcher:x="3"
|
||||
launcher:y="2" />
|
||||
|
||||
</favorites>
|
|
@ -31,19 +31,15 @@ import java.util.ArrayList;
|
|||
* Adapter showing the types of items that can be added to a {@link Workspace}.
|
||||
*/
|
||||
public class AddAdapter extends BaseAdapter {
|
||||
|
||||
private final Launcher mLauncher;
|
||||
|
||||
private final LayoutInflater mInflater;
|
||||
|
||||
private final ArrayList<ListItem> mItems = new ArrayList<ListItem>();
|
||||
|
||||
public static final int ITEM_APPLICATION = 0;
|
||||
public static final int ITEM_SHORTCUT = 1;
|
||||
public static final int ITEM_SEARCH = 2;
|
||||
public static final int ITEM_APPWIDGET = 3;
|
||||
public static final int ITEM_LIVE_FOLDER = 4;
|
||||
public static final int ITEM_FOLDER = 5;
|
||||
public static final int ITEM_WALLPAPER = 6;
|
||||
public static final int ITEM_SHORTCUT = 0;
|
||||
public static final int ITEM_APPWIDGET = 1;
|
||||
public static final int ITEM_LIVE_FOLDER = 2;
|
||||
public static final int ITEM_WALLPAPER = 3;
|
||||
|
||||
/**
|
||||
* Specific item in our list.
|
||||
|
@ -66,30 +62,20 @@ public class AddAdapter extends BaseAdapter {
|
|||
|
||||
public AddAdapter(Launcher launcher) {
|
||||
super();
|
||||
|
||||
mLauncher = launcher;
|
||||
mInflater = (LayoutInflater) mLauncher.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
mInflater = (LayoutInflater) launcher.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
// Create default actions
|
||||
Resources res = launcher.getResources();
|
||||
|
||||
mItems.add(new ListItem(res, R.string.group_applications,
|
||||
R.drawable.ic_launcher_application, ITEM_APPLICATION));
|
||||
|
||||
mItems.add(new ListItem(res, R.string.group_shortcuts,
|
||||
R.drawable.ic_launcher_empty, ITEM_SHORTCUT));
|
||||
|
||||
mItems.add(new ListItem(res, R.string.group_search,
|
||||
R.drawable.ic_search_widget, ITEM_SEARCH));
|
||||
|
||||
R.drawable.ic_launcher_shortcut, ITEM_SHORTCUT));
|
||||
|
||||
mItems.add(new ListItem(res, R.string.group_widgets,
|
||||
R.drawable.ic_launcher_appwidget, ITEM_APPWIDGET));
|
||||
|
||||
mItems.add(new ListItem(res, R.string.group_live_folders,
|
||||
R.drawable.ic_launcher_empty, ITEM_LIVE_FOLDER));
|
||||
|
||||
mItems.add(new ListItem(res, R.string.group_folder,
|
||||
R.drawable.ic_launcher_folder, ITEM_FOLDER));
|
||||
R.drawable.ic_launcher_folder_live, ITEM_LIVE_FOLDER));
|
||||
|
||||
mItems.add(new ListItem(res, R.string.group_wallpapers,
|
||||
R.drawable.ic_launcher_gallery, ITEM_WALLPAPER));
|
||||
|
|
|
@ -31,6 +31,7 @@ import android.content.DialogInterface;
|
|||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.Intent.ShortcutIconResource;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
|
@ -46,6 +47,8 @@ import android.net.Uri;
|
|||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.MessageQueue;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
|
@ -57,20 +60,17 @@ import android.text.SpannableStringBuilder;
|
|||
import android.text.TextUtils;
|
||||
import android.text.method.TextKeyListener;
|
||||
import android.util.Log;
|
||||
import static android.util.Log.*;
|
||||
import android.view.Display;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
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.AdapterView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.GridView;
|
||||
|
@ -81,6 +81,7 @@ import android.appwidget.AppWidgetProviderInfo;
|
|||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Default launcher application.
|
||||
|
@ -91,6 +92,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
|||
|
||||
private static final boolean PROFILE_STARTUP = false;
|
||||
private static final boolean PROFILE_DRAWER = false;
|
||||
private static final boolean PROFILE_ROTATE = false;
|
||||
private static final boolean DEBUG_USER_INTERFACE = false;
|
||||
|
||||
private static final int WALLPAPER_SCREENS_SPAN = 2;
|
||||
|
@ -112,6 +114,9 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
|||
|
||||
static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";
|
||||
|
||||
static final String EXTRA_CUSTOM_WIDGET = "custom_widget";
|
||||
static final String SEARCH_WIDGET = "search_widget";
|
||||
|
||||
static final int SCREEN_COUNT = 3;
|
||||
static final int DEFAULT_SCREN = 1;
|
||||
static final int NUMBER_CELLS_X = 4;
|
||||
|
@ -197,6 +202,8 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
|||
|
||||
private Bundle mSavedInstanceState;
|
||||
|
||||
private DesktopBinder mBinder;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -352,6 +359,19 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
|||
super.onPause();
|
||||
closeDrawer(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object onRetainNonConfigurationInstance() {
|
||||
// Flag any binder to stop early before switching
|
||||
if (mBinder != null) {
|
||||
mBinder.mTerminate = true;
|
||||
}
|
||||
|
||||
if (PROFILE_ROTATE) {
|
||||
android.os.Debug.startMethodTracing("/sdcard/launcher-rotate");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean acceptFilter() {
|
||||
final InputMethodManager inputManager = (InputMethodManager)
|
||||
|
@ -385,7 +405,8 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
|||
intent.putExtra(Contacts.Intents.UI.FILTER_TEXT_EXTRA_KEY, str);
|
||||
}
|
||||
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
|
||||
|
||||
try {
|
||||
startActivity(intent);
|
||||
|
@ -603,7 +624,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
|||
Bundle extras = data.getExtras();
|
||||
int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
|
||||
|
||||
Log.d(LOG_TAG, "dumping extras content="+extras.toString());
|
||||
d(LOG_TAG, "dumping extras content="+extras.toString());
|
||||
|
||||
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
|
||||
|
||||
|
@ -671,7 +692,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
|||
final int id = resources.getIdentifier(iconResource.resourceName, null, null);
|
||||
icon = resources.getDrawable(id);
|
||||
} catch (Exception e) {
|
||||
Log.w(LOG_TAG, "Could not load shortcut icon: " + extra);
|
||||
w(LOG_TAG, "Could not load shortcut icon: " + extra);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -794,7 +815,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
|||
try {
|
||||
mAppWidgetHost.stopListening();
|
||||
} catch (NullPointerException ex) {
|
||||
Log.w(LOG_TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);
|
||||
w(LOG_TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);
|
||||
}
|
||||
|
||||
TextKeyListener.getInstance().release();
|
||||
|
@ -903,21 +924,36 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
|||
}
|
||||
}
|
||||
|
||||
private void updateShortcutsForPackage(String packageName) {
|
||||
if (packageName != null && packageName.length() > 0) {
|
||||
mWorkspace.updateShortcutsForPackage(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
void addAppWidget(Intent data) {
|
||||
// TODO: catch bad widget exception when sent
|
||||
int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
|
||||
AppWidgetProviderInfo appWidget = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
|
||||
|
||||
if (appWidget.configure != null) {
|
||||
// Launch over to configure widget, if needed
|
||||
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
|
||||
intent.setComponent(appWidget.configure);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
||||
|
||||
startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);
|
||||
String customWidget = data.getStringExtra(EXTRA_CUSTOM_WIDGET);
|
||||
if (SEARCH_WIDGET.equals(customWidget)) {
|
||||
// We don't need this any more, since this isn't a real app widget.
|
||||
mAppWidgetHost.deleteAppWidgetId(appWidgetId);
|
||||
// add the search widget
|
||||
addSearch();
|
||||
} else {
|
||||
// Otherwise just add it
|
||||
onActivityResult(REQUEST_CREATE_APPWIDGET, Activity.RESULT_OK, data);
|
||||
AppWidgetProviderInfo appWidget = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
|
||||
|
||||
if (appWidget.configure != null) {
|
||||
// Launch over to configure widget, if needed
|
||||
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
|
||||
intent.setComponent(appWidget.configure);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
||||
|
||||
startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);
|
||||
} else {
|
||||
// Otherwise just add it
|
||||
onActivityResult(REQUEST_CREATE_APPWIDGET, Activity.RESULT_OK, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -942,11 +978,32 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
|||
}
|
||||
|
||||
void addShortcut(Intent intent) {
|
||||
startActivityForResult(intent, REQUEST_CREATE_SHORTCUT);
|
||||
// Handle case where user selected "Applications"
|
||||
String applicationName = getResources().getString(R.string.group_applications);
|
||||
String shortcutName = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
|
||||
|
||||
if (applicationName != null && applicationName.equals(shortcutName)) {
|
||||
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
|
||||
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
|
||||
pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);
|
||||
startActivityForResult(pickIntent, REQUEST_PICK_APPLICATION);
|
||||
} else {
|
||||
startActivityForResult(intent, REQUEST_CREATE_SHORTCUT);
|
||||
}
|
||||
}
|
||||
|
||||
void addLiveFolder(Intent intent) {
|
||||
startActivityForResult(intent, REQUEST_CREATE_LIVE_FOLDER);
|
||||
// Handle case where user selected "Folder"
|
||||
String folderName = getResources().getString(R.string.group_folder);
|
||||
String shortcutName = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
|
||||
|
||||
if (folderName != null && folderName.equals(shortcutName)) {
|
||||
addFolder(!mDesktopLocked);
|
||||
} else {
|
||||
startActivityForResult(intent, REQUEST_CREATE_LIVE_FOLDER);
|
||||
}
|
||||
}
|
||||
|
||||
void addFolder(boolean insertAtFirst) {
|
||||
|
@ -1008,7 +1065,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
|||
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);
|
||||
w(LOG_TAG, "Could not load live folder icon: " + extra);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1107,8 +1164,11 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
|||
switch (event.getKeyCode()) {
|
||||
case KeyEvent.KEYCODE_BACK:
|
||||
mWorkspace.dispatchKeyEvent(event);
|
||||
closeFolder();
|
||||
closeDrawer();
|
||||
if (mDrawer.isOpened()) {
|
||||
closeDrawer();
|
||||
} else {
|
||||
closeFolder();
|
||||
}
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_HOME:
|
||||
return true;
|
||||
|
@ -1163,21 +1223,22 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
|||
|
||||
void onDesktopItemsLoaded() {
|
||||
if (mDestroyed) return;
|
||||
android.util.Log.d("Home", "setting grid adapter");
|
||||
mAllAppsGrid.setAdapter(sModel.getApplicationsAdapter());
|
||||
bindDesktopItems();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Refreshes the shortcuts shown on the workspace.
|
||||
*/
|
||||
private void bindDesktopItems() {
|
||||
final ArrayList<ItemInfo> shortcuts = sModel.getDesktopItems();
|
||||
final ArrayList<LauncherAppWidgetInfo> appWidgets = sModel.getDesktopAppWidgets();
|
||||
if (shortcuts == null || appWidgets == null) {
|
||||
final ApplicationsAdapter drawerAdapter = sModel.getApplicationsAdapter();
|
||||
if (shortcuts == null || appWidgets == null || drawerAdapter == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mAllAppsGrid.setAdapter(drawerAdapter);
|
||||
|
||||
final Workspace workspace = mWorkspace;
|
||||
int count = workspace.getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
@ -1195,9 +1256,14 @@ android.util.Log.d("Home", "setting grid adapter");
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
final DesktopBinder binder = new DesktopBinder(this, shortcuts, appWidgets);
|
||||
binder.startBindingItems();
|
||||
|
||||
// Flag any old binder to terminate early
|
||||
if (mBinder != null) {
|
||||
mBinder.mTerminate = true;
|
||||
}
|
||||
|
||||
mBinder = new DesktopBinder(this, shortcuts, appWidgets);
|
||||
mBinder.startBindingItems();
|
||||
}
|
||||
|
||||
private void bindItems(Launcher.DesktopBinder binder,
|
||||
|
@ -1250,7 +1316,7 @@ android.util.Log.d("Home", "setting grid adapter");
|
|||
|
||||
if (end >= count) {
|
||||
finishBindDesktopItems();
|
||||
binder.startBindingAppWidgets();
|
||||
binder.startBindingAppWidgetsWhenIdle();
|
||||
} else {
|
||||
binder.obtainMessage(DesktopBinder.MESSAGE_BIND_ITEMS, i, count).sendToTarget();
|
||||
}
|
||||
|
@ -1296,44 +1362,44 @@ android.util.Log.d("Home", "setting grid adapter");
|
|||
mDesktopLocked = false;
|
||||
mDrawer.unlock();
|
||||
}
|
||||
|
||||
|
||||
private void bindAppWidgets(Launcher.DesktopBinder binder,
|
||||
ArrayList<LauncherAppWidgetInfo> appWidgets, int start, int count) {
|
||||
|
||||
LinkedList<LauncherAppWidgetInfo> appWidgets) {
|
||||
|
||||
final Workspace workspace = mWorkspace;
|
||||
final boolean desktopLocked = mDesktopLocked;
|
||||
|
||||
final int end = Math.min(start + DesktopBinder.APPWIDGETS_COUNT, count);
|
||||
int i = start;
|
||||
|
||||
for ( ; i < end; i++) {
|
||||
final LauncherAppWidgetInfo item = appWidgets.get(i);
|
||||
|
||||
if (!appWidgets.isEmpty()) {
|
||||
final LauncherAppWidgetInfo item = appWidgets.removeFirst();
|
||||
|
||||
final int appWidgetId = item.appWidgetId;
|
||||
final AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
|
||||
final AppWidgetProviderInfo appWidgetInfo =
|
||||
mAppWidgetManager.getAppWidgetInfo(appWidgetId);
|
||||
item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
|
||||
|
||||
if (LOGD) Log.d(LOG_TAG, String.format("about to setAppWidget for id=%d, info=%s", appWidgetId, appWidgetInfo));
|
||||
if (LOGD) {
|
||||
d(LOG_TAG, String.format("about to setAppWidget for id=%d, info=%s",
|
||||
appWidgetId, appWidgetInfo));
|
||||
}
|
||||
|
||||
item.hostView.setAppWidget(appWidgetId, appWidgetInfo);
|
||||
item.hostView.setTag(item);
|
||||
|
||||
workspace.addInScreen(item.hostView, item.screen, item.cellX,
|
||||
item.cellY, item.spanX, item.spanY, !desktopLocked);
|
||||
|
||||
workspace.requestLayout();
|
||||
}
|
||||
|
||||
workspace.requestLayout();
|
||||
|
||||
if (end >= count) {
|
||||
finishBindDesktopAppWidgets();
|
||||
if (appWidgets.isEmpty()) {
|
||||
if (PROFILE_ROTATE) {
|
||||
android.os.Debug.stopMethodTracing();
|
||||
}
|
||||
} else {
|
||||
binder.obtainMessage(DesktopBinder.MESSAGE_BIND_APPWIDGETS, i, count).sendToTarget();
|
||||
binder.obtainMessage(DesktopBinder.MESSAGE_BIND_APPWIDGETS).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
private void finishBindDesktopAppWidgets() {
|
||||
}
|
||||
|
||||
|
||||
DragController getDragController() {
|
||||
return mDragLayer;
|
||||
}
|
||||
|
@ -1623,11 +1689,10 @@ android.util.Log.d("Home", "setting grid adapter");
|
|||
* Displays the shortcut creation dialog and launches, if necessary, the
|
||||
* appropriate activity.
|
||||
*/
|
||||
private class CreateShortcut implements AdapterView.OnItemClickListener,
|
||||
private class CreateShortcut implements DialogInterface.OnClickListener,
|
||||
DialogInterface.OnCancelListener {
|
||||
private AddAdapter mAdapter;
|
||||
private ListView mList;
|
||||
|
||||
|
||||
Dialog createDialog() {
|
||||
mWaitingForResult = true;
|
||||
|
||||
|
@ -1635,22 +1700,13 @@ android.util.Log.d("Home", "setting grid adapter");
|
|||
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(Launcher.this);
|
||||
builder.setTitle(getString(R.string.menu_item_add_item));
|
||||
builder.setIcon(0);
|
||||
|
||||
mList = (ListView)
|
||||
View.inflate(Launcher.this, R.layout.create_shortcut_list, null);
|
||||
mList.setAdapter(mAdapter);
|
||||
mList.setOnItemClickListener(this);
|
||||
builder.setView(mList);
|
||||
builder.setAdapter(mAdapter, this);
|
||||
|
||||
builder.setInverseBackgroundForced(true);
|
||||
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.setOnCancelListener(this);
|
||||
|
||||
WindowManager.LayoutParams attributes = dialog.getWindow().getAttributes();
|
||||
attributes.gravity = Gravity.TOP;
|
||||
dialog.onWindowAttributesChanged(attributes);
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
@ -1664,74 +1720,94 @@ android.util.Log.d("Home", "setting grid adapter");
|
|||
dismissDialog(DIALOG_CREATE_SHORTCUT);
|
||||
}
|
||||
|
||||
public void onItemClick(AdapterView parent, View view, int position, long id) {
|
||||
// handle which item was clicked based on position
|
||||
// this will launch off pick intent
|
||||
/**
|
||||
* Handle the action clicked in the "Add to home" dialog.
|
||||
*/
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Resources res = getResources();
|
||||
cleanup();
|
||||
|
||||
Object tag = view.getTag();
|
||||
if (tag instanceof AddAdapter.ListItem) {
|
||||
AddAdapter.ListItem item = (AddAdapter.ListItem) tag;
|
||||
cleanup();
|
||||
switch (item.actionTag) {
|
||||
case AddAdapter.ITEM_APPLICATION: {
|
||||
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
|
||||
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
|
||||
pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);
|
||||
startActivityForResult(pickIntent, REQUEST_PICK_APPLICATION);
|
||||
break;
|
||||
}
|
||||
|
||||
case AddAdapter.ITEM_SHORTCUT: {
|
||||
Intent shortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
|
||||
|
||||
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
|
||||
pickIntent.putExtra(Intent.EXTRA_INTENT, shortcutIntent);
|
||||
pickIntent.putExtra(Intent.EXTRA_TITLE,
|
||||
getText(R.string.title_select_shortcut));
|
||||
startActivityForResult(pickIntent, REQUEST_PICK_SHORTCUT);
|
||||
break;
|
||||
}
|
||||
switch (which) {
|
||||
case AddAdapter.ITEM_SHORTCUT: {
|
||||
// Insert extra item to handle picking application
|
||||
Bundle bundle = new Bundle();
|
||||
|
||||
case AddAdapter.ITEM_SEARCH: {
|
||||
addSearch();
|
||||
break;
|
||||
}
|
||||
ArrayList<String> shortcutNames = new ArrayList<String>();
|
||||
shortcutNames.add(res.getString(R.string.group_applications));
|
||||
bundle.putStringArrayList(Intent.EXTRA_SHORTCUT_NAME, shortcutNames);
|
||||
|
||||
case AddAdapter.ITEM_APPWIDGET: {
|
||||
int appWidgetId = Launcher.this.mAppWidgetHost.allocateAppWidgetId();
|
||||
|
||||
Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
|
||||
pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
||||
startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);
|
||||
break;
|
||||
}
|
||||
ArrayList<ShortcutIconResource> shortcutIcons =
|
||||
new ArrayList<ShortcutIconResource>();
|
||||
shortcutIcons.add(ShortcutIconResource.fromContext(Launcher.this,
|
||||
R.drawable.ic_launcher_application));
|
||||
bundle.putParcelableArrayList(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcons);
|
||||
|
||||
case AddAdapter.ITEM_LIVE_FOLDER: {
|
||||
Intent liveFolderIntent = new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER);
|
||||
|
||||
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
|
||||
pickIntent.putExtra(Intent.EXTRA_INTENT, liveFolderIntent);
|
||||
pickIntent.putExtra(Intent.EXTRA_TITLE,
|
||||
getText(R.string.title_select_live_folder));
|
||||
startActivityForResult(pickIntent, REQUEST_PICK_LIVE_FOLDER);
|
||||
break;
|
||||
}
|
||||
|
||||
case AddAdapter.ITEM_FOLDER: {
|
||||
addFolder(!mDesktopLocked);
|
||||
dismissDialog(DIALOG_CREATE_SHORTCUT);
|
||||
break;
|
||||
}
|
||||
|
||||
case AddAdapter.ITEM_WALLPAPER: {
|
||||
startWallpaper();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
|
||||
pickIntent.putExtra(Intent.EXTRA_INTENT,
|
||||
new Intent(Intent.ACTION_CREATE_SHORTCUT));
|
||||
pickIntent.putExtra(Intent.EXTRA_TITLE,
|
||||
getText(R.string.title_select_shortcut));
|
||||
pickIntent.putExtras(bundle);
|
||||
|
||||
startActivityForResult(pickIntent, REQUEST_PICK_SHORTCUT);
|
||||
break;
|
||||
}
|
||||
|
||||
case AddAdapter.ITEM_APPWIDGET: {
|
||||
int appWidgetId = Launcher.this.mAppWidgetHost.allocateAppWidgetId();
|
||||
|
||||
Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
|
||||
pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
||||
// add the search widget
|
||||
ArrayList<AppWidgetProviderInfo> customInfo =
|
||||
new ArrayList<AppWidgetProviderInfo>();
|
||||
AppWidgetProviderInfo info = new AppWidgetProviderInfo();
|
||||
info.provider = new ComponentName(getPackageName(), "XXX.YYY");
|
||||
info.label = getString(R.string.group_search);
|
||||
info.icon = R.drawable.ic_search_widget;
|
||||
customInfo.add(info);
|
||||
pickIntent.putParcelableArrayListExtra(
|
||||
AppWidgetManager.EXTRA_CUSTOM_INFO, customInfo);
|
||||
ArrayList<Bundle> customExtras = new ArrayList<Bundle>();
|
||||
Bundle b = new Bundle();
|
||||
b.putString(EXTRA_CUSTOM_WIDGET, SEARCH_WIDGET);
|
||||
customExtras.add(b);
|
||||
pickIntent.putParcelableArrayListExtra(
|
||||
AppWidgetManager.EXTRA_CUSTOM_EXTRAS, customExtras);
|
||||
// start the pick activity
|
||||
startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);
|
||||
break;
|
||||
}
|
||||
|
||||
case AddAdapter.ITEM_LIVE_FOLDER: {
|
||||
// Insert extra item to handle inserting folder
|
||||
Bundle bundle = new Bundle();
|
||||
|
||||
ArrayList<String> shortcutNames = new ArrayList<String>();
|
||||
shortcutNames.add(res.getString(R.string.group_folder));
|
||||
bundle.putStringArrayList(Intent.EXTRA_SHORTCUT_NAME, shortcutNames);
|
||||
|
||||
ArrayList<ShortcutIconResource> shortcutIcons =
|
||||
new ArrayList<ShortcutIconResource>();
|
||||
shortcutIcons.add(ShortcutIconResource.fromContext(Launcher.this,
|
||||
R.drawable.ic_launcher_folder));
|
||||
bundle.putParcelableArrayList(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcons);
|
||||
|
||||
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
|
||||
pickIntent.putExtra(Intent.EXTRA_INTENT,
|
||||
new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER));
|
||||
pickIntent.putExtra(Intent.EXTRA_TITLE,
|
||||
getText(R.string.title_select_live_folder));
|
||||
pickIntent.putExtras(bundle);
|
||||
|
||||
startActivityForResult(pickIntent, REQUEST_PICK_LIVE_FOLDER);
|
||||
break;
|
||||
}
|
||||
|
||||
case AddAdapter.ITEM_WALLPAPER: {
|
||||
startWallpaper();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1742,23 +1818,47 @@ android.util.Log.d("Home", "setting grid adapter");
|
|||
private class ApplicationsIntentReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
boolean reloadWorkspace = false;
|
||||
android.util.Log.d("Home", "application intent received: " + intent.getAction());
|
||||
android.util.Log.d("Home", " --> " + intent.getData());
|
||||
if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
|
||||
if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
|
||||
removeShortcutsForPackage(intent.getData().getSchemeSpecificPart());
|
||||
} else {
|
||||
reloadWorkspace = true;
|
||||
}
|
||||
final String action = intent.getAction();
|
||||
final String packageName = intent.getData().getSchemeSpecificPart();
|
||||
final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
|
||||
|
||||
if (LauncherModel.DEBUG_LOADERS) {
|
||||
d(LauncherModel.LOG_TAG, "application intent received: " + action +
|
||||
", replacing=" + replacing);
|
||||
d(LauncherModel.LOG_TAG, " --> " + intent.getData());
|
||||
}
|
||||
removeDialog(DIALOG_CREATE_SHORTCUT);
|
||||
if (!reloadWorkspace) {
|
||||
android.util.Log.d("Home", " --> loading apps");
|
||||
sModel.loadApplications(false, Launcher.this, false);
|
||||
|
||||
if (!Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
|
||||
if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
|
||||
if (!replacing) {
|
||||
removeShortcutsForPackage(packageName);
|
||||
if (LauncherModel.DEBUG_LOADERS) {
|
||||
d(LauncherModel.LOG_TAG, " --> remove package");
|
||||
}
|
||||
sModel.removePackage(Launcher.this, packageName);
|
||||
}
|
||||
// else, we are replacing the package, so a PACKAGE_ADDED will be sent
|
||||
// later, we will update the package at this time
|
||||
} else {
|
||||
if (!replacing) {
|
||||
if (LauncherModel.DEBUG_LOADERS) {
|
||||
d(LauncherModel.LOG_TAG, " --> add package");
|
||||
}
|
||||
sModel.addPackage(Launcher.this, packageName);
|
||||
} else {
|
||||
if (LauncherModel.DEBUG_LOADERS) {
|
||||
d(LauncherModel.LOG_TAG, " --> update package " + packageName);
|
||||
}
|
||||
sModel.updatePackage(Launcher.this, packageName);
|
||||
updateShortcutsForPackage(packageName);
|
||||
}
|
||||
}
|
||||
removeDialog(DIALOG_CREATE_SHORTCUT);
|
||||
} else {
|
||||
android.util.Log.d("Home", " --> loading workspace");
|
||||
sModel.loadUserItems(false, Launcher.this, false, true);
|
||||
if (LauncherModel.DEBUG_LOADERS) {
|
||||
d(LauncherModel.LOG_TAG, " --> sync package " + packageName);
|
||||
}
|
||||
sModel.syncPackage(Launcher.this, packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1865,37 +1965,64 @@ android.util.Log.d("Home", " --> loading workspace");
|
|||
}
|
||||
}
|
||||
|
||||
private static class DesktopBinder extends Handler {
|
||||
private static class DesktopBinder extends Handler implements MessageQueue.IdleHandler {
|
||||
static final int MESSAGE_BIND_ITEMS = 0x1;
|
||||
static final int MESSAGE_BIND_APPWIDGETS = 0x2;
|
||||
|
||||
// Number of items to bind in every pass
|
||||
static final int ITEMS_COUNT = 6;
|
||||
static final int APPWIDGETS_COUNT = 1;
|
||||
|
||||
private final ArrayList<ItemInfo> mShortcuts;
|
||||
private final ArrayList<LauncherAppWidgetInfo> mAppWidgets;
|
||||
private final LinkedList<LauncherAppWidgetInfo> mAppWidgets;
|
||||
private final WeakReference<Launcher> mLauncher;
|
||||
|
||||
public volatile boolean mTerminate = false;
|
||||
|
||||
DesktopBinder(Launcher launcher, ArrayList<ItemInfo> shortcuts,
|
||||
ArrayList<LauncherAppWidgetInfo> appWidgets) {
|
||||
|
||||
mLauncher = new WeakReference<Launcher>(launcher);
|
||||
mShortcuts = shortcuts;
|
||||
mAppWidgets = appWidgets;
|
||||
|
||||
// Sort widgets so active workspace is bound first
|
||||
final int currentScreen = launcher.mWorkspace.getCurrentScreen();
|
||||
final int size = appWidgets.size();
|
||||
mAppWidgets = new LinkedList<LauncherAppWidgetInfo>();
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
LauncherAppWidgetInfo appWidgetInfo = appWidgets.get(i);
|
||||
if (appWidgetInfo.screen == currentScreen) {
|
||||
mAppWidgets.addFirst(appWidgetInfo);
|
||||
} else {
|
||||
mAppWidgets.addLast(appWidgetInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void startBindingItems() {
|
||||
obtainMessage(MESSAGE_BIND_ITEMS, 0, mShortcuts.size()).sendToTarget();
|
||||
}
|
||||
|
||||
public void startBindingAppWidgets() {
|
||||
obtainMessage(MESSAGE_BIND_APPWIDGETS, 0, mAppWidgets.size()).sendToTarget();
|
||||
|
||||
public void startBindingAppWidgetsWhenIdle() {
|
||||
// Ask for notification when message queue becomes idle
|
||||
final MessageQueue messageQueue = Looper.myQueue();
|
||||
messageQueue.addIdleHandler(this);
|
||||
}
|
||||
|
||||
public boolean queueIdle() {
|
||||
// Queue is idle, so start binding items
|
||||
startBindingAppWidgets();
|
||||
return false;
|
||||
}
|
||||
|
||||
public void startBindingAppWidgets() {
|
||||
obtainMessage(MESSAGE_BIND_APPWIDGETS).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
Launcher launcher = mLauncher.get();
|
||||
if (launcher == null) {
|
||||
if (launcher == null || mTerminate) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1905,7 +2032,7 @@ android.util.Log.d("Home", " --> loading workspace");
|
|||
break;
|
||||
}
|
||||
case MESSAGE_BIND_APPWIDGETS: {
|
||||
launcher.bindAppWidgets(this, mAppWidgets, msg.arg1, msg.arg2);
|
||||
launcher.bindAppWidgets(this, mAppWidgets);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,9 @@ import android.content.res.Resources;
|
|||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import static android.util.Log.*;
|
||||
import android.os.Process;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -46,13 +47,14 @@ import java.net.URISyntaxException;
|
|||
* for the Launcher.
|
||||
*/
|
||||
public class LauncherModel {
|
||||
static final boolean DEBUG_LOADERS = true;
|
||||
static final String LOG_TAG = "HomeLoaders";
|
||||
|
||||
private static final int UI_NOTIFICATION_RATE = 4;
|
||||
private static final int DEFAULT_APPLICATIONS_NUMBER = 42;
|
||||
private static final long APPLICATION_NOT_RESPONDING_TIMEOUT = 5000;
|
||||
private static final int INITIAL_ICON_CACHE_CAPACITY = 50;
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static final Collator sCollator = Collator.getInstance();
|
||||
|
||||
private boolean mApplicationsLoaded;
|
||||
|
@ -101,14 +103,16 @@ public class LauncherModel {
|
|||
*/
|
||||
synchronized boolean loadApplications(boolean isLaunching, Launcher launcher,
|
||||
boolean localeChanged) {
|
||||
android.util.Log.d("Home", "load applications");
|
||||
|
||||
if (DEBUG_LOADERS) d(LOG_TAG, "load applications");
|
||||
|
||||
if (isLaunching && mApplicationsLoaded && !localeChanged) {
|
||||
mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications);
|
||||
android.util.Log.d("Home", " --> applications loaded, return");
|
||||
if (DEBUG_LOADERS) d(LOG_TAG, " --> applications loaded, return");
|
||||
return false;
|
||||
}
|
||||
|
||||
waitForApplicationsLoader();
|
||||
stopAndWaitForApplicationsLoader();
|
||||
|
||||
if (localeChanged) {
|
||||
dropApplicationCache();
|
||||
|
@ -129,9 +133,9 @@ android.util.Log.d("Home", " --> applications loaded, return");
|
|||
return true;
|
||||
}
|
||||
|
||||
private synchronized void waitForApplicationsLoader() {
|
||||
private synchronized void stopAndWaitForApplicationsLoader() {
|
||||
if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
|
||||
android.util.Log.d("Home", " --> wait for applications loader");
|
||||
if (DEBUG_LOADERS) d(LOG_TAG, " --> wait for applications loader");
|
||||
|
||||
mApplicationsLoader.stop();
|
||||
// Wait for the currently running thread to finish, this can take a little
|
||||
|
@ -145,14 +149,310 @@ android.util.Log.d("Home", " --> applications loaded, return");
|
|||
}
|
||||
|
||||
private synchronized void startApplicationsLoader(Launcher launcher) {
|
||||
android.util.Log.d("Home", " --> starting applications loader");
|
||||
waitForApplicationsLoader();
|
||||
if (DEBUG_LOADERS) d(LOG_TAG, " --> starting applications loader");
|
||||
|
||||
stopAndWaitForApplicationsLoader();
|
||||
|
||||
mApplicationsLoader = new ApplicationsLoader(launcher);
|
||||
mApplicationsLoaderThread = new Thread(mApplicationsLoader, "Applications Loader");
|
||||
mApplicationsLoaderThread.start();
|
||||
}
|
||||
|
||||
synchronized void addPackage(Launcher launcher, String packageName) {
|
||||
if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
|
||||
startApplicationsLoader(launcher);
|
||||
return;
|
||||
}
|
||||
|
||||
if (packageName != null && packageName.length() > 0) {
|
||||
final PackageManager packageManager = launcher.getPackageManager();
|
||||
final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);
|
||||
|
||||
if (matches.size() > 0) {
|
||||
final ApplicationsAdapter adapter = mApplicationsAdapter;
|
||||
final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;
|
||||
|
||||
for (ResolveInfo info : matches) {
|
||||
adapter.setNotifyOnChange(false);
|
||||
adapter.add(makeAndCacheApplicationInfo(packageManager, cache, info));
|
||||
}
|
||||
|
||||
adapter.sort(new ApplicationInfoComparator());
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void removePackage(Launcher launcher, String packageName) {
|
||||
if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
|
||||
dropApplicationCache(); // TODO: this could be optimized
|
||||
startApplicationsLoader(launcher);
|
||||
return;
|
||||
}
|
||||
|
||||
if (packageName != null && packageName.length() > 0) {
|
||||
final ApplicationsAdapter adapter = mApplicationsAdapter;
|
||||
|
||||
final List<ApplicationInfo> toRemove = new ArrayList<ApplicationInfo>();
|
||||
final int count = adapter.getCount();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
final ApplicationInfo applicationInfo = adapter.getItem(i);
|
||||
final Intent intent = applicationInfo.intent;
|
||||
final ComponentName component = intent.getComponent();
|
||||
if (packageName.equals(component.getPackageName())) {
|
||||
toRemove.add(applicationInfo);
|
||||
}
|
||||
}
|
||||
|
||||
final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;
|
||||
for (ApplicationInfo info : toRemove) {
|
||||
adapter.setNotifyOnChange(false);
|
||||
adapter.remove(info);
|
||||
cache.remove(info.intent.getComponent());
|
||||
}
|
||||
|
||||
if (toRemove.size() > 0) {
|
||||
adapter.sort(new ApplicationInfoComparator());
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void updatePackage(Launcher launcher, String packageName) {
|
||||
if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
|
||||
startApplicationsLoader(launcher);
|
||||
return;
|
||||
}
|
||||
|
||||
if (packageName != null && packageName.length() > 0) {
|
||||
final PackageManager packageManager = launcher.getPackageManager();
|
||||
final ApplicationsAdapter adapter = mApplicationsAdapter;
|
||||
|
||||
final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);
|
||||
final int count = matches.size();
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
final ResolveInfo info = matches.get(i);
|
||||
final ApplicationInfo applicationInfo = findIntent(adapter,
|
||||
info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
|
||||
if (applicationInfo != null) {
|
||||
updateAndCacheApplicationInfo(packageManager, info, applicationInfo);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
adapter.sort(new ApplicationInfoComparator());
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAndCacheApplicationInfo(PackageManager packageManager, ResolveInfo info,
|
||||
ApplicationInfo applicationInfo) {
|
||||
|
||||
updateApplicationInfoTitleAndIcon(packageManager, info, applicationInfo);
|
||||
|
||||
ComponentName componentName = new ComponentName(
|
||||
info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
|
||||
mAppInfoCache.put(componentName, applicationInfo);
|
||||
}
|
||||
|
||||
synchronized void syncPackage(Launcher launcher, String packageName) {
|
||||
if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
|
||||
startApplicationsLoader(launcher);
|
||||
return;
|
||||
}
|
||||
|
||||
if (packageName != null && packageName.length() > 0) {
|
||||
final PackageManager packageManager = launcher.getPackageManager();
|
||||
final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);
|
||||
|
||||
if (matches.size() > 0) {
|
||||
final ApplicationsAdapter adapter = mApplicationsAdapter;
|
||||
|
||||
// Find disabled activities and remove them from the adapter
|
||||
boolean removed = removeDisabledActivities(packageName, matches, adapter);
|
||||
// Find enable activities and add them to the adapter
|
||||
// Also updates existing activities with new labels/icons
|
||||
boolean added = addEnabledAndUpdateActivities(matches, adapter, launcher);
|
||||
|
||||
if (added || removed) {
|
||||
adapter.sort(new ApplicationInfoComparator());
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<ResolveInfo> findActivitiesForPackage(PackageManager packageManager,
|
||||
String packageName) {
|
||||
|
||||
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
|
||||
final List<ResolveInfo> apps = packageManager.queryIntentActivities(mainIntent, 0);
|
||||
final List<ResolveInfo> matches = new ArrayList<ResolveInfo>();
|
||||
|
||||
if (apps != null) {
|
||||
// Find all activities that match the packageName
|
||||
int count = apps.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final ResolveInfo info = apps.get(i);
|
||||
final ActivityInfo activityInfo = info.activityInfo;
|
||||
if (packageName.equals(activityInfo.packageName)) {
|
||||
matches.add(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
private boolean addEnabledAndUpdateActivities(List<ResolveInfo> matches,
|
||||
ApplicationsAdapter adapter, Launcher launcher) {
|
||||
|
||||
final List<ApplicationInfo> toAdd = new ArrayList<ApplicationInfo>();
|
||||
final int count = matches.size();
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
final ResolveInfo info = matches.get(i);
|
||||
final ApplicationInfo applicationInfo = findIntent(adapter,
|
||||
info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
|
||||
if (applicationInfo == null) {
|
||||
toAdd.add(makeAndCacheApplicationInfo(launcher.getPackageManager(),
|
||||
mAppInfoCache, info));
|
||||
changed = true;
|
||||
} else {
|
||||
updateAndCacheApplicationInfo(launcher.getPackageManager(), info, applicationInfo);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (ApplicationInfo info : toAdd) {
|
||||
adapter.setNotifyOnChange(false);
|
||||
adapter.add(info);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
private boolean removeDisabledActivities(String packageName, List<ResolveInfo> matches,
|
||||
ApplicationsAdapter adapter) {
|
||||
|
||||
final List<ApplicationInfo> toRemove = new ArrayList<ApplicationInfo>();
|
||||
final int count = adapter.getCount();
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
final ApplicationInfo applicationInfo = adapter.getItem(i);
|
||||
final Intent intent = applicationInfo.intent;
|
||||
final ComponentName component = intent.getComponent();
|
||||
if (packageName.equals(component.getPackageName())) {
|
||||
if (!findIntent(matches, component)) {
|
||||
toRemove.add(applicationInfo);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;
|
||||
for (ApplicationInfo info : toRemove) {
|
||||
adapter.setNotifyOnChange(false);
|
||||
adapter.remove(info);
|
||||
cache.remove(info.intent.getComponent());
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
private static ApplicationInfo findIntent(ApplicationsAdapter adapter, String packageName,
|
||||
String name) {
|
||||
|
||||
final int count = adapter.getCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final ApplicationInfo applicationInfo = adapter.getItem(i);
|
||||
final Intent intent = applicationInfo.intent;
|
||||
final ComponentName component = intent.getComponent();
|
||||
if (packageName.equals(component.getPackageName()) &&
|
||||
name.equals(component.getClassName())) {
|
||||
return applicationInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean findIntent(List<ResolveInfo> apps, ComponentName component) {
|
||||
final String className = component.getClassName();
|
||||
for (ResolveInfo info : apps) {
|
||||
final ActivityInfo activityInfo = info.activityInfo;
|
||||
if (activityInfo.name.equals(className)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Drawable getApplicationInfoIcon(PackageManager manager, ApplicationInfo info) {
|
||||
final ResolveInfo resolveInfo = manager.resolveActivity(info.intent, 0);
|
||||
if (resolveInfo == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ComponentName componentName = new ComponentName(
|
||||
resolveInfo.activityInfo.applicationInfo.packageName,
|
||||
resolveInfo.activityInfo.name);
|
||||
ApplicationInfo application = mAppInfoCache.get(componentName);
|
||||
|
||||
if (application == null) {
|
||||
return resolveInfo.activityInfo.loadIcon(manager);
|
||||
}
|
||||
|
||||
return application.icon;
|
||||
}
|
||||
|
||||
private static ApplicationInfo makeAndCacheApplicationInfo(PackageManager manager,
|
||||
HashMap<ComponentName, ApplicationInfo> appInfoCache, ResolveInfo info) {
|
||||
|
||||
ComponentName componentName = new ComponentName(
|
||||
info.activityInfo.applicationInfo.packageName,
|
||||
info.activityInfo.name);
|
||||
ApplicationInfo application = appInfoCache.get(componentName);
|
||||
|
||||
if (application == null) {
|
||||
application = new ApplicationInfo();
|
||||
application.container = ItemInfo.NO_ID;
|
||||
|
||||
updateApplicationInfoTitleAndIcon(manager, info, application);
|
||||
|
||||
application.setActivity(componentName,
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
|
||||
|
||||
appInfoCache.put(componentName, application);
|
||||
}
|
||||
|
||||
return application;
|
||||
}
|
||||
|
||||
private static void updateApplicationInfoTitleAndIcon(PackageManager manager, ResolveInfo info,
|
||||
ApplicationInfo application) {
|
||||
|
||||
application.title = info.loadLabel(manager);
|
||||
if (application.title == null) {
|
||||
application.title = info.activityInfo.name;
|
||||
}
|
||||
|
||||
application.icon = info.activityInfo.loadIcon(manager);
|
||||
application.filtered = false;
|
||||
}
|
||||
|
||||
private class ApplicationsLoader implements Runnable {
|
||||
private final WeakReference<Launcher> mLauncher;
|
||||
|
||||
|
@ -176,7 +476,7 @@ android.util.Log.d("Home", " --> starting applications loader");
|
|||
|
||||
android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
||||
|
||||
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
|
||||
final Launcher launcher = mLauncher.get();
|
||||
|
@ -185,6 +485,8 @@ android.util.Log.d("Home", " --> starting applications loader");
|
|||
|
||||
if (apps != null && !mStopped) {
|
||||
final int count = apps.size();
|
||||
// Can be set to null on the UI thread by the unbind() method
|
||||
// Do not access without checking for null first
|
||||
final ApplicationsAdapter applicationList = mApplicationsAdapter;
|
||||
|
||||
ChangeNotifier action = new ChangeNotifier(applicationList, true);
|
||||
|
@ -192,28 +494,10 @@ android.util.Log.d("Home", " --> starting applications loader");
|
|||
|
||||
for (int i = 0; i < count && !mStopped; i++) {
|
||||
ResolveInfo info = apps.get(i);
|
||||
ComponentName componentName = new ComponentName(
|
||||
info.activityInfo.applicationInfo.packageName,
|
||||
info.activityInfo.name);
|
||||
ApplicationInfo application = appInfoCache.get(componentName);
|
||||
if (application == null) {
|
||||
application = new ApplicationInfo();
|
||||
application.title = info.loadLabel(manager);
|
||||
if (application.title == null) {
|
||||
application.title = info.activityInfo.name;
|
||||
}
|
||||
application.setActivity(componentName,
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK |
|
||||
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
|
||||
application.container = ItemInfo.NO_ID;
|
||||
application.icon = info.activityInfo.loadIcon(manager);
|
||||
if (DEBUG) {
|
||||
Log.d(Launcher.LOG_TAG, "Loaded ApplicationInfo for " + componentName);
|
||||
}
|
||||
appInfoCache.put(componentName, application);
|
||||
}
|
||||
ApplicationInfo application =
|
||||
makeAndCacheApplicationInfo(manager, appInfoCache, info);
|
||||
|
||||
if (action.add(application)) {
|
||||
if (action.add(application) && !mStopped) {
|
||||
launcher.runOnUiThread(action);
|
||||
action = new ChangeNotifier(applicationList, false);
|
||||
}
|
||||
|
@ -229,7 +513,7 @@ android.util.Log.d("Home", " --> starting applications loader");
|
|||
}
|
||||
}
|
||||
|
||||
private static class ChangeNotifier implements Runnable, Comparator<ApplicationInfo> {
|
||||
private static class ChangeNotifier implements Runnable {
|
||||
private final ApplicationsAdapter mApplicationList;
|
||||
private final ArrayList<ApplicationInfo> mBuffer;
|
||||
|
||||
|
@ -243,6 +527,8 @@ android.util.Log.d("Home", " --> starting applications loader");
|
|||
|
||||
public void run() {
|
||||
final ApplicationsAdapter applicationList = mApplicationList;
|
||||
// Can be set to null on the UI thread by the unbind() method
|
||||
if (applicationList == null) return;
|
||||
|
||||
if (mFirst) {
|
||||
applicationList.setNotifyOnChange(false);
|
||||
|
@ -260,7 +546,7 @@ android.util.Log.d("Home", " --> starting applications loader");
|
|||
|
||||
buffer.clear();
|
||||
|
||||
applicationList.sort(this);
|
||||
applicationList.sort(new ApplicationInfoComparator());
|
||||
applicationList.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
@ -269,7 +555,9 @@ android.util.Log.d("Home", " --> starting applications loader");
|
|||
buffer.add(application);
|
||||
return buffer.size() >= UI_NOTIFICATION_RATE;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ApplicationInfoComparator implements Comparator<ApplicationInfo> {
|
||||
public final int compare(ApplicationInfo a, ApplicationInfo b) {
|
||||
return sCollator.compare(a.title.toString(), b.title.toString());
|
||||
}
|
||||
|
@ -285,10 +573,10 @@ android.util.Log.d("Home", " --> starting applications loader");
|
|||
*/
|
||||
void loadUserItems(boolean isLaunching, Launcher launcher, boolean localeChanged,
|
||||
boolean loadApplications) {
|
||||
android.util.Log.d("Home", "loading user items");
|
||||
if (DEBUG_LOADERS) d(LOG_TAG, "loading user items");
|
||||
|
||||
if (isLaunching && isDesktopLoaded()) {
|
||||
android.util.Log.d("Home", " --> items loaded, return");
|
||||
if (DEBUG_LOADERS) d(LOG_TAG, " --> items loaded, return");
|
||||
if (loadApplications) startApplicationsLoader(launcher);
|
||||
// We have already loaded our data from the DB
|
||||
launcher.onDesktopItemsLoaded();
|
||||
|
@ -306,7 +594,7 @@ android.util.Log.d("Home", " --> items loaded, return");
|
|||
}
|
||||
}
|
||||
|
||||
android.util.Log.d("Home", " --> starting workspace loader");
|
||||
if (DEBUG_LOADERS) d(LOG_TAG, " --> starting workspace loader");
|
||||
mDesktopItemsLoaded = false;
|
||||
mDesktopItemsLoader = new DesktopItemsLoader(launcher, localeChanged, loadApplications);
|
||||
mDesktopLoaderThread = new Thread(mDesktopItemsLoader, "Desktop Items Loader");
|
||||
|
@ -563,7 +851,7 @@ android.util.Log.d("Home", " --> starting workspace loader");
|
|||
|
||||
container = c.getInt(containerIndex);
|
||||
if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
|
||||
Log.e(Launcher.LOG_TAG, "Widget found where container "
|
||||
e(Launcher.LOG_TAG, "Widget found where container "
|
||||
+ "!= CONTAINER_DESKTOP ignoring!");
|
||||
continue;
|
||||
}
|
||||
|
@ -589,7 +877,7 @@ android.util.Log.d("Home", " --> starting workspace loader");
|
|||
|
||||
container = c.getInt(containerIndex);
|
||||
if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
|
||||
Log.e(Launcher.LOG_TAG, "Widget found where container "
|
||||
e(Launcher.LOG_TAG, "Widget found where container "
|
||||
+ "!= CONTAINER_DESKTOP -- ignoring!");
|
||||
continue;
|
||||
}
|
||||
|
@ -599,7 +887,7 @@ android.util.Log.d("Home", " --> starting workspace loader");
|
|||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.w(Launcher.LOG_TAG, "Desktop items loading interrupted:", e);
|
||||
w(Launcher.LOG_TAG, "Desktop items loading interrupted:", e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
@ -699,6 +987,8 @@ android.util.Log.d("Home", " --> starting workspace loader");
|
|||
* Home screen on orientation change.
|
||||
*/
|
||||
void unbind() {
|
||||
// Interrupt the applications loader before setting the adapter to null
|
||||
stopAndWaitForApplicationsLoader();
|
||||
mApplicationsAdapter = null;
|
||||
unbindAppDrawables(mApplications);
|
||||
unbindDrawables(mDesktopItems);
|
||||
|
|
|
@ -24,6 +24,8 @@ import android.content.Intent;
|
|||
import android.content.ComponentName;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
@ -33,19 +35,17 @@ import android.database.Cursor;
|
|||
import android.database.SQLException;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
import android.util.AttributeSet;
|
||||
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 java.util.ArrayList;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import com.android.internal.util.XmlUtils;
|
||||
import com.android.launcher.LauncherSettings.Favorites;
|
||||
|
||||
|
@ -162,19 +162,10 @@ public class LauncherProvider extends ContentProvider {
|
|||
}
|
||||
|
||||
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 static final String TAG_CLOCK = "clock";
|
||||
private static final String TAG_SEARCH = "search";
|
||||
|
||||
private final Context mContext;
|
||||
private final AppWidgetHost mAppWidgetHost;
|
||||
|
@ -217,7 +208,7 @@ public class LauncherProvider extends ContentProvider {
|
|||
|
||||
if (!convertDatabase(db)) {
|
||||
// Populate favorites table with initial favorites
|
||||
loadFavorites(db, DEFAULT_FAVORITES_PATH);
|
||||
loadFavorites(db);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,115 +436,122 @@ public class LauncherProvider extends ContentProvider {
|
|||
* 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;
|
||||
}
|
||||
|
||||
private int loadFavorites(SQLiteDatabase db) {
|
||||
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);
|
||||
|
||||
XmlResourceParser parser = mContext.getResources().getXml(R.xml.default_workspace);
|
||||
AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
XmlUtils.beginDocument(parser, TAG_FAVORITES);
|
||||
|
||||
while (true) {
|
||||
XmlUtils.nextElement(parser);
|
||||
final int depth = parser.getDepth();
|
||||
|
||||
String name = parser.getName();
|
||||
if (!TAG_FAVORITE.equals(name)) {
|
||||
break;
|
||||
int type;
|
||||
while (((type = parser.next()) != XmlPullParser.END_TAG ||
|
||||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
|
||||
|
||||
if (type != XmlPullParser.START_TAG) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
boolean added = false;
|
||||
final String name = parser.getName();
|
||||
|
||||
TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.Favorite);
|
||||
|
||||
values.clear();
|
||||
values.put(LauncherSettings.Favorites.CONTAINER,
|
||||
LauncherSettings.Favorites.CONTAINER_DESKTOP);
|
||||
values.put(LauncherSettings.Favorites.SCREEN,
|
||||
a.getString(R.styleable.Favorite_screen));
|
||||
values.put(LauncherSettings.Favorites.CELLX,
|
||||
a.getString(R.styleable.Favorite_x));
|
||||
values.put(LauncherSettings.Favorites.CELLY,
|
||||
a.getString(R.styleable.Favorite_y));
|
||||
|
||||
if (TAG_FAVORITE.equals(name)) {
|
||||
added = addShortcut(db, values, a, packageManager, intent);
|
||||
} else if (TAG_SEARCH.equals(name)) {
|
||||
added = addSearchWidget(db, values);
|
||||
} else if (TAG_CLOCK.equals(name)) {
|
||||
added = addClockWidget(db, values);
|
||||
}
|
||||
|
||||
if (added) i++;
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
} catch (XmlPullParserException e) {
|
||||
Log.w(LOG_TAG, "Got exception parsing favorites.", e);
|
||||
} catch (IOException e) {
|
||||
Log.w(LOG_TAG, "Got exception parsing favorites.", e);
|
||||
}
|
||||
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
private boolean addShortcut(SQLiteDatabase db, ContentValues values, TypedArray a,
|
||||
PackageManager packageManager, Intent intent) {
|
||||
|
||||
ActivityInfo info;
|
||||
String packageName = a.getString(R.styleable.Favorite_packageName);
|
||||
String className = a.getString(R.styleable.Favorite_className);
|
||||
try {
|
||||
ComponentName cn = new ComponentName(packageName, className);
|
||||
info = packageManager.getActivityInfo(cn, 0);
|
||||
intent.setComponent(cn);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
|
||||
values.put(Favorites.INTENT, intent.toURI());
|
||||
values.put(Favorites.TITLE, info.loadLabel(packageManager).toString());
|
||||
values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_APPLICATION);
|
||||
values.put(Favorites.SPANX, 1);
|
||||
values.put(Favorites.SPANY, 1);
|
||||
db.insert(TABLE_FAVORITES, null, values);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.w(LOG_TAG, "Unable to add favorite: " + packageName +
|
||||
"/" + className, e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean addSearchWidget(SQLiteDatabase db, ContentValues 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);
|
||||
values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_WIDGET_SEARCH);
|
||||
values.put(Favorites.SPANX, 4);
|
||||
values.put(Favorites.SPANY, 1);
|
||||
db.insert(TABLE_FAVORITES, null, values);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean addClockWidget(SQLiteDatabase db, ContentValues values) {
|
||||
final int[] bindSources = new int[] {
|
||||
Favorites.ITEM_TYPE_WIDGET_CLOCK,
|
||||
};
|
||||
|
||||
|
||||
final ArrayList<ComponentName> bindTargets = new ArrayList<ComponentName>();
|
||||
bindTargets.add(new ComponentName("com.android.alarmclock",
|
||||
"com.android.alarmclock.AnalogAppWidgetProvider"));
|
||||
|
||||
|
||||
boolean allocatedAppWidgets = false;
|
||||
|
||||
|
||||
// Try binding to an analog clock widget
|
||||
try {
|
||||
int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
|
||||
|
||||
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);
|
||||
values.put(LauncherSettings.Favorites.APPWIDGET_ID, appWidgetId);
|
||||
|
||||
values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_WIDGET_CLOCK);
|
||||
values.put(Favorites.SPANX, 2);
|
||||
values.put(Favorites.SPANY, 2);
|
||||
values.put(Favorites.APPWIDGET_ID, appWidgetId);
|
||||
db.insert(TABLE_FAVORITES, null, values);
|
||||
|
||||
|
||||
allocatedAppWidgets = true;
|
||||
} catch (RuntimeException ex) {
|
||||
Log.e(LOG_TAG, "Problem allocating appWidgetId", ex);
|
||||
|
@ -563,8 +561,8 @@ public class LauncherProvider extends ContentProvider {
|
|||
if (allocatedAppWidgets) {
|
||||
launchAppWidgetBinder(bindSources, bindTargets);
|
||||
}
|
||||
|
||||
return i;
|
||||
|
||||
return allocatedAppWidgets;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,13 @@ public class LiveFolder extends Folder {
|
|||
if (mLoadingTask != null && mLoadingTask.getStatus() == AsyncTask.Status.RUNNING) {
|
||||
mLoadingTask.cancel(true);
|
||||
}
|
||||
((LiveFolderAdapter) mContent.getAdapter()).cleanup();
|
||||
|
||||
// The adapter can be null if onClose() is called before FolderLoadingTask
|
||||
// is done querying the provider
|
||||
final LiveFolderAdapter adapter = (LiveFolderAdapter) mContent.getAdapter();
|
||||
if (adapter != null) {
|
||||
adapter.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
static class FolderLoadingTask extends AsyncTask<LiveFolderInfo, Void, Cursor> {
|
||||
|
|
|
@ -26,6 +26,7 @@ import android.graphics.Paint;
|
|||
import android.graphics.RectF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.VelocityTracker;
|
||||
|
@ -34,6 +35,7 @@ import android.view.ViewConfiguration;
|
|||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.Scroller;
|
||||
import android.widget.TextView;
|
||||
import android.os.Parcelable;
|
||||
import android.os.Parcel;
|
||||
|
||||
|
@ -1240,7 +1242,41 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void updateShortcutsForPackage(String packageName) {
|
||||
final int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final CellLayout layout = (CellLayout) getChildAt(i);
|
||||
int childCount = layout.getChildCount();
|
||||
for (int j = 0; j < childCount; j++) {
|
||||
final View view = layout.getChildAt(j);
|
||||
Object tag = view.getTag();
|
||||
if (tag instanceof ApplicationInfo) {
|
||||
ApplicationInfo info = (ApplicationInfo) tag;
|
||||
// We need to check for ACTION_MAIN otherwise getComponent() might
|
||||
// return null for some shortcuts (for instance, for shortcuts to
|
||||
// web pages.)
|
||||
final Intent intent = info.intent;
|
||||
final ComponentName name = intent.getComponent();
|
||||
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
|
||||
Intent.ACTION_MAIN.equals(intent.getAction()) && name != null &&
|
||||
packageName.equals(name.getPackageName())) {
|
||||
|
||||
final Drawable icon = Launcher.getModel().getApplicationInfoIcon(
|
||||
mLauncher.getPackageManager(), info);
|
||||
if (icon != null && icon != info.icon) {
|
||||
info.icon.setCallback(null);
|
||||
info.icon = Utilities.createIconThumbnail(icon, mContext);
|
||||
info.filtered = true;
|
||||
((TextView) view).setCompoundDrawablesWithIntrinsicBounds(null,
|
||||
info.icon, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove widgets when appwidgetmanager tells us they're gone
|
||||
// void removeAppWidgetsForProvider() {
|
||||
// }
|
||||
|
|