diff options
64 files changed, 1783 insertions, 604 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 00c959a..9a85dc0 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -128,7 +128,6 @@ <!-- Top-level settings --> <activity android:name="Settings$WifiSettingsActivity" - android:uiOptions="splitActionBarWhenNarrow" android:taskAffinity="" android:label="@string/wifi_settings" android:configChanges="orientation|keyboardHidden|screenSize" @@ -148,7 +147,6 @@ <!-- Keep compatibility with old shortcuts. --> <activity-alias android:name=".wifi.WifiSettings" - android:uiOptions="splitActionBarWhenNarrow" android:taskAffinity="com.android.settings" android:label="@string/wifi_settings" android:targetActivity="Settings$WifiSettingsActivity" @@ -161,7 +159,6 @@ </activity-alias> <activity android:name=".wifi.WifiPickerActivity" - android:uiOptions="splitActionBarWhenNarrow" android:taskAffinity="com.android.settings" android:parentActivityName="Settings"> <intent-filter> @@ -172,7 +169,6 @@ </activity> <activity android:name=".wifi.WifiSetupActivity" - android:uiOptions="splitActionBarWhenNarrow" android:theme="@style/SetupWizardWifiTheme" android:label="@string/wifi_setup_wizard_title" android:icon="@drawable/empty_icon" @@ -185,7 +181,6 @@ </activity> <activity android:name=".wifi.WifiSettingsForSetupWizardXL" - android:uiOptions="splitActionBarWhenNarrow" android:theme="@android:style/Theme.Holo.NoActionBar" android:screenOrientation="behind" android:clearTaskOnLaunch="true" @@ -273,7 +268,6 @@ </activity> <activity android:name="Settings$BluetoothSettingsActivity" - android:uiOptions="splitActionBarWhenNarrow" android:label="@string/bluetooth_settings_title" android:taskAffinity="" android:excludeFromRecents="true"> @@ -292,7 +286,6 @@ <!-- Keep compatibility with old shortcuts. --> <activity-alias android:name=".bluetooth.BluetoothSettings" - android:uiOptions="splitActionBarWhenNarrow" android:label="@string/bluetooth_settings_title" android:targetActivity="Settings$BluetoothSettingsActivity" android:exported="true" @@ -304,7 +297,6 @@ </activity-alias> <activity android:name=".bluetooth.DevicePickerActivity" - android:uiOptions="splitActionBarWhenNarrow" android:theme="@android:style/Theme.Holo.DialogWhenLarge" android:label="@string/device_picker" android:clearTaskOnLaunch="true"> @@ -343,7 +335,6 @@ </activity-alias> <activity android:name="Settings$WifiP2pSettingsActivity" - android:uiOptions="splitActionBarWhenNarrow" android:taskAffinity="com.android.settings" android:parentActivityName="Settings$WifiSettingsActivity"> <intent-filter> @@ -805,7 +796,6 @@ --> <activity android:name="Settings$LocationSettingsActivity" - android:uiOptions="splitActionBarWhenNarrow" android:label="@string/location_settings_title" android:configChanges="orientation|keyboardHidden|screenSize" android:taskAffinity="" @@ -1616,7 +1606,6 @@ </activity> <activity android:name="Settings$DreamSettingsActivity" - android:uiOptions="splitActionBarWhenNarrow" android:label="@string/screensaver_settings_title" android:taskAffinity="" android:excludeFromRecents="true"> @@ -1633,7 +1622,6 @@ </activity> <activity android:name="Settings$UserSettingsActivity" - android:uiOptions="splitActionBarWhenNarrow" android:label="@string/user_settings_title" android:taskAffinity="" android:excludeFromRecents="true"> @@ -1649,7 +1637,6 @@ </activity> <activity android:name="Settings$PaymentSettingsActivity" - android:uiOptions="splitActionBarWhenNarrow" android:label="@string/nfc_payment_settings_title" android:taskAffinity="" android:excludeFromRecents="true"> diff --git a/res/layout/search_result_item.xml b/res/layout/search_result_item.xml index 6fa6d98..30d6fc0 100644 --- a/res/layout/search_result_item.xml +++ b/res/layout/search_result_item.xml @@ -22,6 +22,25 @@ android:paddingStart="@*android:dimen/preference_item_padding_side" android:paddingEnd="?android:attr/scrollbarSize"> + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center" + android:minWidth="@*android:dimen/preference_icon_minWidth" + android:orientation="horizontal"> + + <ImageView + android:id="@+id/icon" + android:layout_width="48dp" + android:layout_height="48dp" + android:layout_gravity="center" + android:minWidth="48dp" + android:scaleType="centerInside" + android:layout_marginEnd="@*android:dimen/preference_item_padding_inner" + /> + + </LinearLayout> + <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -49,23 +68,4 @@ </RelativeLayout> - <LinearLayout - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:gravity="center" - android:minWidth="@*android:dimen/preference_icon_minWidth" - android:orientation="horizontal"> - - <ImageView - android:id="@+id/icon" - android:layout_width="48dp" - android:layout_height="48dp" - android:layout_gravity="center" - android:minWidth="48dp" - android:scaleType="centerInside" - android:layout_marginEnd="@*android:dimen/preference_item_padding_inner" - /> - - </LinearLayout> - </LinearLayout> diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index f000927..eed0ced 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -432,8 +432,8 @@ <string name="device_admin_title" msgid="3562216873644263804">"Администриране на устройство"</string> <string name="manage_device_admin" msgid="5059296715271077278">"Администратори на устройството"</string> <string name="manage_device_admin_summary" msgid="7672709110988761075">"Преглед или деактивиране на администраторите на устройството"</string> - <string name="manage_trust_agents" msgid="4629279457536987768">"Надеждни агенти"</string> - <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Преглед или деактивиране на надеждните агенти"</string> + <string name="manage_trust_agents" msgid="4629279457536987768">"Trust agents"</string> + <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Преглед или деактивиране на trust agents"</string> <string name="manage_notification_access" msgid="5799781079264981979">"Достъп до известията"</string> <string name="manage_notification_access_summary_zero" msgid="2409912785614953348">"Приложенията не могат да четат известията"</string> <plurals name="manage_notification_access_summary_nonzero"> @@ -1716,7 +1716,7 @@ <string name="remove_device_admin" msgid="3596845261596451437">"Деактивиране"</string> <string name="select_device_admin_msg" msgid="2645509057946368094">"Администратори на устройство"</string> <string name="no_device_admins" msgid="702695100241728775">"Няма налични администратори на устройство"</string> - <string name="no_trust_agents" msgid="7450273545568977523">"Няма налични надеждни агенти"</string> + <string name="no_trust_agents" msgid="7450273545568977523">"Няма налични trust agents"</string> <string name="add_device_admin_msg" msgid="6246742476064507965">"Да се активира ли администраторът на устройството?"</string> <string name="add_device_admin" msgid="7133327675884827091">"Активиране"</string> <string name="device_admin_add_title" msgid="7705551449705676363">"Администратор на устройство"</string> diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index aafbd04..b0d7b49 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -1024,8 +1024,8 @@ <string name="location_neighborhood_level" msgid="5626515380188353712">"Permet que les aplicacions utilitzin el servei d\'ubicació de Google per calcular la teva ubicació més ràpidament. Es recopilaran dades d\'ubicació anònimes i s\'enviaran a Google."</string> <string name="location_neighborhood_level_wifi" msgid="4234820941954812210">"Ubicació determinada per Wi-Fi"</string> <string name="location_gps" msgid="8392461023569708478">"Satèl·lits GPS"</string> - <string name="location_street_level" product="tablet" msgid="1669562198260860802">"Permet que les aplicacions utilitzin el GPS de la tauleta per determinar la teva ubicació"</string> - <string name="location_street_level" product="default" msgid="4617445745492014203">"Permet que les aplicacions utilitzin el GPS del telèfon per determinar la teva ubicació"</string> + <string name="location_street_level" product="tablet" msgid="1669562198260860802">"Permet que les aplicacions utilitzin el GPS de la tauleta per determinar la teva ubicació exacta"</string> + <string name="location_street_level" product="default" msgid="4617445745492014203">"Permet que les aplicacions utilitzin el GPS del telèfon per determinar la teva ubicació exacta"</string> <string name="assisted_gps" msgid="4649317129586736885">"Utilitza GPS assistit"</string> <string name="assisted_gps_enabled" msgid="8751899609589792803">"Utilitza el servidor per ajudar al GPS (desmarqueu-ho per reduir l\'ús de la xarxa)"</string> <string name="assisted_gps_disabled" msgid="6982698333968010748">"Utilitza el servidor per ajudar al GPS (desmarqueu-ho per millorar el rendiment del GPS)"</string> diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 5d47a8a..7a293ca 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -2096,7 +2096,7 @@ <string name="dashboard_title" msgid="5453710313046681820">"Nastavení"</string> <string name="search_results_title" msgid="1796252422574886932">"Nastavení"</string> <string name="search_menu" msgid="7053532283559077164">"Vyhledávání"</string> - <string name="query_hint_text" msgid="3350700807437473939">"Nastavení vyhledávání"</string> + <string name="query_hint_text" msgid="3350700807437473939">"Vyhledávání nastavení"</string> <string name="keywords_wifi" msgid="8947676711698613374">"wifi wi-fi síť připojení"</string> <string name="lock_screen_notifications" msgid="6344441622889795466">"Zobrazit při uzamčení"</string> <string name="lock_screen_notifications_summary_off" msgid="7971192950034108756">"Citlivý obsah oznámení bude na obrazovce uzamčení skryt"</string> diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index ba636d2..b467fda 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -432,8 +432,8 @@ <string name="device_admin_title" msgid="3562216873644263804">"Enhedsadministration"</string> <string name="manage_device_admin" msgid="5059296715271077278">"Enhedsadministratorer"</string> <string name="manage_device_admin_summary" msgid="7672709110988761075">"Vis eller deaktiver enhedsadministratorer"</string> - <string name="manage_trust_agents" msgid="4629279457536987768">"Tillidsagenter"</string> - <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Se eller deaktiver tillidsagenter"</string> + <string name="manage_trust_agents" msgid="4629279457536987768">"Trust agents"</string> + <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Se eller deaktivere trust agents"</string> <string name="manage_notification_access" msgid="5799781079264981979">"Underretningsadgang"</string> <string name="manage_notification_access_summary_zero" msgid="2409912785614953348">"Apps kan ikke læse underretninger"</string> <plurals name="manage_notification_access_summary_nonzero"> @@ -1716,7 +1716,7 @@ <string name="remove_device_admin" msgid="3596845261596451437">"Deaktiver"</string> <string name="select_device_admin_msg" msgid="2645509057946368094">"Enhedsadministratorer"</string> <string name="no_device_admins" msgid="702695100241728775">"Ingen tilgængelige enhedsadministratorer"</string> - <string name="no_trust_agents" msgid="7450273545568977523">"Der er ingen tilgængelige tillidsagenter"</string> + <string name="no_trust_agents" msgid="7450273545568977523">"Der er ingen tilgængelige trust agents"</string> <string name="add_device_admin_msg" msgid="6246742476064507965">"Aktivér enhedsadministrator?"</string> <string name="add_device_admin" msgid="7133327675884827091">"Aktivér"</string> <string name="device_admin_add_title" msgid="7705551449705676363">"Enhedsadministrator"</string> diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index d93ae2f..e22732e 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -1345,8 +1345,8 @@ <string name="select_runtime_warning_message" msgid="1937574953265648165">"Neu starten, um Laufzeit von <xliff:g id="OLD">%1$s</xliff:g> zu <xliff:g id="NEW">%2$s</xliff:g> zu ändern?"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Kabellose Übertragung"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Optionen zur Zertifizierung für kabellose Übertragung anzeigen"</string> - <string name="allow_mock_location" msgid="2787962564578664888">"Falsche Standorte"</string> - <string name="allow_mock_location_summary" msgid="317615105156345626">"Falsche Standorte zulassen"</string> + <string name="allow_mock_location" msgid="2787962564578664888">"Simulierte Standorte"</string> + <string name="allow_mock_location_summary" msgid="317615105156345626">"Simulierte Standorte zulassen"</string> <string name="adb_warning_title" msgid="6234463310896563253">"USB-Debugging zulassen?"</string> <string name="adb_warning_message" msgid="7316799925425402244">"USB-Debugging ist nur für Entwicklungszwecke vorgesehen. Damit können Sie Daten zwischen Ihrem Computer und Ihrem Gerät kopieren, Apps auf Ihrem Gerät ohne Benachrichtigung installieren und Protokolldaten lesen."</string> <string name="adb_keys_warning_message" msgid="6932230298032192937">"Zugriff auf USB-Debugging für alle zuvor autorisierten Computer aufheben?"</string> diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 8a425ba..bb61dd1 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -433,7 +433,7 @@ <string name="manage_device_admin" msgid="5059296715271077278">"Διαχειριστές συσκευών"</string> <string name="manage_device_admin_summary" msgid="7672709110988761075">"Προβολή ή απενεργοποίηση των διαχειριστών συσκευής"</string> <string name="manage_trust_agents" msgid="4629279457536987768">"Έμπιστοι αντιπρόσωποι"</string> - <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Προβολή ή απενεργοποίηση έμπιστων αντιπροσώπων"</string> + <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Προβολή ή απενεργοποίηση trust agents"</string> <string name="manage_notification_access" msgid="5799781079264981979">"Πρόσβαση σε ειδοποιήσεις"</string> <string name="manage_notification_access_summary_zero" msgid="2409912785614953348">"Οι εφαρμογές δεν μπορούν να διαβάσουν ειδοποιήσεις"</string> <plurals name="manage_notification_access_summary_nonzero"> @@ -1716,7 +1716,7 @@ <string name="remove_device_admin" msgid="3596845261596451437">"Απενεργοποίηση"</string> <string name="select_device_admin_msg" msgid="2645509057946368094">"Διαχειριστές συσκευών"</string> <string name="no_device_admins" msgid="702695100241728775">"Δεν υπάρχουν διαθέσιμοι διαχειριστές συσκευών"</string> - <string name="no_trust_agents" msgid="7450273545568977523">"Δεν υπάρχουν διαθέσιμοι έμπιστοι αντιπρόσωποι"</string> + <string name="no_trust_agents" msgid="7450273545568977523">"Δεν υπάρχουν διαθέσιμοι trust agents"</string> <string name="add_device_admin_msg" msgid="6246742476064507965">"Ενεργοποίηση διαχειριστή συσκευής;"</string> <string name="add_device_admin" msgid="7133327675884827091">"Ενεργοποίηση"</string> <string name="device_admin_add_title" msgid="7705551449705676363">"Διαχειριστής συσκευής"</string> diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 880e7bb..92d7216 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -1024,8 +1024,8 @@ <string name="location_neighborhood_level" msgid="5626515380188353712">"Permitir que las aplicaciones usen el servicio de ubicación de Google para calcular tu ubicación más rápido. Se recopilarán datos de ubicación anónimos y se enviarán a Google"</string> <string name="location_neighborhood_level_wifi" msgid="4234820941954812210">"Ubicación determinada por Wi-Fi"</string> <string name="location_gps" msgid="8392461023569708478">"Satélites GPS"</string> - <string name="location_street_level" product="tablet" msgid="1669562198260860802">"Permitir que las aplicaciones usen el GPS del tablet para determinar tu ubicación"</string> - <string name="location_street_level" product="default" msgid="4617445745492014203">"Permitir que las aplicaciones usen el GPS del teléfono para determinar tu ubicación"</string> + <string name="location_street_level" product="tablet" msgid="1669562198260860802">"Permitir que las aplicaciones usen el GPS del tablet para determinar tu ubicación exacta"</string> + <string name="location_street_level" product="default" msgid="4617445745492014203">"Permitir que las aplicaciones usen el GPS del teléfono para determinar tu ubicación exacta"</string> <string name="assisted_gps" msgid="4649317129586736885">"Utilizar GPS asistido"</string> <string name="assisted_gps_enabled" msgid="8751899609589792803">"Utilizar el servidor para asistir al GPS (desactivar para reducir el uso de la red)"</string> <string name="assisted_gps_disabled" msgid="6982698333968010748">"Utilizar el servidor para asistir al GPS (desactivar para mejorar el rendimiento del GPS)"</string> diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index fc8460e..29dec77 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -432,8 +432,8 @@ <string name="device_admin_title" msgid="3562216873644263804">"سرپرستی دستگاه"</string> <string name="manage_device_admin" msgid="5059296715271077278">"سرپرست های دستگاه"</string> <string name="manage_device_admin_summary" msgid="7672709110988761075">"مشاهده یا غیر فعال کردن سرپرست های دستگاه"</string> - <string name="manage_trust_agents" msgid="4629279457536987768">"عوامل اعتماد"</string> - <string name="manage_trust_agents_summary" msgid="6804319935640148441">"نمایش یا غیرفعال کردن عوامل اعتماد"</string> + <string name="manage_trust_agents" msgid="4629279457536987768">"Trust agents"</string> + <string name="manage_trust_agents_summary" msgid="6804319935640148441">"نمایش یا غیرفعال کردن trust agents"</string> <string name="manage_notification_access" msgid="5799781079264981979">"دسترسی به اعلان"</string> <string name="manage_notification_access_summary_zero" msgid="2409912785614953348">"برنامهها نمیتوانند اعلانها را بخوانند"</string> <plurals name="manage_notification_access_summary_nonzero"> @@ -1716,7 +1716,7 @@ <string name="remove_device_admin" msgid="3596845261596451437">"غیرفعال کردن"</string> <string name="select_device_admin_msg" msgid="2645509057946368094">"سرپرست های دستگاه"</string> <string name="no_device_admins" msgid="702695100241728775">"هیچ سرپرست دستگاهی موجود نیست"</string> - <string name="no_trust_agents" msgid="7450273545568977523">"عامل اعتمادی در دسترس نیست"</string> + <string name="no_trust_agents" msgid="7450273545568977523">"trust agents در دسترس نیست"</string> <string name="add_device_admin_msg" msgid="6246742476064507965">"سرپرست دستگاه فعال شود؟"</string> <string name="add_device_admin" msgid="7133327675884827091">"فعالسازی"</string> <string name="device_admin_add_title" msgid="7705551449705676363">"سرپرست دستگاه"</string> diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index c815b44..f0dd987 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -1795,7 +1795,7 @@ <string name="really_remove_account_message" product="default" msgid="3483528757922948356">"यह खाता निकालने से, फ़ोन से इसके सभी संदेश, संपर्क और अन्य डेटा हट जाएंगे!"</string> <string name="remove_account_failed" product="tablet" msgid="3086620478225952725">"कुछ ऐप्स के लिए यह खाता आवश्यक है. आप टेबलेट को सेटिंग > सुरक्षित करें और रीसेट करें में फ़ैक्टरी डिफ़ॉल्ट (जो आपके सभी निजी डेटा को हटा देता है) पर रीसेट करके ही इसे हटा सकते हैं."</string> <string name="remove_account_failed" product="default" msgid="6217238709175617517">"कुछ ऐप्स के लिए यह खाता आवश्यक है. आप फ़ोन को सेटिंग > सुरक्षित करें और रीसेट करें में फ़ैक्टरी डिफ़ॉल्ट (जो आपके सभी निजी डेटा को हटा देता है) पर रीसेट करके ही इसे हटा सकते हैं."</string> - <string name="provider_label" msgid="7724593781904508866">"पुश ग्राहकी"</string> + <string name="provider_label" msgid="7724593781904508866">"पुश सदस्यता"</string> <!-- no translation found for sync_item_title (4782834606909853006) --> <skip /> <string name="cant_sync_dialog_title" msgid="8923508322291625282">"मैन्युअल रूप से समन्वयित नहीं कर सकता"</string> diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index a065f16..fe27817 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -998,9 +998,9 @@ <string name="network_settings_title" msgid="7967552516440151852">"Reti mobili"</string> <string name="manage_mobile_plan_title" msgid="7630170375010107744">"Piano dati mobile"</string> <string name="sms_application_title" msgid="6134351177937015839">"App SMS predefinita"</string> - <string name="sms_change_default_dialog_title" msgid="1958688831875804286">"Cambiare app per SMS?"</string> - <string name="sms_change_default_dialog_text" msgid="1522783933230274787">"Utilizzare <xliff:g id="NEW_APP">%1$s</xliff:g> anziché <xliff:g id="CURRENT_APP">%2$s</xliff:g> come app per SMS?"</string> - <string name="sms_change_default_no_previous_dialog_text" msgid="602683880284921998">"Utilizzare <xliff:g id="NEW_APP">%s</xliff:g> come app per SMS?"</string> + <string name="sms_change_default_dialog_title" msgid="1958688831875804286">"Cambiare app per gli SMS?"</string> + <string name="sms_change_default_dialog_text" msgid="1522783933230274787">"Utilizzare <xliff:g id="NEW_APP">%1$s</xliff:g> anziché <xliff:g id="CURRENT_APP">%2$s</xliff:g> come app per gli SMS?"</string> + <string name="sms_change_default_no_previous_dialog_text" msgid="602683880284921998">"Utilizzare <xliff:g id="NEW_APP">%s</xliff:g> come app per gli SMS?"</string> <string name="mobile_unknown_sim_operator" msgid="9101230468757324260">"Operatore SIM sconosciuto"</string> <string name="mobile_no_provisioning_url" msgid="2399426808423775711">"Nessun sito web di provisioning per %1$s"</string> <string name="mobile_insert_sim_card" msgid="9052590985784056395">"Inserisci la scheda SIM e riavvia"</string> diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index 369114d..9dd493e 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -432,8 +432,8 @@ <string name="device_admin_title" msgid="3562216873644263804">"Įrenginio administravimas"</string> <string name="manage_device_admin" msgid="5059296715271077278">"Įrenginio administratoriai"</string> <string name="manage_device_admin_summary" msgid="7672709110988761075">"Žiūrėti arba išaktyvinti įrenginio administratorius"</string> - <string name="manage_trust_agents" msgid="4629279457536987768">"Patikimos priemonės"</string> - <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Peržiūrėkite ar išaktyvinkite patikimas priemones"</string> + <string name="manage_trust_agents" msgid="4629279457536987768">"Trust agents"</string> + <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Peržiūrėkite ar išaktyvinkite „trust agents“"</string> <string name="manage_notification_access" msgid="5799781079264981979">"Prieiga prie pranešimų"</string> <string name="manage_notification_access_summary_zero" msgid="2409912785614953348">"Programos negali skaityti pranešimų"</string> <plurals name="manage_notification_access_summary_nonzero"> @@ -1716,7 +1716,7 @@ <string name="remove_device_admin" msgid="3596845261596451437">"Išaktyvinti"</string> <string name="select_device_admin_msg" msgid="2645509057946368094">"Įrenginio administratoriai"</string> <string name="no_device_admins" msgid="702695100241728775">"Nėra galimų įrenginio administratorių"</string> - <string name="no_trust_agents" msgid="7450273545568977523">"Nėra jokių galimų patikimų priemonių"</string> + <string name="no_trust_agents" msgid="7450273545568977523">"Nėra jokių galimų „trust agents“"</string> <string name="add_device_admin_msg" msgid="6246742476064507965">"Suaktyvinti įrenginio administratorių?"</string> <string name="add_device_admin" msgid="7133327675884827091">"Aktyvinti"</string> <string name="device_admin_add_title" msgid="7705551449705676363">"Įrenginio administratorius"</string> diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml index cf63dc8..f7ff16a 100644 --- a/res/values-ms-rMY/strings.xml +++ b/res/values-ms-rMY/strings.xml @@ -432,10 +432,8 @@ <string name="device_admin_title" msgid="3562216873644263804">"Pentadbiran peranti"</string> <string name="manage_device_admin" msgid="5059296715271077278">"Pentadbir peranti"</string> <string name="manage_device_admin_summary" msgid="7672709110988761075">"Lihat atau nyahaktifkan pentadbir peranti"</string> - <!-- no translation found for manage_trust_agents (4629279457536987768) --> - <skip /> - <!-- no translation found for manage_trust_agents_summary (6804319935640148441) --> - <skip /> + <string name="manage_trust_agents" msgid="4629279457536987768">"Ejen amanah"</string> + <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Lihat atau nyahaktifkan ejen amanah"</string> <string name="manage_notification_access" msgid="5799781079264981979">"Akses pemberitahuan"</string> <string name="manage_notification_access_summary_zero" msgid="2409912785614953348">"Apl tidak boleh membaca pemberitahuan"</string> <plurals name="manage_notification_access_summary_nonzero"> @@ -1718,8 +1716,7 @@ <string name="remove_device_admin" msgid="3596845261596451437">"Nyahaktifkan"</string> <string name="select_device_admin_msg" msgid="2645509057946368094">"Pentadbir peranti"</string> <string name="no_device_admins" msgid="702695100241728775">"Tiada pentadbir peranti tersedia"</string> - <!-- no translation found for no_trust_agents (7450273545568977523) --> - <skip /> + <string name="no_trust_agents" msgid="7450273545568977523">"Tiada ejen amanah tersedia"</string> <string name="add_device_admin_msg" msgid="6246742476064507965">"Aktifkan pentadbir peranti?"</string> <string name="add_device_admin" msgid="7133327675884827091">"Aktifkan"</string> <string name="device_admin_add_title" msgid="7705551449705676363">"Pentadbir peranti"</string> diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index a1c93d3..309ecf8 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -432,8 +432,8 @@ <string name="device_admin_title" msgid="3562216873644263804">"Enhetsadministrasjon"</string> <string name="manage_device_admin" msgid="5059296715271077278">"Enhetsadministratorer"</string> <string name="manage_device_admin_summary" msgid="7672709110988761075">"Se eller deaktiver enhetsadministratorer"</string> - <string name="manage_trust_agents" msgid="4629279457536987768">"Pålitelighetsagenter"</string> - <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Se eller deaktiver pålitelighetsagenter"</string> + <string name="manage_trust_agents" msgid="4629279457536987768">"Tillitsagenter"</string> + <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Se eller deaktiver tillitsagenter"</string> <string name="manage_notification_access" msgid="5799781079264981979">"Varseltilgang"</string> <string name="manage_notification_access_summary_zero" msgid="2409912785614953348">"Apper kan ikke lese varsler"</string> <plurals name="manage_notification_access_summary_nonzero"> @@ -1716,7 +1716,7 @@ <string name="remove_device_admin" msgid="3596845261596451437">"Deaktiver"</string> <string name="select_device_admin_msg" msgid="2645509057946368094">"Enhetsadministratorer"</string> <string name="no_device_admins" msgid="702695100241728775">"Ingen tilgjengelige enhetsadministratorer"</string> - <string name="no_trust_agents" msgid="7450273545568977523">"Ingen tilgjengelige pålitelighetsagenter"</string> + <string name="no_trust_agents" msgid="7450273545568977523">"Ingen tilgjengelige tillitsagenter"</string> <string name="add_device_admin_msg" msgid="6246742476064507965">"Aktiver enhetsadministrator?"</string> <string name="add_device_admin" msgid="7133327675884827091">"Aktiver"</string> <string name="device_admin_add_title" msgid="7705551449705676363">"Enhetsadministrator"</string> @@ -2096,7 +2096,7 @@ <string name="dashboard_title" msgid="5453710313046681820">"Innstillinger"</string> <string name="search_results_title" msgid="1796252422574886932">"Innstillinger"</string> <string name="search_menu" msgid="7053532283559077164">"Søk"</string> - <string name="query_hint_text" msgid="3350700807437473939">"Innstillinger for søk"</string> + <string name="query_hint_text" msgid="3350700807437473939">"Søkeinnstillinger"</string> <string name="keywords_wifi" msgid="8947676711698613374">"wifi wi-fi network connection"</string> <string name="lock_screen_notifications" msgid="6344441622889795466">"Vis når enheten er låst"</string> <string name="lock_screen_notifications_summary_off" msgid="7971192950034108756">"Sensitivt varselinnhold vises ikke på låseskjermen"</string> diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index bd6c66a..0dbf784 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -334,8 +334,8 @@ <string name="crypt_keeper_encrypt_summary" product="tablet" msgid="6291564408810586">"Een numerieke PIN-code of wachtwoord vereisen om uw tablet te decoderen wanneer u deze inschakelt"</string> <string name="crypt_keeper_encrypt_summary" product="default" msgid="514138079795442371">"Een numerieke PIN-code of wachtwoord vereisen om uw telefoon te decoderen wanneer u deze inschakelt"</string> <string name="crypt_keeper_encrypted_summary" msgid="1868233637888132906">"Gecodeerd"</string> - <string name="crypt_keeper_desc" product="tablet" msgid="3839235202103924154">"U kunt uw account, instellingen, gedownloade apps en de bijbehorende gegevens, media en andere bestanden versleutelen. Zodra u uw tablet heeft versleuteld, moet u telkens een pincode of wachtwoord opgeven om de tablet te coderen wanneer u deze opstart. U kunt het versleutelen van uw tablet uitsluitend ongedaan maken door de fabrieksinstellingen te herstellen. Daarbij worden al uw gegevens gewist.\n\nHet versleutelen kan een uur of langer duren. U moet beginnen met een volledig opgeladen accu en de tablet moet gedurende het versleutelen op de oplader zijn aangesloten. Als u het versleutelen onderbreekt, kunt u sommige of al uw gegevens kwijtraken."</string> - <string name="crypt_keeper_desc" product="default" msgid="7663118199519229502">"U kunt uw account, instellingen, gedownloade apps en de bijbehorende gegevens, media en andere bestanden versleutelen. Zodra u uw telefoon heeft versleuteld, moet u telkens een pincode of wachtwoord opgeven om de telefoon te coderen wanneer u deze opstart. U kunt het versleutelen van uw telefoon uitsluitend ongedaan maken door de fabrieksinstellingen te herstellen. Daarbij worden al uw gegevens gewist.\n\nHet versleutelen kan een uur of langer duren. U moet beginnen met een volledig opgeladen accu en u moet de telefoon aansluiten op de oplader totdat het versleutelen is voltooid. Als u het versleutelen onderbreekt, kunt u sommige of al uw gegevens kwijtraken."</string> + <string name="crypt_keeper_desc" product="tablet" msgid="3839235202103924154">"U kunt uw account, instellingen, gedownloade apps en de bijbehorende gegevens, media en andere bestanden versleutelen. Zodra u uw tablet heeft versleuteld, moet u telkens een pincode of wachtwoord opgeven om de tablet te ontsleutelen wanneer u deze opstart. U kunt het versleutelen van uw tablet uitsluitend ongedaan maken door de fabrieksinstellingen te herstellen. Daarbij worden al uw gegevens gewist.\n\nHet versleutelen kan een uur of langer duren. U moet beginnen met een volledig opgeladen accu en de tablet moet gedurende het versleutelen op de oplader zijn aangesloten. Als u het versleutelen onderbreekt, kunt u sommige of al uw gegevens kwijtraken."</string> + <string name="crypt_keeper_desc" product="default" msgid="7663118199519229502">"U kunt uw account, instellingen, gedownloade apps en de bijbehorende gegevens, media en andere bestanden versleutelen. Zodra u uw telefoon heeft versleuteld, moet u telkens een pincode of wachtwoord opgeven om de telefoon te ontsleutelen wanneer u deze opstart. U kunt het versleutelen van uw telefoon uitsluitend ongedaan maken door de fabrieksinstellingen te herstellen. Daarbij worden al uw gegevens gewist.\n\nHet versleutelen kan een uur of langer duren. U moet beginnen met een volledig opgeladen accu en u moet de telefoon aansluiten op de oplader totdat het versleutelen is voltooid. Als u het versleutelen onderbreekt, kunt u sommige of al uw gegevens kwijtraken."</string> <string name="crypt_keeper_button_text" product="tablet" msgid="1189623490604750854">"Tablet versleutelen"</string> <string name="crypt_keeper_button_text" product="default" msgid="2008346408473255519">"Telefoon versleutelen"</string> <string name="crypt_keeper_low_charge_text" msgid="2029407131227814893">"Laad de accu op en probeer het opnieuw."</string> diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 8eda315..d6b7d2c 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -432,8 +432,8 @@ <string name="device_admin_title" msgid="3562216873644263804">"Administração do dispositivo"</string> <string name="manage_device_admin" msgid="5059296715271077278">"Administradores do dispositivo"</string> <string name="manage_device_admin_summary" msgid="7672709110988761075">"Ver ou desativar administradores do dispositivo"</string> - <string name="manage_trust_agents" msgid="4629279457536987768">"Agentes fidedignos"</string> - <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Ver ou desativar agentes fidedignos"</string> + <string name="manage_trust_agents" msgid="4629279457536987768">"Trust agents"</string> + <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Ver ou desativar trust agents"</string> <string name="manage_notification_access" msgid="5799781079264981979">"Acesso a notificações"</string> <string name="manage_notification_access_summary_zero" msgid="2409912785614953348">"As aplicações não conseguem ler notificações"</string> <plurals name="manage_notification_access_summary_nonzero"> @@ -1716,7 +1716,7 @@ <string name="remove_device_admin" msgid="3596845261596451437">"Desativar"</string> <string name="select_device_admin_msg" msgid="2645509057946368094">"Administradores do dispositivo"</string> <string name="no_device_admins" msgid="702695100241728775">"Não existem administradores do dispositivo disponíveis"</string> - <string name="no_trust_agents" msgid="7450273545568977523">"Nenhum agente fidedigno disponível"</string> + <string name="no_trust_agents" msgid="7450273545568977523">"Nenhum trust agent disponível"</string> <string name="add_device_admin_msg" msgid="6246742476064507965">"Ativar administrador do dispositivo?"</string> <string name="add_device_admin" msgid="7133327675884827091">"Ativar"</string> <string name="device_admin_add_title" msgid="7705551449705676363">"Administrador do dispositivo"</string> @@ -1842,7 +1842,7 @@ <string name="simulate_color_space" msgid="6745847141353345872">"Simular espaço de cor"</string> <string name="enable_opengl_traces_title" msgid="6790444011053219871">"Ativar vestígios OpenGL"</string> <string name="use_nuplayer" msgid="5699257393367904387">"Usar NuPlayer (experim.)"</string> - <string name="use_nuplayer_summary" msgid="1991479067478516714">"Utilizar o NuPlayer em vez do AwesomePlayer"</string> + <string name="use_nuplayer_summary" msgid="1991479067478516714">"Usar o NuPlayer em vez do AwesomePlayer"</string> <string name="debug_layout" msgid="5981361776594526155">"Mostrar limit. do esquema"</string> <string name="debug_layout_summary" msgid="2001775315258637682">"Apresentar limites de clipes, margens, etc."</string> <string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"Forçar dir. do esq. RTL"</string> diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index ee7178c..849c08c 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -432,10 +432,8 @@ <string name="device_admin_title" msgid="3562216873644263804">"Administração do dispositivo"</string> <string name="manage_device_admin" msgid="5059296715271077278">"Administradores do dispositivo"</string> <string name="manage_device_admin_summary" msgid="7672709110988761075">"Visualizar ou desativar administradores do dispositivo"</string> - <!-- no translation found for manage_trust_agents (4629279457536987768) --> - <skip /> - <!-- no translation found for manage_trust_agents_summary (6804319935640148441) --> - <skip /> + <string name="manage_trust_agents" msgid="4629279457536987768">"Agentes de confiança"</string> + <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Ver ou desativar agentes de confiança"</string> <string name="manage_notification_access" msgid="5799781079264981979">"Acesso a notificações"</string> <string name="manage_notification_access_summary_zero" msgid="2409912785614953348">"Os aplicativos não podem ler notificações"</string> <plurals name="manage_notification_access_summary_nonzero"> @@ -1718,8 +1716,7 @@ <string name="remove_device_admin" msgid="3596845261596451437">"Desativar"</string> <string name="select_device_admin_msg" msgid="2645509057946368094">"Administradores do dispositivo"</string> <string name="no_device_admins" msgid="702695100241728775">"Não há administradores de dispositivo disponíveis"</string> - <!-- no translation found for no_trust_agents (7450273545568977523) --> - <skip /> + <string name="no_trust_agents" msgid="7450273545568977523">"Nenhum agente de confiança disponível"</string> <string name="add_device_admin_msg" msgid="6246742476064507965">"Ativar o administrador do dispositivo?"</string> <string name="add_device_admin" msgid="7133327675884827091">"Ativar"</string> <string name="device_admin_add_title" msgid="7705551449705676363">"Administrador do dispositivo"</string> diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index 50a248d..cd67139 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -432,10 +432,8 @@ <string name="device_admin_title" msgid="3562216873644263804">"Administrarea dispozitivelor"</string> <string name="manage_device_admin" msgid="5059296715271077278">"Administratori dispozitiv"</string> <string name="manage_device_admin_summary" msgid="7672709110988761075">"Afişaţi sau dezactivaţi administratorii dispozitivului"</string> - <!-- no translation found for manage_trust_agents (4629279457536987768) --> - <skip /> - <!-- no translation found for manage_trust_agents_summary (6804319935640148441) --> - <skip /> + <string name="manage_trust_agents" msgid="4629279457536987768">"Agenți de încredere"</string> + <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Vizualizați sau dezactivați agenți de încredere"</string> <string name="manage_notification_access" msgid="5799781079264981979">"Acces la notificări"</string> <string name="manage_notification_access_summary_zero" msgid="2409912785614953348">"Aplicațiile nu pot citi notificările"</string> <plurals name="manage_notification_access_summary_nonzero"> @@ -1719,8 +1717,7 @@ <string name="remove_device_admin" msgid="3596845261596451437">"Dezactivaţi"</string> <string name="select_device_admin_msg" msgid="2645509057946368094">"Administratori de dispozitive"</string> <string name="no_device_admins" msgid="702695100241728775">"Nu există niciun administrator de dispozitive disponibil"</string> - <!-- no translation found for no_trust_agents (7450273545568977523) --> - <skip /> + <string name="no_trust_agents" msgid="7450273545568977523">"Nu există agenți de încredere disponibili"</string> <string name="add_device_admin_msg" msgid="6246742476064507965">"Activaţi administratorul de dispozitive?"</string> <string name="add_device_admin" msgid="7133327675884827091">"Activaţi"</string> <string name="device_admin_add_title" msgid="7705551449705676363">"Administrator de dispozitive"</string> diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 12be75f..6d5d591 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -432,8 +432,8 @@ <string name="device_admin_title" msgid="3562216873644263804">"Администрирование устройства"</string> <string name="manage_device_admin" msgid="5059296715271077278">"Администраторы устройства"</string> <string name="manage_device_admin_summary" msgid="7672709110988761075">"Просмотрите или отключите администраторов устройств"</string> - <string name="manage_trust_agents" msgid="4629279457536987768">"Промежуточные агенты"</string> - <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Посмотреть или отключить промежуточные агенты"</string> + <string name="manage_trust_agents" msgid="4629279457536987768">"Trust agents"</string> + <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Посмотреть или отключить Trust Agents"</string> <string name="manage_notification_access" msgid="5799781079264981979">"Доступ к уведомлениям"</string> <string name="manage_notification_access_summary_zero" msgid="2409912785614953348">"Приложения не могут просматривать уведомления"</string> <plurals name="manage_notification_access_summary_nonzero"> diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 8e99056..c88f811 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -1841,7 +1841,7 @@ <string name="disable_overlays_summary" msgid="3578941133710758592">"Vždy používať GPU na skladanie obrazovky"</string> <string name="simulate_color_space" msgid="6745847141353345872">"Simulácia far. priestoru"</string> <string name="enable_opengl_traces_title" msgid="6790444011053219871">"Trasovanie OpenGL"</string> - <string name="use_nuplayer" msgid="5699257393367904387">"Použiť NuPlayer (experimentálne)"</string> + <string name="use_nuplayer" msgid="5699257393367904387">"Použiť NuPlayer (experiment.)"</string> <string name="use_nuplayer_summary" msgid="1991479067478516714">"Namiesto prehrávača AwesomePlayer použiť NuPlayer"</string> <string name="debug_layout" msgid="5981361776594526155">"Zobraziť ohraničenia"</string> <string name="debug_layout_summary" msgid="2001775315258637682">"Zobraziť v klipe ohraničenie, okraje a pod."</string> diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index 74bd672..7758927 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -432,8 +432,8 @@ <string name="device_admin_title" msgid="3562216873644263804">"Администрација уређаја"</string> <string name="manage_device_admin" msgid="5059296715271077278">"Администратори уређаја"</string> <string name="manage_device_admin_summary" msgid="7672709110988761075">"Преглед или деактивирање администратора уређаја"</string> - <string name="manage_trust_agents" msgid="4629279457536987768">"Поуздани агенти"</string> - <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Приказ или деактивирање поузданих агената"</string> + <string name="manage_trust_agents" msgid="4629279457536987768">"Trust agents"</string> + <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Trust agents - Приказ или деактивирање"</string> <string name="manage_notification_access" msgid="5799781079264981979">"Приступ обавештењима"</string> <string name="manage_notification_access_summary_zero" msgid="2409912785614953348">"Апликације не могу да читају обавештења"</string> <plurals name="manage_notification_access_summary_nonzero"> @@ -1716,7 +1716,7 @@ <string name="remove_device_admin" msgid="3596845261596451437">"Деактивирај"</string> <string name="select_device_admin_msg" msgid="2645509057946368094">"Администратори уређаја"</string> <string name="no_device_admins" msgid="702695100241728775">"Нема доступних администратора уређаја"</string> - <string name="no_trust_agents" msgid="7450273545568977523">"Нема доступних поузданих агената"</string> + <string name="no_trust_agents" msgid="7450273545568977523">"Trust agents - Недоступно"</string> <string name="add_device_admin_msg" msgid="6246742476064507965">"Желите ли да активирате администратор уређаја?"</string> <string name="add_device_admin" msgid="7133327675884827091">"Активирај"</string> <string name="device_admin_add_title" msgid="7705551449705676363">"Администратор уређаја"</string> @@ -1842,7 +1842,7 @@ <string name="simulate_color_space" msgid="6745847141353345872">"Симулирај простор боје"</string> <string name="enable_opengl_traces_title" msgid="6790444011053219871">"Омогући OpenGL трагове"</string> <string name="use_nuplayer" msgid="5699257393367904387">"Користи NuPlayer (експ.)"</string> - <string name="use_nuplayer_summary" msgid="1991479067478516714">"Користи NuPlayer уместо AwesomePlayer-а"</string> + <string name="use_nuplayer_summary" msgid="1991479067478516714">"Користи NuPlayer а не AwesomePlayer"</string> <string name="debug_layout" msgid="5981361776594526155">"Прикажи границе распореда"</string> <string name="debug_layout_summary" msgid="2001775315258637682">"Прикажи границе клипа, маргине итд."</string> <string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"Наметни смер распореда здесна налево"</string> diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index 70d7f2e..dd2cb47 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -424,8 +424,8 @@ <string name="device_admin_title" msgid="3562216873644263804">"Usimamizi wa kifaa"</string> <string name="manage_device_admin" msgid="5059296715271077278">"Wasimamizi wa kifaa"</string> <string name="manage_device_admin_summary" msgid="7672709110988761075">"Angalia au uzime wasimamizi wa kifaa"</string> - <string name="manage_trust_agents" msgid="4629279457536987768">"Madalali wa kuaminiana"</string> - <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Angalia ama lemaza madalali wa kuaminiana"</string> + <string name="manage_trust_agents" msgid="4629279457536987768">"Madalali wa kuaminiwa"</string> + <string name="manage_trust_agents_summary" msgid="6804319935640148441">"Angalia ama uzime madalali wa kuaminiwa"</string> <string name="manage_notification_access" msgid="5799781079264981979">"Kufikia arifa"</string> <string name="manage_notification_access_summary_zero" msgid="2409912785614953348">"Programu haziwezi kusoma arifa"</string> <plurals name="manage_notification_access_summary_nonzero"> @@ -1710,7 +1710,7 @@ <string name="remove_device_admin" msgid="3596845261596451437">"Zima"</string> <string name="select_device_admin_msg" msgid="2645509057946368094">"Wasimamizi wa kifaa"</string> <string name="no_device_admins" msgid="702695100241728775">"Hakuna wasimamizi kifaa wanaopatikana"</string> - <string name="no_trust_agents" msgid="7450273545568977523">"Hakuna madalali wa kuaminiana wanaopatikana"</string> + <string name="no_trust_agents" msgid="7450273545568977523">"Hakuna madalali wa kuaminiwa wanaopatikana"</string> <string name="add_device_admin_msg" msgid="6246742476064507965">"Kisimamizi cha kifaa kiwashwe?"</string> <string name="add_device_admin" msgid="7133327675884827091">"Washa"</string> <string name="device_admin_add_title" msgid="7705551449705676363">"Msimamizi wa kifaa"</string> @@ -2090,7 +2090,7 @@ <string name="dashboard_title" msgid="5453710313046681820">"Mipangilio"</string> <string name="search_results_title" msgid="1796252422574886932">"Mipangilio"</string> <string name="search_menu" msgid="7053532283559077164">"Utafutaji"</string> - <string name="query_hint_text" msgid="3350700807437473939">"Mipangilio ya Utafutaji"</string> + <string name="query_hint_text" msgid="3350700807437473939">"Mipangilio ya utafutaji"</string> <string name="keywords_wifi" msgid="8947676711698613374">"muunganisho wa mtandao wa wi-fi"</string> <string name="lock_screen_notifications" msgid="6344441622889795466">"Onyesha wakati imefungwa"</string> <string name="lock_screen_notifications_summary_off" msgid="7971192950034108756">"Arifa za maudhui nyeti zitafichwa kwenye skrini iliyofungwa"</string> diff --git a/res/values-th/arrays.xml b/res/values-th/arrays.xml index f749497..6b6f63d 100644 --- a/res/values-th/arrays.xml +++ b/res/values-th/arrays.xml @@ -457,9 +457,9 @@ </string-array> <string-array name="vpn_types_long"> <item msgid="2732002039459078847">"PPTP VPN"</item> - <item msgid="3799752201662127867">"L2TP/IPSec VPN พร้อมด้วยคีย์ที่แบ่งปันไว้ล่วงหน้า"</item> + <item msgid="3799752201662127867">"L2TP/IPSec VPN พร้อมด้วยคีย์ที่แชร์ไว้ล่วงหน้า"</item> <item msgid="4725504331295252103">"L2TP/IPSec VPN พร้อมด้วยใบรับรอง"</item> - <item msgid="7526551163264034377">"IPSec VPN พร้อมด้วยคีย์ที่แบ่งปันไว้ล่วงหน้าและการตรวจสอบสิทธิ์ Xauth"</item> + <item msgid="7526551163264034377">"IPSec VPN พร้อมด้วยคีย์ที่แชร์ไว้ล่วงหน้าและการตรวจสอบสิทธิ์ Xauth"</item> <item msgid="8064740940687465039">"IPSec VPN พร้อมด้วยใบรับรองและการตรวจสอบสิทธิ์ Xauth"</item> <item msgid="4946199982372391490">"IPSec VPN พร้อมด้วยใบรับรองและการตรวจสอบสิทธิ์แบบผสม"</item> </string-array> diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index 58fce57..8c23509 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -487,14 +487,14 @@ <string name="bluetooth_profile_opp" msgid="9168139293654233697">"การถ่ายโอนไฟล์"</string> <string name="bluetooth_profile_hid" msgid="3680729023366986480">"อุปกรณ์อินพุต"</string> <string name="bluetooth_profile_pan" msgid="3391606497945147673">"การเข้าถึงอินเทอร์เน็ต"</string> - <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"การแบ่งปันการเชื่อมต่ออินเทอร์เน็ต"</string> + <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"การแชร์การเชื่อมต่ออินเทอร์เน็ต"</string> <string name="bluetooth_profile_map" msgid="5465271250454324383">"การเข้าถึงข้อความ"</string> <string name="bluetooth_disconnect_a2dp_profile" msgid="3524648279150937177">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> จะถูกตัดการเชื่อมต่อจากเสียงของสื่อ"</string> <string name="bluetooth_disconnect_headset_profile" msgid="8635908811168780720">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> จะถูกตัดการเชื่อมต่อจากเสียงแฮนด์ฟรี"</string> <string name="bluetooth_disconnect_hid_profile" msgid="3282295189719352075">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> จะถูกตัดการเชื่อมต่อจากอุปกรณ์อินพุต"</string> <string name="bluetooth_disconnect_pan_user_profile" msgid="8037627994382458698">"การเข้าถึงอินเทอร์เน็ตผ่าน <xliff:g id="DEVICE_NAME">%1$s</xliff:g> จะถูกยกเลิกการเชื่อมต่อ"</string> - <string name="bluetooth_disconnect_pan_nap_profile" product="tablet" msgid="5455448395850929200">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> จะยกเลิกการเชื่อมต่อจากการแบ่งปันการเชื่อมต่ออินเทอร์เน็ตของแท็บเล็ตนี้"</string> - <string name="bluetooth_disconnect_pan_nap_profile" product="default" msgid="5266851881175033601">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> จะยกเลิกการเชื่อมต่อจากการแบ่งปันการเชื่อมต่ออินเทอร์เน็ตของโทรศัพท์นี้"</string> + <string name="bluetooth_disconnect_pan_nap_profile" product="tablet" msgid="5455448395850929200">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> จะยกเลิกการเชื่อมต่อจากการแชร์การเชื่อมต่ออินเทอร์เน็ตของแท็บเล็ตนี้"</string> + <string name="bluetooth_disconnect_pan_nap_profile" product="default" msgid="5266851881175033601">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> จะยกเลิกการเชื่อมต่อจากการแชร์การเชื่อมต่ออินเทอร์เน็ตของโทรศัพท์นี้"</string> <string name="bluetooth_device_advanced_title" msgid="6066342531927499308">"อุปกรณ์บลูทูธที่จับคู่"</string> <string name="bluetooth_device_advanced_online_mode_title" msgid="3689050071425683114">"เชื่อมต่อ"</string> <string name="bluetooth_device_advanced_online_mode_summary" msgid="1204424107263248336">"เชื่อมต่อกับอุปกรณ์บลูทูธ"</string> @@ -508,7 +508,7 @@ <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"ไม่ได้เชื่อมต่อกับเซิร์ฟเวอร์สำหรับโอนไฟล์"</string> <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"เชื่อมต่อกับอุปกรณ์อินพุตแล้ว"</string> <string name="bluetooth_pan_user_profile_summary_connected" msgid="4602294638909590612">"เชื่อมต่อกับอุปกรณ์สำหรับการเข้าถึงอินเทอร์เน็ต"</string> - <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1561383706411975199">"กำลังแบ่งปันอินเทอร์เน็ตกับอุปกรณ์"</string> + <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1561383706411975199">"กำลังแชร์อินเทอร์เน็ตกับอุปกรณ์"</string> <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"ใช้สำหรับระบบเสียงของสื่อ"</string> <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ใช้สำหรับระบบเสียงของโทรศัพท์"</string> <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ใช้สำหรับการโอนไฟล์"</string> @@ -983,14 +983,14 @@ <string name="usb_tethering_unavailable_subtext" msgid="1044622421184007254">"ไม่ได้เชื่อมต่อ USB"</string> <string name="usb_tethering_errored_subtext" msgid="1377574819427841992">"ข้อผิดพลาดในการปล่อยสัญญาณของ USB"</string> <string name="bluetooth_tether_checkbox_text" msgid="2379175828878753652">"ปล่อยสัญญาณบลูทูธ"</string> - <string name="bluetooth_tethering_available_subtext" product="tablet" msgid="8811610320942954709">"กำลังแบ่งปันอินเทอร์เน็ตของแท็บเล็ตนี้"</string> - <string name="bluetooth_tethering_available_subtext" product="default" msgid="4229220575771946723">"กำลังแบ่งปันการเชื่อมต่ออินเทอร์เน็ตของโทรศัพท์นี้"</string> - <string name="bluetooth_tethering_device_connected_subtext" product="tablet" msgid="2730938191906597896">"กำลังแบ่งปันอินเทอร์เน็ตของแท็บเล็ตนี้กับอุปกรณ์ 1 เครื่อง"</string> - <string name="bluetooth_tethering_device_connected_subtext" product="default" msgid="1666736165420290466">"กำลังแบ่งปันอินเทอร์เน็ตของโทรศัพท์นี้กับอุปกรณ์ 1 เครื่อง"</string> - <string name="bluetooth_tethering_devices_connected_subtext" product="tablet" msgid="1180765608259580143">"กำลังแบ่งปันการเชื่อมต่ออินเทอร์เน็ตของแท็บเล็ตนี้กับอุปกรณ์ <xliff:g id="CONNECTEDDEVICECOUNT">%1$d</xliff:g> เครื่อง"</string> - <string name="bluetooth_tethering_devices_connected_subtext" product="default" msgid="8248942539362173005">"กำลังแบ่งปันการเชื่อมต่ออินเทอร์เน็ตของโทรศัพท์นี้กับอุปกรณ์ <xliff:g id="CONNECTEDDEVICECOUNT">%1$d</xliff:g> เครื่อง"</string> - <string name="bluetooth_tethering_off_subtext" product="tablet" msgid="2093881379028235555">"ไม่แบ่งปันการเชื่อมต่ออินเทอร์เน็ตของแท็บเล็ตนี้"</string> - <string name="bluetooth_tethering_off_subtext" product="default" msgid="706860924389041342">"ไม่แบ่งปันการเชื่อมต่ออินเทอร์เน็ตของโทรศัพท์นี้"</string> + <string name="bluetooth_tethering_available_subtext" product="tablet" msgid="8811610320942954709">"กำลังแชร์อินเทอร์เน็ตของแท็บเล็ตนี้"</string> + <string name="bluetooth_tethering_available_subtext" product="default" msgid="4229220575771946723">"กำลังแชร์การเชื่อมต่ออินเทอร์เน็ตของโทรศัพท์นี้"</string> + <string name="bluetooth_tethering_device_connected_subtext" product="tablet" msgid="2730938191906597896">"กำลังแชร์อินเทอร์เน็ตของแท็บเล็ตนี้กับอุปกรณ์ 1 เครื่อง"</string> + <string name="bluetooth_tethering_device_connected_subtext" product="default" msgid="1666736165420290466">"กำลังแชร์อินเทอร์เน็ตของโทรศัพท์นี้กับอุปกรณ์ 1 เครื่อง"</string> + <string name="bluetooth_tethering_devices_connected_subtext" product="tablet" msgid="1180765608259580143">"กำลังแชร์การเชื่อมต่ออินเทอร์เน็ตของแท็บเล็ตนี้กับอุปกรณ์ <xliff:g id="CONNECTEDDEVICECOUNT">%1$d</xliff:g> เครื่อง"</string> + <string name="bluetooth_tethering_devices_connected_subtext" product="default" msgid="8248942539362173005">"กำลังแชร์การเชื่อมต่ออินเทอร์เน็ตของโทรศัพท์นี้กับอุปกรณ์ <xliff:g id="CONNECTEDDEVICECOUNT">%1$d</xliff:g> เครื่อง"</string> + <string name="bluetooth_tethering_off_subtext" product="tablet" msgid="2093881379028235555">"ไม่แชร์การเชื่อมต่ออินเทอร์เน็ตของแท็บเล็ตนี้"</string> + <string name="bluetooth_tethering_off_subtext" product="default" msgid="706860924389041342">"ไม่แชร์การเชื่อมต่ออินเทอร์เน็ตของโทรศัพท์นี้"</string> <string name="bluetooth_tethering_errored_subtext" msgid="4926566308991142264">"ไม่สามารถเชื่อมต่อ"</string> <string name="bluetooth_tethering_overflow_error" msgid="6285122039489881969">"ไม่สามารถปล่อยการเชื่อมต่อมากกว่า <xliff:g id="MAXCONNECTION">%1$d</xliff:g> อุปกรณ์"</string> <string name="bluetooth_untether_blank" msgid="2871192409329334813">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> จะถูกยกเลิกการปล่อยสัญญาณ"</string> @@ -1333,8 +1333,8 @@ <string name="enable_adb" msgid="7982306934419797485">"การแก้ไขข้อบกพร่อง USB"</string> <string name="enable_adb_summary" msgid="4881186971746056635">"โหมดแก้ไขข้อบกพร่องเมื่อเชื่อมต่อ USB"</string> <string name="clear_adb_keys" msgid="4038889221503122743">"ยกเลิกการให้สิทธิ์การแก้ปัญหา USB"</string> - <string name="bugreport_in_power" msgid="4548816486587403971">"รายงานบั๊กเกี่ยวกับเมนูเปิดปิด"</string> - <string name="bugreport_in_power_summary" msgid="5764234382355067053">"เพิ่มตัวเลือกในเมนูเปิดปิดสำหรับการใช้รายงานบั๊ก"</string> + <string name="bugreport_in_power" msgid="4548816486587403971">"รายงานข้อบกพร่องเกี่ยวกับเมนูเปิดปิด"</string> + <string name="bugreport_in_power_summary" msgid="5764234382355067053">"เพิ่มตัวเลือกในเมนูเปิดปิดสำหรับการใช้รายงานข้อบกพร่อง"</string> <string name="keep_screen_on" msgid="1146389631208760344">"เปิดหน้าจอค้าง"</string> <string name="keep_screen_on_summary" msgid="2173114350754293009">"หน้าจอจะไม่เข้าสู่โหมดสลีปขณะชาร์จ"</string> <string name="bt_hci_snoop_log" msgid="3340699311158865670">"เปิดใช้งานบันทึกสอดแนมบลูทูธ HCI"</string> @@ -1940,7 +1940,7 @@ <string name="vpn_mppe" msgid="6639001940500288972">"การเข้ารหัส PPP (MPPE)"</string> <string name="vpn_l2tp_secret" msgid="529359749677142076">"ข้อมูลลับ L2TP"</string> <string name="vpn_ipsec_identifier" msgid="4098175859460006296">"ตัวระบุ IPSec"</string> - <string name="vpn_ipsec_secret" msgid="4526453255704888704">"คีย์ IPSec ที่แบ่งปันไว้ล่วงหน้า"</string> + <string name="vpn_ipsec_secret" msgid="4526453255704888704">"คีย์ IPSec ที่แชร์ไว้ล่วงหน้า"</string> <string name="vpn_ipsec_user_cert" msgid="6880651510020187230">"ใบรับรองผู้ใช้ IPSec"</string> <string name="vpn_ipsec_ca_cert" msgid="91338213449148229">"ใบรับรอง IPSec CA"</string> <string name="vpn_ipsec_server_cert" msgid="6599276718456935010">"ใบรับรองเซิร์ฟเวอร์ IPSec"</string> diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 929176e..800a33c 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -1716,7 +1716,7 @@ <string name="remove_device_admin" msgid="3596845261596451437">"取消激活"</string> <string name="select_device_admin_msg" msgid="2645509057946368094">"设备管理器"</string> <string name="no_device_admins" msgid="702695100241728775">"没有可供显示的设备管理器"</string> - <string name="no_trust_agents" msgid="7450273545568977523">"没有信任的代理可显示"</string> + <string name="no_trust_agents" msgid="7450273545568977523">"没有信任的代理"</string> <string name="add_device_admin_msg" msgid="6246742476064507965">"要激活设备管理器吗?"</string> <string name="add_device_admin" msgid="7133327675884827091">"激活"</string> <string name="device_admin_add_title" msgid="7705551449705676363">"设备管理器"</string> diff --git a/res/values/colors.xml b/res/values/colors.xml index c2ef388..fcbf46b 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -45,4 +45,17 @@ <color name="circle_avatar_frame_color">#ffffffff</color> <color name="circle_avatar_frame_shadow_color">#80000000</color> <color name="circle_avatar_frame_pressed_color">#ffffffff</color> + + <color name="quantum_blue_grey_50">#ffeceff1</color> + <color name="quantum_blue_grey_100">#ffcfd8dc</color> + <color name="quantum_blue_grey_300">#ff90a4ae</color> + <color name="quantum_blue_grey_500">#ff607d8b</color> + <color name="quantum_blue_grey_700">#ff455a64</color> + + <color name="quantum_orange_100">#ffffe0b2</color> + <color name="quantum_orange_300">#ffffb74d</color> + <color name="quantum_orange_500">#ffff9800</color> + <color name="quantum_orange_700">#fff57c00</color> + <color name="quantum_orange_A200">#ffffab40</color> + <color name="quantum_orange_A400">#ffff9100</color> </resources> diff --git a/res/values/themes.xml b/res/values/themes.xml index 7100f2d..5c8f6c1 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -70,5 +70,10 @@ <item name="ic_menu_moreoverflow">@*android:drawable/ic_menu_moreoverflow_holo_dark</item> <item name="ic_wps">@drawable/ic_wps_dark</item> <item name="wifi_signal">@drawable/wifi_signal_dark</item> + + <item name="android:colorPrimaryLight">@color/quantum_blue_grey_100</item> + <item name="android:colorPrimary">@color/quantum_blue_grey_500</item> + <item name="android:colorPrimaryDark">@color/quantum_blue_grey_700</item> + <item name="android:colorAccent">@color/quantum_orange_A200</item> </style> </resources> diff --git a/src/com/android/settings/ChooseLockSettingsHelper.java b/src/com/android/settings/ChooseLockSettingsHelper.java index a069712..15d1203 100644 --- a/src/com/android/settings/ChooseLockSettingsHelper.java +++ b/src/com/android/settings/ChooseLockSettingsHelper.java @@ -25,6 +25,7 @@ import android.content.Intent; public final class ChooseLockSettingsHelper { + static final String EXTRA_KEY_TYPE = "type"; static final String EXTRA_KEY_PASSWORD = "password"; private LockPatternUtils mLockPatternUtils; diff --git a/src/com/android/settings/ConfirmLockPassword.java b/src/com/android/settings/ConfirmLockPassword.java index 7fc48cd..a2302bb 100644 --- a/src/com/android/settings/ConfirmLockPassword.java +++ b/src/com/android/settings/ConfirmLockPassword.java @@ -28,6 +28,7 @@ import android.os.Bundle; import android.os.CountDownTimer; import android.os.Handler; import android.os.SystemClock; +import android.os.storage.StorageManager; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; @@ -168,6 +169,9 @@ public class ConfirmLockPassword extends SettingsActivity { if (mLockPatternUtils.checkPassword(pin)) { Intent intent = new Intent(); + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE, + mIsAlpha ? StorageManager.CRYPT_TYPE_PASSWORD + : StorageManager.CRYPT_TYPE_PIN); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pin); getActivity().setResult(RESULT_OK, intent); diff --git a/src/com/android/settings/ConfirmLockPattern.java b/src/com/android/settings/ConfirmLockPattern.java index 81b325b..a4b9991 100644 --- a/src/com/android/settings/ConfirmLockPattern.java +++ b/src/com/android/settings/ConfirmLockPattern.java @@ -27,6 +27,7 @@ import android.content.Intent; import android.os.CountDownTimer; import android.os.SystemClock; import android.os.Bundle; +import android.os.storage.StorageManager; import android.widget.TextView; import android.view.LayoutInflater; import android.view.View; @@ -266,6 +267,8 @@ public class ConfirmLockPattern extends SettingsActivity { if (mLockPatternUtils.checkPattern(pattern)) { Intent intent = new Intent(); + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE, + StorageManager.CRYPT_TYPE_PATTERN); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, LockPatternUtils.patternToString(pattern)); diff --git a/src/com/android/settings/CryptKeeperConfirm.java b/src/com/android/settings/CryptKeeperConfirm.java index 4822a83..71d5e96 100644 --- a/src/com/android/settings/CryptKeeperConfirm.java +++ b/src/com/android/settings/CryptKeeperConfirm.java @@ -72,7 +72,7 @@ public class CryptKeeperConfirm extends Fragment { IMountService mountService = IMountService.Stub.asInterface(service); try { Bundle args = getIntent().getExtras(); - mountService.encryptStorage(args.getString("password")); + mountService.encryptStorage(args.getInt("type", -1), args.getString("password")); } catch (Exception e) { Log.e("CryptKeeper", "Error while encrypting...", e); } diff --git a/src/com/android/settings/CryptKeeperSettings.java b/src/com/android/settings/CryptKeeperSettings.java index cedf530..1846580 100644 --- a/src/com/android/settings/CryptKeeperSettings.java +++ b/src/com/android/settings/CryptKeeperSettings.java @@ -29,6 +29,7 @@ import android.content.IntentFilter; import android.content.res.Resources; import android.os.BatteryManager; import android.os.Bundle; +import android.os.storage.StorageManager; import android.preference.Preference; import android.text.TextUtils; import android.view.LayoutInflater; @@ -41,10 +42,6 @@ public class CryptKeeperSettings extends Fragment { private static final int KEYGUARD_REQUEST = 55; - // This is the minimum acceptable password quality. If the current password quality is - // lower than this, encryption should not be activated. - static final int MIN_PASSWORD_QUALITY = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; - // Minimum battery charge level (in percent) to launch encryption. If the battery charge is // lower than this, encryption should not be activated. private static final int MIN_BATTERY_LEVEL = 80; @@ -157,24 +154,18 @@ public class CryptKeeperSettings extends Fragment { * @return true if confirmation launched */ private boolean runKeyguardConfirmation(int request) { - // 1. Confirm that we have a sufficient PIN/Password to continue - LockPatternUtils lockPatternUtils = new LockPatternUtils(getActivity()); - int quality = lockPatternUtils.getActivePasswordQuality(); - if (quality == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK - && lockPatternUtils.isLockPasswordEnabled()) { - // Use the alternate as the quality. We expect this to be - // PASSWORD_QUALITY_SOMETHING(pattern) or PASSWORD_QUALITY_NUMERIC(PIN). - quality = lockPatternUtils.getKeyguardStoredPasswordQuality(); - } - if (quality < MIN_PASSWORD_QUALITY) { - return false; - } - // 2. Ask the user to confirm the current PIN/Password Resources res = getActivity().getResources(); - return new ChooseLockSettingsHelper(getActivity(), this) - .launchConfirmationActivity(request, - res.getText(R.string.master_clear_gesture_prompt), - res.getText(R.string.master_clear_gesture_explanation)); + ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(getActivity(), this); + + if (helper.utils().getKeyguardStoredPasswordQuality() + == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { + showFinalConfirmation(StorageManager.CRYPT_TYPE_DEFAULT, ""); + return true; + } + + return helper.launchConfirmationActivity(request, + res.getText(R.string.master_clear_gesture_prompt), + res.getText(R.string.master_clear_gesture_explanation)); } @Override @@ -188,17 +179,19 @@ public class CryptKeeperSettings extends Fragment { // If the user entered a valid keyguard trace, present the final // confirmation prompt; otherwise, go back to the initial state. if (resultCode == Activity.RESULT_OK && data != null) { + int type = data.getIntExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE, -1); String password = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); if (!TextUtils.isEmpty(password)) { - showFinalConfirmation(password); + showFinalConfirmation(type, password); } } } - private void showFinalConfirmation(String password) { + private void showFinalConfirmation(int type, String password) { Preference preference = new Preference(getActivity()); preference.setFragment(CryptKeeperConfirm.class.getName()); preference.setTitle(R.string.crypt_keeper_confirm_title); + preference.getExtras().putInt("type", type); preference.getExtras().putString("password", password); ((SettingsActivity) getActivity()).onPreferenceStartFragment(null, preference); } diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java index 396c76a..563a343 100644 --- a/src/com/android/settings/DataUsageSummary.java +++ b/src/com/android/settings/DataUsageSummary.java @@ -53,7 +53,6 @@ import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; import android.app.Fragment; -import android.app.FragmentManager; import android.app.FragmentTransaction; import android.app.LoaderManager.LoaderCallbacks; import android.content.ContentResolver; @@ -134,6 +133,9 @@ import com.android.settings.net.NetworkPolicyEditor; import com.android.settings.net.SummaryForAllUidLoader; import com.android.settings.net.UidDetail; import com.android.settings.net.UidDetailProvider; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.Indexable; +import com.android.settings.search.SearchIndexableRaw; import com.android.settings.widget.ChartDataUsageView; import com.android.settings.widget.ChartDataUsageView.DataUsageChartListener; import com.android.settings.widget.PieChartView; @@ -150,7 +152,7 @@ import java.util.Locale; * Panel showing data usage history across various networks, including options * to inspect based on usage cycle and control through {@link NetworkPolicy}. */ -public class DataUsageSummary extends Fragment { +public class DataUsageSummary extends Fragment implements Indexable { private static final String TAG = "DataUsage"; private static final boolean LOGD = false; @@ -692,7 +694,6 @@ public class DataUsageSummary extends Fragment { mListView.setVisibility(View.VISIBLE); } - final boolean tabChanged = !currentTab.equals(mCurrentTab); mCurrentTab = currentTab; if (LOGD) Log.d(TAG, "updateBody() with currentTab=" + currentTab); @@ -700,7 +701,6 @@ public class DataUsageSummary extends Fragment { mDataEnabledView.setVisibility(isOwner ? View.VISIBLE : View.GONE); // TODO: remove mobile tabs when SIM isn't ready - final TelephonyManager tele = TelephonyManager.from(context); if (TAB_MOBILE.equals(currentTab)) { setPreferenceTitle(mDataEnabledView, R.string.data_usage_enable_mobile); @@ -2383,4 +2383,44 @@ public class DataUsageSummary extends Fragment { summary.setVisibility(View.VISIBLE); summary.setText(string); } + + /** + * For search + */ + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { + final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>(); + + final Resources res = context.getResources(); + + // Add fragment title + SearchIndexableRaw data = new SearchIndexableRaw(context); + data.title = res.getString(R.string.data_usage_summary_title); + data.screenTitle = res.getString(R.string.data_usage_summary_title); + result.add(data); + + // Mobile data + data = new SearchIndexableRaw(context); + data.title = res.getString(R.string.data_usage_enable_mobile); + data.screenTitle = res.getString(R.string.data_usage_summary_title); + result.add(data); + + // Set mobile data limit + data = new SearchIndexableRaw(context); + data.title = res.getString(R.string.data_usage_disable_mobile_limit); + data.screenTitle = res.getString(R.string.data_usage_summary_title); + result.add(data); + + // Data usage cycke + data = new SearchIndexableRaw(context); + data.title = res.getString(R.string.data_usage_cycle); + data.screenTitle = res.getString(R.string.data_usage_summary_title); + result.add(data); + + return result; + } + }; + } diff --git a/src/com/android/settings/DreamSettings.java b/src/com/android/settings/DreamSettings.java index f4e251e..1575bee 100644 --- a/src/com/android/settings/DreamSettings.java +++ b/src/com/android/settings/DreamSettings.java @@ -82,7 +82,8 @@ public class DreamSettings extends SettingsPreferenceFragment { public void onCreate(Bundle icicle) { logd("onCreate(%s)", icicle); super.onCreate(icicle); - Activity activity = getActivity(); + + final Activity activity = getActivity(); mBackend = new DreamBackend(activity); mSwitch = new Switch(activity); @@ -99,18 +100,28 @@ public class DreamSettings extends SettingsPreferenceFragment { final int padding = activity.getResources().getDimensionPixelSize( R.dimen.action_bar_switch_padding); mSwitch.setPaddingRelative(0, 0, padding, 0); - activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, + + setHasOptionsMenu(true); + } + + @Override + public void onStart() { + logd("onStart()"); + super.onStart(); + + final ActionBar actionBar = getActivity().getActionBar(); + + actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM); - activity.getActionBar().setCustomView(mSwitch, new ActionBar.LayoutParams( + actionBar.setCustomView(mSwitch, new ActionBar.LayoutParams( ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT, Gravity.CENTER_VERTICAL | Gravity.END)); - - setHasOptionsMenu(true); } @Override public void onDestroyView() { + logd("onDestroyView()"); getActivity().getActionBar().setCustomView(null); super.onDestroyView(); } @@ -121,7 +132,6 @@ public class DreamSettings extends SettingsPreferenceFragment { super.onActivityCreated(savedInstanceState); ListView listView = getListView(); - listView.setItemsCanFocus(true); TextView emptyView = (TextView) getView().findViewById(android.R.id.empty); diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java index c4f0c7f..30a1df7 100644 --- a/src/com/android/settings/SecuritySettings.java +++ b/src/com/android/settings/SecuritySettings.java @@ -29,6 +29,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; +import android.content.res.Resources; import android.nfc.NfcUnlock; import android.os.Bundle; import android.os.UserHandle; @@ -39,21 +40,27 @@ import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.PreferenceGroup; import android.preference.PreferenceScreen; +import android.provider.SearchIndexableResource; import android.provider.Settings; import android.security.KeyStore; import android.telephony.TelephonyManager; import android.util.Log; import com.android.internal.widget.LockPatternUtils; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.Indexable; +import com.android.settings.search.SearchIndexableRaw; import java.util.ArrayList; import java.util.List; +import static com.android.settings.search.SearchIndexableResources.RANK_SECURITY; + /** * Gesture lock pattern settings. */ public class SecuritySettings extends RestrictedSettingsFragment - implements OnPreferenceChangeListener, DialogInterface.OnClickListener { + implements OnPreferenceChangeListener, DialogInterface.OnClickListener, Indexable { static final String TAG = "SecuritySettings"; // Lock Settings @@ -86,7 +93,6 @@ public class SecuritySettings extends RestrictedSettingsFragment private static final String KEY_CREDENTIALS_MANAGER = "credentials_management"; private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; - private PackageManager mPM; private DevicePolicyManager mDPM; private ChooseLockSettingsHelper mChooseLockSettingsHelper; @@ -119,38 +125,30 @@ public class SecuritySettings extends RestrictedSettingsFragment mLockPatternUtils = new LockPatternUtils(getActivity()); - mPM = getActivity().getPackageManager(); mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE); mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity()); } - private PreferenceScreen createPreferenceHierarchy() { - PreferenceScreen root = getPreferenceScreen(); - if (root != null) { - root.removeAll(); - } - addPreferencesFromResource(R.xml.security_settings); - root = getPreferenceScreen(); - - // Add options for lock/unlock screen + private static int getResIdForLockUnlockScreen(Context context, + LockPatternUtils lockPatternUtils) { int resid = 0; - if (!mLockPatternUtils.isSecure()) { + if (!lockPatternUtils.isSecure()) { // if there are multiple users, disable "None" setting - UserManager mUm = (UserManager) getSystemService(Context.USER_SERVICE); + UserManager mUm = (UserManager) context. getSystemService(Context.USER_SERVICE); List<UserInfo> users = mUm.getUsers(true); final boolean singleUser = users.size() == 1; - if (singleUser && mLockPatternUtils.isLockScreenDisabled()) { + if (singleUser && lockPatternUtils.isLockScreenDisabled()) { resid = R.xml.security_settings_lockscreen; } else { resid = R.xml.security_settings_chooser; } - } else if (mLockPatternUtils.usingBiometricWeak() && - mLockPatternUtils.isBiometricWeakInstalled()) { + } else if (lockPatternUtils.usingBiometricWeak() && + lockPatternUtils.isBiometricWeakInstalled()) { resid = R.xml.security_settings_biometric_weak; } else { - switch (mLockPatternUtils.getKeyguardStoredPasswordQuality()) { + switch (lockPatternUtils.getKeyguardStoredPasswordQuality()) { case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: resid = R.xml.security_settings_pattern; break; @@ -164,8 +162,26 @@ public class SecuritySettings extends RestrictedSettingsFragment break; } } - addPreferencesFromResource(resid); + return resid; + } + + /** + * Important! + * + * Dont forget to update the SecuritySearchIndexProvider if you are doing any change in the + * logic or adding/removing preferences here. + */ + private PreferenceScreen createPreferenceHierarchy() { + PreferenceScreen root = getPreferenceScreen(); + if (root != null) { + root.removeAll(); + } + addPreferencesFromResource(R.xml.security_settings); + root = getPreferenceScreen(); + // Add options for lock/unlock screen + final int resid = getResIdForLockUnlockScreen(getActivity(), mLockPatternUtils); + addPreferencesFromResource(resid); // Add options for device encryption mIsPrimary = UserHandle.myUserId() == UserHandle.USER_OWNER; @@ -619,4 +635,155 @@ public class SecuritySettings extends RestrictedSettingsFragment intent.setClassName("com.android.facelock", "com.android.facelock.AddToSetup"); startActivity(intent); } + + /** + * For Search. Please keep it in sync when updating "createPreferenceHierarchy()" + */ + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new SecuritySearchIndexProvider(); + + static private class SecuritySearchIndexProvider extends BaseSearchIndexProvider { + + boolean mIsPrimary; + + public SecuritySearchIndexProvider() { + super(); + + mIsPrimary = UserHandle.myUserId() == UserHandle.USER_OWNER; + } + + @Override + public List<SearchIndexableResource> getXmlResourcesToIndex( + Context context, boolean enabled) { + + List<SearchIndexableResource> result = new ArrayList<SearchIndexableResource>(); + + LockPatternUtils lockPatternUtils = new LockPatternUtils(context); + // Add options for lock/unlock screen + int resId = getResIdForLockUnlockScreen(context, lockPatternUtils); + + SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = resId; + result.add(sir); + + if (mIsPrimary) { + DevicePolicyManager dpm = (DevicePolicyManager) + context.getSystemService(Context.DEVICE_POLICY_SERVICE); + + switch (dpm.getStorageEncryptionStatus()) { + case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE: + // The device is currently encrypted. + resId = R.xml.security_settings_encrypted; + break; + case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE: + // This device supports encryption but isn't encrypted. + resId = R.xml.security_settings_unencrypted; + break; + } + + sir = new SearchIndexableResource(context); + sir.xmlResId = resId; + result.add(sir); + } + + // Append the rest of the settings + sir = new SearchIndexableResource(context); + sir.xmlResId = R.xml.security_settings_misc; + result.add(sir); + + return result; + } + + @Override + public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { + final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>(); + final Resources res = context.getResources(); + + final String screenTitle = res.getString(R.string.security_settings_title); + + SearchIndexableRaw data; + + if (!mIsPrimary) { + int resId = (UserManager.get(context).isLinkedUser()) ? + R.string.profile_info_settings_title : R.string.user_info_settings_title; + + data = new SearchIndexableRaw(context); + data.title = res.getString(resId); + data.screenTitle = screenTitle; + result.add(data); + } + + LockPatternUtils lockPatternUtils = new LockPatternUtils(context); + + if (!ActivityManager.isLowRamDeviceStatic() + && !lockPatternUtils.isLockScreenDisabled()) { + DevicePolicyManager dpm = (DevicePolicyManager) + context.getSystemService(Context.DEVICE_POLICY_SERVICE); + + final boolean disabled = (0 != (dpm.getKeyguardDisabledFeatures(null) + & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL)); + + if (disabled) { + data = new SearchIndexableRaw(context); + data.title = res.getString(R.string.security_enable_widgets_disabled_summary); + data.screenTitle = screenTitle; + result.add(data); + } + } + + // Credential storage + final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); + + if (!um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) { + KeyStore keyStore = KeyStore.getInstance(); + + final int storageSummaryRes = keyStore.isHardwareBacked() ? + R.string.credential_storage_type_hardware : + R.string.credential_storage_type_software; + + data = new SearchIndexableRaw(context); + data.title = res.getString(storageSummaryRes); + data.screenTitle = screenTitle; + result.add(data); + } + + return result; + } + + @Override + public List<String> getNonIndexableKeys(Context context) { + final List<String> keys = new ArrayList<String>(); + + LockPatternUtils lockPatternUtils = new LockPatternUtils(context); + // Add options for lock/unlock screen + int resId = getResIdForLockUnlockScreen(context, lockPatternUtils); + + // don't display visible pattern if biometric and backup is not pattern + if (resId == R.xml.security_settings_biometric_weak && + lockPatternUtils.getKeyguardStoredPasswordQuality() != + DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) { + keys.add(KEY_VISIBLE_PATTERN); + } + + // Do not display SIM lock for devices without an Icc card + TelephonyManager tm = TelephonyManager.getDefault(); + if (!mIsPrimary || !tm.hasIccCard()) { + keys.add(KEY_SIM_LOCK); + } + + if (ActivityManager.isLowRamDeviceStatic() + || lockPatternUtils.isLockScreenDisabled()) { + // Widgets take a lot of RAM, so disable them on low-memory devices + keys.add(KEY_ENABLE_WIDGETS); + } + + final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); + if (um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) { + keys.add(KEY_CREDENTIALS_MANAGER); + } + + return keys; + } + } + } diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index 7cdf781..0680762 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -84,6 +84,7 @@ import com.android.settings.dashboard.SearchResultsSummary; import com.android.settings.deviceinfo.Memory; import com.android.settings.deviceinfo.UsbSettings; import com.android.settings.fuelgauge.PowerUsageSummary; +import com.android.settings.search.DynamicIndexableContentMonitor; import com.android.settings.search.Index; import com.android.settings.inputmethod.InputMethodAndLanguageSettings; import com.android.settings.inputmethod.KeyboardLayoutPickerFragment; @@ -146,6 +147,11 @@ public class SettingsActivity extends Activity public static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args"; /** + * Fragment "key" argument passed thru {@link #EXTRA_SHOW_FRAGMENT_ARGUMENTS} + */ + public static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key"; + + /** * When starting this activity, the invoking Intent can contain this extra * boolean that the header list should not be displayed. This is most often * used in conjunction with {@link #EXTRA_SHOW_FRAGMENT} to launch @@ -299,6 +305,9 @@ public class SettingsActivity extends Activity } }; + private final DynamicIndexableContentMonitor mDynamicIndexableContentMonitor = + new DynamicIndexableContentMonitor(); + private Button mNextButton; private ActionBar mActionBar; private boolean mDisplayHomeAsUpEnabled; @@ -403,7 +412,6 @@ public class SettingsActivity extends Activity if (getIntent().hasExtra(EXTRA_UI_OPTIONS)) { getWindow().setUiOptions(getIntent().getIntExtra(EXTRA_UI_OPTIONS, 0)); } - Index.getInstance(this).update(); mAuthenticatorHelper = new AuthenticatorHelper(); @@ -461,6 +469,7 @@ public class SettingsActivity extends Activity final String initialTitle = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT_TITLE); mInitialTitle = (initialTitle != null) ? initialTitle : getTitle(); setTitle(mInitialTitle); + switchToFragment( initialFragmentName, initialArguments, true, false, mInitialTitle, false); } else { @@ -605,6 +614,8 @@ public class SettingsActivity extends Activity invalidateHeaders(); registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); + + mDynamicIndexableContentMonitor.register(this); } @Override @@ -619,6 +630,8 @@ public class SettingsActivity extends Activity mDevelopmentPreferencesListener); mDevelopmentPreferencesListener = null; + + mDynamicIndexableContentMonitor.unregister(); } @Override @@ -654,12 +667,6 @@ public class SettingsActivity extends Activity header.getTitle(getResources())); } else if (header.intent != null) { startActivity(header.intent); - } else { - String title = header.getTitle(getResources()).toString(); - Log.e(LOG_TAG, "Can't switch to header that has no Fragment nor Intent. Title: " + - title + " Position: " + position); - throw new IllegalStateException( - "Can't switch to header that has no Fragment nor Intent"); } } @@ -740,8 +747,11 @@ public class SettingsActivity extends Activity String title; if (titleRes > 0) { title = getString(titleRes); - } else { + } else if (titleText != null) { title = titleText.toString(); + } else { + // There not much we can do in that case + title = ""; } startWithFragment(fragmentClass, args, resultTo, resultRequestCode, title); } diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java index 35893ff..d575153 100644 --- a/src/com/android/settings/SettingsPreferenceFragment.java +++ b/src/com/android/settings/SettingsPreferenceFragment.java @@ -26,12 +26,15 @@ import android.content.pm.PackageManager; import android.os.Bundle; import android.preference.Preference; import android.preference.PreferenceFragment; +import android.preference.PreferenceGroup; +import android.preference.PreferenceGroupAdapter; import android.text.TextUtils; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.widget.Button; +import android.widget.ListAdapter; /** * Base class for Settings fragments, with some helper functions and dialog management. @@ -41,6 +44,7 @@ public class SettingsPreferenceFragment extends PreferenceFragment implements Di private static final String TAG = "SettingsPreferenceFragment"; private static final int MENU_HELP = Menu.FIRST + 100; + private static final int HIGHLIGHT_DURATION_MILLIS = 750; private SettingsDialogFragment mDialogFragment; @@ -66,6 +70,47 @@ public class SettingsPreferenceFragment extends PreferenceFragment implements Di if (!TextUtils.isEmpty(mHelpUrl)) { setHasOptionsMenu(true); } + + final Bundle args = getArguments(); + if (args != null) { + final String key = args.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY); + final int position = findPositionFromKey(getPreferenceScreen(), key); + if (position >= 0) { + final ListAdapter adapter = getListView().getAdapter(); + if (adapter instanceof PreferenceGroupAdapter) { + ((PreferenceGroupAdapter) adapter).setActivated(position); + + getListView().postDelayed(new Runnable() { + @Override + public void run() { + ((PreferenceGroupAdapter) adapter).setActivated(-1); + ((PreferenceGroupAdapter) adapter).notifyDataSetChanged(); + } + }, HIGHLIGHT_DURATION_MILLIS); + } + } + } + } + + private int findPositionFromKey(PreferenceGroup group, String key) { + if (group != null) { + int count = group.getPreferenceCount(); + for (int n = 0; n < count; n++) { + final Preference preference = group.getPreference(n); + final String preferenceKey = preference.getKey(); + if (preferenceKey != null && preferenceKey.equals(key)) { + return n; + } + if (preference instanceof PreferenceGroup) { + PreferenceGroup nestedGroup = (PreferenceGroup) preference; + final int nestedPosition = findPositionFromKey(nestedGroup, key); + if (nestedPosition >= 0) { + return n + 1 + nestedPosition; + } + } + } + } + return -1; } protected void removePreference(String key) { diff --git a/src/com/android/settings/SoundSettings.java b/src/com/android/settings/SoundSettings.java index 45fd0db..49928f5 100644 --- a/src/com/android/settings/SoundSettings.java +++ b/src/com/android/settings/SoundSettings.java @@ -47,11 +47,14 @@ import android.provider.MediaStore; import android.provider.Settings; import android.telephony.TelephonyManager; import android.util.Log; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.Indexable; +import java.util.ArrayList; import java.util.List; public class SoundSettings extends SettingsPreferenceFragment implements - Preference.OnPreferenceChangeListener { + Preference.OnPreferenceChangeListener, Indexable { private static final String TAG = "SoundSettings"; private static final int DIALOG_NOT_DOCKED = 1; @@ -446,5 +449,23 @@ public class SoundSettings extends SettingsPreferenceFragment implements ab.setPositiveButton(android.R.string.ok, null); return ab.create(); } + + public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List<String> getNonIndexableKeys(Context context) { + final List<String> keys = new ArrayList<String>(); + + int activePhoneType = TelephonyManager.getDefault().getCurrentPhoneType(); + + if (TelephonyManager.PHONE_TYPE_CDMA != activePhoneType) { + // device is not CDMA, do not display CDMA emergency_tone + keys.add(KEY_EMERGENCY_TONE); + } + + return keys; + } + }; + } diff --git a/src/com/android/settings/WallpaperTypeSettings.java b/src/com/android/settings/WallpaperTypeSettings.java index b9237fa..7b2dcbf 100644 --- a/src/com/android/settings/WallpaperTypeSettings.java +++ b/src/com/android/settings/WallpaperTypeSettings.java @@ -24,7 +24,7 @@ import android.content.pm.ResolveInfo; import android.os.Bundle; import android.preference.Preference; import android.preference.PreferenceScreen; -import android.provider.SearchIndexableResource; +import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settings.search.SearchIndexableRaw; @@ -65,13 +65,7 @@ public class WallpaperTypeSettings extends SettingsPreferenceFragment implements } public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new SearchIndexProvider() { - @Override - public List<SearchIndexableResource> getXmlResourcesToIndex( - Context context, boolean enabled) { - return null; - } - + new BaseSearchIndexProvider() { @Override public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>(); diff --git a/src/com/android/settings/ZenModeSettings.java b/src/com/android/settings/ZenModeSettings.java index 65acb15..51b43fd 100644 --- a/src/com/android/settings/ZenModeSettings.java +++ b/src/com/android/settings/ZenModeSettings.java @@ -28,7 +28,6 @@ import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.provider.Settings.Global; -import android.provider.SearchIndexableResource; import android.util.Log; import android.util.TypedValue; import android.view.Gravity; @@ -45,6 +44,7 @@ import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.Switch; import android.widget.TextView; +import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settings.search.SearchIndexableRaw; @@ -292,14 +292,7 @@ public class ZenModeSettings extends SettingsPreferenceFragment implements Index // Enable indexing of searchable data public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new Indexable.SearchIndexProvider() { - - @Override - public List<SearchIndexableResource> getXmlResourcesToIndex( - Context context, boolean enabled) { - return null; - } - + new BaseSearchIndexProvider() { @Override public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>(); diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java index 9c1e300..1144985 100644 --- a/src/com/android/settings/accessibility/AccessibilitySettings.java +++ b/src/com/android/settings/accessibility/AccessibilitySettings.java @@ -20,6 +20,7 @@ import android.accessibilityservice.AccessibilityServiceInfo; import android.app.ActivityManagerNative; import android.content.ComponentName; import android.content.Context; +import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.res.Configuration; @@ -32,6 +33,7 @@ import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceCategory; import android.preference.PreferenceScreen; +import android.provider.SearchIndexableResource; import android.provider.Settings; import android.text.TextUtils; import android.text.TextUtils.SimpleStringSplitter; @@ -48,7 +50,11 @@ import com.android.settings.DialogCreatable; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.Indexable; +import com.android.settings.search.SearchIndexableRaw; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -59,7 +65,7 @@ import java.util.Set; * Activity with the accessibility settings. */ public class AccessibilitySettings extends SettingsPreferenceFragment implements DialogCreatable, - Preference.OnPreferenceChangeListener { + Preference.OnPreferenceChangeListener, Indexable { private static final float LARGE_FONT_SCALE = 1.3f; @@ -570,4 +576,45 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements installedServices.add(installedService); } } + + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { + List<SearchIndexableRaw> indexables = new ArrayList<SearchIndexableRaw>(); + + PackageManager packageManager = context.getPackageManager(); + AccessibilityManager accessibilityManager = (AccessibilityManager) + context.getSystemService(Context.ACCESSIBILITY_SERVICE); + + String screenTitle = context.getResources().getString( + R.string.accessibility_services_title); + + // Indexing all services, reagardles if enabled. + List<AccessibilityServiceInfo> services = accessibilityManager + .getInstalledAccessibilityServiceList(); + final int serviceCount = services.size(); + for (int i = 0; i < serviceCount; i++) { + AccessibilityServiceInfo service = services.get(i); + SearchIndexableRaw indexable = new SearchIndexableRaw(context); + indexable.title = service.getResolveInfo().loadLabel(packageManager).toString(); + indexable.summaryOn = context.getString(R.string.accessibility_feature_state_on); + indexable.summaryOff = context.getString(R.string.accessibility_feature_state_off); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + } + + return indexables; + } + + @Override + public List<SearchIndexableResource> getXmlResourcesToIndex(Context context, + boolean enabled) { + List<SearchIndexableResource> indexables = new ArrayList<SearchIndexableResource>(); + SearchIndexableResource indexable = new SearchIndexableResource(context); + indexable.xmlResId = R.xml.accessibility_settings; + indexables.add(indexable); + return indexables; + } + }; } diff --git a/src/com/android/settings/accessibility/CaptionPropertiesFragment.java b/src/com/android/settings/accessibility/CaptionPropertiesFragment.java index 49e31cf..810b8b5 100644 --- a/src/com/android/settings/accessibility/CaptionPropertiesFragment.java +++ b/src/com/android/settings/accessibility/CaptionPropertiesFragment.java @@ -129,11 +129,14 @@ public class CaptionPropertiesFragment extends SettingsPreferenceFragment mPreviewText = (SubtitleView) view.findViewById(R.id.preview_text); mPreviewText.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE); - final Context context = view.getContext(); + final Context context = getActivity().getActionBar().getThemedContext(); final int padding = context.getResources().getDimensionPixelSize( R.dimen.action_bar_switch_padding); mToggleSwitch = new ToggleSwitch(context); mToggleSwitch.setPaddingRelative(0, 0, padding, 0); + mToggleSwitch.setLayoutParams(new ActionBar.LayoutParams( + ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT, + Gravity.CENTER_VERTICAL | Gravity.END)); mToggleSwitch.setCheckedInternal(enabled); mPreviewWindow = view.findViewById(R.id.preview_window); @@ -220,11 +223,8 @@ public class CaptionPropertiesFragment extends SettingsPreferenceFragment private void installActionBarToggleSwitch() { final ActionBar ab = getActivity().getActionBar(); - final ActionBar.LayoutParams params = new ActionBar.LayoutParams( - ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT, - Gravity.CENTER_VERTICAL | Gravity.END); ab.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM); - ab.setCustomView(mToggleSwitch, params); + ab.setCustomView(mToggleSwitch); onInstallActionBarToggleSwitch(); } diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java index 03f9072..a6901ad 100644 --- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java @@ -88,11 +88,14 @@ public abstract class ToggleFeaturePreferenceFragment public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - final Context context = view.getContext(); + final Context context = getActivity().getActionBar().getThemedContext(); final int padding = context.getResources().getDimensionPixelSize( R.dimen.action_bar_switch_padding); mToggleSwitch = new ToggleSwitch(context); mToggleSwitch.setPaddingRelative(0, 0, padding, 0); + mToggleSwitch.setLayoutParams(new ActionBar.LayoutParams( + ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT, + Gravity.CENTER_VERTICAL | Gravity.END)); onProcessArguments(getArguments()); } @@ -127,11 +130,8 @@ public abstract class ToggleFeaturePreferenceFragment private void installActionBarToggleSwitch() { final ActionBar ab = getActivity().getActionBar(); - final ActionBar.LayoutParams params = new ActionBar.LayoutParams( - ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT, - Gravity.CENTER_VERTICAL | Gravity.END); ab.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM); - ab.setCustomView(mToggleSwitch, params); + ab.setCustomView(mToggleSwitch); onInstallActionBarToggleSwitch(); } diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java index 80a3d1f..e336ae4 100644 --- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java +++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java @@ -35,6 +35,8 @@ import android.view.View.OnClickListener; import android.widget.ImageView; import com.android.settings.R; +import com.android.settings.search.Index; +import com.android.settings.search.SearchIndexableRaw; import java.util.List; @@ -209,6 +211,17 @@ public final class BluetoothDevicePreference extends Preference implements if (!mCachedDevice.startPairing()) { Utils.showError(getContext(), mCachedDevice.getName(), R.string.bluetooth_pairing_error_message); + } else { + final Context context = getContext(); + + SearchIndexableRaw data = new SearchIndexableRaw(context); + data.className = BluetoothSettings.class.getName(); + data.title = mCachedDevice.getName(); + data.screenTitle = context.getResources().getString(R.string.bluetooth_settings); + data.iconResId = R.drawable.ic_settings_bluetooth2; + data.enabled = true; + + Index.getInstance(context).updateFromSearchIndexableData(data); } } diff --git a/src/com/android/settings/bluetooth/BluetoothEnabler.java b/src/com/android/settings/bluetooth/BluetoothEnabler.java index bbf5fcc..70a8097 100644 --- a/src/com/android/settings/bluetooth/BluetoothEnabler.java +++ b/src/com/android/settings/bluetooth/BluetoothEnabler.java @@ -166,6 +166,6 @@ public final class BluetoothEnabler implements CompoundButton.OnCheckedChangeLis private void updateSearchIndex(boolean isBluetoothOn) { Index.getInstance(mContext).updateFromClassNameResource( - BluetoothSettings.class.getName(), isBluetoothOn); + BluetoothSettings.class.getName(), false, isBluetoothOn); } } diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java index 7068bc7..b707e7b 100755 --- a/src/com/android/settings/bluetooth/BluetoothSettings.java +++ b/src/com/android/settings/bluetooth/BluetoothSettings.java @@ -32,7 +32,6 @@ import android.preference.Preference; import android.preference.PreferenceCategory; import android.preference.PreferenceGroup; import android.preference.PreferenceScreen; -import android.provider.SearchIndexableResource; import android.util.Log; import android.view.Gravity; import android.view.Menu; @@ -44,6 +43,7 @@ import android.widget.TextView; import com.android.settings.R; import com.android.settings.SettingsActivity; +import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settings.search.SearchIndexableRaw; @@ -418,14 +418,7 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem } public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new SearchIndexProvider() { - - @Override - public List<SearchIndexableResource> getXmlResourcesToIndex( - Context context, boolean enabled) { - return null; - } - + new BaseSearchIndexProvider() { @Override public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { diff --git a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java index 335d888..b50d2b4 100755 --- a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java +++ b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java @@ -38,6 +38,8 @@ import android.widget.Button; import android.text.Editable; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.search.Index; +import com.android.settings.search.SearchIndexableRaw; import java.util.HashMap; @@ -230,6 +232,16 @@ public final class DeviceProfilesSettings extends SettingsPreferenceFragment if (key.equals(KEY_UNPAIR)) { unpairDevice(); finish(); + final Context context = preference.getContext(); + + SearchIndexableRaw data = new SearchIndexableRaw(context); + data.className = BluetoothSettings.class.getName(); + data.title = mCachedDevice.getName(); + data.screenTitle = context.getResources().getString(R.string.bluetooth_settings); + data.iconResId = R.drawable.ic_settings_bluetooth2; + data.enabled = false; + + Index.getInstance(context).updateFromSearchIndexableData(data); return true; } diff --git a/src/com/android/settings/dashboard/SearchResultsSummary.java b/src/com/android/settings/dashboard/SearchResultsSummary.java index 706ae0f..94f3778 100644 --- a/src/com/android/settings/dashboard/SearchResultsSummary.java +++ b/src/com/android/settings/dashboard/SearchResultsSummary.java @@ -46,11 +46,14 @@ public class SearchResultsSummary extends Fragment { private static final String LOG_TAG = "SearchResultsSummary"; + private static char ELLIPSIS = '\u2026'; + private ListView mListView; private SearchResultsAdapter mAdapter; private UpdateSearchResultsTask mUpdateSearchResultsTask; + /** * A basic AsyncTask for updating the query results cursor */ @@ -109,15 +112,18 @@ public class SearchResultsSummary extends Fragment { final String className = cursor.getString(Index.COLUMN_INDEX_CLASS_NAME); final String screenTitle = cursor.getString(Index.COLUMN_INDEX_SCREEN_TITLE); - final String action = cursor.getString(Index.COLUMN_INDEX_INTENT_ACTION); + final String key = cursor.getString(Index.COLUMN_INDEX_KEY); final SettingsActivity sa = (SettingsActivity) getActivity(); sa.needToRevertToInitialFragment(); if (TextUtils.isEmpty(action)) { - sa.startWithFragment(className, null, null, 0, screenTitle); + Bundle args = new Bundle(); + args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key); + + sa.startWithFragment(className, args, null, 0, screenTitle); } else { final Intent intent = new Intent(action); @@ -130,6 +136,7 @@ public class SearchResultsSummary extends Fragment { new ComponentName(targetPackage, targetClass); intent.setComponent(component); } + intent.putExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key); sa.startActivity(intent); } @@ -194,21 +201,23 @@ public class SearchResultsSummary extends Fragment { } private static class SearchResult { + public Context context; public String title; public String summaryOn; public String summaryOff; public String entries; public int iconResId; - public Context context; + public String key; public SearchResult(Context context, String title, String summaryOn, String summaryOff, - String entries, int iconResId) { + String entries, int iconResId, String key) { this.context = context; this.title = title; this.summaryOn = summaryOn; this.summaryOff = summaryOff; this.entries = entries; this.iconResId = iconResId; + this.key = key; } } @@ -263,6 +272,8 @@ public class SearchResultsSummary extends Fragment { Index.COLUMN_INDEX_CLASS_NAME); final String packageName = mCursor.getString( Index.COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE); + final String key = mCursor.getString( + Index.COLUMN_INDEX_KEY); Context packageContext; if (TextUtils.isEmpty(className) && !TextUtils.isEmpty(packageName)) { @@ -284,7 +295,7 @@ public class SearchResultsSummary extends Fragment { R.drawable.empty_icon : Integer.parseInt(iconResStr); return new SearchResult(packageContext, title, summaryOn, summaryOff, - entries, iconResId); + entries, iconResId, key); } return null; } @@ -323,7 +334,6 @@ public class SearchResultsSummary extends Fragment { textTitle.setText(result.title); String summaryOn = result.summaryOn; - String summaryOff = result.summaryOff; String entries = result.entries; final StringBuilder sb = new StringBuilder(); @@ -331,18 +341,19 @@ public class SearchResultsSummary extends Fragment { if (!TextUtils.isEmpty(summaryOn) && !summaryOn.contains(PERCENT_RECLACE) && !summaryOn.contains(DOLLAR_REPLACE)) { sb.append(summaryOn); - if (!TextUtils.isEmpty(summaryOff) && - !summaryOff.contains(PERCENT_RECLACE) && - !summaryOff.contains(DOLLAR_REPLACE)) { - sb.append(" \n "); - sb.append(summaryOff); + sb.append(ELLIPSIS); + } else if (!TextUtils.isEmpty(entries)) { + final int index = entries.indexOf(Index.ENTRIES_SEPARATOR); + if (index > 0) { + final String firstEntriesValue = entries.substring(0, index); + sb.append(firstEntriesValue); + } else { + sb.append(entries); } - } - if (!TextUtils.isEmpty(entries)) { - sb.append(" \n "); - sb.append(entries); + sb.append(ELLIPSIS); } textSummary.setText(sb.toString()); + if (result.iconResId != R.drawable.empty_icon) { final Context packageContext = result.context; final Drawable drawable; diff --git a/src/com/android/settings/deviceinfo/Memory.java b/src/com/android/settings/deviceinfo/Memory.java index de793cf..68d0d5f 100644 --- a/src/com/android/settings/deviceinfo/Memory.java +++ b/src/com/android/settings/deviceinfo/Memory.java @@ -52,6 +52,7 @@ import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; +import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settings.search.SearchIndexableRaw; import com.google.android.collect.Lists; @@ -432,14 +433,7 @@ public class Memory extends SettingsPreferenceFragment implements Indexable{ * Enable indexing of searchable data */ public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new SearchIndexProvider() { - - @Override - public List<SearchIndexableResource> getXmlResourcesToIndex( - Context context, boolean enabled) { - return null; - } - + new BaseSearchIndexProvider() { @Override public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>(); diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java index dbfa1bc..c0e930e 100644 --- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java +++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java @@ -23,6 +23,9 @@ import com.android.settings.SettingsPreferenceFragment; import com.android.settings.UserDictionarySettings; import com.android.settings.Utils; import com.android.settings.VoiceInputOutputSettings; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.Indexable; +import com.android.settings.search.SearchIndexableRaw; import android.app.Activity; import android.app.Fragment; @@ -30,6 +33,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.database.ContentObserver; @@ -47,10 +51,13 @@ import android.preference.PreferenceCategory; import android.preference.PreferenceScreen; import android.provider.Settings; import android.provider.Settings.System; +import android.speech.RecognitionService; +import android.speech.tts.TtsEngines; import android.text.TextUtils; import android.view.InputDevice; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; +import android.view.inputmethod.InputMethodSubtype; import android.widget.BaseAdapter; import java.util.ArrayList; @@ -60,7 +67,7 @@ import java.util.TreeSet; public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment implements Preference.OnPreferenceChangeListener, InputManager.InputDeviceListener, - KeyboardLayoutDialogFragment.OnSetupKeyboardLayoutsListener { + KeyboardLayoutDialogFragment.OnSetupKeyboardLayoutsListener, Indexable { private static final String KEY_PHONE_LANGUAGE = "phone_language"; private static final String KEY_CURRENT_INPUT_METHOD = "current_input_method"; @@ -242,34 +249,8 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment if (!mIsOnlyImeSettings) { if (mLanguagePref != null) { - Configuration conf = getResources().getConfiguration(); - String language = conf.locale.getLanguage(); - String localeString; - // TODO: This is not an accurate way to display the locale, as it is - // just working around the fact that we support limited dialects - // and want to pretend that the language is valid for all locales. - // We need a way to support languages that aren't tied to a particular - // locale instead of hiding the locale qualifier. - if (language.equals("zz")) { - String country = conf.locale.getCountry(); - if (country.equals("ZZ")) { - localeString = "[Developer] Accented English (zz_ZZ)"; - } else if (country.equals("ZY")) { - localeString = "[Developer] Fake Bi-Directional (zz_ZY)"; - } else { - localeString = ""; - } - } else if (hasOnlyOneLanguageInstance(language, - Resources.getSystem().getAssets().getLocales())) { - localeString = conf.locale.getDisplayLanguage(conf.locale); - } else { - localeString = conf.locale.getDisplayName(conf.locale); - } - if (localeString.length() > 1) { - localeString = Character.toUpperCase(localeString.charAt(0)) - + localeString.substring(1); - mLanguagePref.setSummary(localeString); - } + String localeName = getLocaleName(getResources()); + mLanguagePref.setSummary(localeName); } updateUserDictionaryPreference(findPreference(KEY_USER_DICTIONARY_SETTINGS)); @@ -361,7 +342,40 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment return super.onPreferenceTreeClick(preferenceScreen, preference); } - private boolean hasOnlyOneLanguageInstance(String languageCode, String[] locales) { + private static String getLocaleName(Resources resources) { + Configuration conf = resources.getConfiguration(); + String language = conf.locale.getLanguage(); + String localeName; + // TODO: This is not an accurate way to display the locale, as it is + // just working around the fact that we support limited dialects + // and want to pretend that the language is valid for all locales. + // We need a way to support languages that aren't tied to a particular + // locale instead of hiding the locale qualifier. + if (language.equals("zz")) { + String country = conf.locale.getCountry(); + if (country.equals("ZZ")) { + localeName = "[Developer] Accented English (zz_ZZ)"; + } else if (country.equals("ZY")) { + localeName = "[Developer] Fake Bi-Directional (zz_ZY)"; + } else { + localeName = ""; + } + } else if (hasOnlyOneLanguageInstance(language, + Resources.getSystem().getAssets().getLocales())) { + localeName = conf.locale.getDisplayLanguage(conf.locale); + } else { + localeName = conf.locale.getDisplayName(conf.locale); + } + + if (localeName.length() > 1) { + localeName = Character.toUpperCase(localeName.charAt(0)) + + localeName.substring(1); + } + + return localeName; + } + + private static boolean hasOnlyOneLanguageInstance(String languageCode, String[] locales) { int count = 0; for (String localeCode : locales) { if (localeCode.length() > 2 @@ -582,7 +596,7 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment } } - private boolean haveInputDeviceWithVibrator() { + private static boolean haveInputDeviceWithVibrator() { final int[] devices = InputDevice.getDeviceIds(); for (int i = 0; i < devices.length; i++) { InputDevice device = InputDevice.getDevice(devices[i]); @@ -617,4 +631,225 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment mContext.getContentResolver().unregisterContentObserver(this); } } + + public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { + List<SearchIndexableRaw> indexables = new ArrayList<SearchIndexableRaw>(); + + Resources resources = context.getResources(); + String screenTitle = context.getString(R.string.language_keyboard_settings_title); + + // Locale picker. + if (context.getAssets().getLocales().length > 1) { + String localeName = getLocaleName(resources); + SearchIndexableRaw indexable = new SearchIndexableRaw(context); + indexable.title = context.getString(R.string.phone_language); + indexable.summaryOn = localeName; + indexable.summaryOff = localeName; + indexable.screenTitle = screenTitle; + indexables.add(indexable); + } + + // Spell checker. + SearchIndexableRaw indexable = new SearchIndexableRaw(context); + indexable.title = context.getString(R.string.spellcheckers_settings_title); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + + // User dictionary. + if (UserDictionaryList.getUserDictionaryLocalesSet(context) != null) { + indexable = new SearchIndexableRaw(context); + indexable.title = context.getString(R.string.user_dict_settings_title); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + } + + // Keyboard settings. + indexable = new SearchIndexableRaw(context); + indexable.title = context.getString(R.string.keyboard_settings_category); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + + InputMethodSettingValuesWrapper immValues = InputMethodSettingValuesWrapper + .getInstance(context); + immValues.refreshAllInputMethodAndSubtypes(); + + // Current IME. + String currImeName = immValues.getCurrentInputMethodName(context).toString(); + indexable = new SearchIndexableRaw(context); + indexable.title = context.getString(R.string.current_input_method); + indexable.summaryOn = currImeName; + indexable.summaryOff = currImeName; + indexable.screenTitle = screenTitle; + indexables.add(indexable); + + InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService( + Context.INPUT_METHOD_SERVICE); + + // All other IMEs. + List<InputMethodInfo> inputMethods = immValues.getInputMethodList(); + final int inputMethodCount = (inputMethods == null ? 0 : inputMethods.size()); + for (int i = 0; i < inputMethodCount; ++i) { + InputMethodInfo inputMethod = inputMethods.get(i); + + StringBuilder builder = new StringBuilder(); + List<InputMethodSubtype> subtypes = inputMethodManager + .getEnabledInputMethodSubtypeList(inputMethod, true); + final int subtypeCount = subtypes.size(); + for (int j = 0; j < subtypeCount; j++) { + InputMethodSubtype subtype = subtypes.get(j); + if (builder.length() > 0) { + builder.append(','); + } + CharSequence subtypeLabel = subtype.getDisplayName(context, + inputMethod.getPackageName(), inputMethod.getServiceInfo() + .applicationInfo); + builder.append(subtypeLabel); + } + String summary = builder.toString(); + + indexable = new SearchIndexableRaw(context); + indexable.title = inputMethod.loadLabel(context.getPackageManager()).toString(); + indexable.summaryOn = summary; + indexable.summaryOff = summary; + indexable.screenTitle = screenTitle; + indexables.add(indexable); + } + + // Hard keyboards + InputManager inputManager = (InputManager) context.getSystemService( + Context.INPUT_SERVICE); + if (resources.getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY) { + boolean hasHardKeyboards = false; + + final int[] devices = InputDevice.getDeviceIds(); + for (int i = 0; i < devices.length; i++) { + InputDevice device = InputDevice.getDevice(devices[i]); + if (device == null || device.isVirtual() || !device.isFullKeyboard()) { + continue; + } + + hasHardKeyboards = true; + + InputDeviceIdentifier identifier = device.getIdentifier(); + String keyboardLayoutDescriptor = + inputManager.getCurrentKeyboardLayoutForInputDevice(identifier); + KeyboardLayout keyboardLayout = keyboardLayoutDescriptor != null ? + inputManager.getKeyboardLayout(keyboardLayoutDescriptor) : null; + + String summary; + if (keyboardLayout != null) { + summary = keyboardLayout.toString(); + } else { + summary = context.getString(R.string.keyboard_layout_default_label); + } + + indexable = new SearchIndexableRaw(context); + indexable.title = device.getName(); + indexable.summaryOn = summary; + indexable.summaryOff = summary; + indexable.screenTitle = screenTitle; + indexables.add(indexable); + } + + if (hasHardKeyboards) { + // Hard keyboard category. + indexable = new SearchIndexableRaw(context); + indexable.title = context.getString( + R.string.builtin_keyboard_settings_title); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + + // Auto replace. + indexable = new SearchIndexableRaw(context); + indexable.title = context.getString(R.string.auto_replace); + indexable.summaryOn = context.getString(R.string.auto_replace_summary); + indexable.summaryOff = context.getString(R.string.auto_replace_summary); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + + // Auto caps. + indexable = new SearchIndexableRaw(context); + indexable.title = context.getString(R.string.auto_caps); + indexable.summaryOn = context.getString(R.string.auto_caps_summary); + indexable.summaryOff = context.getString(R.string.auto_caps_summary); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + + // Auto punctuate. + indexable = new SearchIndexableRaw(context); + indexable.title = context.getString(R.string.auto_punctuate); + indexable.summaryOn = context.getString(R.string.auto_punctuate_summary); + indexable.summaryOff = context.getString(R.string.auto_punctuate_summary); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + } + } + + // Voice recognizers. + List<ResolveInfo> recognizers = context.getPackageManager() + .queryIntentServices(new Intent(RecognitionService.SERVICE_INTERFACE), + PackageManager.GET_META_DATA); + + final int recognizerCount = recognizers.size(); + + // Recognizer settings. + if (recognizerCount > 0) { + indexable = new SearchIndexableRaw(context); + indexable.title = context.getString(R.string.recognizer_settings_title); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + } + + if (recognizerCount > 1) { + // Recognizer chooser. + indexable = new SearchIndexableRaw(context); + indexable.title = context.getString(R.string.recognizer_title); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + } + + for (int i = 0; i < recognizerCount; i++) { + ResolveInfo recognizer = recognizers.get(i); + indexable = new SearchIndexableRaw(context); + indexable.title = recognizer.loadLabel(context.getPackageManager()).toString(); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + } + + // Text-to-speech. + TtsEngines ttsEngines = new TtsEngines(context); + if (!ttsEngines.getEngines().isEmpty()) { + indexable = new SearchIndexableRaw(context); + indexable.title = context.getString(R.string.tts_settings_title); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + } + + // Pointer settings. + indexable = new SearchIndexableRaw(context); + indexable.title = context.getString(R.string.pointer_settings_category); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + + indexable = new SearchIndexableRaw(context); + indexable.title = context.getString(R.string.pointer_speed); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + + // Game controllers. + if (haveInputDeviceWithVibrator()) { + indexable = new SearchIndexableRaw(context); + indexable.title = context.getString(R.string.vibrate_input_devices); + indexable.summaryOn = context.getString(R.string.vibrate_input_devices_summary); + indexable.summaryOff = context.getString(R.string.vibrate_input_devices_summary); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + } + + return indexables; + } + }; } diff --git a/src/com/android/settings/inputmethod/UserDictionaryList.java b/src/com/android/settings/inputmethod/UserDictionaryList.java index 24acb4a..7439001 100644 --- a/src/com/android/settings/inputmethod/UserDictionaryList.java +++ b/src/com/android/settings/inputmethod/UserDictionaryList.java @@ -72,22 +72,27 @@ public class UserDictionaryList extends SettingsPreferenceFragment { mLocale = locale; } - public static TreeSet<String> getUserDictionaryLocalesSet(Activity activity) { - @SuppressWarnings("deprecation") - final Cursor cursor = activity.managedQuery(UserDictionary.Words.CONTENT_URI, - new String[] { UserDictionary.Words.LOCALE }, + public static TreeSet<String> getUserDictionaryLocalesSet(Context context) { + final Cursor cursor = context.getContentResolver().query( + UserDictionary.Words.CONTENT_URI, new String[] { UserDictionary.Words.LOCALE }, null, null, null); final TreeSet<String> localeSet = new TreeSet<String>(); if (null == cursor) { // The user dictionary service is not present or disabled. Return null. return null; - } else if (cursor.moveToFirst()) { - final int columnIndex = cursor.getColumnIndex(UserDictionary.Words.LOCALE); - do { - final String locale = cursor.getString(columnIndex); - localeSet.add(null != locale ? locale : ""); - } while (cursor.moveToNext()); } + try { + if (cursor.moveToFirst()) { + final int columnIndex = cursor.getColumnIndex(UserDictionary.Words.LOCALE); + do { + final String locale = cursor.getString(columnIndex); + localeSet.add(null != locale ? locale : ""); + } while (cursor.moveToNext()); + } + } finally { + cursor.close(); + } + // CAVEAT: Keep this for consistency of the implementation between Keyboard and Settings // if (!UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED) { // // For ICS, we need to show "For all languages" in case that the keyboard locale @@ -96,7 +101,7 @@ public class UserDictionaryList extends SettingsPreferenceFragment { // } final InputMethodManager imm = - (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE); + (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); final List<InputMethodInfo> imis = imm.getEnabledInputMethodList(); for (final InputMethodInfo imi : imis) { final List<InputMethodSubtype> subtypes = diff --git a/src/com/android/settings/print/PrintServiceSettingsFragment.java b/src/com/android/settings/print/PrintServiceSettingsFragment.java index d5bfce2..3bba963 100644 --- a/src/com/android/settings/print/PrintServiceSettingsFragment.java +++ b/src/com/android/settings/print/PrintServiceSettingsFragment.java @@ -62,7 +62,6 @@ import android.widget.SearchView; import android.widget.TextView; import com.android.settings.R; -import com.android.settings.SettingsActivity; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.print.PrintSettingsFragment.ToggleSwitch; import com.android.settings.print.PrintSettingsFragment.ToggleSwitch.OnBeforeCheckedChangeListener; @@ -160,8 +159,14 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment } @Override + public void onStart() { + super.onStart(); + setupActionBarToggleSwitch(getActivity(), mToggleSwitch); + } + + @Override public void onDestroyView() { - getActivity().getActionBar().setCustomView(null); + removeActionBarToggleSwitch(getActivity()); if (mOldActivityTitle != null) { getActivity().getActionBar().setTitle(mOldActivityTitle); } @@ -289,7 +294,7 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment mPrintersAdapter = new PrintersAdapter(); mPrintersAdapter.registerDataSetObserver(mDataObserver); - mToggleSwitch = createAndAddActionBarToggleSwitch(getActivity()); + mToggleSwitch = createActionBarToggleSwitch(getActivity()); mToggleSwitch.setOnBeforeCheckedChangeListener(new OnBeforeCheckedChangeListener() { @Override public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) { @@ -440,18 +445,25 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment } } - private ToggleSwitch createAndAddActionBarToggleSwitch(Activity activity) { + private ToggleSwitch createActionBarToggleSwitch(Activity activity) { ToggleSwitch toggleSwitch = new ToggleSwitch(activity); final int padding = activity.getResources().getDimensionPixelSize( R.dimen.action_bar_switch_padding); toggleSwitch.setPaddingRelative(0, 0, padding, 0); + return toggleSwitch; + } + + private void setupActionBarToggleSwitch(Activity activity, ToggleSwitch toggleSwitch) { activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM); activity.getActionBar().setCustomView(toggleSwitch, new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT, Gravity.CENTER_VERTICAL | Gravity.END)); - return toggleSwitch; + } + + private void removeActionBarToggleSwitch(Activity activity) { + activity.getActionBar().setCustomView(null); } private static abstract class SettingsContentObserver extends ContentObserver { diff --git a/src/com/android/settings/print/PrintSettingsFragment.java b/src/com/android/settings/print/PrintSettingsFragment.java index df38db4..0215ad8 100644 --- a/src/com/android/settings/print/PrintSettingsFragment.java +++ b/src/com/android/settings/print/PrintSettingsFragment.java @@ -40,6 +40,7 @@ import android.print.PrintJobInfo; import android.print.PrintManager; import android.print.PrintManager.PrintJobStateChangeListener; import android.printservice.PrintServiceInfo; +import android.provider.SearchIndexableResource; import android.provider.Settings; import android.text.TextUtils; import android.text.format.DateUtils; @@ -49,6 +50,7 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.view.accessibility.AccessibilityNodeInfo; import android.widget.Switch; import android.widget.TextView; @@ -56,6 +58,9 @@ import com.android.internal.content.PackageMonitor; import com.android.settings.DialogCreatable; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.Indexable;; +import com.android.settings.search.SearchIndexableRaw; import java.text.DateFormat; import java.util.ArrayList; @@ -64,7 +69,8 @@ import java.util.List; /** * Fragment with the top level print settings. */ -public class PrintSettingsFragment extends SettingsPreferenceFragment implements DialogCreatable { +public class PrintSettingsFragment extends SettingsPreferenceFragment + implements DialogCreatable, Indexable { static final char ENABLED_PRINT_SERVICES_SEPARATOR = ':'; @@ -119,7 +125,7 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment implements mActivePrintJobsCategory = (PreferenceCategory) findPreference( PRINT_JOBS_CATEGORY); - mPrintServicesCategory= (PreferenceCategory) findPreference( + mPrintServicesCategory = (PreferenceCategory) findPreference( PRINT_SERVICES_CATEGORY); getPreferenceScreen().removePreference(mActivePrintJobsCategory); @@ -153,7 +159,7 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment implements if (!TextUtils.isEmpty(searchUri)) { MenuItem menuItem = menu.add(R.string.print_menu_item_add_service); menuItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM); - menuItem.setIntent(new Intent(Intent.ACTION_VIEW,Uri.parse(searchUri))); + menuItem.setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(searchUri))); } } @@ -162,7 +168,7 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment implements super.onViewCreated(view, savedInstanceState); ViewGroup contentRoot = (ViewGroup) getListView().getParent(); View emptyView = getActivity().getLayoutInflater().inflate( - R.layout.empty_print_state, contentRoot, false); + R.layout.empty_print_state, contentRoot, false); TextView textView = (TextView) emptyView.findViewById(R.id.message); textView.setText(R.string.print_no_services_installed); contentRoot.addView(emptyView); @@ -272,7 +278,7 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment implements private class SettingsPackageMonitor extends PackageMonitor { @Override public void onPackageAdded(String packageName, int uid) { - mHandler.obtainMessage().sendToTarget(); + mHandler.obtainMessage().sendToTarget(); } @Override @@ -443,7 +449,7 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment implements private static final boolean DEBUG = false; - private List <PrintJobInfo> mPrintJobs = new ArrayList<PrintJobInfo>(); + private List<PrintJobInfo> mPrintJobs = new ArrayList<PrintJobInfo>(); private final PrintManager mPrintManager; @@ -453,7 +459,7 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment implements super(context); mPrintManager = ((PrintManager) context.getSystemService( Context.PRINT_SERVICE)).getGlobalPrintManagerForUser( - ActivityManager.getCurrentUser()); + ActivityManager.getCurrentUser()); } @Override @@ -544,4 +550,43 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment implements return false; } } -} + + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { + List<SearchIndexableRaw> indexables = new ArrayList<SearchIndexableRaw>(); + + PackageManager packageManager = context.getPackageManager(); + PrintManager printManager = (PrintManager) context.getSystemService( + Context.PRINT_SERVICE); + + String screenTitle = context.getResources().getString(R.string.print_settings_title); + + // Indexing all services, reagardles if enabled. + List<PrintServiceInfo> services = printManager.getInstalledPrintServices(); + final int serviceCount = services.size(); + for (int i = 0; i < serviceCount; i++) { + PrintServiceInfo service = services.get(i); + SearchIndexableRaw indexable = new SearchIndexableRaw(context); + indexable.title = service.getResolveInfo().loadLabel(packageManager).toString(); + indexable.summaryOn = context.getString(R.string.print_feature_state_on); + indexable.summaryOff = context.getString(R.string.print_feature_state_off); + indexable.screenTitle = screenTitle; + indexables.add(indexable); + } + + return indexables; + } + + @Override + public List<SearchIndexableResource> getXmlResourcesToIndex(Context context, + boolean enabled) { + List<SearchIndexableResource> indexables = new ArrayList<SearchIndexableResource>(); + SearchIndexableResource indexable = new SearchIndexableResource(context); + indexable.xmlResId = R.xml.print_settings; + indexables.add(indexable); + return indexables; + } + }; +}
\ No newline at end of file diff --git a/src/com/android/settings/search/BaseSearchIndexProvider.java b/src/com/android/settings/search/BaseSearchIndexProvider.java new file mode 100644 index 0000000..0fe1944 --- /dev/null +++ b/src/com/android/settings/search/BaseSearchIndexProvider.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 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.settings.search; + +import android.content.Context; +import android.provider.SearchIndexableResource; + +import java.util.Collections; +import java.util.List; + +/** + * A basic SearchIndexProvider that returns no data to index. + */ +public class BaseSearchIndexProvider implements Indexable.SearchIndexProvider { + + private static final List<String> EMPTY_LIST = Collections.<String>emptyList(); + + public BaseSearchIndexProvider() { + } + + @Override + public List<SearchIndexableResource> getXmlResourcesToIndex(Context context, boolean enabled) { + return null; + } + + @Override + public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { + return null; + } + + @Override + public List<String> getNonIndexableKeys(Context context) { + return EMPTY_LIST; + } +} diff --git a/src/com/android/settings/search/DynamicIndexableContentMonitor.java b/src/com/android/settings/search/DynamicIndexableContentMonitor.java new file mode 100644 index 0000000..ad2cce8 --- /dev/null +++ b/src/com/android/settings/search/DynamicIndexableContentMonitor.java @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2014 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.settings.search; + +import android.accessibilityservice.AccessibilityService; +import android.accessibilityservice.AccessibilityServiceInfo; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.database.ContentObserver; +import android.hardware.input.InputManager; +import android.net.Uri; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.os.UserHandle; +import android.print.PrintManager; +import android.printservice.PrintService; +import android.printservice.PrintServiceInfo; +import android.provider.UserDictionary; +import android.view.accessibility.AccessibilityManager; +import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodManager; +import com.android.internal.content.PackageMonitor; +import com.android.settings.accessibility.AccessibilitySettings; +import com.android.settings.inputmethod.InputMethodAndLanguageSettings; +import com.android.settings.print.PrintSettingsFragment; + +import java.util.ArrayList; +import java.util.List; + +public final class DynamicIndexableContentMonitor extends PackageMonitor implements + InputManager.InputDeviceListener { + + private static final long DELAY_PROCESS_PACKAGE_CHANGE = 2000; + + private static final int MSG_PACKAGE_AVAILABLE = 1; + private static final int MSG_PACKAGE_UNAVAILABLE = 2; + + private final List<String> mAccessibilityServices = new ArrayList<String>(); + private final List<String> mPrintServices = new ArrayList<String>(); + private final List<String> mImeServices = new ArrayList<String>(); + + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_PACKAGE_AVAILABLE: { + String packageName = (String) msg.obj; + handlePackageAvailable(packageName); + } break; + + case MSG_PACKAGE_UNAVAILABLE: { + String packageName = (String) msg.obj; + handlePackageUnavailable(packageName); + } break; + } + } + }; + + private final ContentObserver mContentObserver = new MyContentObserver(mHandler); + + private Context mContext; + + private static Intent getAccessibilityServiceIntent(String packageName) { + final Intent intent = new Intent(AccessibilityService.SERVICE_INTERFACE); + intent.setPackage(packageName); + return intent; + } + + private static Intent getPrintServiceIntent(String packageName) { + final Intent intent = new Intent(PrintService.SERVICE_INTERFACE); + intent.setPackage(packageName); + return intent; + } + + private static Intent getIMEServiceIntent(String packageName) { + final Intent intent = new Intent("android.view.InputMethod"); + intent.setPackage(packageName); + return intent; + } + + public void register(Context context) { + mContext = context; + + // Cache accessibility service packages to know when they go away. + AccessibilityManager accessibilityManager = (AccessibilityManager) + mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); + List<AccessibilityServiceInfo> accessibilityServices = accessibilityManager + .getInstalledAccessibilityServiceList(); + final int accessibilityServiceCount = accessibilityServices.size(); + for (int i = 0; i < accessibilityServiceCount; i++) { + AccessibilityServiceInfo accessibilityService = accessibilityServices.get(i); + mAccessibilityServices.add(accessibilityService.getResolveInfo() + .serviceInfo.packageName); + } + + // Cache print service packages to know when they go away. + PrintManager printManager = (PrintManager) + mContext.getSystemService(Context.PRINT_SERVICE); + List<PrintServiceInfo> printServices = printManager.getInstalledPrintServices(); + final int serviceCount = printServices.size(); + for (int i = 0; i < serviceCount; i++) { + PrintServiceInfo printService = printServices.get(i); + mPrintServices.add(printService.getResolveInfo() + .serviceInfo.packageName); + } + + // Cache IME service packages to know when they go away. + InputMethodManager imeManager = (InputMethodManager) + mContext.getSystemService(Context.INPUT_METHOD_SERVICE); + List<InputMethodInfo> inputMethods = imeManager.getInputMethodList(); + final int inputMethodCount = inputMethods.size(); + for (int i = 0; i < inputMethodCount; i++) { + InputMethodInfo inputMethod = inputMethods.get(i); + mImeServices.add(inputMethod.getServiceInfo().packageName); + } + + // Watch for related content URIs. + mContext.getContentResolver().registerContentObserver( + UserDictionary.Words.CONTENT_URI, true, mContentObserver); + + // Watch for input device changes. + InputManager inputManager = (InputManager) context.getSystemService( + Context.INPUT_SERVICE); + inputManager.registerInputDeviceListener(this, mHandler); + + // Start tracking packages. + register(context, Looper.getMainLooper(), UserHandle.CURRENT, false); + } + + public void unregister() { + super.unregister(); + + InputManager inputManager = (InputManager) mContext.getSystemService( + Context.INPUT_SERVICE); + inputManager.unregisterInputDeviceListener(this); + + mContext.getContentResolver().unregisterContentObserver(mContentObserver); + + mAccessibilityServices.clear(); + mPrintServices.clear(); + mImeServices.clear(); + } + + // Covers installed, appeared external storage with the package, upgraded. + @Override + public void onPackageAppeared(String packageName, int uid) { + postMessage(MSG_PACKAGE_AVAILABLE, packageName); + } + + // Covers uninstalled, removed external storage with the package. + @Override + public void onPackageDisappeared(String packageName, int uid) { + postMessage(MSG_PACKAGE_UNAVAILABLE, packageName); + } + + // Covers enabled, disabled. + @Override + public void onPackageModified(String packageName) { + super.onPackageModified(packageName); + final int state = mContext.getPackageManager().getApplicationEnabledSetting( + packageName); + if (state == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT + || state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { + postMessage(MSG_PACKAGE_AVAILABLE, packageName); + } else { + postMessage(MSG_PACKAGE_UNAVAILABLE, packageName); + } + } + + @Override + public void onInputDeviceAdded(int deviceId) { + Index.getInstance(mContext).updateFromClassNameResource( + InputMethodAndLanguageSettings.class.getName(), false, true); + } + + @Override + public void onInputDeviceRemoved(int deviceId) { + onInputDeviceChanged(deviceId); + } + + @Override + public void onInputDeviceChanged(int deviceId) { + Index.getInstance(mContext).updateFromClassNameResource( + InputMethodAndLanguageSettings.class.getName(), true, true); + } + + private void postMessage(int what, String packageName) { + Message message = mHandler.obtainMessage(what, packageName); + mHandler.sendMessageDelayed(message, DELAY_PROCESS_PACKAGE_CHANGE); + } + + private void handlePackageAvailable(String packageName) { + if (!mAccessibilityServices.contains(packageName)) { + final Intent intent = getAccessibilityServiceIntent(packageName); + if (!mContext.getPackageManager().queryIntentServices(intent, 0).isEmpty()) { + mAccessibilityServices.add(packageName); + Index.getInstance(mContext).updateFromClassNameResource( + AccessibilitySettings.class.getName(), false, true); + } + } + + if (!mPrintServices.contains(packageName)) { + final Intent intent = getPrintServiceIntent(packageName); + if (!mContext.getPackageManager().queryIntentServices(intent, 0).isEmpty()) { + mPrintServices.add(packageName); + Index.getInstance(mContext).updateFromClassNameResource( + PrintSettingsFragment.class.getName(), false, true); + } + } + + if (!mImeServices.contains(packageName)) { + Intent intent = getIMEServiceIntent(packageName); + if (!mContext.getPackageManager().queryIntentServices(intent, 0).isEmpty()) { + mImeServices.add(packageName); + Index.getInstance(mContext).updateFromClassNameResource( + InputMethodAndLanguageSettings.class.getName(), false, true); + } + } + } + + private void handlePackageUnavailable(String packageName) { + final int accessibilityIndex = mAccessibilityServices.indexOf(packageName); + if (accessibilityIndex >= 0) { + mAccessibilityServices.remove(accessibilityIndex); + Index.getInstance(mContext).updateFromClassNameResource( + AccessibilitySettings.class.getName(), true, true); + } + + final int printIndex = mPrintServices.indexOf(packageName); + if (printIndex >= 0) { + mPrintServices.remove(printIndex); + Index.getInstance(mContext).updateFromClassNameResource( + PrintSettingsFragment.class.getName(), true, true); + } + + final int imeIndex = mImeServices.indexOf(packageName); + if (imeIndex >= 0) { + mImeServices.remove(imeIndex); + Index.getInstance(mContext).updateFromClassNameResource( + InputMethodAndLanguageSettings.class.getName(), true, true); + } + } + + private final class MyContentObserver extends ContentObserver { + + public MyContentObserver(Handler handler) { + super(handler); + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + if (UserDictionary.Words.CONTENT_URI.equals(uri)) { + Index.getInstance(mContext).updateFromClassNameResource( + InputMethodAndLanguageSettings.class.getName(), true, true); + } + }; + } +} diff --git a/src/com/android/settings/search/Index.java b/src/com/android/settings/search/Index.java index 987539b..6f91981 100644 --- a/src/com/android/settings/search/Index.java +++ b/src/com/android/settings/search/Index.java @@ -20,6 +20,8 @@ import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.TypedArray; @@ -44,11 +46,37 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicBoolean; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_RANK; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_TITLE; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_ON; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_OFF; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ENTRIES; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEYWORDS; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SCREEN_TITLE; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_CLASS_NAME; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ICON_RESID; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_ACTION; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_CLASS; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEY; + +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RANK; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RESID; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS; + import static com.android.settings.search.IndexDatabaseHelper.Tables; import static com.android.settings.search.IndexDatabaseHelper.IndexColumns; @@ -57,20 +85,22 @@ public class Index { private static final String LOG_TAG = "Index"; // Those indices should match the indices of SELECT_COLUMNS ! + public static final int COLUMN_INDEX_RANK = 0; public static final int COLUMN_INDEX_TITLE = 1; public static final int COLUMN_INDEX_SUMMARY_ON = 2; public static final int COLUMN_INDEX_SUMMARY_OFF = 3; public static final int COLUMN_INDEX_ENTRIES = 4; - public static final int COLUMN_INDEX_SWITCH_ON = 5; - public static final int COLUMN_INDEX_SWITCH_OFF = 6; - public static final int COLUMN_INDEX_KEYWORDS = 7; - public static final int COLUMN_INDEX_CLASS_NAME = 8; - public static final int COLUMN_INDEX_SCREEN_TITLE = 9; - public static final int COLUMN_INDEX_ICON = 10; - public static final int COLUMN_INDEX_INTENT_ACTION = 11; - public static final int COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE = 12; - public static final int COLUMN_INDEX_INTENT_ACTION_TARGET_CLASS = 13; - public static final int COLUMN_INDEX_ENABLED = 14; + public static final int COLUMN_INDEX_KEYWORDS = 5; + public static final int COLUMN_INDEX_CLASS_NAME = 6; + public static final int COLUMN_INDEX_SCREEN_TITLE = 7; + public static final int COLUMN_INDEX_ICON = 8; + public static final int COLUMN_INDEX_INTENT_ACTION = 9; + public static final int COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE = 10; + public static final int COLUMN_INDEX_INTENT_ACTION_TARGET_CLASS = 11; + public static final int COLUMN_INDEX_ENABLED = 12; + public static final int COLUMN_INDEX_KEY = 13; + + public static final String ENTRIES_SEPARATOR = "|"; // If you change the order of columns here, you SHOULD change the COLUMN_INDEX_XXX values private static final String[] SELECT_COLUMNS = new String[] { @@ -79,15 +109,15 @@ public class Index { IndexColumns.DATA_SUMMARY_ON, // 2 IndexColumns.DATA_SUMMARY_OFF, // 3 IndexColumns.DATA_ENTRIES, // 4 - IndexColumns.DATA_SWITCH_ON, // 5 - IndexColumns.DATA_SWITCH_OFF, // 6 - IndexColumns.DATA_KEYWORDS, // 7 - IndexColumns.CLASS_NAME, // 8 - IndexColumns.SCREEN_TITLE, // 9 - IndexColumns.ICON, // 10 - IndexColumns.INTENT_ACTION, // 11 - IndexColumns.INTENT_TARGET_PACKAGE, // 12 - IndexColumns.INTENT_TARGET_CLASS // 13 + IndexColumns.DATA_KEYWORDS, // 5 + IndexColumns.CLASS_NAME, // 6 + IndexColumns.SCREEN_TITLE, // 7 + IndexColumns.ICON, // 8 + IndexColumns.INTENT_ACTION, // 9 + IndexColumns.INTENT_TARGET_PACKAGE, // 10 + IndexColumns.INTENT_TARGET_CLASS, // 11 + IndexColumns.ENABLED, // 12 + IndexColumns.DATA_KEY_REF // 13 }; private static final String[] MATCH_COLUMNS = { @@ -97,10 +127,6 @@ public class Index { IndexColumns.DATA_SUMMARY_ON_NORMALIZED, IndexColumns.DATA_SUMMARY_OFF, IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, - IndexColumns.DATA_SWITCH_ON, - IndexColumns.DATA_SWITCH_ON_NORMALIZED, - IndexColumns.DATA_SWITCH_OFF, - IndexColumns.DATA_SWITCH_OFF_NORMALIZED, IndexColumns.DATA_ENTRIES, IndexColumns.DATA_KEYWORDS }; @@ -115,7 +141,8 @@ public class Index { private static final String NODE_NAME_PREFERENCE_SCREEN = "PreferenceScreen"; private static final String NODE_NAME_CHECK_BOX_PREFERENCE = "CheckBoxPreference"; private static final String NODE_NAME_LIST_PREFERENCE = "ListPreference"; - private static final String NODE_NAME_SWITCH_PREFERENCE = "SwitchPreference"; + + private static final List<String> EMPTY_LIST = Collections.<String>emptyList(); private static Index sInstance; private final AtomicBoolean mIsAvailable = new AtomicBoolean(false); @@ -127,17 +154,21 @@ public class Index { */ private class UpdateData { public List<SearchIndexableData> dataToUpdate; - public List<String> dataToDelete; + public List<SearchIndexableData> dataToDelete; + public Map<String, List<String>> nonIndexableKeys; + public boolean forceUpdate = false; public UpdateData() { dataToUpdate = new ArrayList<SearchIndexableData>(); - dataToDelete = new ArrayList<String>(); + dataToDelete = new ArrayList<SearchIndexableData>(); + nonIndexableKeys = new HashMap<String, List<String>>(); } public void clear() { dataToUpdate.clear(); dataToDelete.clear(); + nonIndexableKeys.clear(); forceUpdate = false; } } @@ -172,6 +203,94 @@ public class Index { return getReadableDatabase().rawQuery(sql, null); } + public boolean update() { + final Intent intent = new Intent(SearchIndexablesContract.PROVIDER_INTERFACE); + List<ResolveInfo> list = + mContext.getPackageManager().queryIntentContentProviders(intent, 0); + + final int size = list.size(); + for (int n = 0; n < size; n++) { + final ResolveInfo info = list.get(n); + if (!isWellKnownProvider(info)) { + continue; + } + final String authority = info.providerInfo.authority; + final String packageName = info.providerInfo.packageName; + + addIndexablesFromRemoteProvider(packageName, authority); + addNonIndexablesKeysFromRemoteProvider(packageName, authority); + } + + return updateInternal(); + } + + private boolean addIndexablesFromRemoteProvider(String packageName, String authority) { + try { + final Context packageContext = mContext.createPackageContext(packageName, 0); + + final Uri uriForResources = buildUriForXmlResources(authority); + addIndexablesForXmlResourceUri(packageContext, packageName, uriForResources, + SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS); + + final Uri uriForRawData = buildUriForRawData(authority); + addIndexablesForRawDataUri(packageContext, packageName, uriForRawData, + SearchIndexablesContract.INDEXABLES_RAW_COLUMNS); + return true; + } catch (PackageManager.NameNotFoundException e) { + Log.w(LOG_TAG, "Could not create context for " + packageName + ": " + + Log.getStackTraceString(e)); + return false; + } + } + + private void addNonIndexablesKeysFromRemoteProvider(String packageName, + String authority) { + final List<String> keys = + getNonIndexablesKeysFromRemoteProvider(packageName, authority); + addNonIndexableKeys(packageName, keys); + } + + private List<String> getNonIndexablesKeysFromRemoteProvider(String packageName, + String authority) { + try { + final Context packageContext = mContext.createPackageContext(packageName, 0); + + final Uri uriForNonIndexableKeys = buildUriForNonIndexableKeys(authority); + return getNonIndexablesKeys(packageContext, uriForNonIndexableKeys, + SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS); + } catch (PackageManager.NameNotFoundException e) { + Log.w(LOG_TAG, "Could not create context for " + packageName + ": " + + Log.getStackTraceString(e)); + return EMPTY_LIST; + } + } + + private List<String> getNonIndexablesKeys(Context packageContext, Uri uri, + String[] projection) { + + final ContentResolver resolver = packageContext.getContentResolver(); + final Cursor cursor = resolver.query(uri, projection, null, null, null); + + if (cursor == null) { + Log.w(LOG_TAG, "Cannot add index data for Uri: " + uri.toString()); + return EMPTY_LIST; + } + + List<String> result = new ArrayList<String>(); + try { + final int count = cursor.getCount(); + if (count > 0) { + while (cursor.moveToNext()) { + final String key = cursor.getString(COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE); + result.add(key); + } + } + return result; + } finally { + cursor.close(); + } + } + public void addIndexableData(SearchIndexableData data) { synchronized (mDataToProcess) { mDataToProcess.dataToUpdate.add(data); @@ -187,29 +306,55 @@ public class Index { } } - public void deleteIndexableData(String[] array) { + public void deleteIndexableData(SearchIndexableData data) { synchronized (mDataToProcess) { - final int count = array.length; - for (int n = 0; n < count; n++) { - mDataToProcess.dataToDelete.add(array[n]); - } + mDataToProcess.dataToDelete.add(data); } } - public boolean update() { - final Intent intent = new Intent(SearchIndexablesContract.PROVIDER_INTERFACE); - List<ResolveInfo> list = - mContext.getPackageManager().queryIntentContentProviders(intent, 0); + public void addNonIndexableKeys(String authority, List<String> keys) { + synchronized (mDataToProcess) { + mDataToProcess.nonIndexableKeys.put(authority, keys); + } + } - final int size = list.size(); - for (int n = 0; n < size; n++) { - final ResolveInfo info = list.get(n); - final String authority = info.providerInfo.authority; - final String packageName = info.providerInfo.packageName; - addIndexablesFromRemoteProvider(packageName, authority); + /** + * Only allow a "well known" SearchIndexablesProvider. The provider should: + * + * - have read/write {@link android.Manifest.permission#READ_SEARCH_INDEXABLES} + * - be from a privileged package + */ + private boolean isWellKnownProvider(ResolveInfo info) { + final String authority = info.providerInfo.authority; + final String packageName = info.providerInfo.applicationInfo.packageName; + + if (TextUtils.isEmpty(authority) || TextUtils.isEmpty(packageName)) { + return false; } - return updateInternal(); + final String readPermission = info.providerInfo.readPermission; + final String writePermission = info.providerInfo.writePermission; + + if (TextUtils.isEmpty(readPermission) || TextUtils.isEmpty(writePermission)) { + return false; + } + + if (!android.Manifest.permission.READ_SEARCH_INDEXABLES.equals(readPermission) || + !android.Manifest.permission.READ_SEARCH_INDEXABLES.equals(writePermission)) { + return false; + } + + return isPrivilegedPackage(packageName); + } + + private boolean isPrivilegedPackage(String packageName) { + final PackageManager pm = mContext.getPackageManager(); + try { + PackageInfo packInfo = pm.getPackageInfo(packageName, 0); + return ((packInfo.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0); + } catch (PackageManager.NameNotFoundException e) { + return false; + } } public boolean updateFromRemoteProvider(String packageName, String authority) { @@ -219,7 +364,17 @@ public class Index { return updateInternal(); } - public boolean updateFromClassNameResource(String className, boolean includeInSearchResults) { + /** + * Update the Index for a specific class name resources + * + * @param className the class name (typically a fragment name). + * @param rebuild true means that you want to delete the data from the Index first. + * @param includeInSearchResults true means that you want the bit "enabled" set so that the + * data will be seen included into the search results + * @return true of the Index update has been successful. + */ + public boolean updateFromClassNameResource(String className, boolean rebuild, + boolean includeInSearchResults) { if (className == null) { throw new IllegalArgumentException("class name cannot be null!"); } @@ -229,6 +384,9 @@ public class Index { return false; } res.enabled = includeInSearchResults; + if (rebuild) { + deleteIndexableData(res); + } addIndexableData(res); mDataToProcess.forceUpdate = true; boolean result = updateInternal(); @@ -236,8 +394,9 @@ public class Index { return result; } - private boolean updateFromSearchIndexableData(SearchIndexableData data) { + public boolean updateFromSearchIndexableData(SearchIndexableData data) { addIndexableData(data); + mDataToProcess.forceUpdate = true; return updateInternal(); } @@ -249,26 +408,6 @@ public class Index { return IndexDatabaseHelper.getInstance(mContext).getWritableDatabase(); } - private boolean addIndexablesFromRemoteProvider(String packageName, String authority) { - final Context packageContext; - try { - packageContext = mContext.createPackageContext(packageName, 0); - - final Uri uriForResources = buildUriForXmlResources(authority); - addIndexablesForXmlResourceUri(packageContext, packageName, uriForResources, - SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS); - - final Uri uriForRawData = buildUriForRawData(authority); - addIndexablesForRawDataUri(packageContext, packageName, uriForRawData, - SearchIndexablesContract.INDEXABLES_RAW_COLUMNS); - return true; - } catch (PackageManager.NameNotFoundException e) { - Log.w(LOG_TAG, "Could not create context for " + packageName + ": " - + Log.getStackTraceString(e)); - return false; - } - } - private static Uri buildUriForXmlResources(String authority) { return Uri.parse("content://" + authority + "/" + SearchIndexablesContract.INDEXABLES_XML_RES_PATH); @@ -279,6 +418,11 @@ public class Index { SearchIndexablesContract.INDEXABLES_RAW_PATH); } + private static Uri buildUriForNonIndexableKeys(String authority) { + return Uri.parse("content://" + authority + "/" + + SearchIndexablesContract.NON_INDEXABLES_KEYS_PATH); + } + private boolean updateInternal() { synchronized (mDataToProcess) { final UpdateIndexTask task = new UpdateIndexTask(); @@ -301,8 +445,7 @@ public class Index { Uri uri, String[] projection) { final ContentResolver resolver = packageContext.getContentResolver(); - final Cursor cursor = resolver.query(uri, projection, - null, null, null); + final Cursor cursor = resolver.query(uri, projection, null, null, null); if (cursor == null) { Log.w(LOG_TAG, "Cannot add index data for Uri: " + uri.toString()); @@ -313,15 +456,17 @@ public class Index { final int count = cursor.getCount(); if (count > 0) { while (cursor.moveToNext()) { - final int rank = cursor.getInt(0); - final int xmlResId = cursor.getInt(1); + final int rank = cursor.getInt(COLUMN_INDEX_XML_RES_RANK); + final int xmlResId = cursor.getInt(COLUMN_INDEX_XML_RES_RESID); - final String className = cursor.getString(2); - final int iconResId = cursor.getInt(3); + final String className = cursor.getString(COLUMN_INDEX_XML_RES_CLASS_NAME); + final int iconResId = cursor.getInt(COLUMN_INDEX_XML_RES_ICON_RESID); - final String action = cursor.getString(4); - final String targetPackage = cursor.getString(5); - final String targetClass = cursor.getString(6); + final String action = cursor.getString(COLUMN_INDEX_XML_RES_INTENT_ACTION); + final String targetPackage = cursor.getString( + COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE); + final String targetClass = cursor.getString( + COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS); SearchIndexableResource sir = new SearchIndexableResource(packageContext); sir.rank = rank; @@ -345,8 +490,7 @@ public class Index { Uri uri, String[] projection) { final ContentResolver resolver = packageContext.getContentResolver(); - final Cursor cursor = resolver.query(uri, projection, - null, null, null); + final Cursor cursor = resolver.query(uri, projection, null, null, null); if (cursor == null) { Log.w(LOG_TAG, "Cannot add index data for Uri: " + uri.toString()); @@ -357,23 +501,25 @@ public class Index { final int count = cursor.getCount(); if (count > 0) { while (cursor.moveToNext()) { - final int rank = cursor.getInt(0); - final String title = cursor.getString(1); - final String summaryOn = cursor.getString(2); - final String summaryOff = cursor.getString(3); - final String entries = cursor.getString(4); - final String switchOn = cursor.getString(5); - final String switchOff = cursor.getString(6); - final String keywords = cursor.getString(7); + final int rank = cursor.getInt(COLUMN_INDEX_RAW_RANK); + final String title = cursor.getString(COLUMN_INDEX_RAW_TITLE); + final String summaryOn = cursor.getString(COLUMN_INDEX_RAW_SUMMARY_ON); + final String summaryOff = cursor.getString(COLUMN_INDEX_RAW_SUMMARY_OFF); + final String entries = cursor.getString(COLUMN_INDEX_RAW_ENTRIES); + final String keywords = cursor.getString(COLUMN_INDEX_RAW_KEYWORDS); - final String screenTitle = cursor.getString(8); + final String screenTitle = cursor.getString(COLUMN_INDEX_RAW_SCREEN_TITLE); - final String className = cursor.getString(9); - final int iconResId = cursor.getInt(10); + final String className = cursor.getString(COLUMN_INDEX_RAW_CLASS_NAME); + final int iconResId = cursor.getInt(COLUMN_INDEX_RAW_ICON_RESID); - final String action = cursor.getString(11); - final String targetPackage = cursor.getString(12); - final String targetClass = cursor.getString(13); + final String action = cursor.getString(COLUMN_INDEX_RAW_INTENT_ACTION); + final String targetPackage = cursor.getString( + COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE); + final String targetClass = cursor.getString( + COLUMN_INDEX_RAW_INTENT_TARGET_CLASS); + + final String key = cursor.getString(COLUMN_INDEX_RAW_KEY); SearchIndexableRaw data = new SearchIndexableRaw(packageContext); data.rank = rank; @@ -381,8 +527,6 @@ public class Index { data.summaryOn = summaryOn; data.summaryOff = summaryOff; data.entries = entries; - data.switchOn = switchOn; - data.switchOff = switchOff; data.keywords = keywords; data.screenTitle = screenTitle; data.className = className; @@ -391,6 +535,7 @@ public class Index { data.intentAction = action; data.intentTargetPackage = targetPackage; data.intentTargetClass = targetClass; + data.key = key; addIndexableData(data); } @@ -455,29 +600,95 @@ public class Index { } private void indexOneSearchIndexableData(SQLiteDatabase database, String localeStr, - SearchIndexableData data) { + SearchIndexableData data, Map<String, List<String>> nonIndexableKeys) { if (data instanceof SearchIndexableResource) { - indexOneResource(database, localeStr, (SearchIndexableResource) data); + indexOneResource(database, localeStr, (SearchIndexableResource) data, nonIndexableKeys); } else if (data instanceof SearchIndexableRaw) { indexOneRaw(database, localeStr, (SearchIndexableRaw) data); } } + private void indexOneRaw(SQLiteDatabase database, String localeStr, + SearchIndexableRaw raw) { + // Should be the same locale as the one we are processing + if (!raw.locale.toString().equalsIgnoreCase(localeStr)) { + return; + } + + updateOneRowWithFilteredData(database, localeStr, + raw.title, + raw.summaryOn, + raw.summaryOff, + raw.entries, + raw.className, + raw.screenTitle, + raw.iconResId, + raw.rank, + raw.keywords, + raw.intentAction, + raw.intentTargetPackage, + raw.intentTargetClass, + raw.enabled, + raw.key); + } + private void indexOneResource(SQLiteDatabase database, String localeStr, - SearchIndexableResource sir) { - if (sir.xmlResId > 0) { + SearchIndexableResource sir, Map<String, List<String>> nonIndexableKeysFromResource) { + + if (sir == null) { + Log.e(LOG_TAG, "Cannot index a null resource!"); + return; + } + + // Will be non null only for a Local provider + final Indexable.SearchIndexProvider provider = + TextUtils.isEmpty(sir.className) ? null : getSearchIndexProvider(sir.className); + + List<String> nonIndexableKeys = new ArrayList<String>(); + + if (sir.xmlResId > SearchIndexableResources.NO_DATA_RES_ID) { + List<String> resNonIndxableKeys = nonIndexableKeysFromResource.get(sir.packageName); + if (resNonIndxableKeys != null && resNonIndxableKeys.size() > 0) { + nonIndexableKeys.addAll(resNonIndxableKeys); + } indexFromResource(sir.context, database, localeStr, sir.xmlResId, sir.className, sir.iconResId, sir.rank, - sir.intentAction, sir.intentTargetPackage, sir.intentTargetClass); + sir.intentAction, sir.intentTargetPackage, sir.intentTargetClass, + nonIndexableKeys); } else if (!TextUtils.isEmpty(sir.className)) { - sir.context = mContext; - indexFromLocalProvider(database, localeStr, sir); + if (provider != null) { + List<String> providerNonIndexableKeys = provider.getNonIndexableKeys(sir.context); + if (providerNonIndexableKeys != null && providerNonIndexableKeys.size() > 0) { + nonIndexableKeys.addAll(providerNonIndexableKeys); + } + } + indexFromLocalProvider(mContext, database, localeStr, provider, sir.className, + sir.iconResId, sir.rank, sir.enabled, nonIndexableKeys); + } + } + + private Indexable.SearchIndexProvider getSearchIndexProvider(String className) { + try { + final Class<?> clazz = Class.forName(className); + if (Indexable.class.isAssignableFrom(clazz)) { + final Field f = clazz.getField(FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER); + return (Indexable.SearchIndexProvider) f.get(null); + } + } catch (ClassNotFoundException e) { + Log.e(LOG_TAG, "Cannot find class: " + className, e); + } catch (NoSuchFieldException e) { + Log.e(LOG_TAG, "Cannot find field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'", e); + } catch (IllegalAccessException e) { + Log.e(LOG_TAG, + "Illegal access to field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'", e); } + return null; } private void indexFromResource(Context context, SQLiteDatabase database, String localeStr, - int xmlResId, String fragmentName, int iconResId, int rank, - String intentAction, String intentTargetPackage, String intentTargetClass) { + int xmlResId, String fragmentName, int iconResId, int rank, + String intentAction, String intentTargetPackage, String intentTargetClass, + List<String> nonIndexableKeys) { XmlResourceParser parser = null; try { @@ -498,17 +709,26 @@ public class Index { final int outerDepth = parser.getDepth(); final AttributeSet attrs = Xml.asAttributeSet(parser); + final String screenTitle = getDataTitle(context, attrs); - String title = getDataTitle(context, attrs); - String summary = getDataSummary(context, attrs); - String keywords = getDataKeywords(context, attrs); + String key = getDataKey(context, attrs); + + String title; + String summary; + String keywords; // Insert rows for the main PreferenceScreen node. Rewrite the data for removing // hyphens. - updateOneRowWithFilteredData(database, localeStr, title, summary, null, null, - null, null, fragmentName, screenTitle, iconResId, rank, keywords, - intentAction, intentTargetPackage, intentTargetClass, true); + if (!nonIndexableKeys.contains(key)) { + title = getDataTitle(context, attrs); + summary = getDataSummary(context, attrs); + keywords = getDataKeywords(context, attrs); + + updateOneRowWithFilteredData(database, localeStr, title, summary, null, null, + fragmentName, screenTitle, iconResId, rank, + keywords, intentAction, intentTargetPackage, intentTargetClass, true, key); + } while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { @@ -518,6 +738,11 @@ public class Index { nodeName = parser.getName(); + key = getDataKey(context, attrs); + if (nonIndexableKeys.contains(key)) { + continue; + } + title = getDataTitle(context, attrs); keywords = getDataKeywords(context, attrs); @@ -525,27 +750,24 @@ public class Index { summary = getDataSummary(context, attrs); String entries = null; - String switchOn = null; - String switchOff = null; if (nodeName.endsWith(NODE_NAME_LIST_PREFERENCE)) { entries = getDataEntries(context, attrs); - } else if (nodeName.endsWith(NODE_NAME_SWITCH_PREFERENCE)) { - switchOn = getDataSwitchOn(context, attrs); - switchOff = getDataSwitchOff(context, attrs); } // Insert rows for the child nodes of PreferenceScreen updateOneRowWithFilteredData(database, localeStr, title, summary, null, entries, - switchOn, switchOff, fragmentName, screenTitle, iconResId, rank, keywords, - intentAction, intentTargetPackage, intentTargetClass, true); - } else if (nodeName.equals(NODE_NAME_CHECK_BOX_PREFERENCE)) { + fragmentName, screenTitle, iconResId, rank, + keywords, intentAction, intentTargetPackage, intentTargetClass, + true, key); + } else { final String summaryOn = getDataSummaryOn(context, attrs); final String summaryOff = getDataSummaryOff(context, attrs); updateOneRowWithFilteredData(database, localeStr, title, summaryOn, summaryOff, - null, null, null, fragmentName, screenTitle, iconResId, rank, keywords, - intentAction, intentTargetPackage, intentTargetClass, true); + null, fragmentName, screenTitle, iconResId, rank, + keywords, intentAction, intentTargetPackage, intentTargetClass, + true, key); } } @@ -558,106 +780,80 @@ public class Index { } } - private void indexOneRaw(SQLiteDatabase database, String localeStr, - SearchIndexableRaw raw) { - // Should be the same locale as the one we are processing - if (!raw.locale.toString().equalsIgnoreCase(localeStr)) { + private void indexFromLocalProvider(Context context, SQLiteDatabase database, String localeStr, + Indexable.SearchIndexProvider provider, String className, int iconResId, int rank, + boolean enabled, List<String> nonIndexableKeys) { + + if (provider == null) { + Log.w(LOG_TAG, "Cannot find provider: " + className); return; } - updateOneRowWithFilteredData(database, localeStr, - raw.title, - raw.summaryOn, - raw.summaryOff, - raw.entries, - raw.switchOn, - raw.switchOff, - raw.className, - raw.screenTitle, - raw.iconResId, - raw.rank, - raw.keywords, - raw.intentAction, - raw.intentTargetPackage, - raw.intentTargetClass, - raw.enabled); - } + final List<SearchIndexableRaw> rawList = provider.getRawDataToIndex(context, enabled); - private void indexFromLocalProvider(SQLiteDatabase database, String localeStr, - SearchIndexableResource sir) { - try { - final Class<?> clazz = Class.forName(sir.className); - if (Indexable.class.isAssignableFrom(clazz)) { - final Field f = clazz.getField(FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER); - final Indexable.SearchIndexProvider provider = - (Indexable.SearchIndexProvider) f.get(null); - - final List<SearchIndexableRaw> rawList = - provider.getRawDataToIndex(sir.context, sir.enabled); - if (rawList != null) { - final int rawSize = rawList.size(); - for (int i = 0; i < rawSize; i++) { - SearchIndexableRaw raw = rawList.get(i); - - // Should be the same locale as the one we are processing - if (!raw.locale.toString().equalsIgnoreCase(localeStr)) { - continue; - } + if (rawList != null) { + final int rawSize = rawList.size(); + for (int i = 0; i < rawSize; i++) { + SearchIndexableRaw raw = rawList.get(i); - updateOneRowWithFilteredData(database, localeStr, - raw.title, - raw.summaryOn, - raw.summaryOff, - raw.entries, - raw.switchOn, - raw.switchOff, - sir.className, - raw.screenTitle, - sir.iconResId, - sir.rank, - raw.keywords, - raw.intentAction, - raw.intentTargetPackage, - raw.intentTargetClass, - raw.enabled); - } + // Should be the same locale as the one we are processing + if (!raw.locale.toString().equalsIgnoreCase(localeStr)) { + continue; } - final List<SearchIndexableResource> resList = - provider.getXmlResourcesToIndex(sir.context, sir.enabled); - if (resList != null) { - final int resSize = resList.size(); - for (int i = 0; i < resSize; i++) { - SearchIndexableResource item = resList.get(i); + if (nonIndexableKeys.contains(raw.key)) { + continue; + } - // Should be the same locale as the one we are processing - if (!item.locale.toString().equalsIgnoreCase(localeStr)) { - continue; - } + updateOneRowWithFilteredData(database, localeStr, + raw.title, + raw.summaryOn, + raw.summaryOff, + raw.entries, + className, + raw.screenTitle, + iconResId, + rank, + raw.keywords, + raw.intentAction, + raw.intentTargetPackage, + raw.intentTargetClass, + raw.enabled, + raw.key); + } + } - indexFromResource(sir.context, database, localeStr, - item.xmlResId, item.className, item.iconResId, item.rank, - item.intentAction, item.intentTargetPackage, - item.intentTargetClass); - } + final List<SearchIndexableResource> resList = + provider.getXmlResourcesToIndex(context, enabled); + if (resList != null) { + final int resSize = resList.size(); + for (int i = 0; i < resSize; i++) { + SearchIndexableResource item = resList.get(i); + + // Should be the same locale as the one we are processing + if (!item.locale.toString().equalsIgnoreCase(localeStr)) { + continue; } + + final int itemIconResId = (item.iconResId == 0) ? iconResId : item.iconResId; + final int itemRank = (item.rank == 0) ? rank : item.rank; + String itemClassName = (TextUtils.isEmpty(item.className)) + ? className : item.className; + + indexFromResource(context, database, localeStr, + item.xmlResId, itemClassName, itemIconResId, itemRank, + item.intentAction, item.intentTargetPackage, + item.intentTargetClass, nonIndexableKeys); } - } catch (ClassNotFoundException e) { - Log.e(LOG_TAG, "Cannot find class: " + sir.className, e); - } catch (NoSuchFieldException e) { - Log.e(LOG_TAG, "Cannot find field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'", e); - } catch (IllegalAccessException e) { - Log.e(LOG_TAG, - "Illegal access to field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'", e); } } private void updateOneRowWithFilteredData(SQLiteDatabase database, String locale, String title, String summaryOn, String summaryOff, String entries, - String switchOn, String switchOff, String className, + String className, String screenTitle, int iconResId, int rank, String keywords, String intentAction, String intentTargetPackage, String intentTargetClass, - boolean enabled) { + boolean enabled, String key) { String updatedTitle; if (title != null) { @@ -681,43 +877,24 @@ public class Index { updatedSummaryOff = EMPTY; } - String updatedSwitchOn; - if (switchOn != null) { - updatedSwitchOn = switchOn.replaceAll(NON_BREAKING_HYPHEN, HYPHEN); - } else { - updatedSwitchOn = EMPTY; - } - - String updatedSwitchOff; - if (switchOff != null) { - updatedSwitchOff = switchOff.replaceAll(NON_BREAKING_HYPHEN, HYPHEN); - } else { - updatedSwitchOff = EMPTY; - } - String normalizedTitle = updatedTitle.replaceAll(HYPHEN, EMPTY); String normalizedSummaryOn = updatedSummaryOn.replaceAll(HYPHEN, EMPTY); String normalizedSummaryOff = updatedSummaryOff.replaceAll(HYPHEN, EMPTY); - String normalizedSwitchOn = updatedSwitchOn.replaceAll(HYPHEN, EMPTY); - String normalizedSwitchOff = updatedSwitchOff.replaceAll(HYPHEN, EMPTY); updateOneRow(database, locale, updatedTitle, normalizedTitle, updatedSummaryOn, normalizedSummaryOn, updatedSummaryOff, normalizedSummaryOff, entries, - updatedSwitchOn, normalizedSwitchOn, updatedSwitchOff, normalizedSwitchOff, className, screenTitle, iconResId, - rank, keywords, intentAction, intentTargetPackage, intentTargetClass, enabled); + rank, keywords, intentAction, intentTargetPackage, intentTargetClass, enabled, key); } private void updateOneRow(SQLiteDatabase database, String locale, String updatedTitle, String normalizedTitle, String updatedSummaryOn, String normalizedSummaryOn, String updatedSummaryOff, String normalizedSummaryOff, String entries, - String updatedSwitchOn, String normalizedSwitchOn, - String updatedSwitchOff, String normalizedSwitchOff, String className, String screenTitle, int iconResId, int rank, String keywords, String intentAction, String intentTargetPackage, String intentTargetClass, - boolean enabled) { + boolean enabled, String key) { if (TextUtils.isEmpty(updatedTitle)) { return; @@ -734,10 +911,6 @@ public class Index { values.put(IndexColumns.DATA_SUMMARY_OFF, updatedSummaryOff); values.put(IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, normalizedSummaryOff); values.put(IndexColumns.DATA_ENTRIES, entries); - values.put(IndexColumns.DATA_SWITCH_ON, updatedSwitchOn); - values.put(IndexColumns.DATA_SWITCH_ON_NORMALIZED, normalizedSwitchOn); - values.put(IndexColumns.DATA_SWITCH_OFF, updatedSwitchOff); - values.put(IndexColumns.DATA_SWITCH_OFF_NORMALIZED, normalizedSwitchOff); values.put(IndexColumns.DATA_KEYWORDS, keywords); values.put(IndexColumns.CLASS_NAME, className); values.put(IndexColumns.SCREEN_TITLE, screenTitle); @@ -746,10 +919,17 @@ public class Index { values.put(IndexColumns.INTENT_TARGET_CLASS, intentTargetClass); values.put(IndexColumns.ICON, iconResId); values.put(IndexColumns.ENABLED, enabled); + values.put(IndexColumns.DATA_KEY_REF, key); database.replaceOrThrow(Tables.TABLE_PREFS_INDEX, null, values); } + private String getDataKey(Context context, AttributeSet attrs) { + return getData(context, attrs, + com.android.internal.R.styleable.Preference, + com.android.internal.R.styleable.Preference_key); + } + private String getDataTitle(Context context, AttributeSet attrs) { return getData(context, attrs, com.android.internal.R.styleable.Preference, @@ -780,18 +960,6 @@ public class Index { com.android.internal.R.styleable.ListPreference_entries); } - private String getDataSwitchOn(Context context, AttributeSet attrs) { - return getData(context, attrs, - com.android.internal.R.styleable.SwitchPreference, - com.android.internal.R.styleable.SwitchPreference_switchTextOn); - } - - private String getDataSwitchOff(Context context, AttributeSet attrs) { - return getData(context, attrs, - com.android.internal.R.styleable.SwitchPreference, - com.android.internal.R.styleable.SwitchPreference_switchTextOff); - } - private String getDataKeywords(Context context, AttributeSet attrs) { return getData(context, attrs, R.styleable.Preference, R.styleable.Preference_keywords); } @@ -828,7 +996,7 @@ public class Index { final StringBuilder result = new StringBuilder(); for (int n = 0; n < count; n++) { result.append(data[n]); - result.append(" "); + result.append(ENTRIES_SEPARATOR); } return result.toString(); } @@ -866,19 +1034,23 @@ public class Index { boolean result = false; final List<SearchIndexableData> dataToUpdate = params[0].dataToUpdate; - final List<String> dataToDelete = params[0].dataToDelete; + final List<SearchIndexableData> dataToDelete = params[0].dataToDelete; + final Map<String, List<String>> nonIndexableKeys = params[0].nonIndexableKeys; + final boolean forceUpdate = params[0].forceUpdate; + final SQLiteDatabase database = getWritableDatabase(); final String localeStr = Locale.getDefault().toString(); try { database.beginTransaction(); - if (dataToUpdate.size() > 0) { - processDataToUpdate(database, localeStr, dataToUpdate, forceUpdate); - } if (dataToDelete.size() > 0) { processDataToDelete(database, localeStr, dataToDelete); } + if (dataToUpdate.size() > 0) { + processDataToUpdate(database, localeStr, dataToUpdate, nonIndexableKeys, + forceUpdate); + } database.setTransactionSuccessful(); result = true; } finally { @@ -888,7 +1060,8 @@ public class Index { } private boolean processDataToUpdate(SQLiteDatabase database, String localeStr, - List<SearchIndexableData> dataToUpdate, boolean forceUpdate) { + List<SearchIndexableData> dataToUpdate, Map<String, List<String>> nonIndexableKeys, + boolean forceUpdate) { if (!forceUpdate && isLocaleAlreadyIndexed(database, localeStr)) { Log.d(LOG_TAG, "Locale '" + localeStr + "' is already indexed"); @@ -901,7 +1074,7 @@ public class Index { final int count = dataToUpdate.size(); for (int n = 0; n < count; n++) { final SearchIndexableData data = dataToUpdate.get(n); - indexOneSearchIndexableData(database, localeStr, data); + indexOneSearchIndexableData(database, localeStr, data, nonIndexableKeys); } final long now = System.currentTimeMillis(); @@ -911,15 +1084,27 @@ public class Index { } private boolean processDataToDelete(SQLiteDatabase database, String localeStr, - List<String> dataToDelete) { + List<SearchIndexableData> dataToDelete) { boolean result = false; final long current = System.currentTimeMillis(); final int count = dataToDelete.size(); for (int n = 0; n < count; n++) { - final String data = dataToDelete.get(n); - delete(database, data); + final SearchIndexableData data = dataToDelete.get(n); + if (data == null) { + continue; + } + if (!TextUtils.isEmpty(data.className)) { + delete(database, IndexColumns.CLASS_NAME, data.className); + } else { + if (data instanceof SearchIndexableRaw) { + final SearchIndexableRaw raw = (SearchIndexableRaw) data; + if (!TextUtils.isEmpty(raw.title)) { + delete(database, IndexColumns.DATA_TITLE, raw.title); + } + } + } } final long now = System.currentTimeMillis(); @@ -928,9 +1113,9 @@ public class Index { return result; } - private int delete(SQLiteDatabase database, String title) { - final String whereClause = IndexColumns.DATA_TITLE + "=?"; - final String[] whereArgs = new String[] { title }; + private int delete(SQLiteDatabase database, String columName, String value) { + final String whereClause = columName + "=?"; + final String[] whereArgs = new String[] { value }; return database.delete(Tables.TABLE_PREFS_INDEX, whereClause, whereArgs); } diff --git a/src/com/android/settings/search/IndexDatabaseHelper.java b/src/com/android/settings/search/IndexDatabaseHelper.java index bd035c3..4e94cb1 100644 --- a/src/com/android/settings/search/IndexDatabaseHelper.java +++ b/src/com/android/settings/search/IndexDatabaseHelper.java @@ -28,7 +28,7 @@ public class IndexDatabaseHelper extends SQLiteOpenHelper { private static final String TAG = "IndexDatabaseHelper"; private static final String DATABASE_NAME = "search_index.db"; - private static final int DATABASE_VERSION = 106; + private static final int DATABASE_VERSION = 109; public interface Tables { public static final String TABLE_PREFS_INDEX = "prefs_index"; @@ -46,10 +46,6 @@ public class IndexDatabaseHelper extends SQLiteOpenHelper { public static final String DATA_SUMMARY_OFF = "data_summary_off"; public static final String DATA_SUMMARY_OFF_NORMALIZED = "data_summary_off_normalized"; public static final String DATA_ENTRIES = "data_entries"; - public static final String DATA_SWITCH_ON = "data_switch_on"; - public static final String DATA_SWITCH_ON_NORMALIZED = "data_switch_on_normalized"; - public static final String DATA_SWITCH_OFF = "data_switch_off"; - public static final String DATA_SWITCH_OFF_NORMALIZED = "data_switch_off_normalized"; public static final String DATA_KEYWORDS = "data_keywords"; public static final String CLASS_NAME = "class_name"; public static final String SCREEN_TITLE = "screen_title"; @@ -58,6 +54,7 @@ public class IndexDatabaseHelper extends SQLiteOpenHelper { public static final String INTENT_TARGET_CLASS = "intent_target_class"; public static final String ICON = "icon"; public static final String ENABLED = "enabled"; + public static final String DATA_KEY_REF = "data_key_reference"; } public interface MetaColumns { @@ -85,14 +82,6 @@ public class IndexDatabaseHelper extends SQLiteOpenHelper { ", " + IndexColumns.DATA_ENTRIES + ", " + - IndexColumns.DATA_SWITCH_ON + - ", " + - IndexColumns.DATA_SWITCH_ON_NORMALIZED + - ", " + - IndexColumns.DATA_SWITCH_OFF + - ", " + - IndexColumns.DATA_SWITCH_OFF_NORMALIZED + - ", " + IndexColumns.DATA_KEYWORDS + ", " + IndexColumns.SCREEN_TITLE + @@ -108,6 +97,8 @@ public class IndexDatabaseHelper extends SQLiteOpenHelper { IndexColumns.INTENT_TARGET_CLASS + ", " + IndexColumns.ENABLED + + ", " + + IndexColumns.DATA_KEY_REF + ");"; private static final String CREATE_META_TABLE = diff --git a/src/com/android/settings/search/Indexable.java b/src/com/android/settings/search/Indexable.java index 004e5a7..19f88ae 100644 --- a/src/com/android/settings/search/Indexable.java +++ b/src/com/android/settings/search/Indexable.java @@ -57,5 +57,13 @@ public interface Indexable { * @return a list of {@link SearchIndexableRaw} references. Can be null. */ List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled); + + /** + * Return a list of data keys that cannot be indexed. See {@link SearchIndexableRaw} + * + * @param context the context. + * @return a list of {@link SearchIndexableRaw} references. Can be null. + */ + List<String> getNonIndexableKeys(Context context); } } diff --git a/src/com/android/settings/search/SearchIndexableRaw.java b/src/com/android/settings/search/SearchIndexableRaw.java index e661c87..b8a1699 100644 --- a/src/com/android/settings/search/SearchIndexableRaw.java +++ b/src/com/android/settings/search/SearchIndexableRaw.java @@ -28,14 +28,34 @@ import android.provider.SearchIndexableData; */ public class SearchIndexableRaw extends SearchIndexableData { + /** + * Title's raw data. + */ public String title; + + /** + * Summary's raw data when the data is "ON". + */ public String summaryOn; + + /** + * Summary's raw data when the data is "OFF". + */ public String summaryOff; + + /** + * Entries associated with the raw data (when the data can have several values). + */ public String entries; - public String switchOn; - public String switchOff; + + /** + * Keywords' raw data. + */ public String keywords; + /** + * Fragment's or Activity's title associated with the raw data. + */ public String screenTitle; public SearchIndexableRaw(Context context) { diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java index 9c0e5ea..6f8efce 100644 --- a/src/com/android/settings/search/SearchIndexableResources.java +++ b/src/com/android/settings/search/SearchIndexableResources.java @@ -17,6 +17,7 @@ package com.android.settings.search; import android.provider.SearchIndexableResource; +import com.android.settings.DataUsageSummary; import com.android.settings.DateTimeSettings; import com.android.settings.DevelopmentSettings; import com.android.settings.DeviceInfoSettings; @@ -46,29 +47,29 @@ import java.util.HashMap; public final class SearchIndexableResources { - private static int NO_DATA_RES_ID = 0; - - private static final int RANK_WIFI = 1; - private static final int RANK_BT = 2; - private static final int RANK_DATA_USAGE = 3; - private static final int RANK_WIRELESS = 4; - private static final int RANK_HOME = 5; - private static final int RANK_SOUND = 6; - private static final int RANK_DISPLAY = 7; - private static final int RANK_WALLPAPER = 7; - private static final int RANK_NOTIFICATIONS = 8; - private static final int RANK_MEMORY = 9; - private static final int RANK_POWER_USAGE = 10; - private static final int RANK_USERS = 11; - private static final int RANK_LOCATION = 12; - private static final int RANK_SECURITY = 13; - private static final int RANK_IME = 14; - private static final int RANK_PRIVACY = 15; - private static final int RANK_DATE_TIME = 16; - private static final int RANK_ACCESSIBILITY = 17; - private static final int RANK_PRINTING = 18; - private static final int RANK_DEVELOPEMENT = 19; - private static final int RANK_DEVICE_INFO = 20; + public static int NO_DATA_RES_ID = 0; + + public static final int RANK_WIFI = 1; + public static final int RANK_BT = 2; + public static final int RANK_DATA_USAGE = 3; + public static final int RANK_WIRELESS = 4; + public static final int RANK_HOME = 5; + public static final int RANK_SOUND = 6; + public static final int RANK_DISPLAY = 7; + public static final int RANK_WALLPAPER = 7; + public static final int RANK_NOTIFICATIONS = 8; + public static final int RANK_MEMORY = 9; + public static final int RANK_POWER_USAGE = 10; + public static final int RANK_USERS = 11; + public static final int RANK_LOCATION = 12; + public static final int RANK_SECURITY = 13; + public static final int RANK_IME = 14; + public static final int RANK_PRIVACY = 15; + public static final int RANK_DATE_TIME = 16; + public static final int RANK_ACCESSIBILITY = 17; + public static final int RANK_PRINTING = 18; + public static final int RANK_DEVELOPEMENT = 19; + public static final int RANK_DEVICE_INFO = 20; private static HashMap<String, SearchIndexableResource> sResMap = new HashMap<String, SearchIndexableResource>(); @@ -87,10 +88,10 @@ public final class SearchIndexableResources { BluetoothSettings.class.getName(), R.drawable.ic_settings_bluetooth2)); - sResMap.put(DataUsageMeteredSettings.class.getName(), + sResMap.put(DataUsageSummary.class.getName(), new SearchIndexableResource(RANK_DATA_USAGE, - R.xml.data_usage_metered_prefs, - DataUsageMeteredSettings.class.getName(), + NO_DATA_RES_ID, + DataUsageSummary.class.getName(), R.drawable.ic_settings_data_usage)); sResMap.put(WirelessSettings.class.getName(), @@ -161,13 +162,13 @@ public final class SearchIndexableResources { sResMap.put(SecuritySettings.class.getName(), new SearchIndexableResource(RANK_SECURITY, - R.xml.security_settings, + NO_DATA_RES_ID, SecuritySettings.class.getName(), R.drawable.ic_settings_security)); sResMap.put(InputMethodAndLanguageSettings.class.getName(), new SearchIndexableResource(RANK_IME, - R.xml.language_settings, + NO_DATA_RES_ID, InputMethodAndLanguageSettings.class.getName(), R.drawable.ic_settings_language)); @@ -185,13 +186,13 @@ public final class SearchIndexableResources { sResMap.put(AccessibilitySettings.class.getName(), new SearchIndexableResource(RANK_ACCESSIBILITY, - R.xml.accessibility_settings, + NO_DATA_RES_ID, AccessibilitySettings.class.getName(), R.drawable.ic_settings_accessibility)); sResMap.put(PrintSettingsFragment.class.getName(), new SearchIndexableResource(RANK_PRINTING, - R.xml.print_settings, + NO_DATA_RES_ID, PrintSettingsFragment.class.getName(), com.android.internal.R.drawable.ic_print)); diff --git a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java index 603175e..c0afcaf 100644 --- a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java +++ b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java @@ -23,8 +23,17 @@ import android.provider.SearchIndexablesProvider; import java.util.Collection; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RANK; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RESID; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS; + import static android.provider.SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS; import static android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS; +import static android.provider.SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS; public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider { private static final String TAG = "SettingsSearchIndexablesProvider"; @@ -40,13 +49,13 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider { Collection<SearchIndexableResource> values = SearchIndexableResources.values(); for (SearchIndexableResource val : values) { Object[] ref = new Object[7]; - ref[0] = val.rank; - ref[1] = val.xmlResId; - ref[2] = val.className; - ref[3] = val.iconResId; - ref[4] = null; // intent action - ref[5] = null; // intent target package - ref[6] = null; // intent target class + ref[COLUMN_INDEX_XML_RES_RANK] = val.rank; + ref[COLUMN_INDEX_XML_RES_RESID] = val.xmlResId; + ref[COLUMN_INDEX_XML_RES_CLASS_NAME] = val.className; + ref[COLUMN_INDEX_XML_RES_ICON_RESID] = val.iconResId; + ref[COLUMN_INDEX_XML_RES_INTENT_ACTION] = null; // intent action + ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE] = null; // intent target package + ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS] = null; // intent target class cursor.addRow(ref); } return cursor; @@ -54,7 +63,13 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider { @Override public Cursor queryRawData(String[] projection) { - Cursor result = new MatrixCursor(INDEXABLES_RAW_COLUMNS); + MatrixCursor result = new MatrixCursor(INDEXABLES_RAW_COLUMNS); return result; } + + @Override + public Cursor queryNonIndexableKeys(String[] projection) { + MatrixCursor cursor = new MatrixCursor(NON_INDEXABLES_KEYS_COLUMNS); + return cursor; + } } diff --git a/src/com/android/settings/wifi/WifiEnabler.java b/src/com/android/settings/wifi/WifiEnabler.java index e41429b..9f141ff 100644 --- a/src/com/android/settings/wifi/WifiEnabler.java +++ b/src/com/android/settings/wifi/WifiEnabler.java @@ -20,12 +20,10 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.database.ContentObserver; import android.net.NetworkInfo; import android.net.wifi.SupplicantState; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; -import android.os.UserHandle; import android.provider.Settings; import android.widget.CompoundButton; import android.widget.Switch; @@ -157,7 +155,7 @@ public class WifiEnabler implements CompoundButton.OnCheckedChangeListener { private void updateSearchIndex(boolean isWiFiOn) { Index.getInstance(mContext).updateFromClassNameResource( - WifiSettings.class.getName(), isWiFiOn); + WifiSettings.class.getName(), false, isWiFiOn); } private void setSwitchChecked(boolean checked) { diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index 7b3cf7b..15a184c 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -20,10 +20,10 @@ import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID; import static android.os.UserManager.DISALLOW_CONFIG_WIFI; import android.preference.PreferenceActivity; -import android.provider.SearchIndexableResource; import com.android.settings.R; import com.android.settings.RestrictedSettingsFragment; import com.android.settings.SettingsActivity; +import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settings.search.SearchIndexableRaw; import com.android.settings.wifi.p2p.WifiP2pSettings; @@ -1181,13 +1181,7 @@ public class WifiSettings extends RestrictedSettingsFragment } public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new SearchIndexProvider() { - @Override - public List<SearchIndexableResource> getXmlResourcesToIndex( - Context context, boolean enabled) { - return null; - } - + new BaseSearchIndexProvider() { @Override public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>(); |