diff options
44 files changed, 0 insertions, 5197 deletions
diff --git a/Android.mk b/Android.mk deleted file mode 100644 index 977074e..0000000 --- a/Android.mk +++ /dev/null @@ -1,19 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := user - -LOCAL_SRC_FILES := $(call all-java-files-under,src) - -LOCAL_JAVA_LIBRARIES := ext \ - com.android.im.plugin # TODO: remove this and load this on demand. - # (HACK: include this so we can load the - # classes defined in this plugin package) - -LOCAL_PACKAGE_NAME := ImProvider -LOCAL_CERTIFICATE := vendor/google/certs/app - -include $(BUILD_PACKAGE) - -# additionally, build sub-tests in a separate .apk -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/AndroidManifest.xml b/AndroidManifest.xml deleted file mode 100644 index 5d39ed1..0000000 --- a/AndroidManifest.xml +++ /dev/null @@ -1,48 +0,0 @@ -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.providers.im" - android:sharedUserId="com.google.uid.shared"> - - <permission android:name="com.android.providers.im.permission.READ_ONLY" - android:permissionGroup="android.permission-group.MESSAGES" - android:protectionLevel="dangerous" - android:label="@string/ro_perm_label" - android:description="@string/ro_perm_desc" /> - - <permission android:name="com.android.providers.im.permission.WRITE_ONLY" - android:permissionGroup="android.permission-group.MESSAGES" - android:protectionLevel="dangerous" - android:label="@string/wo_perm_label" - android:description="@string/wo_perm_desc" /> - - <uses-permission android:name="com.android.providers.im.permission.READ_ONLY" /> - <uses-permission android:name="com.android.providers.im.permission.WRITE_ONLY" /> - - <application android:process="com.google.process.gapps" - android:label="@string/im_label" - android:icon="@drawable/ic_launcher_im" - android:taskAffinity="android.task.im"> - <!-- TODO: remove this library include. It's a hack so we can load its classes --> - <uses-library android:name="com.android.im.plugin" /> - - <provider android:name="ImProvider" android:authorities="im" - android:multiprocess="false" - android:readPermission="com.android.providers.im.permission.READ_ONLY" - android:writePermission="com.android.providers.im.permission.WRITE_ONLY" - android:grantUriPermissions="true" /> - - <activity android:name=".LandingPage" - android:enabled="@bool/enableLandingPageActivity"> - <intent-filter> - <action android:name="android.intent.action.MAIN" /> - <action android:name="android.intent.action.VIEW" /> - <category android:name="android.intent.category.DEFAULT" /> - <category android:name="android.intent.category.LAUNCHER" /> - </intent-filter> - <intent-filter> - <action android:name="android.intent.action.VIEW" /> - <category android:name="android.intent.category.DEFAULT" /> - <data android:mimeType="vnd.android.cursor.dir/im-providers" /> - </intent-filter> - </activity> - </application> -</manifest> diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29..0000000 --- a/MODULE_LICENSE_APACHE2 +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - 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. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/res/color/landing_page_text.xml b/res/color/landing_page_text.xml deleted file mode 100644 index 6e967d9..0000000 --- a/res/color/landing_page_text.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_focused="true" android:color="#ff000000"/> - <item android:state_selected="true" android:color="#ff000000"/> - <item android:state_pressed="true" android:color="#ff000000"/> - <item android:color="#ffffffff"/> -</selector> diff --git a/res/color/landing_page_text_secondary.xml b/res/color/landing_page_text_secondary.xml deleted file mode 100644 index 78cc390..0000000 --- a/res/color/landing_page_text_secondary.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_focused="true" android:color="#ff000000"/> - <item android:state_selected="true" android:color="#ff000000"/> - <item android:state_pressed="true" android:color="#ff000000"/> - <item android:color="#ffbebebe"/> -</selector> diff --git a/res/drawable/bubble.xml b/res/drawable/bubble.xml deleted file mode 100644 index 38cff25..0000000 --- a/res/drawable/bubble.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* bubble_with_chats.xml -** -** Copyright 2009, Google Inc. -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_pressed="true" android:drawable="@drawable/im_bubble_pressed" /> - <item android:state_selected="true" android:drawable="@drawable/im_bubble_highlight" /> - <item android:state_enabled="false" android:drawable="@drawable/im_bubble_normal" /> - <item android:drawable="@drawable/im_bubble_normal" /> -</selector> diff --git a/res/drawable/default_background.9.png b/res/drawable/default_background.9.png Binary files differdeleted file mode 100644 index 33cb551..0000000 --- a/res/drawable/default_background.9.png +++ /dev/null diff --git a/res/drawable/ic_launcher_im.png b/res/drawable/ic_launcher_im.png Binary files differdeleted file mode 100644 index afc35a2..0000000 --- a/res/drawable/ic_launcher_im.png +++ /dev/null diff --git a/res/drawable/im_bubble_highlight.9.png b/res/drawable/im_bubble_highlight.9.png Binary files differdeleted file mode 100644 index 9b5588a..0000000 --- a/res/drawable/im_bubble_highlight.9.png +++ /dev/null diff --git a/res/drawable/im_bubble_normal.9.png b/res/drawable/im_bubble_normal.9.png Binary files differdeleted file mode 100644 index a9b327c..0000000 --- a/res/drawable/im_bubble_normal.9.png +++ /dev/null diff --git a/res/drawable/im_bubble_pressed.9.png b/res/drawable/im_bubble_pressed.9.png Binary files differdeleted file mode 100644 index 3933268..0000000 --- a/res/drawable/im_bubble_pressed.9.png +++ /dev/null diff --git a/res/drawable/imlogo_s.png b/res/drawable/imlogo_s.png Binary files differdeleted file mode 100644 index b7aa43a..0000000 --- a/res/drawable/imlogo_s.png +++ /dev/null diff --git a/res/layout/account_view.xml b/res/layout/account_view.xml deleted file mode 100644 index 46bdecf..0000000 --- a/res/layout/account_view.xml +++ /dev/null @@ -1,92 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> - -<com.android.providers.im.ProviderListItem - xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="horizontal" - android:layout_width="fill_parent" - android:layout_height="?android:attr/listPreferredItemHeight"> - - <ImageView - android:id="@+id/providerIcon" - android:layout_gravity="center_vertical" - android:scaleType="fitXY" - android:paddingLeft="5dip" - android:paddingRight="2dip" - android:layout_width="39dip" - android:layout_height="32dip"/> - - <LinearLayout - android:id="@+id/underBubble" - android:orientation="horizontal" - android:layout_weight="1" - android:layout_width="0dip" - android:layout_height="fill_parent"> - - <LinearLayout - android:orientation="vertical" - android:layout_weight="1" - android:layout_width="0dip" - android:layout_height="wrap_content" - android:layout_gravity="center_vertical"> - - <LinearLayout - android:orientation="horizontal" - android:layout_width="fill_parent" - android:layout_height="wrap_content"> - - <TextView android:id="@+id/providerName" - android:textColor="@color/landing_page_text" - android:textAppearance="?android:attr/textAppearanceLarge" - android:textStyle="bold" - android:maxLines="1" - android:layout_weight="0" - android:ellipsize="marquee" - android:layout_width="wrap_content" - android:layout_height="wrap_content" /> - <TextView android:id="@+id/conversations" - android:textAppearance="?android:attr/textAppearanceMedium" - android:textColor="@color/landing_page_text_secondary" - android:maxLines="1" - android:layout_weight="1" - android:paddingRight="3dip" - android:paddingLeft="5dip" - android:layout_width="wrap_content" - android:layout_height="wrap_content" /> - </LinearLayout> - - <TextView android:id="@+id/loginName" - android:textAppearance="?android:attr/textAppearanceSmall" - android:textColor="@color/landing_page_text" - android:ellipsize="marquee" - android:maxLines="1" - android:layout_width="fill_parent" - android:layout_height="wrap_content"/> - </LinearLayout> - <ImageView - android:id="@+id/statusIcon" - android:scaleType="fitXY" - android:paddingRight="6dip" - android:paddingLeft="6dip" - android:layout_weight="0" - android:layout_gravity="center_vertical" - android:layout_width="30dip" - android:layout_height="18dip"/> - </LinearLayout> -</com.android.providers.im.ProviderListItem> diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml deleted file mode 100644 index d078c76..0000000 --- a/res/values-cs/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"číst zprávy chatu"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Povoluje aplikacím číst data z poskytovatele obsahu chatu."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"chatovat"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Povoluje aplikacím zapisovat data do poskytovatele obsahu chatových zpráv."</string> - <string name="im_label" msgid="5040064040105432386">"Chat"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Chat – vyberte účet"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Přidat účet"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Upravit účet"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Odstranit účet"</string> - <string name="sign_in" msgid="8420453507342456753">"Přihlásit se"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Odhlásit se"</string> - <string name="menu_settings" msgid="590956137301210916">"Nastavení"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Odhlásit se ze všech služeb"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Chat – vyberte účet"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"Přidat účet <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Seznam kontaktů"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Přihlašování..."</string> -</resources> diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml deleted file mode 100644 index 603d785..0000000 --- a/res/values-da/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"læs chatbeskeder"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Tillader programmer at læse data fra IM-indholdsleverandøren."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"skriv chatbeskeder"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Tillader programmer at skrive data til IM-indholdsleverandøren."</string> - <string name="im_label" msgid="5040064040105432386">"IM"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Chat – Vælg en konto"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Tilføj konto"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Rediger konto"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Fjern konto"</string> - <string name="sign_in" msgid="8420453507342456753">"Log ind"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Log ud"</string> - <string name="menu_settings" msgid="590956137301210916">"Indstillinger"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Log alle ud"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Chat – Vælg en konto"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"Tilføj <xliff:g id="ACCOUNT">%1$s</xliff:g>-konto"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Liste over kontakter"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Logger ind ..."</string> -</resources> diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml deleted file mode 100644 index 559733a..0000000 --- a/res/values-de/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"Chat-Nachrichten lesen"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Ermöglicht Anwendungen das Lesen von Daten des IM-Content-Providers."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"Chat-Nachrichten verfassen"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Ermöglicht Anwendungen das Schreiben von Daten an den IM-Content-Provider."</string> - <string name="im_label" msgid="5040064040105432386">"IM"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Chat - Konto auswählen"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Konto hinzufügen"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Konto bearbeiten"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Konto entfernen"</string> - <string name="sign_in" msgid="8420453507342456753">"Anmelden"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Abmelden"</string> - <string name="menu_settings" msgid="590956137301210916">"Einstellungen"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Alle abmelden"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Chat - Konto auswählen"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"<xliff:g id="ACCOUNT">%1$s</xliff:g>-Konto hinzufügen"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Kontaktliste"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Anmeldung..."</string> -</resources> diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml deleted file mode 100644 index 414b87c..0000000 --- a/res/values-el/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"ανάγνωση άμεσων μηνυμάτων"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Επιτρέπει στις εφαρμογές την ανάγνωση δεδομένων από τον πάροχο περιεχομένου ανταλλαγής άμεσων μηνυμάτων (IM)."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"εγγραφή άμεσων μηνυμάτων"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Επιτρέπει στις εφαρμογές την εγγραφή δεδομένων από τον πάροχο περιεχομένου ανταλλαγής άμεσων μηνυμάτων (IM)."</string> - <string name="im_label" msgid="5040064040105432386">"Ανταλ.άμεσων μην.(IM)"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Συζήτηση - Επιλογή λογαριασμού"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Προσθήκη λογαριασμού"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Επεξεργασία λογαριασμού"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Κατάργηση λογαριασμού"</string> - <string name="sign_in" msgid="8420453507342456753">"Σύνδεση"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Αποσύνδεση"</string> - <string name="menu_settings" msgid="590956137301210916">"Ρυθμίσεις"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Αποσύνδεση όλων"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Συζήτηση - Επιλογή λογαριασμού"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"Προσθήκη λογαριασμού <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Λίστα επαφών"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Σύνδεση..."</string> -</resources> diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml deleted file mode 100644 index 5d7df89..0000000 --- a/res/values-es-rUS/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"leer mensajes instantáneos"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Permite a una aplicación leer datos del proveedor de contenido de mensajería instantánea"</string> - <string name="wo_perm_label" msgid="4771652386754813294">"escribir mensajes instantáneos"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Permite a una aplicación introducir datos en el proveedor de contenido de mensajería instantánea"</string> - <string name="im_label" msgid="5040064040105432386">"Mensajería instantánea"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Chat - Seleccionar una cuenta"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Agregar cuenta"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Editar cuenta"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Suprimir cuenta"</string> - <string name="sign_in" msgid="8420453507342456753">"Inicia sesión"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Cerrar sesión"</string> - <string name="menu_settings" msgid="590956137301210916">"Configuración"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Cerrar sesión de todo"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Chat - Seleccionar una cuenta"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"Agregar cuenta <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Lista de contactos"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Iniciando sesión..."</string> -</resources> diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml deleted file mode 100644 index ac9b14f..0000000 --- a/res/values-es/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"leer mensajes instantáneos"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Permite que las aplicaciones lean datos del proveedor de contenido de MI."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"escribir mensajes instantáneos"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Permite que las aplicaciones escriban datos en el proveedor de contenido de MI."</string> - <string name="im_label" msgid="5040064040105432386">"MI"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Chat: seleccionar una cuenta"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Añadir cuenta"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Editar cuenta"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Eliminar cuenta"</string> - <string name="sign_in" msgid="8420453507342456753">"Acceder"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Salir"</string> - <string name="menu_settings" msgid="590956137301210916">"Configuración"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Salir de todo"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Chat: seleccionar una cuenta"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"Añadir cuenta <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Lista de contactos"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Accediendo..."</string> -</resources> diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml deleted file mode 100644 index 7e4a5d6..0000000 --- a/res/values-fr/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"Lecture des messages instantanés"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Permet aux applications de lire les données du prestataire de contenu de messagerie instantanée."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"écrire des messages instantanées"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Permet aux applications d\'écrire les données pour le prestataire de contenu de messagerie instantanée."</string> - <string name="im_label" msgid="5040064040105432386">"Chat"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Chat : sélectionner un compte"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Ajouter un compte"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Modifier un compte"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Supprimer un compte"</string> - <string name="sign_in" msgid="8420453507342456753">"Connexion"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Déconnexion"</string> - <string name="menu_settings" msgid="590956137301210916">"Paramètres"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Se déconnecter de tout"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Chat : sélectionner un compte"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"Ajouter le compte <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Liste de contacts"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Connexion..."</string> -</resources> diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml deleted file mode 100644 index e5b2965..0000000 --- a/res/values-it/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"leggere messaggi immediati"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Consente alle applicazioni di leggere dati del provider di contenuti IM."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"scrivere messaggi immediati"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Consente alle applicazioni di scrivere dati per il provider di contenuti IM."</string> - <string name="im_label" msgid="5040064040105432386">"Chat"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Chat - Seleziona un account"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Aggiungi account"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Modifica account"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Rimuovi account"</string> - <string name="sign_in" msgid="8420453507342456753">"Accedi"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Esci"</string> - <string name="menu_settings" msgid="590956137301210916">"Impostazioni"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Esci da tutto"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Chat - Seleziona un account"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"Aggiungi account <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Elenco contatti"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Accesso..."</string> -</resources> diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml deleted file mode 100644 index 0111762..0000000 --- a/res/values-ja/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"インスタントメッセージを表示"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"IMコンテンツプロバイダーからのデータ読み取りをアプリケーションに許可します。"</string> - <string name="wo_perm_label" msgid="4771652386754813294">"インスタントメッセージを作成"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"IMコンテンツプロバイダーからのデータ書き込みをアプリケーションに許可します。"</string> - <string name="im_label" msgid="5040064040105432386">"チャット"</string> - <string name="landing_page_title" msgid="2177721703095999384">"チャット: アカウントを選択"</string> - <string name="menu_add_account" msgid="4184762314855405486">"アカウントを追加"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"アカウントを編集"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"アカウントを削除"</string> - <string name="sign_in" msgid="8420453507342456753">"ログイン"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"ログアウト"</string> - <string name="menu_settings" msgid="590956137301210916">"設定"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"すべてログアウト"</string> - <string name="choose_account_title" msgid="3179220583433723296">"チャット: アカウントを選択"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"<xliff:g id="ACCOUNT">%1$s</xliff:g>アカウントを追加"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"連絡先リスト"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"ログイン中..."</string> -</resources> diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml deleted file mode 100644 index c6265f2..0000000 --- a/res/values-ko/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"인스턴트 메시지 읽기"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"응용프로그램이 메신저 콘텐츠 제공업체에서 제공한 데이터를 읽을 수 있도록 합니다."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"인스턴트 메시지 쓰기"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"응용프로그램이 메신저 콘텐츠 제공업체에 데이터를 쓸 수 있도록 합니다."</string> - <string name="im_label" msgid="5040064040105432386">"메신저"</string> - <string name="landing_page_title" msgid="2177721703095999384">"채팅 - 계정 선택"</string> - <string name="menu_add_account" msgid="4184762314855405486">"계정 추가"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"계정 수정"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"계정 삭제"</string> - <string name="sign_in" msgid="8420453507342456753">"로그인"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"로그아웃"</string> - <string name="menu_settings" msgid="590956137301210916">"설정"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"모두 로그아웃"</string> - <string name="choose_account_title" msgid="3179220583433723296">"채팅 - 계정 선택"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"<xliff:g id="ACCOUNT">%1$s</xliff:g> 계정 추가"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"연락처 목록"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"로그인하는 중..."</string> -</resources> diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml deleted file mode 100644 index d07e131..0000000 --- a/res/values-nb/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"les lynmeldinger"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Tillat applikasjoner å lese data fra lynmeldingsoperatøren."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"write instant messages"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Tillat applikasjonerå skrive data til lynmeldingsoperatøren."</string> - <string name="im_label" msgid="5040064040105432386">"Nettprat"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Lynmeldinger - velg en konto"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Legg til konto"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Rediger konto"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Fjern konto"</string> - <string name="sign_in" msgid="8420453507342456753">"Logg på"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Logg av"</string> - <string name="menu_settings" msgid="590956137301210916">"Innstillinger"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Logg av alle"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Lynmeldinger - velg en konto"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"Legg til <xliff:g id="ACCOUNT">%1$s</xliff:g>-konto"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Kontaktliste"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Logger på…"</string> -</resources> diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml deleted file mode 100644 index 7d71291..0000000 --- a/res/values-nl/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"chatberichten lezen"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Toepassingen toestaan gegevens te lezen van de provider van chatinhoud."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"chatberichten schrijven"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Toepassingen toestaan gegevens te schrijven naar de provider van chatinhoud."</string> - <string name="im_label" msgid="5040064040105432386">"Chat"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Chatten - Een account selecteren"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Account toevoegen"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Account bewerken"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Account verwijderen"</string> - <string name="sign_in" msgid="8420453507342456753">"Aanmelden"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Afmelden"</string> - <string name="menu_settings" msgid="590956137301210916">"Instellingen"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Overal afmelden"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Chatten - Een account selecteren"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"<xliff:g id="ACCOUNT">%1$s</xliff:g>-account toevoegen"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Lijst met contacten"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Aanmelden..."</string> -</resources> diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml deleted file mode 100644 index e5d6f9b..0000000 --- a/res/values-pl/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"odczytaj wiadomości czatu"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Zezwala aplikacjom na odczytywanie danych od dostawcy zawartości czatu."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"zapisz wiadomości czatu"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Zezwala aplikacjom na zapisywanie danych do dostawcy zawartości czatu."</string> - <string name="im_label" msgid="5040064040105432386">"Czat"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Czat: Wybierz konto"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Dodaj konto"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Edytuj konto"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Usuń konto"</string> - <string name="sign_in" msgid="8420453507342456753">"Zaloguj się"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Wyloguj się"</string> - <string name="menu_settings" msgid="590956137301210916">"Ustawienia"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Wyloguj wszystkie"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Czat: Wybierz konto"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"Dodaj konto <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Lista kontaktów"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Trwa logowanie..."</string> -</resources> diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml deleted file mode 100644 index fa7a31d..0000000 --- a/res/values-pt-rPT/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"ler mensagens instantâneas"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Permite que as aplicações leiam dados a partir do fornecedor de conteúdo de MI."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"escrever mensagens instantâneas"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Permite que as aplicações escrevam dados para o fornecedor de conteúdo de MI."</string> - <string name="im_label" msgid="5040064040105432386">"MI"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Chat - Seleccione uma conta"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Adicionar conta"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Editar conta"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Remover conta"</string> - <string name="sign_in" msgid="8420453507342456753">"Iniciar sessão"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Terminar sessão"</string> - <string name="menu_settings" msgid="590956137301210916">"Definições"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Terminar sessão em todos"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Chat - Seleccionar uma conta"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"Adicionar a conta <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Lista de contactos"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"A iniciar sessão..."</string> -</resources> diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml deleted file mode 100644 index 884a215..0000000 --- a/res/values-pt/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"ler mensagens instantâneas"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Permite que os aplicativos leiam os dados do provedor de conteúdo de mensagem instantânea."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"gravar mensagens instantâneas"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Permite que os aplicativos gravem os dados no provedor de conteúdo de mensagem instantânea."</string> - <string name="im_label" msgid="5040064040105432386">"Mensagem instantânea"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Bate-papo - Selecione uma conta"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Adicionar conta"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Editar conta"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Remover conta"</string> - <string name="sign_in" msgid="8420453507342456753">"Fazer login"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Sair"</string> - <string name="menu_settings" msgid="590956137301210916">"Configurações"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Sair de todos"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Bate-papo - Selecione uma conta"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"Adicionar conta <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Lista de contatos"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Fazendo login..."</string> -</resources> diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml deleted file mode 100644 index dd27d43..0000000 --- a/res/values-ru/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"читать мгновенные сообщения"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Позволяет приложениям считывать данные через поставщика чата."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"писать мгновенные сообщения"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Позволяет приложениям записывать данные через поставщика чата."</string> - <string name="im_label" msgid="5040064040105432386">"Чат"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Чат – выберите аккаунт"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Добавить аккаунт"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Изменить аккаунт"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Удалить аккаунт"</string> - <string name="sign_in" msgid="8420453507342456753">"Вход"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Выход"</string> - <string name="menu_settings" msgid="590956137301210916">"Настройки"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Выйти отовсюду"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Чат – выберите аккаунт"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"Добавить аккаунт <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Список контактов"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Выполняется вход..."</string> -</resources> diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml deleted file mode 100644 index 0df5c5d..0000000 --- a/res/values-sv/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"läsa chattmeddelanden"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Tillåter att ett program läser data från chattens innehållsleverantör."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"skriva chattmeddelanden"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Tillåter att ett program skriver data till innehållsleverantören för chatten."</string> - <string name="im_label" msgid="5040064040105432386">"Chatt"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Chatt – välj ett konto"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Lägg till konto"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Redigera konto"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Ta bort konto"</string> - <string name="sign_in" msgid="8420453507342456753">"Logga in"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Logga ut"</string> - <string name="menu_settings" msgid="590956137301210916">"Inställningar"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Logga ut från alla"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Chatt – Välj ett konto"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"Lägg till kontot <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Kontaktlista"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Loggar in…"</string> -</resources> diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml deleted file mode 100644 index d3b4f15..0000000 --- a/res/values-tr/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"anlık iletileri oku"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"Uygulamalara, IM içerik sağlayıcısından gelen verileri okuma izni verir."</string> - <string name="wo_perm_label" msgid="4771652386754813294">"anlık iletiler yazın"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"Uygulamaların IM içerik sağlayıcısına veri yazmasına izin verir."</string> - <string name="im_label" msgid="5040064040105432386">"IM"</string> - <string name="landing_page_title" msgid="2177721703095999384">"Sohbet - Bir hesap seçin"</string> - <string name="menu_add_account" msgid="4184762314855405486">"Hesap ekle"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"Hesabı düzenle"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"Hesabı kaldır"</string> - <string name="sign_in" msgid="8420453507342456753">"Oturum aç"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"Çıkış"</string> - <string name="menu_settings" msgid="590956137301210916">"Ayarlar"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"Tüm hizmetlerden çık"</string> - <string name="choose_account_title" msgid="3179220583433723296">"Sohbet - Bir hesap seçin"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"<xliff:g id="ACCOUNT">%1$s</xliff:g> hesabını ekle"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"Kişi listesi"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"Oturum açılıyor..."</string> -</resources> diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml deleted file mode 100644 index e68b069..0000000 --- a/res/values-zh-rCN/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"阅读即时消息"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"允许应用程序从即时消息内容提供者处读取数据。"</string> - <string name="wo_perm_label" msgid="4771652386754813294">"编写即时消息"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"允许应用程序向即时消息内容提供者写入数据。"</string> - <string name="im_label" msgid="5040064040105432386">"即时消息"</string> - <string name="landing_page_title" msgid="2177721703095999384">"聊天 - 选择一个帐户"</string> - <string name="menu_add_account" msgid="4184762314855405486">"添加帐户"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"编辑帐户"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"删除帐户"</string> - <string name="sign_in" msgid="8420453507342456753">"登录"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"退出"</string> - <string name="menu_settings" msgid="590956137301210916">"设置"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"全部退出"</string> - <string name="choose_account_title" msgid="3179220583433723296">"聊天 - 选择一个帐户"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"添加 <xliff:g id="ACCOUNT">%1$s</xliff:g> 帐户"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"联系人列表"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"正在登录..."</string> -</resources> diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml deleted file mode 100644 index 061e98d..0000000 --- a/res/values-zh-rTW/strings.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label" msgid="8923213594676670163">"讀取即時訊息"</string> - <string name="ro_perm_desc" msgid="6154703403388711809">"允許應用程式讀取來自即時訊息內容提供者的資料。"</string> - <string name="wo_perm_label" msgid="4771652386754813294">"撰寫即時訊息"</string> - <string name="wo_perm_desc" msgid="470416777693330370">"允許應用程式將資料寫入即時訊息內容提供者。"</string> - <string name="im_label" msgid="5040064040105432386">"即時訊息"</string> - <string name="landing_page_title" msgid="2177721703095999384">"即時通訊 - 選取帳戶"</string> - <string name="menu_add_account" msgid="4184762314855405486">"新增帳戶"</string> - <string name="menu_edit_account" msgid="6585077522972888350">"編輯帳戶"</string> - <string name="menu_remove_account" msgid="8013513817623405880">"移除帳戶"</string> - <string name="sign_in" msgid="8420453507342456753">"登入"</string> - <string name="menu_sign_out" msgid="2737051932405259853">"登出"</string> - <string name="menu_settings" msgid="590956137301210916">"設定"</string> - <string name="menu_sign_out_all" msgid="945106187701517280">"全部登出"</string> - <string name="choose_account_title" msgid="3179220583433723296">"即時通訊 - 選取帳戶"</string> - <string name="conversations" msgid="6809253595345281731">"(%1$d)"</string> - <string name="add_account" msgid="3793076059089010851">"新增 <xliff:g id="ACCOUNT">%1$s</xliff:g> 帳戶"</string> - <string name="menu_view_contact_list" msgid="4703362007911835460">"聯絡人"</string> - <string name="signing_in_wait" msgid="8262004726366994582">"登入中…"</string> -</resources> diff --git a/res/values/config.xml b/res/values/config.xml deleted file mode 100644 index 8060c3d..0000000 --- a/res/values/config.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2009, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<!-- These resources are around just to allow their values to be customized - for different hardware and product builds. --> -<resources> - <!-- Flag indicating whether IM app should be shown in the application tray --> - <bool name="enableLandingPageActivity">false</bool> -</resources> diff --git a/res/values/strings.xml b/res/values/strings.xml deleted file mode 100644 index 2519476..0000000 --- a/res/values/strings.xml +++ /dev/null @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ro_perm_label">read instant messages</string> - <string name="ro_perm_desc"> - Allows applications to read data from the IM content provider. - </string> - - <string name="wo_perm_label">write instant messages</string> - <string name="wo_perm_desc"> - Allows applications to write data to the IM content provider. - </string> - - <!-- The application label --> - <string name="im_label">IM</string> - - <!-- These strings displayed on the landing page. --> - <!-- The title of the landing page.--> - <string name="landing_page_title">Chat - Select an account</string> - - <!-- Landing page screen menu and context menu items. --> - <!-- Conext menu item: add a new account.--> - <string name="menu_add_account">Add account</string> - <!-- Conext menu item: edit an account.--> - <string name="menu_edit_account">Edit account</string> - <!-- Conext menu item: remove an account.--> - <string name="menu_remove_account">Remove account</string> - <!-- Context menu item: sign into service. --> - <string name="sign_in">Sign in</string> - <!-- Context menu item: sign out the service.--> - <string name="menu_sign_out">Sign out</string> - <!-- Context menu item: go to the setting page.--> - <string name="menu_settings">Settings</string> - <!-- Screen menu item: sign out all service.--> - <string name="menu_sign_out_all">Sign out all</string> - - <!-- These strings displayed on the landing page. --> - <!-- The title of the landing page.--> - <string name="choose_account_title">Chat - Select an account</string> - <!-- Displays the number of ongoing chats on the landing page.--> - <string name="conversations">(%1$d)</string> - <!-- The add account label on the landing page if there isn't any account.--> - <string name="add_account">Add <xliff:g id="account">%1$s</xliff:g> account</string> - - <!-- Screen menu item: go the contact list screen. May be overrided by the plugin.--> - <string name="menu_view_contact_list">Contact list</string> - - <!-- Connection status --> - <string name="signing_in_wait">Signing in\u2026</string> - -</resources> diff --git a/src/com/android/providers/im/BrandingResources.java b/src/com/android/providers/im/BrandingResources.java deleted file mode 100644 index e232a96..0000000 --- a/src/com/android/providers/im/BrandingResources.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.providers.im; - -import android.content.Context; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.res.Resources; -import android.graphics.drawable.Drawable; -import android.os.RemoteException; -import android.util.Log; - -import java.util.Map; - -/** - * The provider specific branding resources. - */ -public class BrandingResources { - private static final String TAG = "IM"; - private static final boolean LOCAL_DEBUG = false; - - private Map<Integer, Integer> mResMapping; - private Resources mPackageRes; - - private BrandingResources mDefaultRes; - - /** - * Creates a new BrandingResource of a specific plug-in. The resources will - * be retrieved from the plug-in package. - * - * @param context The current application context. - * @param pluginInfo The info about the plug-in. - * @param provider the name of the IM service provider. - * @param defaultRes The default branding resources. If the resource is not - * found in the plug-in, the default resource will be returned. - */ - public BrandingResources(Context context, LandingPage.PluginInfo pluginInfo, String provider, - BrandingResources defaultRes) { - String packageName = null; - mDefaultRes = defaultRes; - - try { - mResMapping = pluginInfo.mPlugin.getResourceMapForProvider(provider); - packageName = pluginInfo.mPlugin.getResourcePackageNameForProvider(provider); - } catch (RemoteException e) { - Log.e(TAG, "Failed load the plugin resource map", e); - } - - if (packageName == null) { - packageName = pluginInfo.mPackageName; - } - - PackageManager pm = context.getPackageManager(); - try { - if (LOCAL_DEBUG) log("load resources from " + packageName); - mPackageRes = pm.getResourcesForApplication(packageName); - } catch (NameNotFoundException e) { - Log.e(TAG, "Can not load resources from " + packageName); - } - } - - /** - * Creates a BrandingResource with application context and the resource ID map. - * The resource will be retrieved from the context directly instead from the plug-in package. - * - * @param context - * @param resMapping - */ - public BrandingResources(Context context, Map<Integer, Integer> resMapping, - BrandingResources defaultRes) { - mPackageRes = context.getResources(); - mResMapping = resMapping; - mDefaultRes = defaultRes; - } - - /** - * Gets a drawable object associated with a particular resource ID defined - * in {@link com.android.im.plugin.BrandingResourceIDs} - * - * @param id The ID defined in - * {@link com.android.im.plugin.BrandingResourceIDs} - * @return Drawable An object that can be used to draw this resource. - */ - public Drawable getDrawable(int id) { - int resId = getPackageResourceId(id); - if (resId != 0) { - return mPackageRes.getDrawable(resId); - } else if (mDefaultRes != null){ - return mDefaultRes.getDrawable(id); - } else { - return null; - } - } - - /** - * Gets the string value associated with a particular resource ID defined in - * {@link com.android.im.plugin.BrandingResourceIDs} - * - * @param id The ID of the string resource defined in - * {@link com.android.im.plugin.BrandingResourceIDs} - * @param formatArgs The format arguments that will be used for - * substitution. - * @return The string data associated with the resource - */ - public String getString(int id, Object... formatArgs) { - int resId = getPackageResourceId(id); - if (resId != 0) { - return mPackageRes.getString(resId, formatArgs); - } else if (mDefaultRes != null){ - return mDefaultRes.getString(id, formatArgs); - } else { - return null; - } - } - - /** - * Gets the string array associated with a particular resource ID defined in - * {@link com.android.im.plugin.BrandingResourceIDs} - * - * @param id The ID of the string resource defined in - * {@link com.android.im.plugin.BrandingResourceIDs} - * @return The string array associated with the resource. - */ - public String[] getStringArray(int id) { - int resId = getPackageResourceId(id); - if (resId != 0) { - return mPackageRes.getStringArray(resId); - } else if (mDefaultRes != null){ - return mDefaultRes.getStringArray(id); - } else { - return null; - } - } - - private int getPackageResourceId(int id) { - if (mResMapping == null || mPackageRes == null) { - return 0; - } - Integer resId = mResMapping.get(id); - return resId == null ? 0 : resId; - } - - private void log(String msg) { - Log.d(TAG, "[BrandingRes] " + msg); - } -} diff --git a/src/com/android/providers/im/ImProvider.java b/src/com/android/providers/im/ImProvider.java deleted file mode 100644 index 319a197..0000000 --- a/src/com/android/providers/im/ImProvider.java +++ /dev/null @@ -1,2768 +0,0 @@ -/* - * Copyright (C) 2007 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.providers.im; - -import android.content.ContentProvider; -import android.content.ContentValues; -import android.content.Context; -import android.content.UriMatcher; -import android.content.ContentResolver; -import android.database.Cursor; -import android.database.DatabaseUtils; -import android.database.sqlite.SQLiteConstraintException; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; -import android.database.sqlite.SQLiteQueryBuilder; -import android.net.Uri; -import android.os.ParcelFileDescriptor; -import android.provider.Im; -import android.text.TextUtils; -import android.util.Log; - - -import java.io.FileNotFoundException; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.HashMap; - -/** - * A content provider for IM - */ -public class ImProvider extends ContentProvider { - private static final String LOG_TAG = "imProvider"; - private static final boolean DBG = false; - - private static final String AUTHORITY = "im"; - - private static final boolean USE_CONTACT_PRESENCE_TRIGGER = false; - - private static final String TABLE_ACCOUNTS = "accounts"; - private static final String TABLE_PROVIDERS = "providers"; - private static final String TABLE_PROVIDER_SETTINGS = "providerSettings"; - - private static final String TABLE_CONTACTS = "contacts"; - private static final String TABLE_CONTACTS_ETAG = "contactsEtag"; - private static final String TABLE_BLOCKED_LIST = "blockedList"; - private static final String TABLE_CONTACT_LIST = "contactList"; - private static final String TABLE_INVITATIONS = "invitations"; - private static final String TABLE_GROUP_MEMBERS = "groupMembers"; - private static final String TABLE_GROUP_MESSAGES = "groupMessages"; - private static final String TABLE_PRESENCE = "presence"; - private static final String USERNAME = "username"; - private static final String TABLE_CHATS = "chats"; - private static final String TABLE_AVATARS = "avatars"; - private static final String TABLE_SESSION_COOKIES = "sessionCookies"; - private static final String TABLE_MESSAGES = "messages"; - private static final String TABLE_OUTGOING_RMQ_MESSAGES = "outgoingRmqMessages"; - private static final String TABLE_LAST_RMQ_ID = "lastrmqid"; - private static final String TABLE_ACCOUNT_STATUS = "accountStatus"; - private static final String TABLE_BRANDING_RESOURCE_MAP_CACHE = "brandingResMapCache"; - - private static final String DATABASE_NAME = "im.db"; - private static final int DATABASE_VERSION = 47; - - protected static final int MATCH_PROVIDERS = 1; - protected static final int MATCH_PROVIDERS_BY_ID = 2; - protected static final int MATCH_PROVIDERS_WITH_ACCOUNT = 3; - protected static final int MATCH_ACCOUNTS = 10; - protected static final int MATCH_ACCOUNTS_BY_ID = 11; - protected static final int MATCH_CONTACTS = 18; - protected static final int MATCH_CONTACTS_JOIN_PRESENCE = 19; - protected static final int MATCH_CONTACTS_BAREBONE = 20; - protected static final int MATCH_CHATTING_CONTACTS = 21; - protected static final int MATCH_CONTACTS_BY_PROVIDER = 22; - protected static final int MATCH_CHATTING_CONTACTS_BY_PROVIDER = 23; - protected static final int MATCH_NO_CHATTING_CONTACTS_BY_PROVIDER = 24; - protected static final int MATCH_ONLINE_CONTACTS_BY_PROVIDER = 25; - protected static final int MATCH_OFFLINE_CONTACTS_BY_PROVIDER = 26; - protected static final int MATCH_CONTACT = 27; - protected static final int MATCH_CONTACTS_BULK = 28; - protected static final int MATCH_ONLINE_CONTACT_COUNT = 30; - protected static final int MATCH_BLOCKED_CONTACTS = 31; - protected static final int MATCH_CONTACTLISTS = 32; - protected static final int MATCH_CONTACTLISTS_BY_PROVIDER = 33; - protected static final int MATCH_CONTACTLIST = 34; - protected static final int MATCH_BLOCKEDLIST = 35; - protected static final int MATCH_BLOCKEDLIST_BY_PROVIDER = 36; - protected static final int MATCH_CONTACTS_ETAGS = 37; - protected static final int MATCH_CONTACTS_ETAG = 38; - protected static final int MATCH_PRESENCE = 40; - protected static final int MATCH_PRESENCE_ID = 41; - protected static final int MATCH_PRESENCE_BY_ACCOUNT = 42; - protected static final int MATCH_PRESENCE_SEED_BY_ACCOUNT = 43; - protected static final int MATCH_PRESENCE_BULK = 44; - protected static final int MATCH_MESSAGES = 50; - protected static final int MATCH_MESSAGES_BY_CONTACT = 51; - protected static final int MATCH_MESSAGE = 52; - protected static final int MATCH_GROUP_MESSAGES = 53; - protected static final int MATCH_GROUP_MESSAGE_BY = 54; - protected static final int MATCH_GROUP_MESSAGE = 55; - protected static final int MATCH_GROUP_MEMBERS = 58; - protected static final int MATCH_GROUP_MEMBERS_BY_GROUP = 59; - protected static final int MATCH_AVATARS = 60; - protected static final int MATCH_AVATAR = 61; - protected static final int MATCH_AVATAR_BY_PROVIDER = 62; - protected static final int MATCH_CHATS = 70; - protected static final int MATCH_CHATS_BY_ACCOUNT = 71; - protected static final int MATCH_CHATS_ID = 72; - protected static final int MATCH_SESSIONS = 80; - protected static final int MATCH_SESSIONS_BY_PROVIDER = 81; - protected static final int MATCH_PROVIDER_SETTINGS = 90; - protected static final int MATCH_PROVIDER_SETTINGS_BY_ID = 91; - protected static final int MATCH_PROVIDER_SETTINGS_BY_ID_AND_NAME = 92; - protected static final int MATCH_INVITATIONS = 100; - protected static final int MATCH_INVITATION = 101; - protected static final int MATCH_OUTGOING_RMQ_MESSAGES = 110; - protected static final int MATCH_OUTGOING_RMQ_MESSAGE = 111; - protected static final int MATCH_OUTGOING_HIGHEST_RMQ_ID = 112; - protected static final int MATCH_LAST_RMQ_ID = 113; - protected static final int MATCH_ACCOUNTS_STATUS = 114; - protected static final int MATCH_ACCOUNT_STATUS = 115; - protected static final int MATCH_BRANDING_RESOURCE_MAP_CACHE = 120; - - - protected final UriMatcher mUrlMatcher = new UriMatcher(UriMatcher.NO_MATCH); - private final String mTransientDbName; - - private static final HashMap<String, String> sProviderAccountsProjectionMap; - private static final HashMap<String, String> sContactsProjectionMap; - private static final HashMap<String, String> sContactListProjectionMap; - private static final HashMap<String, String> sBlockedListProjectionMap; - - private static final String PROVIDER_JOIN_ACCOUNT_TABLE = - "providers LEFT OUTER JOIN accounts ON " + - "(providers._id = accounts.provider AND accounts.active = 1) " + - "LEFT OUTER JOIN accountStatus ON (accounts._id = accountStatus.account)"; - - - private static final String CONTACT_JOIN_PRESENCE_TABLE = - "contacts LEFT OUTER JOIN presence ON (contacts._id = presence.contact_id)"; - - private static final String CONTACT_JOIN_PRESENCE_CHAT_TABLE = - CONTACT_JOIN_PRESENCE_TABLE + - " LEFT OUTER JOIN chats ON (contacts._id = chats.contact_id)"; - - private static final String CONTACT_JOIN_PRESENCE_CHAT_AVATAR_TABLE = - CONTACT_JOIN_PRESENCE_CHAT_TABLE + - " LEFT OUTER JOIN avatars ON (contacts.username = avatars.contact" + - " AND contacts.account = avatars.account_id)"; - - private static final String BLOCKEDLIST_JOIN_AVATAR_TABLE = - "blockedList LEFT OUTER JOIN avatars ON (blockedList.username = avatars.contact" + - " AND blockedList.account = avatars.account_id)"; - - /** - * The where clause for filtering out blocked contacts - */ - private static final String NON_BLOCKED_CONTACTS_WHERE_CLAUSE = "(" - + Im.Contacts.TYPE + " IS NULL OR " - + Im.Contacts.TYPE + "!=" - + String.valueOf(Im.Contacts.TYPE_BLOCKED) - + ")"; - - private static final String BLOCKED_CONTACTS_WHERE_CLAUSE = - "(contacts." + Im.Contacts.TYPE + "=" + Im.Contacts.TYPE_BLOCKED + ")"; - - private static final String CONTACT_ID = TABLE_CONTACTS + '.' + Im.Contacts._ID; - private static final String PRESENCE_CONTACT_ID = TABLE_PRESENCE + '.' + Im.Presence.CONTACT_ID; - - protected SQLiteOpenHelper mOpenHelper; - private final String mDatabaseName; - private final int mDatabaseVersion; - - private final String[] BACKFILL_PROJECTION = { - Im.Chats._ID, Im.Chats.SHORTCUT, Im.Chats.LAST_MESSAGE_DATE - }; - - private final String[] FIND_SHORTCUT_PROJECTION = { - Im.Chats._ID, Im.Chats.SHORTCUT - }; - - private class DatabaseHelper extends SQLiteOpenHelper { - - DatabaseHelper(Context context) { - super(context, mDatabaseName, null, mDatabaseVersion); - } - - @Override - public void onCreate(SQLiteDatabase db) { - - if (DBG) log("##### bootstrapDatabase"); - - db.execSQL("CREATE TABLE " + TABLE_PROVIDERS + " (" + - "_id INTEGER PRIMARY KEY," + - "name TEXT," + // eg AIM - "fullname TEXT," + // eg AOL Instance Messenger - "category TEXT," + // a category used for forming intent - "signup_url TEXT" + // web url to visit to create a new account - ");"); - - db.execSQL("CREATE TABLE " + TABLE_ACCOUNTS + " (" + - "_id INTEGER PRIMARY KEY," + - "name TEXT," + - "provider INTEGER," + - "username TEXT," + - "pw TEXT," + - "active INTEGER NOT NULL DEFAULT 0," + - "locked INTEGER NOT NULL DEFAULT 0," + - "keep_signed_in INTEGER NOT NULL DEFAULT 0," + - "last_login_state INTEGER NOT NULL DEFAULT 0," + - "UNIQUE (provider, username)" + - ");"); - - createContactsTables(db); - - db.execSQL("CREATE TABLE " + TABLE_AVATARS + " (" + - "_id INTEGER PRIMARY KEY," + - "contact TEXT," + - "provider_id INTEGER," + - "account_id INTEGER," + - "hash TEXT," + - "data BLOB," + // raw image data - "UNIQUE (account_id, contact)" + - ");"); - - db.execSQL("CREATE TABLE " + TABLE_PROVIDER_SETTINGS + " (" + - "_id INTEGER PRIMARY KEY," + - "provider INTEGER," + - "name TEXT," + - "value TEXT," + - "UNIQUE (provider, name)" + - ");"); - - db.execSQL("create TABLE " + TABLE_OUTGOING_RMQ_MESSAGES + " (" + - "_id INTEGER PRIMARY KEY," + - "rmq_id INTEGER," + - "type INTEGER," + - "ts INTEGER," + - "data TEXT" + - ");"); - - db.execSQL("create TABLE " + TABLE_LAST_RMQ_ID + " (" + - "_id INTEGER PRIMARY KEY," + - "rmq_id INTEGER" + - ");"); - - db.execSQL("create TABLE " + TABLE_BRANDING_RESOURCE_MAP_CACHE + " (" + - "_id INTEGER PRIMARY KEY," + - "provider_id INTEGER," + - "app_res_id INTEGER," + - "plugin_res_id INTEGER" + - ");"); - - // clean up account specific data when an account is deleted. - db.execSQL("CREATE TRIGGER account_cleanup " + - "DELETE ON " + TABLE_ACCOUNTS + - " BEGIN " + - "DELETE FROM " + TABLE_AVATARS + " WHERE account_id= OLD._id;" + - "END"); - - // add a database trigger to clean up associated provider settings - // while deleting a provider - db.execSQL("CREATE TRIGGER provider_cleanup " + - "DELETE ON " + TABLE_PROVIDERS + - " BEGIN " + - "DELETE FROM " + TABLE_PROVIDER_SETTINGS + " WHERE provider= OLD._id;" + - "END"); - } - - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - Log.d(LOG_TAG, "Upgrading database from version " + oldVersion + " to " + newVersion); - - switch (oldVersion) { - case 43: // this is the db version shipped in Dream 1.0 - // no-op: no schema changed from 43 to 44. The db version was changed to flush - // old provider settings, so new provider setting (including new name/value - // pairs) could be inserted by the plugins. - - // follow thru. - case 44: - if (newVersion <= 44) { - return; - } - - db.beginTransaction(); - try { - // add category column to the providers table - db.execSQL("ALTER TABLE " + TABLE_PROVIDERS + " ADD COLUMN category TEXT;"); - // add otr column to the contacts table - db.execSQL("ALTER TABLE " + TABLE_CONTACTS + " ADD COLUMN otr INTEGER;"); - - db.setTransactionSuccessful(); - } catch (Throwable ex) { - Log.e(LOG_TAG, ex.getMessage(), ex); - break; // force to destroy all old data; - } finally { - db.endTransaction(); - } - - case 45: - if (newVersion <= 45) { - return; - } - - db.beginTransaction(); - try { - // add an otr_etag column to contact etag table - db.execSQL( - "ALTER TABLE " + TABLE_CONTACTS_ETAG + " ADD COLUMN otr_etag TEXT;"); - db.setTransactionSuccessful(); - } catch (Throwable ex) { - Log.e(LOG_TAG, ex.getMessage(), ex); - break; // force to destroy all old data; - } finally { - db.endTransaction(); - } - - case 46: - if (newVersion <= 46) { - return; - } - - db.beginTransaction(); - try { - // add branding resource map cache table - db.execSQL("create TABLE " + TABLE_BRANDING_RESOURCE_MAP_CACHE + " (" + - "_id INTEGER PRIMARY KEY," + - "provider_id INTEGER," + - "app_res_id INTEGER," + - "plugin_res_id INTEGER" + - ");"); - db.setTransactionSuccessful(); - } catch (Throwable ex) { - Log.e(LOG_TAG, ex.getMessage(), ex); - break; // force to destroy all old data; - } finally { - db.endTransaction(); - } - - return; - } - - Log.w(LOG_TAG, "Couldn't upgrade db to " + newVersion + ". Destroying old data."); - destroyOldTables(db); - onCreate(db); - } - - private void destroyOldTables(SQLiteDatabase db) { - db.execSQL("DROP TABLE IF EXISTS " + TABLE_PROVIDERS); - db.execSQL("DROP TABLE IF EXISTS " + TABLE_ACCOUNTS); - db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACT_LIST); - db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS); - db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS_ETAG); - db.execSQL("DROP TABLE IF EXISTS " + TABLE_AVATARS); - db.execSQL("DROP TABLE IF EXISTS " + TABLE_PROVIDER_SETTINGS); - db.execSQL("DROP TABLE IF EXISTS " + TABLE_OUTGOING_RMQ_MESSAGES); - db.execSQL("DROP TABLE IF EXISTS " + TABLE_LAST_RMQ_ID); - db.execSQL("DROP TABLE IF EXISTS " + TABLE_BRANDING_RESOURCE_MAP_CACHE); - } - - private void createContactsTables(SQLiteDatabase db) { - StringBuilder buf = new StringBuilder(); - String contactsTableName = TABLE_CONTACTS; - - // creating the "contacts" table - buf.append("CREATE TABLE IF NOT EXISTS "); - buf.append(contactsTableName); - buf.append(" ("); - buf.append("_id INTEGER PRIMARY KEY,"); - buf.append("username TEXT,"); - buf.append("nickname TEXT,"); - buf.append("provider INTEGER,"); - buf.append("account INTEGER,"); - buf.append("contactList INTEGER,"); - buf.append("type INTEGER,"); - buf.append("subscriptionStatus INTEGER,"); - buf.append("subscriptionType INTEGER,"); - - // the following are derived from Google Contact Extension, we don't include all - // the attributes, just the ones we can use. - // (see http://code.google.com/apis/talk/jep_extensions/roster_attributes.html) - // - // qc: quick contact (derived from message count) - // rejected: if the contact has ever been rejected by the user - buf.append("qc INTEGER,"); - buf.append("rejected INTEGER,"); - - // Off the record status - buf.append("otr INTEGER"); - - buf.append(");"); - - db.execSQL(buf.toString()); - - buf.delete(0, buf.length()); - - // creating contact etag table - buf.append("CREATE TABLE IF NOT EXISTS "); - buf.append(TABLE_CONTACTS_ETAG); - buf.append(" ("); - buf.append("_id INTEGER PRIMARY KEY,"); - buf.append("etag TEXT,"); - buf.append("otr_etag TEXT,"); - buf.append("account INTEGER UNIQUE"); - buf.append(");"); - - db.execSQL(buf.toString()); - - buf.delete(0, buf.length()); - - // creating the "contactList" table - buf.append("CREATE TABLE IF NOT EXISTS "); - buf.append(TABLE_CONTACT_LIST); - buf.append(" ("); - buf.append("_id INTEGER PRIMARY KEY,"); - buf.append("name TEXT,"); - buf.append("provider INTEGER,"); - buf.append("account INTEGER"); - buf.append(");"); - - db.execSQL(buf.toString()); - - buf.delete(0, buf.length()); - - // creating the "blockedList" table - buf.append("CREATE TABLE IF NOT EXISTS "); - buf.append(TABLE_BLOCKED_LIST); - buf.append(" ("); - buf.append("_id INTEGER PRIMARY KEY,"); - buf.append("username TEXT,"); - buf.append("nickname TEXT,"); - buf.append("provider INTEGER,"); - buf.append("account INTEGER"); - buf.append(");"); - - db.execSQL(buf.toString()); - } - - @Override - public void onOpen(SQLiteDatabase db) { - if (db.isReadOnly()) { - Log.w(LOG_TAG, "ImProvider database opened in read only mode."); - Log.w(LOG_TAG, "Transient tables not created."); - return; - } - - if (DBG) log("##### createTransientTables"); - - // Create transient tables - String cpDbName; - db.execSQL("ATTACH DATABASE ':memory:' AS " + mTransientDbName + ";"); - cpDbName = mTransientDbName + "."; - - // message table (since the UI currently doesn't require saving message history - // across IM sessions, store the message table in memory db only) - db.execSQL("CREATE TABLE IF NOT EXISTS " + cpDbName + TABLE_MESSAGES + " (" + - "_id INTEGER PRIMARY KEY," + - "packet_id TEXT UNIQUE," + - "contact TEXT," + - "provider INTEGER," + - "account INTEGER," + - "body TEXT," + - "date INTEGER," + // in seconds - "type INTEGER," + - "err_code INTEGER NOT NULL DEFAULT 0," + - "err_msg TEXT" + - ");"); - - // presence - db.execSQL("CREATE TABLE IF NOT EXISTS " + cpDbName + TABLE_PRESENCE + " ("+ - "_id INTEGER PRIMARY KEY," + - "contact_id INTEGER UNIQUE," + - "jid_resource TEXT," + // jid resource for the presence - "client_type INTEGER," + // client type - "priority INTEGER," + // presence priority (XMPP) - "mode INTEGER," + // presence mode - "status TEXT" + // custom status - ");"); - - // group chat invitations - db.execSQL("CREATE TABLE IF NOT EXISTS " + cpDbName + TABLE_INVITATIONS + " (" + - "_id INTEGER PRIMARY KEY," + - "providerId INTEGER," + - "accountId INTEGER," + - "inviteId TEXT," + - "sender TEXT," + - "groupName TEXT," + - "note TEXT," + - "status INTEGER" + - ");"); - - // group chat members - db.execSQL("CREATE TABLE IF NOT EXISTS " + cpDbName + TABLE_GROUP_MEMBERS + " (" + - "_id INTEGER PRIMARY KEY," + - "groupId INTEGER," + - "username TEXT," + - "nickname TEXT" + - ");"); - - // group chat messages - db.execSQL("CREATE TABLE IF NOT EXISTS " + cpDbName + TABLE_GROUP_MESSAGES + " (" + - "_id INTEGER PRIMARY KEY," + - "packet_id TEXT UNIQUE," + - "contact TEXT," + - "groupId INTEGER," + - "body TEXT," + - "date INTEGER," + - "type INTEGER," + - "err_code INTEGER NOT NULL DEFAULT 0," + - "err_msg TEXT" + - ");"); - - // chat sessions, including single person chats and group chats - db.execSQL("CREATE TABLE IF NOT EXISTS " + cpDbName + TABLE_CHATS + " ("+ - "_id INTEGER PRIMARY KEY," + - "contact_id INTEGER UNIQUE," + - "jid_resource TEXT," + // the JID resource for the user, only for non-group chats - "groupchat INTEGER," + // 1 if group chat, 0 if not TODO: remove this column - "last_unread_message TEXT," + // the last unread message - "last_message_date INTEGER," + // in seconds - "unsent_composed_message TEXT," + // a composed, but not sent message - "shortcut INTEGER" + // which of 10 slots (if any) this chat occupies - ");"); - - db.execSQL("CREATE TABLE IF NOT EXISTS " + cpDbName + TABLE_ACCOUNT_STATUS + " (" + - "_id INTEGER PRIMARY KEY," + - "account INTEGER UNIQUE," + - "presenceStatus INTEGER," + - "connStatus INTEGER" + - ");" - ); - - /* when we moved the contact table out of transient_db and into the main db, the - contact_cleanup and group_cleanup triggers don't work anymore. It seems we can't - create triggers that reference objects in a different database! - - String contactsTableName = TABLE_CONTACTS; - - if (USE_CONTACT_PRESENCE_TRIGGER) { - // Insert a default presence for newly inserted contact - db.execSQL("CREATE TRIGGER IF NOT EXISTS " + cpDbName + "contact_create_presence " + - "INSERT ON " + cpDbName + contactsTableName + - " FOR EACH ROW WHEN NEW.type != " + Im.Contacts.TYPE_GROUP + - " OR NEW.type != " + Im.Contacts.TYPE_BLOCKED + - " BEGIN " + - "INSERT INTO presence (contact_id) VALUES (NEW._id);" + - " END"); - } - - db.execSQL("CREATE TRIGGER IF NOT EXISTS " + cpDbName + "contact_cleanup " + - "DELETE ON " + cpDbName + contactsTableName + - " BEGIN " + - "DELETE FROM presence WHERE contact_id = OLD._id;" + - "DELETE FROM chats WHERE contact_id = OLD._id;" + - "END"); - - // Cleans up group members and group messages when a group chat is deleted - db.execSQL("CREATE TRIGGER IF NOT EXISTS " + cpDbName + "group_cleanup " + - "DELETE ON " + cpDbName + contactsTableName + - " FOR EACH ROW WHEN OLD.type = " + Im.Contacts.TYPE_GROUP + - " BEGIN " + - "DELETE FROM groupMembers WHERE groupId = OLD._id;" + - "DELETE FROM groupMessages WHERE groupId = OLD._id;" + - " END"); - */ - - // only store the session cookies in memory right now. This means - // that we don't persist them across device reboot - db.execSQL("CREATE TABLE IF NOT EXISTS " + cpDbName + TABLE_SESSION_COOKIES + " ("+ - "_id INTEGER PRIMARY KEY," + - "provider INTEGER," + - "account INTEGER," + - "name TEXT," + - "value TEXT" + - ");"); - - } - } - - static { - sProviderAccountsProjectionMap = new HashMap<String, String>(); - sProviderAccountsProjectionMap.put(Im.Provider._ID, - "providers._id AS _id"); - sProviderAccountsProjectionMap.put(Im.Provider._COUNT, - "COUNT(*) AS _account"); - sProviderAccountsProjectionMap.put(Im.Provider.NAME, - "providers.name AS name"); - sProviderAccountsProjectionMap.put(Im.Provider.FULLNAME, - "providers.fullname AS fullname"); - sProviderAccountsProjectionMap.put(Im.Provider.CATEGORY, - "providers.category AS category"); - sProviderAccountsProjectionMap.put(Im.Provider.ACTIVE_ACCOUNT_ID, - "accounts._id AS account_id"); - sProviderAccountsProjectionMap.put(Im.Provider.ACTIVE_ACCOUNT_USERNAME, - "accounts.username AS account_username"); - sProviderAccountsProjectionMap.put(Im.Provider.ACTIVE_ACCOUNT_PW, - "accounts.pw AS account_pw"); - sProviderAccountsProjectionMap.put(Im.Provider.ACTIVE_ACCOUNT_LOCKED, - "accounts.locked AS account_locked"); - sProviderAccountsProjectionMap.put(Im.Provider.ACCOUNT_PRESENCE_STATUS, - "accountStatus.presenceStatus AS account_presenceStatus"); - sProviderAccountsProjectionMap.put(Im.Provider.ACCOUNT_CONNECTION_STATUS, - "accountStatus.connStatus AS account_connStatus"); - - // contacts projection map - sContactsProjectionMap = new HashMap<String, String>(); - - // Base column - sContactsProjectionMap.put(Im.Contacts._ID, "contacts._id AS _id"); - sContactsProjectionMap.put(Im.Contacts._COUNT, "COUNT(*) AS _count"); - - // contacts column - sContactsProjectionMap.put(Im.Contacts._ID, "contacts._id as _id"); - sContactsProjectionMap.put(Im.Contacts.USERNAME, "contacts.username as username"); - sContactsProjectionMap.put(Im.Contacts.NICKNAME, "contacts.nickname as nickname"); - sContactsProjectionMap.put(Im.Contacts.PROVIDER, "contacts.provider as provider"); - sContactsProjectionMap.put(Im.Contacts.ACCOUNT, "contacts.account as account"); - sContactsProjectionMap.put(Im.Contacts.CONTACTLIST, "contacts.contactList as contactList"); - sContactsProjectionMap.put(Im.Contacts.TYPE, "contacts.type as type"); - sContactsProjectionMap.put(Im.Contacts.SUBSCRIPTION_STATUS, - "contacts.subscriptionStatus as subscriptionStatus"); - sContactsProjectionMap.put(Im.Contacts.SUBSCRIPTION_TYPE, - "contacts.subscriptionType as subscriptionType"); - sContactsProjectionMap.put(Im.Contacts.QUICK_CONTACT, "contacts.qc as qc"); - sContactsProjectionMap.put(Im.Contacts.REJECTED, "contacts.rejected as rejected"); - - // Presence columns - sContactsProjectionMap.put(Im.Presence.CONTACT_ID, - "presence.contact_id AS contact_id"); - sContactsProjectionMap.put(Im.Contacts.PRESENCE_STATUS, - "presence.mode AS mode"); - sContactsProjectionMap.put(Im.Contacts.PRESENCE_CUSTOM_STATUS, - "presence.status AS status"); - sContactsProjectionMap.put(Im.Contacts.CLIENT_TYPE, - "presence.client_type AS client_type"); - - // Chats columns - sContactsProjectionMap.put(Im.Contacts.CHATS_CONTACT, - "chats.contact_id AS chats_contact_id"); - sContactsProjectionMap.put(Im.Chats.JID_RESOURCE, - "chats.jid_resource AS jid_resource"); - sContactsProjectionMap.put(Im.Chats.GROUP_CHAT, - "chats.groupchat AS groupchat"); - sContactsProjectionMap.put(Im.Contacts.LAST_UNREAD_MESSAGE, - "chats.last_unread_message AS last_unread_message"); - sContactsProjectionMap.put(Im.Contacts.LAST_MESSAGE_DATE, - "chats.last_message_date AS last_message_date"); - sContactsProjectionMap.put(Im.Contacts.UNSENT_COMPOSED_MESSAGE, - "chats.unsent_composed_message AS unsent_composed_message"); - sContactsProjectionMap.put(Im.Contacts.SHORTCUT, "chats.SHORTCUT AS shortcut"); - - // Avatars columns - sContactsProjectionMap.put(Im.Contacts.AVATAR_HASH, "avatars.hash AS avatars_hash"); - sContactsProjectionMap.put(Im.Contacts.AVATAR_DATA, "avatars.data AS avatars_data"); - - // contactList projection map - sContactListProjectionMap = new HashMap<String, String>(); - sContactListProjectionMap.put(Im.ContactList._ID, - "contactList._id AS _id"); - sContactListProjectionMap.put(Im.ContactList._COUNT, - "COUNT(*) AS _count"); - sContactListProjectionMap.put(Im.ContactList.NAME, "name"); - sContactListProjectionMap.put(Im.ContactList.PROVIDER, "provider"); - sContactListProjectionMap.put(Im.ContactList.ACCOUNT, "account"); - - // blockedList projection map - sBlockedListProjectionMap = new HashMap<String, String>(); - sBlockedListProjectionMap.put(Im.BlockedList._ID, - "blockedList._id AS _id"); - sBlockedListProjectionMap.put(Im.BlockedList._COUNT, - "COUNT(*) AS _count"); - sBlockedListProjectionMap.put(Im.BlockedList.USERNAME, "username"); - sBlockedListProjectionMap.put(Im.BlockedList.NICKNAME, "nickname"); - sBlockedListProjectionMap.put(Im.BlockedList.PROVIDER, "provider"); - sBlockedListProjectionMap.put(Im.BlockedList.ACCOUNT, "account"); - sBlockedListProjectionMap.put(Im.BlockedList.AVATAR_DATA, - "avatars.data AS avatars_data"); - } - - public ImProvider() { - this(AUTHORITY, DATABASE_NAME, DATABASE_VERSION); - } - - protected ImProvider(String authority, String dbName, int dbVersion) { - mDatabaseName = dbName; - mDatabaseVersion = dbVersion; - - mTransientDbName = "transient_" + dbName.replace(".", "_"); - - mUrlMatcher.addURI(authority, "providers", MATCH_PROVIDERS); - mUrlMatcher.addURI(authority, "providers/#", MATCH_PROVIDERS_BY_ID); - mUrlMatcher.addURI(authority, "providers/account", MATCH_PROVIDERS_WITH_ACCOUNT); - - mUrlMatcher.addURI(authority, "accounts", MATCH_ACCOUNTS); - mUrlMatcher.addURI(authority, "accounts/#", MATCH_ACCOUNTS_BY_ID); - - mUrlMatcher.addURI(authority, "contacts", MATCH_CONTACTS); - mUrlMatcher.addURI(authority, "contactsWithPresence", MATCH_CONTACTS_JOIN_PRESENCE); - mUrlMatcher.addURI(authority, "contactsBarebone", MATCH_CONTACTS_BAREBONE); - mUrlMatcher.addURI(authority, "contacts/#/#", MATCH_CONTACTS_BY_PROVIDER); - mUrlMatcher.addURI(authority, "contacts/chatting", MATCH_CHATTING_CONTACTS); - mUrlMatcher.addURI(authority, "contacts/chatting/#/#", MATCH_CHATTING_CONTACTS_BY_PROVIDER); - mUrlMatcher.addURI(authority, "contacts/online/#/#", MATCH_ONLINE_CONTACTS_BY_PROVIDER); - mUrlMatcher.addURI(authority, "contacts/offline/#/#", MATCH_OFFLINE_CONTACTS_BY_PROVIDER); - mUrlMatcher.addURI(authority, "contacts/#", MATCH_CONTACT); - mUrlMatcher.addURI(authority, "contacts/blocked", MATCH_BLOCKED_CONTACTS); - mUrlMatcher.addURI(authority, "bulk_contacts", MATCH_CONTACTS_BULK); - mUrlMatcher.addURI(authority, "contacts/onlineCount", MATCH_ONLINE_CONTACT_COUNT); - - mUrlMatcher.addURI(authority, "contactLists", MATCH_CONTACTLISTS); - mUrlMatcher.addURI(authority, "contactLists/#/#", MATCH_CONTACTLISTS_BY_PROVIDER); - mUrlMatcher.addURI(authority, "contactLists/#", MATCH_CONTACTLIST); - mUrlMatcher.addURI(authority, "blockedList", MATCH_BLOCKEDLIST); - mUrlMatcher.addURI(authority, "blockedList/#/#", MATCH_BLOCKEDLIST_BY_PROVIDER); - - mUrlMatcher.addURI(authority, "contactsEtag", MATCH_CONTACTS_ETAGS); - mUrlMatcher.addURI(authority, "contactsEtag/#", MATCH_CONTACTS_ETAG); - - mUrlMatcher.addURI(authority, "presence", MATCH_PRESENCE); - mUrlMatcher.addURI(authority, "presence/#", MATCH_PRESENCE_ID); - mUrlMatcher.addURI(authority, "presence/account/#", MATCH_PRESENCE_BY_ACCOUNT); - mUrlMatcher.addURI(authority, "seed_presence/account/#", MATCH_PRESENCE_SEED_BY_ACCOUNT); - mUrlMatcher.addURI(authority, "bulk_presence", MATCH_PRESENCE_BULK); - - mUrlMatcher.addURI(authority, "messages", MATCH_MESSAGES); - mUrlMatcher.addURI(authority, "messagesBy/#/#/*", MATCH_MESSAGES_BY_CONTACT); - mUrlMatcher.addURI(authority, "messages/#", MATCH_MESSAGE); - - mUrlMatcher.addURI(authority, "groupMessages", MATCH_GROUP_MESSAGES); - mUrlMatcher.addURI(authority, "groupMessagesBy/#", MATCH_GROUP_MESSAGE_BY); - mUrlMatcher.addURI(authority, "groupMessages/#", MATCH_GROUP_MESSAGE); - mUrlMatcher.addURI(authority, "groupMembers", MATCH_GROUP_MEMBERS); - mUrlMatcher.addURI(authority, "groupMembers/#", MATCH_GROUP_MEMBERS_BY_GROUP); - - mUrlMatcher.addURI(authority, "avatars", MATCH_AVATARS); - mUrlMatcher.addURI(authority, "avatars/#", MATCH_AVATAR); - mUrlMatcher.addURI(authority, "avatarsBy/#/#", MATCH_AVATAR_BY_PROVIDER); - mUrlMatcher.addURI(authority, "chats", MATCH_CHATS); - mUrlMatcher.addURI(authority, "chats/account/#", MATCH_CHATS_BY_ACCOUNT); - mUrlMatcher.addURI(authority, "chats/#", MATCH_CHATS_ID); - - mUrlMatcher.addURI(authority, "sessionCookies", MATCH_SESSIONS); - mUrlMatcher.addURI(authority, "sessionCookiesBy/#/#", MATCH_SESSIONS_BY_PROVIDER); - mUrlMatcher.addURI(authority, "providerSettings", MATCH_PROVIDER_SETTINGS); - mUrlMatcher.addURI(authority, "providerSettings/#", MATCH_PROVIDER_SETTINGS_BY_ID); - mUrlMatcher.addURI(authority, "providerSettings/#/*", - MATCH_PROVIDER_SETTINGS_BY_ID_AND_NAME); - - mUrlMatcher.addURI(authority, "invitations", MATCH_INVITATIONS); - mUrlMatcher.addURI(authority, "invitations/#", MATCH_INVITATION); - - mUrlMatcher.addURI(authority, "outgoingRmqMessages", MATCH_OUTGOING_RMQ_MESSAGES); - mUrlMatcher.addURI(authority, "outgoingRmqMessages/#", MATCH_OUTGOING_RMQ_MESSAGE); - mUrlMatcher.addURI(authority, "outgoingHighestRmqId", MATCH_OUTGOING_HIGHEST_RMQ_ID); - mUrlMatcher.addURI(authority, "lastRmqId", MATCH_LAST_RMQ_ID); - - mUrlMatcher.addURI(authority, "accountStatus", MATCH_ACCOUNTS_STATUS); - mUrlMatcher.addURI(authority, "accountStatus/#", MATCH_ACCOUNT_STATUS); - - mUrlMatcher.addURI(authority, "brandingResMapCache", MATCH_BRANDING_RESOURCE_MAP_CACHE); - } - - @Override - public boolean onCreate() { - mOpenHelper = new DatabaseHelper(getContext()); - return true; - } - - @Override - public final int update(final Uri url, final ContentValues values, - final String selection, final String[] selectionArgs) { - - int result = 0; - SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - db.beginTransaction(); - try { - result = updateInternal(url, values, selection, selectionArgs); - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - if (result > 0) { - getContext().getContentResolver() - .notifyChange(url, null /* observer */, false /* sync */); - } - return result; - } - - @Override - public final int delete(final Uri url, final String selection, - final String[] selectionArgs) { - int result; - SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - db.beginTransaction(); - try { - result = deleteInternal(url, selection, selectionArgs); - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - if (result > 0) { - getContext().getContentResolver() - .notifyChange(url, null /* observer */, false /* sync */); - } - return result; - } - - @Override - public final Uri insert(final Uri url, final ContentValues values) { - Uri result; - SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - db.beginTransaction(); - try { - result = insertInternal(url, values); - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - if (result != null) { - getContext().getContentResolver() - .notifyChange(url, null /* observer */, false /* sync */); - } - return result; - } - - @Override - public final Cursor query(final Uri url, final String[] projection, - final String selection, final String[] selectionArgs, - final String sortOrder) { - return queryInternal(url, projection, selection, selectionArgs, sortOrder); - } - - public Cursor queryInternal(Uri url, String[] projectionIn, - String selection, String[] selectionArgs, String sort) { - SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); - StringBuilder whereClause = new StringBuilder(); - if(selection != null) { - whereClause.append(selection); - } - String groupBy = null; - String limit = null; - - // Generate the body of the query - int match = mUrlMatcher.match(url); - - if (DBG) { - log("query " + url + ", match " + match + ", where " + selection); - if (selectionArgs != null) { - for (String selectionArg : selectionArgs) { - log(" selectionArg: " + selectionArg); - } - } - } - - switch (match) { - case MATCH_PROVIDERS_BY_ID: - appendWhere(whereClause, Im.Provider._ID, "=", url.getPathSegments().get(1)); - // fall thru. - - case MATCH_PROVIDERS: - qb.setTables(TABLE_PROVIDERS); - break; - - case MATCH_PROVIDERS_WITH_ACCOUNT: - qb.setTables(PROVIDER_JOIN_ACCOUNT_TABLE); - qb.setProjectionMap(sProviderAccountsProjectionMap); - break; - - case MATCH_ACCOUNTS_BY_ID: - appendWhere(whereClause, Im.Account._ID, "=", url.getPathSegments().get(1)); - // falls down - case MATCH_ACCOUNTS: - qb.setTables(TABLE_ACCOUNTS); - break; - - case MATCH_CONTACTS: - qb.setTables(CONTACT_JOIN_PRESENCE_CHAT_AVATAR_TABLE); - qb.setProjectionMap(sContactsProjectionMap); - break; - - case MATCH_CONTACTS_JOIN_PRESENCE: - qb.setTables(CONTACT_JOIN_PRESENCE_TABLE); - qb.setProjectionMap(sContactsProjectionMap); - break; - - case MATCH_CONTACTS_BAREBONE: - qb.setTables(TABLE_CONTACTS); - break; - - case MATCH_CHATTING_CONTACTS: - qb.setTables(CONTACT_JOIN_PRESENCE_CHAT_AVATAR_TABLE); - qb.setProjectionMap(sContactsProjectionMap); - appendWhere(whereClause, "chats.last_message_date IS NOT NULL"); - // no need to add the non blocked contacts clause because - // blocked contacts can't have conversations. - break; - - case MATCH_CONTACTS_BY_PROVIDER: - buildQueryContactsByProvider(qb, whereClause, url); - appendWhere(whereClause, NON_BLOCKED_CONTACTS_WHERE_CLAUSE); - break; - - case MATCH_CHATTING_CONTACTS_BY_PROVIDER: - buildQueryContactsByProvider(qb, whereClause, url); - appendWhere(whereClause, "chats.last_message_date IS NOT NULL"); - // no need to add the non blocked contacts clause because - // blocked contacts can't have conversations. - break; - - case MATCH_NO_CHATTING_CONTACTS_BY_PROVIDER: - buildQueryContactsByProvider(qb, whereClause, url); - appendWhere(whereClause, "chats.last_message_date IS NULL"); - appendWhere(whereClause, NON_BLOCKED_CONTACTS_WHERE_CLAUSE); - break; - - case MATCH_ONLINE_CONTACTS_BY_PROVIDER: - buildQueryContactsByProvider(qb, whereClause, url); - appendWhere(whereClause, Im.Contacts.PRESENCE_STATUS, "!=", Im.Presence.OFFLINE); - appendWhere(whereClause, NON_BLOCKED_CONTACTS_WHERE_CLAUSE); - break; - - case MATCH_OFFLINE_CONTACTS_BY_PROVIDER: - buildQueryContactsByProvider(qb, whereClause, url); - appendWhere(whereClause, Im.Contacts.PRESENCE_STATUS, "=", Im.Presence.OFFLINE); - appendWhere(whereClause, NON_BLOCKED_CONTACTS_WHERE_CLAUSE); - break; - - case MATCH_BLOCKED_CONTACTS: - qb.setTables(CONTACT_JOIN_PRESENCE_CHAT_AVATAR_TABLE); - qb.setProjectionMap(sContactsProjectionMap); - appendWhere(whereClause, BLOCKED_CONTACTS_WHERE_CLAUSE); - break; - - case MATCH_CONTACT: - qb.setTables(CONTACT_JOIN_PRESENCE_CHAT_AVATAR_TABLE); - qb.setProjectionMap(sContactsProjectionMap); - appendWhere(whereClause, "contacts._id", "=", url.getPathSegments().get(1)); - break; - - case MATCH_ONLINE_CONTACT_COUNT: - qb.setTables(CONTACT_JOIN_PRESENCE_CHAT_TABLE); - qb.setProjectionMap(sContactsProjectionMap); - appendWhere(whereClause, Im.Contacts.PRESENCE_STATUS, "!=", Im.Presence.OFFLINE); - appendWhere(whereClause, "chats.last_message_date IS NULL"); - appendWhere(whereClause, NON_BLOCKED_CONTACTS_WHERE_CLAUSE); - groupBy = Im.Contacts.CONTACTLIST; - break; - - case MATCH_CONTACTLISTS_BY_PROVIDER: - appendWhere(whereClause, Im.ContactList.ACCOUNT, "=", - url.getPathSegments().get(2)); - // fall through - case MATCH_CONTACTLISTS: - qb.setTables(TABLE_CONTACT_LIST); - qb.setProjectionMap(sContactListProjectionMap); - break; - - case MATCH_CONTACTLIST: - qb.setTables(TABLE_CONTACT_LIST); - appendWhere(whereClause, Im.ContactList._ID, "=", url.getPathSegments().get(1)); - break; - - case MATCH_BLOCKEDLIST: - qb.setTables(BLOCKEDLIST_JOIN_AVATAR_TABLE); - qb.setProjectionMap(sBlockedListProjectionMap); - break; - - case MATCH_BLOCKEDLIST_BY_PROVIDER: - qb.setTables(BLOCKEDLIST_JOIN_AVATAR_TABLE); - qb.setProjectionMap(sBlockedListProjectionMap); - appendWhere(whereClause, Im.BlockedList.ACCOUNT, "=", - url.getPathSegments().get(2)); - break; - - case MATCH_CONTACTS_ETAGS: - qb.setTables(TABLE_CONTACTS_ETAG); - break; - - case MATCH_CONTACTS_ETAG: - qb.setTables(TABLE_CONTACTS_ETAG); - appendWhere(whereClause, "_id", "=", url.getPathSegments().get(1)); - break; - - case MATCH_MESSAGES: - qb.setTables(TABLE_MESSAGES); - break; - - case MATCH_MESSAGES_BY_CONTACT: - // we don't really need the provider id in query. account id - // is enough. - qb.setTables(TABLE_MESSAGES); - appendWhere(whereClause, Im.Messages.ACCOUNT, "=", - url.getPathSegments().get(2)); - appendWhere(whereClause, Im.Messages.CONTACT, "=", - decodeURLSegment(url.getPathSegments().get(3))); - break; - - case MATCH_MESSAGE: - qb.setTables(TABLE_MESSAGES); - appendWhere(whereClause, Im.Messages._ID, "=", url.getPathSegments().get(1)); - break; - - case MATCH_INVITATIONS: - qb.setTables(TABLE_INVITATIONS); - break; - - case MATCH_INVITATION: - qb.setTables(TABLE_INVITATIONS); - appendWhere(whereClause, Im.Invitation._ID, "=", url.getPathSegments().get(1)); - break; - - case MATCH_GROUP_MEMBERS: - qb.setTables(TABLE_GROUP_MEMBERS); - break; - - case MATCH_GROUP_MEMBERS_BY_GROUP: - qb.setTables(TABLE_GROUP_MEMBERS); - appendWhere(whereClause, Im.GroupMembers.GROUP, "=", url.getPathSegments().get(1)); - break; - - case MATCH_GROUP_MESSAGES: - qb.setTables(TABLE_GROUP_MESSAGES); - break; - - case MATCH_GROUP_MESSAGE_BY: - qb.setTables(TABLE_GROUP_MESSAGES); - appendWhere(whereClause, Im.GroupMessages.GROUP, "=", - url.getPathSegments().get(1)); - break; - - case MATCH_GROUP_MESSAGE: - qb.setTables(TABLE_GROUP_MESSAGES); - appendWhere(whereClause, Im.GroupMessages._ID, "=", - url.getPathSegments().get(1)); - break; - - case MATCH_AVATARS: - qb.setTables(TABLE_AVATARS); - break; - - case MATCH_AVATAR_BY_PROVIDER: - qb.setTables(TABLE_AVATARS); - appendWhere(whereClause, Im.Avatars.ACCOUNT, "=", url.getPathSegments().get(2)); - break; - - case MATCH_CHATS: - qb.setTables(TABLE_CHATS); - break; - - case MATCH_CHATS_ID: - qb.setTables(TABLE_CHATS); - appendWhere(whereClause, Im.Chats.CONTACT_ID, "=", url.getPathSegments().get(1)); - break; - - case MATCH_PRESENCE: - qb.setTables(TABLE_PRESENCE); - break; - - case MATCH_PRESENCE_ID: - qb.setTables(TABLE_PRESENCE); - appendWhere(whereClause, Im.Presence.CONTACT_ID, "=", url.getPathSegments().get(1)); - break; - - case MATCH_SESSIONS: - qb.setTables(TABLE_SESSION_COOKIES); - break; - - case MATCH_SESSIONS_BY_PROVIDER: - qb.setTables(TABLE_SESSION_COOKIES); - appendWhere(whereClause, Im.SessionCookies.ACCOUNT, "=", url.getPathSegments().get(2)); - break; - - case MATCH_PROVIDER_SETTINGS_BY_ID_AND_NAME: - appendWhere(whereClause, Im.ProviderSettings.NAME, "=", url.getPathSegments().get(2)); - // fall through - case MATCH_PROVIDER_SETTINGS_BY_ID: - appendWhere(whereClause, Im.ProviderSettings.PROVIDER, "=", url.getPathSegments().get(1)); - // fall through - case MATCH_PROVIDER_SETTINGS: - qb.setTables(TABLE_PROVIDER_SETTINGS); - break; - - case MATCH_OUTGOING_RMQ_MESSAGES: - qb.setTables(TABLE_OUTGOING_RMQ_MESSAGES); - break; - - case MATCH_OUTGOING_HIGHEST_RMQ_ID: - qb.setTables(TABLE_OUTGOING_RMQ_MESSAGES); - sort = "rmq_id DESC"; - limit = "1"; - break; - - case MATCH_LAST_RMQ_ID: - qb.setTables(TABLE_LAST_RMQ_ID); - limit = "1"; - break; - - case MATCH_ACCOUNTS_STATUS: - qb.setTables(TABLE_ACCOUNT_STATUS); - break; - - case MATCH_ACCOUNT_STATUS: - qb.setTables(TABLE_ACCOUNT_STATUS); - appendWhere(whereClause, Im.AccountStatus.ACCOUNT, "=", - url.getPathSegments().get(1)); - break; - - case MATCH_BRANDING_RESOURCE_MAP_CACHE: - qb.setTables(TABLE_BRANDING_RESOURCE_MAP_CACHE); - break; - - default: - throw new IllegalArgumentException("Unknown URL " + url); - } - - // run the query - final SQLiteDatabase db = mOpenHelper.getReadableDatabase(); - Cursor c = null; - - try { - c = qb.query(db, projectionIn, whereClause.toString(), selectionArgs, - groupBy, null, sort, limit); - if (c != null) { - switch(match) { - case MATCH_CHATTING_CONTACTS: - case MATCH_CONTACTS_BY_PROVIDER: - case MATCH_CHATTING_CONTACTS_BY_PROVIDER: - case MATCH_ONLINE_CONTACTS_BY_PROVIDER: - case MATCH_OFFLINE_CONTACTS_BY_PROVIDER: - case MATCH_CONTACTS_BAREBONE: - case MATCH_CONTACTS_JOIN_PRESENCE: - case MATCH_ONLINE_CONTACT_COUNT: - url = Im.Contacts.CONTENT_URI; - break; - } - if (DBG) log("set notify url " + url); - c.setNotificationUri(getContext().getContentResolver(), url); - } - } catch (Exception ex) { - Log.e(LOG_TAG, "query db caught ", ex); - } - - return c; - } - - private void buildQueryContactsByProvider(SQLiteQueryBuilder qb, - StringBuilder whereClause, Uri url) { - qb.setTables(CONTACT_JOIN_PRESENCE_CHAT_AVATAR_TABLE); - qb.setProjectionMap(sContactsProjectionMap); - // we don't really need the provider id in query. account id - // is enough. - appendWhere(whereClause, Im.Contacts.ACCOUNT, "=", url.getLastPathSegment()); - } - - @Override - public String getType(Uri url) { - int match = mUrlMatcher.match(url); - switch (match) { - case MATCH_PROVIDERS: - return Im.Provider.CONTENT_TYPE; - - case MATCH_PROVIDERS_BY_ID: - return Im.Provider.CONTENT_ITEM_TYPE; - - case MATCH_ACCOUNTS: - return Im.Account.CONTENT_TYPE; - - case MATCH_ACCOUNTS_BY_ID: - return Im.Account.CONTENT_ITEM_TYPE; - - case MATCH_CONTACTS: - case MATCH_CONTACTS_BY_PROVIDER: - case MATCH_ONLINE_CONTACTS_BY_PROVIDER: - case MATCH_OFFLINE_CONTACTS_BY_PROVIDER: - case MATCH_CONTACTS_BULK: - case MATCH_CONTACTS_BAREBONE: - case MATCH_CONTACTS_JOIN_PRESENCE: - return Im.Contacts.CONTENT_TYPE; - - case MATCH_CONTACT: - return Im.Contacts.CONTENT_ITEM_TYPE; - - case MATCH_CONTACTLISTS: - case MATCH_CONTACTLISTS_BY_PROVIDER: - return Im.ContactList.CONTENT_TYPE; - - case MATCH_CONTACTLIST: - return Im.ContactList.CONTENT_ITEM_TYPE; - - case MATCH_BLOCKEDLIST: - case MATCH_BLOCKEDLIST_BY_PROVIDER: - return Im.BlockedList.CONTENT_TYPE; - - case MATCH_CONTACTS_ETAGS: - case MATCH_CONTACTS_ETAG: - return Im.ContactsEtag.CONTENT_TYPE; - - case MATCH_MESSAGES: - case MATCH_MESSAGES_BY_CONTACT: - return Im.Messages.CONTENT_TYPE; - - case MATCH_MESSAGE: - return Im.Messages.CONTENT_ITEM_TYPE; - - case MATCH_GROUP_MESSAGES: - case MATCH_GROUP_MESSAGE_BY: - return Im.GroupMessages.CONTENT_TYPE; - - case MATCH_GROUP_MESSAGE: - return Im.GroupMessages.CONTENT_ITEM_TYPE; - - case MATCH_PRESENCE: - case MATCH_PRESENCE_BULK: - return Im.Presence.CONTENT_TYPE; - - case MATCH_AVATARS: - return Im.Avatars.CONTENT_TYPE; - - case MATCH_AVATAR: - return Im.Avatars.CONTENT_ITEM_TYPE; - - case MATCH_CHATS: - return Im.Chats.CONTENT_TYPE; - - case MATCH_CHATS_ID: - return Im.Chats.CONTENT_ITEM_TYPE; - - case MATCH_INVITATIONS: - return Im.Invitation.CONTENT_TYPE; - - case MATCH_INVITATION: - return Im.Invitation.CONTENT_ITEM_TYPE; - - case MATCH_GROUP_MEMBERS: - case MATCH_GROUP_MEMBERS_BY_GROUP: - return Im.GroupMembers.CONTENT_TYPE; - - case MATCH_SESSIONS: - case MATCH_SESSIONS_BY_PROVIDER: - return Im.SessionCookies.CONTENT_TYPE; - - case MATCH_PROVIDER_SETTINGS: - return Im.ProviderSettings.CONTENT_TYPE; - - case MATCH_ACCOUNTS_STATUS: - return Im.AccountStatus.CONTENT_TYPE; - - case MATCH_ACCOUNT_STATUS: - return Im.AccountStatus.CONTENT_ITEM_TYPE; - - default: - throw new IllegalArgumentException("Unknown URL"); - } - } - - // package scope for testing. - boolean insertBulkContacts(ContentValues values) { - //if (DBG) log("insertBulkContacts: begin"); - - ArrayList<String> usernames = values.getStringArrayList(Im.Contacts.USERNAME); - ArrayList<String> nicknames = values.getStringArrayList(Im.Contacts.NICKNAME); - int usernameCount = usernames.size(); - int nicknameCount = nicknames.size(); - - if (usernameCount != nicknameCount) { - Log.e(LOG_TAG, "[ImProvider] insertBulkContacts: input bundle " + - "username & nickname lists have diff. length!"); - return false; - } - - ArrayList<String> contactTypeArray = values.getStringArrayList(Im.Contacts.TYPE); - ArrayList<String> subscriptionStatusArray = - values.getStringArrayList(Im.Contacts.SUBSCRIPTION_STATUS); - ArrayList<String> subscriptionTypeArray = - values.getStringArrayList(Im.Contacts.SUBSCRIPTION_TYPE); - ArrayList<String> quickContactArray = values.getStringArrayList(Im.Contacts.QUICK_CONTACT); - ArrayList<String> rejectedArray = values.getStringArrayList(Im.Contacts.REJECTED); - int sum = 0; - - final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - - db.beginTransaction(); - try { - Long provider = values.getAsLong(Im.Contacts.PROVIDER); - Long account = values.getAsLong(Im.Contacts.ACCOUNT); - Long listId = values.getAsLong(Im.Contacts.CONTACTLIST); - - ContentValues contactValues = new ContentValues(); - contactValues.put(Im.Contacts.PROVIDER, provider); - contactValues.put(Im.Contacts.ACCOUNT, account); - contactValues.put(Im.Contacts.CONTACTLIST, listId); - ContentValues presenceValues = new ContentValues(); - presenceValues.put(Im.Presence.PRESENCE_STATUS, - Im.Presence.OFFLINE); - - for (int i=0; i<usernameCount; i++) { - String username = usernames.get(i); - String nickname = nicknames.get(i); - int type = 0; - int subscriptionStatus = 0; - int subscriptionType = 0; - int quickContact = 0; - int rejected = 0; - - try { - type = Integer.parseInt(contactTypeArray.get(i)); - if (subscriptionStatusArray != null) { - subscriptionStatus = Integer.parseInt(subscriptionStatusArray.get(i)); - } - if (subscriptionTypeArray != null) { - subscriptionType = Integer.parseInt(subscriptionTypeArray.get(i)); - } - if (quickContactArray != null) { - quickContact = Integer.parseInt(quickContactArray.get(i)); - } - if (rejectedArray != null) { - rejected = Integer.parseInt(rejectedArray.get(i)); - } - } catch (NumberFormatException ex) { - Log.e(LOG_TAG, "insertBulkContacts: caught " + ex); - } - - /* - if (DBG) log("insertBulkContacts[" + i + "] username=" + - username + ", nickname=" + nickname + ", type=" + type + - ", subscriptionStatus=" + subscriptionStatus + ", subscriptionType=" + - subscriptionType + ", qc=" + quickContact); - */ - - contactValues.put(Im.Contacts.USERNAME, username); - contactValues.put(Im.Contacts.NICKNAME, nickname); - contactValues.put(Im.Contacts.TYPE, type); - if (subscriptionStatusArray != null) { - contactValues.put(Im.Contacts.SUBSCRIPTION_STATUS, subscriptionStatus); - } - if (subscriptionTypeArray != null) { - contactValues.put(Im.Contacts.SUBSCRIPTION_TYPE, subscriptionType); - } - if (quickContactArray != null) { - contactValues.put(Im.Contacts.QUICK_CONTACT, quickContact); - } - if (rejectedArray != null) { - contactValues.put(Im.Contacts.REJECTED, rejected); - } - - long rowId = 0; - - /* save this code for when we add constraint (account, username) to the contacts - table - try { - rowId = db.insertOrThrow(TABLE_CONTACTS, USERNAME, contactValues); - } catch (android.database.sqlite.SQLiteConstraintException ex) { - if (DBG) log("insertBulkContacts: insert " + username + " caught " + ex); - - // append username to the selection clause - updateSelection.delete(0, updateSelection.length()); - updateSelection.append(Im.Contacts.USERNAME); - updateSelection.append("=?"); - updateSelectionArgs[0] = username; - - int updated = db.update(TABLE_CONTACTS, contactValues, - updateSelection.toString(), updateSelectionArgs); - - if (DBG && updated != 1) { - log("insertBulkContacts: update " + username + " failed!"); - } - } - */ - - rowId = db.insert(TABLE_CONTACTS, USERNAME, contactValues); - if (rowId > 0) { - sum++; - if (!USE_CONTACT_PRESENCE_TRIGGER) { - // seed the presence for the new contact - //if (DBG) log("seedPresence for pid " + rowId); - presenceValues.put(Im.Presence.CONTACT_ID, rowId); - db.insert(TABLE_PRESENCE, null, presenceValues); - } - } - - // yield the lock if anyone else is trying to - // perform a db operation here. - db.yieldIfContended(); - } - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - - // We know that we succeeded becuase endTransaction throws if the transaction failed. - if (DBG) log("insertBulkContacts: added " + sum + " contacts!"); - return true; - } - - // package scope for testing. - int updateBulkContacts(ContentValues values, String userWhere) { - ArrayList<String> usernames = values.getStringArrayList(Im.Contacts.USERNAME); - ArrayList<String> nicknames = values.getStringArrayList(Im.Contacts.NICKNAME); - - int usernameCount = usernames.size(); - int nicknameCount = nicknames.size(); - - if (usernameCount != nicknameCount) { - Log.e(LOG_TAG, "[ImProvider] updateBulkContacts: input bundle " + - "username & nickname lists have diff. length!"); - return 0; - } - - ArrayList<String> contactTypeArray = values.getStringArrayList(Im.Contacts.TYPE); - ArrayList<String> subscriptionStatusArray = - values.getStringArrayList(Im.Contacts.SUBSCRIPTION_STATUS); - ArrayList<String> subscriptionTypeArray = - values.getStringArrayList(Im.Contacts.SUBSCRIPTION_TYPE); - ArrayList<String> quickContactArray = values.getStringArrayList(Im.Contacts.QUICK_CONTACT); - ArrayList<String> rejectedArray = values.getStringArrayList(Im.Contacts.REJECTED); - final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - - db.beginTransaction(); - int sum = 0; - - try { - Long provider = values.getAsLong(Im.Contacts.PROVIDER); - Long account = values.getAsLong(Im.Contacts.ACCOUNT); - - ContentValues contactValues = new ContentValues(); - contactValues.put(Im.Contacts.PROVIDER, provider); - contactValues.put(Im.Contacts.ACCOUNT, account); - - StringBuilder updateSelection = new StringBuilder(); - String[] updateSelectionArgs = new String[1]; - - for (int i=0; i<usernameCount; i++) { - String username = usernames.get(i); - String nickname = nicknames.get(i); - int type = 0; - int subscriptionStatus = 0; - int subscriptionType = 0; - int quickContact = 0; - int rejected = 0; - - try { - type = Integer.parseInt(contactTypeArray.get(i)); - subscriptionStatus = Integer.parseInt(subscriptionStatusArray.get(i)); - subscriptionType = Integer.parseInt(subscriptionTypeArray.get(i)); - quickContact = Integer.parseInt(quickContactArray.get(i)); - rejected = Integer.parseInt(rejectedArray.get(i)); - } catch (NumberFormatException ex) { - Log.e(LOG_TAG, "insertBulkContacts: caught " + ex); - } - - if (DBG) log("updateBulkContacts[" + i + "] username=" + - username + ", nickname=" + nickname + ", type=" + type + - ", subscriptionStatus=" + subscriptionStatus + ", subscriptionType=" + - subscriptionType + ", qc=" + quickContact); - - contactValues.put(Im.Contacts.USERNAME, username); - contactValues.put(Im.Contacts.NICKNAME, nickname); - contactValues.put(Im.Contacts.TYPE, type); - contactValues.put(Im.Contacts.SUBSCRIPTION_STATUS, subscriptionStatus); - contactValues.put(Im.Contacts.SUBSCRIPTION_TYPE, subscriptionType); - contactValues.put(Im.Contacts.QUICK_CONTACT, quickContact); - contactValues.put(Im.Contacts.REJECTED, rejected); - - // append username to the selection clause - updateSelection.delete(0, updateSelection.length()); - updateSelection.append(userWhere); - updateSelection.append(" AND "); - updateSelection.append(Im.Contacts.USERNAME); - updateSelection.append("=?"); - - updateSelectionArgs[0] = username; - - int numUpdated = db.update(TABLE_CONTACTS, contactValues, - updateSelection.toString(), updateSelectionArgs); - if (numUpdated == 0) { - Log.e(LOG_TAG, "[ImProvider] updateBulkContacts: " + - " update failed for selection = " + updateSelection); - } else { - sum += numUpdated; - } - - // yield the lock if anyone else is trying to - // perform a db operation here. - db.yieldIfContended(); - } - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - - if (DBG) log("updateBulkContacts: " + sum + " entries updated"); - return sum; - } - - // constants definitions use for the query in seedInitialPresenceByAccount() - private static final String[] CONTACT_ID_PROJECTION = new String[] { - Im.Contacts._ID, // 0 - }; - - private static final int COLUMN_ID = 0; - - private static final String CONTACTS_WITH_NO_PRESENCE_SELECTION = - Im.Contacts.ACCOUNT + "=?" + " AND " + Im.Contacts._ID + - " in (select " + CONTACT_ID + " from " + TABLE_CONTACTS + - " left outer join " + TABLE_PRESENCE + " on " + CONTACT_ID + '=' + - PRESENCE_CONTACT_ID + " where " + PRESENCE_CONTACT_ID + " IS NULL)"; - - // selection args for the query. - private String[] mQueryContactPresenceSelectionArgs = new String[1]; - - /** - * This method first performs a query for all the contacts (for the given account) that - * don't have a presence entry in the presence table. Then for each of those contacts, - * the method creates a presence row. The whole thing is done inside one database transaction - * to increase performance. - * - * @param account the account of the contacts for which we want to create seed presence rows. - */ - private void seedInitialPresenceByAccount(long account) { - SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); - qb.setTables(TABLE_CONTACTS); - qb.setProjectionMap(sContactsProjectionMap); - - mQueryContactPresenceSelectionArgs[0] = String.valueOf(account); - - final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - db.beginTransaction(); - - Cursor c = null; - - try { - ContentValues presenceValues = new ContentValues(); - presenceValues.put(Im.Presence.PRESENCE_STATUS, Im.Presence.OFFLINE); - presenceValues.put(Im.Presence.PRESENCE_CUSTOM_STATUS, ""); - - // First: update all the presence for the account so they are offline - StringBuilder buf = new StringBuilder(); - buf.append(Im.Presence.CONTACT_ID); - buf.append(" in (select "); - buf.append(Im.Contacts._ID); - buf.append(" from "); - buf.append(TABLE_CONTACTS); - buf.append(" where "); - buf.append(Im.Contacts.ACCOUNT); - buf.append("=?) "); - - String selection = buf.toString(); - if (DBG) log("seedInitialPresence: reset presence selection=" + selection); - - int count = db.update(TABLE_PRESENCE, presenceValues, selection, - mQueryContactPresenceSelectionArgs); - if (DBG) log("seedInitialPresence: reset " + count + " presence rows to OFFLINE"); - - // second: add a presence row for each contact that doesn't have a presence - if (DBG) { - log("seedInitialPresence: contacts_with_no_presence_selection => " + - CONTACTS_WITH_NO_PRESENCE_SELECTION); - } - - c = qb.query(db, - CONTACT_ID_PROJECTION, - CONTACTS_WITH_NO_PRESENCE_SELECTION, - mQueryContactPresenceSelectionArgs, - null, null, null, null); - - if (DBG) log("seedInitialPresence: found " + c.getCount() + " contacts w/o presence"); - - count = 0; - - while (c.moveToNext()) { - long id = c.getLong(COLUMN_ID); - presenceValues.put(Im.Presence.CONTACT_ID, id); - - try { - if (db.insert(TABLE_PRESENCE, null, presenceValues) > 0) { - count++; - } - } catch (SQLiteConstraintException ex) { - // we could possibly catch this exception, since there could be a presence - // row with the same contact_id. That's fine, just ignore the error - if (DBG) log("seedInitialPresence: insert presence for contact_id " + id + - " failed, caught " + ex); - } - } - - db.setTransactionSuccessful(); - - if (DBG) log("seedInitialPresence: added " + count + " new presence rows"); - } finally { - c.close(); - db.endTransaction(); - } - } - - private int updateBulkPresence(ContentValues values, String userWhere, String[] whereArgs) { - ArrayList<String> usernames = values.getStringArrayList(Im.Contacts.USERNAME); - int count = usernames.size(); - Long account = values.getAsLong(Im.Contacts.ACCOUNT); - - ArrayList<String> priorityArray = values.getStringArrayList(Im.Presence.PRIORITY); - ArrayList<String> modeArray = values.getStringArrayList(Im.Presence.PRESENCE_STATUS); - ArrayList<String> statusArray = values.getStringArrayList( - Im.Presence.PRESENCE_CUSTOM_STATUS); - ArrayList<String> clientTypeArray = values.getStringArrayList(Im.Presence.CLIENT_TYPE); - ArrayList<String> resourceArray = values.getStringArrayList(Im.Presence.JID_RESOURCE); - - // append username to the selection clause - StringBuilder buf = new StringBuilder(); - - if (!TextUtils.isEmpty(userWhere)) { - buf.append(userWhere); - buf.append(" AND "); - } - - buf.append(Im.Presence.CONTACT_ID); - buf.append(" in (select "); - buf.append(Im.Contacts._ID); - buf.append(" from "); - buf.append(TABLE_CONTACTS); - buf.append(" where "); - buf.append(Im.Contacts.ACCOUNT); - buf.append("=? AND "); - - // use username LIKE ? for case insensitive comparison - buf.append(Im.Contacts.USERNAME); - buf.append(" LIKE ?) AND ("); - - buf.append(Im.Presence.PRIORITY); - buf.append("<=? OR "); - buf.append(Im.Presence.PRIORITY); - buf.append(" IS NULL OR "); - buf.append(Im.Presence.JID_RESOURCE); - buf.append("=?)"); - - String selection = buf.toString(); - - if (DBG) log("updateBulkPresence: selection => " + selection); - - int numArgs = (whereArgs != null ? whereArgs.length + 4 : 4); - String[] selectionArgs = new String[numArgs]; - int selArgsIndex = 0; - - if (whereArgs != null) { - for (selArgsIndex=0; selArgsIndex<numArgs-1; selArgsIndex++) { - selectionArgs[selArgsIndex] = whereArgs[selArgsIndex]; - } - } - - final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - - db.beginTransaction(); - int sum = 0; - - try { - ContentValues presenceValues = new ContentValues(); - - for (int i=0; i<count; i++) { - String username = usernames.get(i); - int priority = 0; - int mode = 0; - String status = statusArray.get(i); - String jidResource = resourceArray == null ? "" : resourceArray.get(i); - int clientType = Im.Presence.CLIENT_TYPE_DEFAULT; - - try { - if (priorityArray != null) { - priority = Integer.parseInt(priorityArray.get(i)); - } - if (modeArray != null) { - mode = Integer.parseInt(modeArray.get(i)); - } - if (clientTypeArray != null) { - clientType = Integer.parseInt(clientTypeArray.get(i)); - } - } catch (NumberFormatException ex) { - Log.e(LOG_TAG, "[ImProvider] updateBulkPresence: caught " + ex); - } - - /* - if (DBG) { - log("updateBulkPresence[" + i + "] username=" + username + ", priority=" + - priority + ", mode=" + mode + ", status=" + status + ", resource=" + - jidResource + ", clientType=" + clientType); - } - */ - - if (modeArray != null) { - presenceValues.put(Im.Presence.PRESENCE_STATUS, mode); - } - if (priorityArray != null) { - presenceValues.put(Im.Presence.PRIORITY, priority); - } - presenceValues.put(Im.Presence.PRESENCE_CUSTOM_STATUS, status); - if (clientTypeArray != null) { - presenceValues.put(Im.Presence.CLIENT_TYPE, clientType); - } - - if (!TextUtils.isEmpty(jidResource)) { - presenceValues.put(Im.Presence.JID_RESOURCE, jidResource); - } - - // fill in the selection args - int idx = selArgsIndex; - selectionArgs[idx++] = String.valueOf(account); - selectionArgs[idx++] = username; - selectionArgs[idx++] = String.valueOf(priority); - selectionArgs[idx] = jidResource; - - int numUpdated = db.update(TABLE_PRESENCE, - presenceValues, selection, selectionArgs); - if (numUpdated == 0) { - Log.e(LOG_TAG, "[ImProvider] updateBulkPresence: failed for " + username); - } else { - sum += numUpdated; - } - - // yield the lock if anyone else is trying to - // perform a db operation here. - db.yieldIfContended(); - } - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - - if (DBG) log("updateBulkPresence: " + sum + " entries updated"); - return sum; - } - - public Uri insertInternal(Uri url, ContentValues initialValues) { - Uri resultUri = null; - long rowID = 0; - boolean notifyContactListContentUri = false; - boolean notifyContactContentUri = false; - boolean notifyMessagesContentUri = false; - boolean notifyGroupMessagesContentUri = false; - boolean notifyProviderAccountContentUri = false; - - final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - int match = mUrlMatcher.match(url); - - if (DBG) log("insert to " + url + ", match " + match); - switch (match) { - case MATCH_PROVIDERS: - // Insert into the providers table - rowID = db.insert(TABLE_PROVIDERS, "name", initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.Provider.CONTENT_URI + "/" + rowID); - } - notifyProviderAccountContentUri = true; - break; - - case MATCH_ACCOUNTS: - // Insert into the accounts table - rowID = db.insert(TABLE_ACCOUNTS, "name", initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.Account.CONTENT_URI + "/" + rowID); - } - notifyProviderAccountContentUri = true; - break; - - case MATCH_CONTACTS_BY_PROVIDER: - appendValuesFromUrl(initialValues, url, Im.Contacts.PROVIDER, - Im.Contacts.ACCOUNT); - // fall through - case MATCH_CONTACTS: - case MATCH_CONTACTS_BAREBONE: - // Insert into the contacts table - rowID = db.insert(TABLE_CONTACTS, "username", initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.Contacts.CONTENT_URI + "/" + rowID); - } - - notifyContactContentUri = true; - break; - - case MATCH_CONTACTS_BULK: - if (insertBulkContacts(initialValues)) { - // notify change using the "content://im/contacts" url, - // so the change will be observed by listeners interested - // in contacts changes. - resultUri = Im.Contacts.CONTENT_URI; - } - notifyContactContentUri = true; - break; - - case MATCH_CONTACTLISTS_BY_PROVIDER: - appendValuesFromUrl(initialValues, url, Im.ContactList.PROVIDER, - Im.ContactList.ACCOUNT); - // fall through - case MATCH_CONTACTLISTS: - // Insert into the contactList table - rowID = db.insert(TABLE_CONTACT_LIST, "name", initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.ContactList.CONTENT_URI + "/" + rowID); - } - notifyContactListContentUri = true; - break; - - case MATCH_BLOCKEDLIST_BY_PROVIDER: - appendValuesFromUrl(initialValues, url, Im.BlockedList.PROVIDER, - Im.BlockedList.ACCOUNT); - // fall through - case MATCH_BLOCKEDLIST: - // Insert into the blockedList table - rowID = db.insert(TABLE_BLOCKED_LIST, "username", initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.BlockedList.CONTENT_URI + "/" + rowID); - } - - break; - - case MATCH_CONTACTS_ETAGS: - rowID = db.replace(TABLE_CONTACTS_ETAG, Im.ContactsEtag.ETAG, initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.ContactsEtag.CONTENT_URI + "/" + rowID); - } - break; - - case MATCH_MESSAGES_BY_CONTACT: - appendValuesFromUrl(initialValues, url, Im.Messages.PROVIDER, - Im.Messages.ACCOUNT, Im.Messages.CONTACT); - notifyMessagesContentUri = true; - // fall through - case MATCH_MESSAGES: - // Insert into the messages table. - rowID = db.insert(TABLE_MESSAGES, "contact", initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.Messages.CONTENT_URI + "/" + rowID); - } - - break; - - case MATCH_INVITATIONS: - rowID = db.insert(TABLE_INVITATIONS, null, initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.Invitation.CONTENT_URI + "/" + rowID); - } - break; - - case MATCH_GROUP_MEMBERS: - rowID = db.insert(TABLE_GROUP_MEMBERS, "nickname", initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.GroupMembers.CONTENT_URI + "/" + rowID); - } - break; - - case MATCH_GROUP_MEMBERS_BY_GROUP: - appendValuesFromUrl(initialValues, url, Im.GroupMembers.GROUP); - rowID = db.insert(TABLE_GROUP_MEMBERS, "nickname", initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.GroupMembers.CONTENT_URI + "/" + rowID); - } - break; - - case MATCH_GROUP_MESSAGE_BY: - appendValuesFromUrl(initialValues, url, Im.GroupMembers.GROUP); - notifyGroupMessagesContentUri = true; - // fall through - case MATCH_GROUP_MESSAGES: - rowID = db.insert(TABLE_GROUP_MESSAGES, "group", initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.GroupMessages.CONTENT_URI + "/" + rowID); - } - break; - - case MATCH_AVATAR_BY_PROVIDER: - appendValuesFromUrl(initialValues, url, Im.Avatars.PROVIDER, Im.Avatars.ACCOUNT); - // fall through - case MATCH_AVATARS: - // Insert into the avatars table - rowID = db.replace(TABLE_AVATARS, "contact", initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.Avatars.CONTENT_URI + "/" + rowID); - } - break; - - case MATCH_CHATS_ID: - appendValuesFromUrl(initialValues, url, Im.Chats.CONTACT_ID); - // fall through - case MATCH_CHATS: - // Insert into the chats table - initialValues.put(Im.Chats.SHORTCUT, -1); - rowID = db.replace(TABLE_CHATS, Im.Chats.CONTACT_ID, initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.Chats.CONTENT_URI + "/" + rowID); - addToQuickSwitch(rowID); - } - notifyContactContentUri = true; - break; - - case MATCH_PRESENCE: - rowID = db.replace(TABLE_PRESENCE, null, initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.Presence.CONTENT_URI + "/" + rowID); - } - notifyContactContentUri = true; - break; - - case MATCH_PRESENCE_SEED_BY_ACCOUNT: - try { - seedInitialPresenceByAccount(Long.parseLong(url.getLastPathSegment())); - resultUri = Im.Presence.CONTENT_URI; - } catch (NumberFormatException ex) { - throw new IllegalArgumentException(); - } - break; - - case MATCH_SESSIONS_BY_PROVIDER: - appendValuesFromUrl(initialValues, url, Im.SessionCookies.PROVIDER, - Im.SessionCookies.ACCOUNT); - // fall through - case MATCH_SESSIONS: - rowID = db.insert(TABLE_SESSION_COOKIES, null, initialValues); - if(rowID > 0) { - resultUri = Uri.parse(Im.SessionCookies.CONTENT_URI + "/" + rowID); - } - break; - - case MATCH_PROVIDER_SETTINGS: - rowID = db.replace(TABLE_PROVIDER_SETTINGS, null, initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.ProviderSettings.CONTENT_URI + "/" + rowID); - } - break; - - case MATCH_OUTGOING_RMQ_MESSAGES: - rowID = db.insert(TABLE_OUTGOING_RMQ_MESSAGES, null, initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.OutgoingRmq.CONTENT_URI + "/" + rowID); - } - break; - - case MATCH_LAST_RMQ_ID: - rowID = db.replace(TABLE_LAST_RMQ_ID, null, initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.LastRmqId.CONTENT_URI + "/" + rowID); - } - break; - - case MATCH_ACCOUNTS_STATUS: - rowID = db.replace(TABLE_ACCOUNT_STATUS, null, initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.AccountStatus.CONTENT_URI + "/" + rowID); - } - notifyProviderAccountContentUri = true; - break; - - case MATCH_BRANDING_RESOURCE_MAP_CACHE: - rowID = db.insert(TABLE_BRANDING_RESOURCE_MAP_CACHE, null, initialValues); - if (rowID > 0) { - resultUri = Uri.parse(Im.BrandingResourceMapCache.CONTENT_URI + "/" + rowID); - } - break; - - default: - throw new UnsupportedOperationException("Cannot insert into URL: " + url); - } - // TODO: notify the data change observer? - - if (resultUri != null) { - ContentResolver resolver = getContext().getContentResolver(); - - // In most case, we query contacts with presence and chats joined, thus - // we should also notify that contacts changes when presence or chats changed. - if (notifyContactContentUri) { - resolver.notifyChange(Im.Contacts.CONTENT_URI, null); - } - - if (notifyContactListContentUri) { - resolver.notifyChange(Im.ContactList.CONTENT_URI, null); - } - - if (notifyMessagesContentUri) { - resolver.notifyChange(Im.Messages.CONTENT_URI, null); - } - - if (notifyGroupMessagesContentUri) { - resolver.notifyChange(Im.GroupMessages.CONTENT_URI, null); - } - - if (notifyProviderAccountContentUri) { - if (DBG) log("notify insert for " + Im.Provider.CONTENT_URI_WITH_ACCOUNT); - resolver.notifyChange(Im.Provider.CONTENT_URI_WITH_ACCOUNT, - null); - } - } - return resultUri; - } - - private void appendValuesFromUrl(ContentValues values, Uri url, String...columns){ - if(url.getPathSegments().size() <= columns.length) { - throw new IllegalArgumentException("Not enough values in url"); - } - for(int i = 0; i < columns.length; i++){ - if(values.containsKey(columns[i])){ - throw new UnsupportedOperationException("Cannot override the value for " + columns[i]); - } - values.put(columns[i], decodeURLSegment(url.getPathSegments().get(i + 1))); - } - } - - // Quick-switch management - // The chat UI provides slots (0, 9, .., 1) for the first 10 chats. This allows you to - // quickly switch between these chats by chording menu+#. We number from the right end of - // the number row and move leftward to make an easier two-hand chord with the menu button - // on the left side of the keyboard. - private void addToQuickSwitch(long newRow) { - // Since there are fewer than 10, there must be an empty slot. Let's find it. - int slot = findEmptyQuickSwitchSlot(); - - if (slot == -1) { - return; - } - - updateSlotForChat(newRow, slot); - } - - // If there are more than 10 chats and one with a quick switch slot ends then pick a chat - // that doesn't have a slot and have it inhabit the newly emptied slot. - private void backfillQuickSwitchSlots() { - // Find all the chats without a quick switch slot, and order - Cursor c = query(Im.Chats.CONTENT_URI, - BACKFILL_PROJECTION, - Im.Chats.SHORTCUT + "=-1", null, Im.Chats.LAST_MESSAGE_DATE + " DESC"); - - try { - if (c.getCount() < 1) { - return; - } - - int slot = findEmptyQuickSwitchSlot(); - - if (slot != -1) { - c.moveToFirst(); - - long id = c.getLong(c.getColumnIndex(Im.Chats._ID)); - - updateSlotForChat(id, slot); - } - } finally { - c.close(); - } - } - - private int updateSlotForChat(long chatId, int slot) { - ContentValues values = new ContentValues(); - - values.put(Im.Chats.SHORTCUT, slot); - - return update(Im.Chats.CONTENT_URI, values, Im.Chats._ID + "=?", - new String[] { Long.toString(chatId) }); - } - - private int findEmptyQuickSwitchSlot() { - Cursor c = queryInternal(Im.Chats.CONTENT_URI, FIND_SHORTCUT_PROJECTION, null, null, null); - final int N = c.getCount(); - - try { - // If there are 10 or more chats then all the quick switch slots are already filled - if (N >= 10) { - return -1; - } - - int slots = 0; - int column = c.getColumnIndex(Im.Chats.SHORTCUT); - - // The map is here because numbers go from 0-9, but we want to assign slots in - // 0, 9, 8, ..., 1 order to match the right-to-left reading of the number row - // on the keyboard. - int[] map = new int[] { 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; - - // Mark all the slots that are in use - // The shortcuts represent actual keyboard number row keys, and not ordinals. - // So 7 would mean the shortcut is the 7 key on the keyboard and NOT the 7th - // shortcut. The passing of slot through map[] below maps these keyboard key - // shortcuts into an ordinal bit position in the 'slots' bitfield. - for (c.moveToFirst(); ! c.isAfterLast(); c.moveToNext()) { - int slot = c.getInt(column); - - if (slot != -1) { - slots |= (1 << map[slot]); - } - } - - // Try to find an empty one - // As we exit this, the push of i through map[] maps the ordinal bit position - // in the 'slots' bitfield onto a key on the number row of the device keyboard. - // The keyboard key is what is used to designate the shortcut. - for (int i = 0; i < 10; i++) { - if ((slots & (1 << i)) == 0) { - return map[i]; - } - } - - return -1; - } finally { - c.close(); - } - } - - /** - * manual trigger for deleting contacts - */ - private static final String DELETE_PRESENCE_SELECTION = - Im.Presence.CONTACT_ID + " in (select " + - PRESENCE_CONTACT_ID + " from " + TABLE_PRESENCE + " left outer join " + TABLE_CONTACTS + - " on " + PRESENCE_CONTACT_ID + '=' + CONTACT_ID + " where " + CONTACT_ID + " IS NULL)"; - - private static final String CHATS_CONTACT_ID = TABLE_CHATS + '.' + Im.Chats.CONTACT_ID; - private static final String DELETE_CHATS_SELECTION = Im.Chats.CONTACT_ID + " in (select "+ - CHATS_CONTACT_ID + " from " + TABLE_CHATS + " left outer join " + TABLE_CONTACTS + - " on " + CHATS_CONTACT_ID + '=' + CONTACT_ID + " where " + CONTACT_ID + " IS NULL)"; - - private static final String GROUP_MEMBER_ID = TABLE_GROUP_MEMBERS + '.' + Im.GroupMembers.GROUP; - private static final String DELETE_GROUP_MEMBER_SELECTION = - Im.GroupMembers.GROUP + " in (select "+ - GROUP_MEMBER_ID + " from " + TABLE_GROUP_MEMBERS + " left outer join " + TABLE_CONTACTS + - " on " + GROUP_MEMBER_ID + '=' + CONTACT_ID + " where " + CONTACT_ID + " IS NULL)"; - - private static final String GROUP_MESSAGES_ID = - TABLE_GROUP_MESSAGES + '.' + Im.GroupMessages.GROUP; - private static final String DELETE_GROUP_MESSAGES_SELECTION = - Im.GroupMessages.GROUP + " in (select "+ GROUP_MESSAGES_ID + " from " + - TABLE_GROUP_MESSAGES + " left outer join " + TABLE_CONTACTS + " on " + - GROUP_MESSAGES_ID + '=' + CONTACT_ID + " where " + CONTACT_ID + " IS NULL)"; - - private void performContactRemovalCleanup(long contactId) { - final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - - if (contactId > 0) { - deleteWithContactId(db, contactId, TABLE_PRESENCE, Im.Presence.CONTACT_ID); - deleteWithContactId(db, contactId, TABLE_CHATS, Im.Chats.CONTACT_ID); - deleteWithContactId(db, contactId, TABLE_GROUP_MEMBERS, Im.GroupMembers.GROUP); - deleteWithContactId(db, contactId, TABLE_GROUP_MESSAGES, Im.GroupMessages.GROUP); - } else { - performComplexDelete(db, TABLE_PRESENCE, DELETE_PRESENCE_SELECTION, null); - performComplexDelete(db, TABLE_CHATS, DELETE_CHATS_SELECTION, null); - performComplexDelete(db, TABLE_GROUP_MEMBERS, DELETE_GROUP_MEMBER_SELECTION, null); - performComplexDelete(db, TABLE_GROUP_MESSAGES, DELETE_GROUP_MESSAGES_SELECTION, null); - } - } - - private void deleteWithContactId(SQLiteDatabase db, long contactId, - String tableName, String columnName) { - db.delete(tableName, columnName + '=' + contactId, null /* selection args */); - } - - private void performComplexDelete(SQLiteDatabase db, String tableName, - String selection, String[] selectionArgs) { - if (DBG) log("performComplexDelete for table " + tableName + ", selection => " + selection); - int count = db.delete(tableName, selection, selectionArgs); - if (DBG) log("performComplexDelete: deleted " + count + " rows"); - } - - public int deleteInternal(Uri url, String userWhere, - String[] whereArgs) { - String tableToChange; - String idColumnName = null; - String changedItemId = null; - - StringBuilder whereClause = new StringBuilder(); - if(userWhere != null) { - whereClause.append(userWhere); - } - - boolean notifyMessagesContentUri = false; - boolean notifyGroupMessagesContentUri = false; - boolean notifyContactListContentUri = false; - boolean notifyProviderAccountContentUri = false; - int match = mUrlMatcher.match(url); - - boolean contactDeleted = false; - long deletedContactId = 0; - - boolean backfillQuickSwitchSlots = false; - - switch (match) { - case MATCH_PROVIDERS: - tableToChange = TABLE_PROVIDERS; - notifyProviderAccountContentUri = true; - break; - - case MATCH_ACCOUNTS_BY_ID: - changedItemId = url.getPathSegments().get(1); - // fall through - case MATCH_ACCOUNTS: - tableToChange = TABLE_ACCOUNTS; - notifyProviderAccountContentUri = true; - break; - - case MATCH_ACCOUNT_STATUS: - changedItemId = url.getPathSegments().get(1); - // fall through - case MATCH_ACCOUNTS_STATUS: - tableToChange = TABLE_ACCOUNT_STATUS; - notifyProviderAccountContentUri = true; - break; - - case MATCH_CONTACTS: - case MATCH_CONTACTS_BAREBONE: - tableToChange = TABLE_CONTACTS; - contactDeleted = true; - break; - - case MATCH_CONTACT: - tableToChange = TABLE_CONTACTS; - changedItemId = url.getPathSegments().get(1); - - try { - deletedContactId = Long.parseLong(changedItemId); - } catch (NumberFormatException ex) { - } - - contactDeleted = true; - break; - - case MATCH_CONTACTS_BY_PROVIDER: - tableToChange = TABLE_CONTACTS; - appendWhere(whereClause, Im.Contacts.ACCOUNT, "=", url.getPathSegments().get(2)); - contactDeleted = true; - break; - - case MATCH_CONTACTLISTS_BY_PROVIDER: - appendWhere(whereClause, Im.ContactList.ACCOUNT, "=", - url.getPathSegments().get(2)); - // fall through - case MATCH_CONTACTLISTS: - tableToChange = TABLE_CONTACT_LIST; - notifyContactListContentUri = true; - break; - - case MATCH_CONTACTLIST: - tableToChange = TABLE_CONTACT_LIST; - changedItemId = url.getPathSegments().get(1); - break; - - case MATCH_BLOCKEDLIST: - tableToChange = TABLE_BLOCKED_LIST; - break; - - case MATCH_BLOCKEDLIST_BY_PROVIDER: - tableToChange = TABLE_BLOCKED_LIST; - appendWhere(whereClause, Im.BlockedList.ACCOUNT, "=", url.getPathSegments().get(2)); - break; - - case MATCH_CONTACTS_ETAGS: - tableToChange = TABLE_CONTACTS_ETAG; - break; - - case MATCH_CONTACTS_ETAG: - tableToChange = TABLE_CONTACTS_ETAG; - changedItemId = url.getPathSegments().get(1); - break; - - case MATCH_MESSAGES: - tableToChange = TABLE_MESSAGES; - break; - - case MATCH_MESSAGES_BY_CONTACT: - tableToChange = TABLE_MESSAGES; - appendWhere(whereClause, Im.Messages.ACCOUNT, "=", - url.getPathSegments().get(2)); - appendWhere(whereClause, Im.Messages.CONTACT, "=", - decodeURLSegment(url.getPathSegments().get(3))); - notifyMessagesContentUri = true; - break; - - case MATCH_MESSAGE: - tableToChange = TABLE_MESSAGES; - changedItemId = url.getPathSegments().get(1); - notifyMessagesContentUri = true; - break; - - case MATCH_GROUP_MEMBERS: - tableToChange = TABLE_GROUP_MEMBERS; - break; - - case MATCH_GROUP_MEMBERS_BY_GROUP: - tableToChange = TABLE_GROUP_MEMBERS; - appendWhere(whereClause, Im.GroupMembers.GROUP, "=", url.getPathSegments().get(1)); - break; - - case MATCH_GROUP_MESSAGES: - tableToChange = TABLE_GROUP_MESSAGES; - break; - - case MATCH_GROUP_MESSAGE_BY: - tableToChange = TABLE_GROUP_MESSAGES; - changedItemId = url.getPathSegments().get(1); - idColumnName = Im.GroupMessages.GROUP; - notifyGroupMessagesContentUri = true; - break; - - case MATCH_GROUP_MESSAGE: - tableToChange = TABLE_GROUP_MESSAGES; - changedItemId = url.getPathSegments().get(1); - notifyGroupMessagesContentUri = true; - break; - - case MATCH_INVITATIONS: - tableToChange = TABLE_INVITATIONS; - break; - - case MATCH_INVITATION: - tableToChange = TABLE_INVITATIONS; - changedItemId = url.getPathSegments().get(1); - break; - - case MATCH_AVATARS: - tableToChange = TABLE_AVATARS; - break; - - case MATCH_AVATAR: - tableToChange = TABLE_AVATARS; - changedItemId = url.getPathSegments().get(1); - break; - - case MATCH_AVATAR_BY_PROVIDER: - tableToChange = TABLE_AVATARS; - changedItemId = url.getPathSegments().get(2); - idColumnName = Im.Avatars.ACCOUNT; - break; - - case MATCH_CHATS: - tableToChange = TABLE_CHATS; - backfillQuickSwitchSlots = true; - break; - - case MATCH_CHATS_BY_ACCOUNT: - tableToChange = TABLE_CHATS; - - if (whereClause.length() > 0) { - whereClause.append(" AND "); - } - whereClause.append(Im.Chats.CONTACT_ID); - whereClause.append(" in (select "); - whereClause.append(Im.Contacts._ID); - whereClause.append(" from "); - whereClause.append(TABLE_CONTACTS); - whereClause.append(" where "); - whereClause.append(Im.Contacts.ACCOUNT); - whereClause.append("='"); - whereClause.append(url.getLastPathSegment()); - whereClause.append("')"); - - if (DBG) log("deleteInternal (MATCH_CHATS_BY_ACCOUNT): sel => " + - whereClause.toString()); - - changedItemId = null; - break; - - case MATCH_CHATS_ID: - tableToChange = TABLE_CHATS; - changedItemId = url.getPathSegments().get(1); - idColumnName = Im.Chats.CONTACT_ID; - break; - - case MATCH_PRESENCE: - tableToChange = TABLE_PRESENCE; - break; - - case MATCH_PRESENCE_ID: - tableToChange = TABLE_PRESENCE; - changedItemId = url.getPathSegments().get(1); - idColumnName = Im.Presence.CONTACT_ID; - break; - - case MATCH_PRESENCE_BY_ACCOUNT: - tableToChange = TABLE_PRESENCE; - - if (whereClause.length() > 0) { - whereClause.append(" AND "); - } - whereClause.append(Im.Presence.CONTACT_ID); - whereClause.append(" in (select "); - whereClause.append(Im.Contacts._ID); - whereClause.append(" from "); - whereClause.append(TABLE_CONTACTS); - whereClause.append(" where "); - whereClause.append(Im.Contacts.ACCOUNT); - whereClause.append("='"); - whereClause.append(url.getLastPathSegment()); - whereClause.append("')"); - - if (DBG) log("deleteInternal (MATCH_PRESENCE_BY_ACCOUNT): sel => " + - whereClause.toString()); - - changedItemId = null; - break; - - case MATCH_SESSIONS: - tableToChange = TABLE_SESSION_COOKIES; - break; - - case MATCH_SESSIONS_BY_PROVIDER: - tableToChange = TABLE_SESSION_COOKIES; - changedItemId = url.getPathSegments().get(2); - idColumnName = Im.SessionCookies.ACCOUNT; - break; - - case MATCH_PROVIDER_SETTINGS_BY_ID_AND_NAME: - tableToChange = TABLE_PROVIDER_SETTINGS; - - String providerId = url.getPathSegments().get(1); - String name = url.getPathSegments().get(2); - - appendWhere(whereClause, Im.ProviderSettings.PROVIDER, "=", providerId); - appendWhere(whereClause, Im.ProviderSettings.NAME, "=", name); - break; - - case MATCH_OUTGOING_RMQ_MESSAGES: - tableToChange = TABLE_OUTGOING_RMQ_MESSAGES; - break; - - case MATCH_LAST_RMQ_ID: - tableToChange = TABLE_LAST_RMQ_ID; - break; - - case MATCH_BRANDING_RESOURCE_MAP_CACHE: - tableToChange = TABLE_BRANDING_RESOURCE_MAP_CACHE; - break; - - default: - throw new UnsupportedOperationException("Cannot delete that URL: " + url); - } - - if (idColumnName == null) { - idColumnName = "_id"; - } - - if (changedItemId != null) { - appendWhere(whereClause, idColumnName, "=", changedItemId); - } - - if (DBG) log("delete from " + url + " WHERE " + whereClause); - - final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - int count = db.delete(tableToChange, whereClause.toString(), whereArgs); - - if (contactDeleted && count > 0) { - // since the contact cleanup triggers no longer work for cross database tables, - // we have to do it by hand here. - performContactRemovalCleanup(deletedContactId); - } - - if (count > 0) { - // In most case, we query contacts with presence and chats joined, thus - // we should also notify that contacts changes when presence or chats changed. - if (match == MATCH_CHATS || match == MATCH_CHATS_ID - || match == MATCH_PRESENCE || match == MATCH_PRESENCE_ID - || match == MATCH_CONTACTS_BAREBONE) { - getContext().getContentResolver().notifyChange(Im.Contacts.CONTENT_URI, null); - } else if (notifyMessagesContentUri) { - getContext().getContentResolver().notifyChange(Im.Messages.CONTENT_URI, null); - } else if (notifyGroupMessagesContentUri) { - getContext().getContentResolver().notifyChange(Im.GroupMessages.CONTENT_URI, null); - } else if (notifyContactListContentUri) { - getContext().getContentResolver().notifyChange(Im.ContactList.CONTENT_URI, null); - } else if (notifyProviderAccountContentUri) { - if (DBG) log("notify delete for " + Im.Provider.CONTENT_URI_WITH_ACCOUNT); - getContext().getContentResolver().notifyChange(Im.Provider.CONTENT_URI_WITH_ACCOUNT, - null); - } - - if (backfillQuickSwitchSlots) { - backfillQuickSwitchSlots(); - } - } - - return count; - } - - public int updateInternal(Uri url, ContentValues values, String userWhere, - String[] whereArgs) { - String tableToChange; - String idColumnName = null; - String changedItemId = null; - int count; - - StringBuilder whereClause = new StringBuilder(); - if(userWhere != null) { - whereClause.append(userWhere); - } - - boolean notifyMessagesContentUri = false; - boolean notifyGroupMessagesContentUri = false; - boolean notifyContactListContentUri = false; - boolean notifyProviderAccountContentUri = false; - - int match = mUrlMatcher.match(url); - switch (match) { - case MATCH_PROVIDERS_BY_ID: - changedItemId = url.getPathSegments().get(1); - // fall through - case MATCH_PROVIDERS: - tableToChange = TABLE_PROVIDERS; - break; - - case MATCH_ACCOUNTS_BY_ID: - changedItemId = url.getPathSegments().get(1); - // fall through - case MATCH_ACCOUNTS: - tableToChange = TABLE_ACCOUNTS; - notifyProviderAccountContentUri = true; - break; - - case MATCH_ACCOUNT_STATUS: - changedItemId = url.getPathSegments().get(1); - // fall through - case MATCH_ACCOUNTS_STATUS: - tableToChange = TABLE_ACCOUNT_STATUS; - notifyProviderAccountContentUri = true; - break; - - case MATCH_CONTACTS: - case MATCH_CONTACTS_BAREBONE: - tableToChange = TABLE_CONTACTS; - break; - - case MATCH_CONTACTS_BY_PROVIDER: - tableToChange = TABLE_CONTACTS; - changedItemId = url.getPathSegments().get(2); - idColumnName = Im.Contacts.ACCOUNT; - break; - - case MATCH_CONTACT: - tableToChange = TABLE_CONTACTS; - changedItemId = url.getPathSegments().get(1); - break; - - case MATCH_CONTACTS_BULK: - count = updateBulkContacts(values, userWhere); - // notify change using the "content://im/contacts" url, - // so the change will be observed by listeners interested - // in contacts changes. - if (count > 0) { - getContext().getContentResolver().notifyChange( - Im.Contacts.CONTENT_URI, null); - } - return count; - - case MATCH_CONTACTLIST: - tableToChange = TABLE_CONTACT_LIST; - changedItemId = url.getPathSegments().get(1); - notifyContactListContentUri = true; - break; - - case MATCH_CONTACTS_ETAGS: - tableToChange = TABLE_CONTACTS_ETAG; - break; - - case MATCH_CONTACTS_ETAG: - tableToChange = TABLE_CONTACTS_ETAG; - changedItemId = url.getPathSegments().get(1); - break; - - case MATCH_MESSAGES: - tableToChange = TABLE_MESSAGES; - break; - - case MATCH_MESSAGES_BY_CONTACT: - tableToChange = TABLE_MESSAGES; - appendWhere(whereClause, Im.Messages.ACCOUNT, "=", - url.getPathSegments().get(2)); - appendWhere(whereClause, Im.Messages.CONTACT, "=", - decodeURLSegment(url.getPathSegments().get(3))); - notifyMessagesContentUri = true; - break; - - case MATCH_MESSAGE: - tableToChange = TABLE_MESSAGES; - changedItemId = url.getPathSegments().get(1); - notifyMessagesContentUri = true; - break; - - case MATCH_GROUP_MESSAGES: - tableToChange = TABLE_GROUP_MESSAGES; - break; - - case MATCH_GROUP_MESSAGE_BY: - tableToChange = TABLE_GROUP_MESSAGES; - changedItemId = url.getPathSegments().get(1); - idColumnName = Im.GroupMessages.GROUP; - notifyGroupMessagesContentUri = true; - break; - - case MATCH_GROUP_MESSAGE: - tableToChange = TABLE_GROUP_MESSAGES; - changedItemId = url.getPathSegments().get(1); - notifyGroupMessagesContentUri = true; - break; - - case MATCH_AVATARS: - tableToChange = TABLE_AVATARS; - break; - - case MATCH_AVATAR: - tableToChange = TABLE_AVATARS; - changedItemId = url.getPathSegments().get(1); - break; - - case MATCH_AVATAR_BY_PROVIDER: - tableToChange = TABLE_AVATARS; - changedItemId = url.getPathSegments().get(2); - idColumnName = Im.Avatars.ACCOUNT; - break; - - case MATCH_CHATS: - tableToChange = TABLE_CHATS; - break; - - case MATCH_CHATS_ID: - tableToChange = TABLE_CHATS; - changedItemId = url.getPathSegments().get(1); - idColumnName = Im.Chats.CONTACT_ID; - break; - - case MATCH_PRESENCE: - //if (DBG) log("update presence: where='" + userWhere + "'"); - tableToChange = TABLE_PRESENCE; - break; - - case MATCH_PRESENCE_ID: - tableToChange = TABLE_PRESENCE; - changedItemId = url.getPathSegments().get(1); - idColumnName = Im.Presence.CONTACT_ID; - break; - - case MATCH_PRESENCE_BULK: - count = updateBulkPresence(values, userWhere, whereArgs); - // notify change using the "content://im/contacts" url, - // so the change will be observed by listeners interested - // in contacts changes. - if (count > 0) { - getContext().getContentResolver().notifyChange(Im.Contacts.CONTENT_URI, null); - } - - return count; - - case MATCH_INVITATION: - tableToChange = TABLE_INVITATIONS; - changedItemId = url.getPathSegments().get(1); - break; - - case MATCH_SESSIONS: - tableToChange = TABLE_SESSION_COOKIES; - break; - - case MATCH_PROVIDER_SETTINGS_BY_ID_AND_NAME: - tableToChange = TABLE_PROVIDER_SETTINGS; - - String providerId = url.getPathSegments().get(1); - String name = url.getPathSegments().get(2); - - if (values.containsKey(Im.ProviderSettings.PROVIDER) || - values.containsKey(Im.ProviderSettings.NAME)) { - throw new SecurityException("Cannot override the value for provider|name"); - } - - appendWhere(whereClause, Im.ProviderSettings.PROVIDER, "=", providerId); - appendWhere(whereClause, Im.ProviderSettings.NAME, "=", name); - - break; - - case MATCH_OUTGOING_RMQ_MESSAGES: - tableToChange = TABLE_OUTGOING_RMQ_MESSAGES; - break; - - case MATCH_LAST_RMQ_ID: - tableToChange = TABLE_LAST_RMQ_ID; - break; - - default: - throw new UnsupportedOperationException("Cannot update URL: " + url); - } - - if (idColumnName == null) { - idColumnName = "_id"; - } - if(changedItemId != null) { - appendWhere(whereClause, idColumnName, "=", changedItemId); - } - - if (DBG) log("update " + url + " WHERE " + whereClause); - - final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - count = db.update(tableToChange, values, whereClause.toString(), whereArgs); - - if (count > 0) { - // In most case, we query contacts with presence and chats joined, thus - // we should also notify that contacts changes when presence or chats changed. - if (match == MATCH_CHATS || match == MATCH_CHATS_ID - || match == MATCH_PRESENCE || match == MATCH_PRESENCE_ID - || match == MATCH_CONTACTS_BAREBONE) { - getContext().getContentResolver().notifyChange(Im.Contacts.CONTENT_URI, null); - } else if (notifyMessagesContentUri) { - if (DBG) log("notify change for " + Im.Messages.CONTENT_URI); - getContext().getContentResolver().notifyChange(Im.Messages.CONTENT_URI, null); - } else if (notifyGroupMessagesContentUri) { - getContext().getContentResolver().notifyChange(Im.GroupMessages.CONTENT_URI, null); - } else if (notifyContactListContentUri) { - getContext().getContentResolver().notifyChange(Im.ContactList.CONTENT_URI, null); - } else if (notifyProviderAccountContentUri) { - if (DBG) log("notify change for " + Im.Provider.CONTENT_URI_WITH_ACCOUNT); - getContext().getContentResolver().notifyChange(Im.Provider.CONTENT_URI_WITH_ACCOUNT, - null); - } - } - - return count; - } - - @Override - public ParcelFileDescriptor openFile(Uri uri, String mode) - throws FileNotFoundException { - return openFileHelper(uri, mode); - } - - private static void appendWhere(StringBuilder where, String columnName, - String condition, Object value) { - if (where.length() > 0) { - where.append(" AND "); - } - where.append(columnName).append(condition); - if(value != null) { - DatabaseUtils.appendValueToSql(where, value); - } - } - - private static void appendWhere(StringBuilder where, String clause) { - if (where.length() > 0) { - where.append(" AND "); - } - where.append(clause); - } - - private static String decodeURLSegment(String segment) { - try { - return URLDecoder.decode(segment, "UTF-8"); - } catch (UnsupportedEncodingException e) { - // impossible - return segment; - } - } - - static void log(String message) { - Log.d(LOG_TAG, message); - } -} diff --git a/src/com/android/providers/im/LandingPage.java b/src/com/android/providers/im/LandingPage.java deleted file mode 100644 index 2c09b02..0000000 --- a/src/com/android/providers/im/LandingPage.java +++ /dev/null @@ -1,710 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.providers.im; - -import android.app.ListActivity; -import android.app.ActivityManagerNative; -import android.app.ActivityThread; -import android.app.Application; -import android.content.ContentUris; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.pm.ServiceInfo; -import android.database.Cursor; -import android.im.IImPlugin; -import android.im.ImPluginConsts; -import android.im.BrandingResourceIDs; -import android.net.Uri; -import android.os.Bundle; -import android.os.RemoteException; -import android.os.IBinder; -import android.provider.Im; -import android.util.Log; -import android.util.AttributeSet; -import android.view.ContextMenu; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.LayoutInflater; -import android.view.ContextMenu.ContextMenuInfo; -import android.widget.AdapterView; -import android.widget.ListView; -import android.widget.CursorAdapter; - -import java.util.List; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; - -import com.android.providers.im.R; - -import dalvik.system.PathClassLoader; - -public class LandingPage extends ListActivity implements View.OnCreateContextMenuListener { - private static final String TAG = "IM"; - private final static boolean LOCAL_DEBUG = false; - - private static final int ID_SIGN_IN = Menu.FIRST + 1; - private static final int ID_SIGN_OUT = Menu.FIRST + 2; - private static final int ID_EDIT_ACCOUNT = Menu.FIRST + 3; - private static final int ID_REMOVE_ACCOUNT = Menu.FIRST + 4; - private static final int ID_SIGN_OUT_ALL = Menu.FIRST + 5; - private static final int ID_ADD_ACCOUNT = Menu.FIRST + 6; - private static final int ID_VIEW_CONTACT_LIST = Menu.FIRST + 7; - private static final int ID_SETTINGS = Menu.FIRST + 8; - - private ProviderAdapter mAdapter; - private Cursor mProviderCursor; - - private static final String[] PROVIDER_PROJECTION = { - Im.Provider._ID, - Im.Provider.NAME, - Im.Provider.FULLNAME, - Im.Provider.CATEGORY, - Im.Provider.ACTIVE_ACCOUNT_ID, - Im.Provider.ACTIVE_ACCOUNT_USERNAME, - Im.Provider.ACTIVE_ACCOUNT_PW, - Im.Provider.ACTIVE_ACCOUNT_LOCKED, - Im.Provider.ACCOUNT_PRESENCE_STATUS, - Im.Provider.ACCOUNT_CONNECTION_STATUS, - }; - - private static final int PROVIDER_ID_COLUMN = 0; - private static final int PROVIDER_NAME_COLUMN = 1; - private static final int PROVIDER_FULLNAME_COLUMN = 2; - private static final int PROVIDER_CATEGORY_COLUMN = 3; - private static final int ACTIVE_ACCOUNT_ID_COLUMN = 4; - private static final int ACTIVE_ACCOUNT_USERNAME_COLUMN = 5; - private static final int ACTIVE_ACCOUNT_PW_COLUMN = 6; - private static final int ACTIVE_ACCOUNT_LOCKED = 7; - private static final int ACCOUNT_PRESENCE_STATUS = 8; - private static final int ACCOUNT_CONNECTION_STATUS = 9; - - private static final String PROVIDER_SELECTION = "providers.name!=?"; - - private HashMap<String, PluginInfo> mProviderToPluginMap; - private HashMap<Long, PluginInfo> mAccountToPluginMap; - private HashMap<Long, BrandingResources> mBrandingResources; - private BrandingResources mDefaultBrandingResources; - - private String[] mProviderSelectionArgs = new String[1]; - - public class PluginInfo { - public IImPlugin mPlugin; - /** - * The name of the package that the plugin is in. - */ - public String mPackageName; - - /** - * The name of the class that implements {@link @ImFrontDoorPlugin} in this plugin. - */ - public String mClassName; - - /** - * The full path to the location of the package that the plugin is in. - */ - public String mSrcPath; - - public PluginInfo(IImPlugin plugin, String packageName, String className, - String srcPath) { - mPackageName = packageName; - mClassName = className; - mSrcPath = srcPath; - mPlugin = plugin; - } - }; - - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - - setTitle(R.string.landing_page_title); - - if (!loadPlugins()) { - Log.e(TAG, "[onCreate] load plugin failed, no plugin found!"); - finish(); - return; - } - - startPlugins(); - - // get everything except for Google Talk. - mProviderSelectionArgs[0] = Im.ProviderNames.GTALK; - mProviderCursor = managedQuery(Im.Provider.CONTENT_URI_WITH_ACCOUNT, - PROVIDER_PROJECTION, - PROVIDER_SELECTION /* selection */, - mProviderSelectionArgs /* selection args */, - Im.Provider.DEFAULT_SORT_ORDER); - mAdapter = new ProviderAdapter(this, mProviderCursor); - setListAdapter(mAdapter); - - rebuildAccountToPluginMap(); - - mBrandingResources = new HashMap<Long, BrandingResources>(); - loadDefaultBrandingRes(); - loadBrandingResources(); - - registerForContextMenu(getListView()); - } - - @Override - protected void onRestart() { - super.onRestart(); - - // refresh the accountToPlugin map after mProviderCursor is requeried - if (!rebuildAccountToPluginMap()) { - Log.w(TAG, "[onRestart] rebuiltAccountToPluginMap failed, reload plugins..."); - - if (!loadPlugins()) { - Log.e(TAG, "[onRestart] load plugin failed, no plugin found!"); - finish(); - return; - } - rebuildAccountToPluginMap(); - } - - startPlugins(); - } - - @Override - protected void onStop() { - super.onStop(); - stopPlugins(); - } - - private boolean loadPlugins() { - mProviderToPluginMap = new HashMap<String, PluginInfo>(); - - PackageManager pm = getPackageManager(); - List<ResolveInfo> plugins = pm.queryIntentServices( - new Intent(ImPluginConsts.PLUGIN_ACTION_NAME), - PackageManager.GET_META_DATA); - for (ResolveInfo info : plugins) { - if (Log.isLoggable(TAG, Log.DEBUG)) log("loadPlugins: found plugin " + info); - - ServiceInfo serviceInfo = info.serviceInfo; - if (serviceInfo == null) { - Log.e(TAG, "Ignore bad IM frontdoor plugin: " + info); - continue; - } - - IImPlugin plugin = null; - - // Load the plug-in directly from the apk instead of binding the service - // and calling through the IPC binder API. It's more effective in this way - // and we can avoid the async behaviors of binding service. - PathClassLoader classLoader = new PathClassLoader(serviceInfo.applicationInfo.sourceDir, - getClassLoader()); - try { - if (Log.isLoggable(TAG, Log.DEBUG)) { - log("loadPlugin: load class " + serviceInfo.name); - } - Class cls = classLoader.loadClass(serviceInfo.name); - Object newInstance = cls.newInstance(); - Method m; - - // call "attach" method, so the plugin will get initialized with the proper context - m = cls.getMethod("attach", Context.class, ActivityThread.class, String.class, - IBinder.class, Application.class, Object.class); - m.invoke(newInstance, - new Object[] {this, null, serviceInfo.name, null, getApplication(), - ActivityManagerNative.getDefault()}); - - // call "bind" to get the plugin object - m = cls.getMethod("onBind", Intent.class); - plugin = (IImPlugin)m.invoke(newInstance, new Object[]{null}); - } catch (ClassNotFoundException e) { - Log.e(TAG, "Failed load the plugin", e); - } catch (IllegalAccessException e) { - Log.e(TAG, "Failed load the plugin", e); - } catch (InstantiationException e) { - Log.e(TAG, "Failed load the plugin", e); - } catch (SecurityException e) { - Log.e(TAG, "Failed load the plugin", e); - } catch (NoSuchMethodException e) { - Log.e(TAG, "Failed load the plugin", e); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Failed load the plugin", e); - } catch (InvocationTargetException e) { - Log.e(TAG, "Failed load the plugin", e); - } - - if (plugin != null) { - if (Log.isLoggable(TAG, Log.DEBUG)) log("loadPlugin: plugin " + plugin + " loaded"); - ArrayList<String> providers = getSupportedProviders(plugin); - - if (providers == null || providers.size() == 0) { - Log.e(TAG, "Ignore bad IM frontdoor plugin: " + info + ". No providers found"); - continue; - } - - PluginInfo pluginInfo = new PluginInfo(plugin, - serviceInfo.packageName, - serviceInfo.name, - serviceInfo.applicationInfo.sourceDir); - - for (String providerName : providers) { - mProviderToPluginMap.put(providerName, pluginInfo); - } - } - } - - return mProviderToPluginMap.size() > 0; - } - - private void startPlugins() { - Iterator<PluginInfo> itor = mProviderToPluginMap.values().iterator(); - - while (itor.hasNext()) { - PluginInfo pluginInfo = itor.next(); - try { - pluginInfo.mPlugin.onStart(); - } catch (RemoteException e) { - Log.e(TAG, "Could not start plugin " + pluginInfo.mPackageName, e); - } - } - } - - private void stopPlugins() { - Iterator<PluginInfo> itor = mProviderToPluginMap.values().iterator(); - - while (itor.hasNext()) { - PluginInfo pluginInfo = itor.next(); - try { - pluginInfo.mPlugin.onStop(); - } catch (RemoteException e) { - Log.e(TAG, "Could not stop plugin " + pluginInfo.mPackageName, e); - } - } - } - - private ArrayList<String> getSupportedProviders(IImPlugin plugin) { - ArrayList<String> providers = null; - - try { - providers = (ArrayList<String>) plugin.getSupportedProviders(); - } catch (RemoteException ex) { - Log.e(TAG, "getSupportedProviders caught ", ex); - } - - return providers; - } - - private void loadDefaultBrandingRes() { - HashMap<Integer, Integer> resMapping = new HashMap<Integer, Integer>(); - - resMapping.put(BrandingResourceIDs.DRAWABLE_LOGO, R.drawable.imlogo_s); - resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_ONLINE, - android.R.drawable.presence_online); - resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_AWAY, - android.R.drawable.presence_away); - resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_BUSY, - android.R.drawable.presence_busy); - resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_INVISIBLE, - android.R.drawable.presence_invisible); - resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_OFFLINE, - android.R.drawable.presence_offline); - resMapping.put(BrandingResourceIDs.STRING_MENU_CONTACT_LIST, - R.string.menu_view_contact_list); - - mDefaultBrandingResources = new BrandingResources(this, resMapping, null /* default res */); - } - - private void loadBrandingResources() { - mProviderCursor.moveToFirst(); - do { - long providerId = mProviderCursor.getLong(PROVIDER_ID_COLUMN); - String providerName = mProviderCursor.getString(PROVIDER_NAME_COLUMN); - PluginInfo pluginInfo = mProviderToPluginMap.get(providerName); - - if (pluginInfo == null) { - Log.w(TAG, "[LandingPage] loadBrandingResources: no plugin found for " + providerName); - continue; - } - - if (!mBrandingResources.containsKey(providerId)) { - BrandingResources res = new BrandingResources(this, pluginInfo, providerName, - mDefaultBrandingResources); - mBrandingResources.put(providerId, res); - } - } while (mProviderCursor.moveToNext()) ; - } - - public BrandingResources getBrandingResource(long providerId) { - BrandingResources res = mBrandingResources.get(providerId); - return res == null ? mDefaultBrandingResources : res; - } - - private boolean rebuildAccountToPluginMap() { - if (Log.isLoggable(TAG, Log.DEBUG)) { - log("rebuildAccountToPluginMap"); - } - - if (mAccountToPluginMap != null) { - mAccountToPluginMap.clear(); - } - - mAccountToPluginMap = new HashMap<Long, PluginInfo>(); - - mProviderCursor.moveToFirst(); - - boolean retVal = true; - - do { - long accountId = mProviderCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN); - - if (accountId == 0) { - continue; - } - - String name = mProviderCursor.getString(PROVIDER_NAME_COLUMN); - PluginInfo pluginInfo = mProviderToPluginMap.get(name); - if (pluginInfo != null) { - if (Log.isLoggable(TAG, Log.DEBUG)) { - log("rebuildAccountToPluginMap: add plugin for acct=" + accountId + ", provider=" + name); - } - mAccountToPluginMap.put(accountId, pluginInfo); - } else { - Log.w(TAG, "[LandingPage] no plugin found for " + name); - retVal = false; - } - } while (mProviderCursor.moveToNext()) ; - - return retVal; - } - - private void signIn(long accountId) { - if (accountId == 0) { - Log.w(TAG, "signIn: account id is 0, bail"); - return; - } - - boolean isAccountEditible = mProviderCursor.getInt(ACTIVE_ACCOUNT_LOCKED) == 0; - if (isAccountEditible && mProviderCursor.isNull(ACTIVE_ACCOUNT_PW_COLUMN)) { - // no password, edit the account - if (Log.isLoggable(TAG, Log.DEBUG)) log("no pw for account " + accountId); - Intent intent = getEditAccountIntent(); - startActivity(intent); - return; - } - - - PluginInfo pluginInfo = mAccountToPluginMap.get(accountId); - if (pluginInfo == null) { - Log.e(TAG, "signIn: cannot find plugin for account " + accountId); - return; - } - - try { - if (Log.isLoggable(TAG, Log.DEBUG)) log("sign in for account " + accountId); - pluginInfo.mPlugin.signIn(accountId); - } catch (RemoteException ex) { - Log.e(TAG, "signIn failed", ex); - } - } - - boolean isSigningIn(Cursor cursor) { - int connectionStatus = cursor.getInt(ACCOUNT_CONNECTION_STATUS); - return connectionStatus == Im.ConnectionStatus.CONNECTING; - } - - boolean isSignedIn(Cursor cursor) { - int connectionStatus = cursor.getInt(ACCOUNT_CONNECTION_STATUS); - return connectionStatus == Im.ConnectionStatus.ONLINE; - } - - private boolean allAccountsSignedOut() { - mProviderCursor.moveToFirst(); - do { - if (isSignedIn(mProviderCursor)) { - return false; - } - } while (mProviderCursor.moveToNext()) ; - - return true; - } - - private void signoutAll() { - do { - long accountId = mProviderCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN); - signOut(accountId); - } while (mProviderCursor.moveToNext()) ; - } - - private void signOut(long accountId) { - if (accountId == 0) { - Log.w(TAG, "signOut: account id is 0, bail"); - return; - } - - PluginInfo pluginInfo = mAccountToPluginMap.get(accountId); - if (pluginInfo == null) { - Log.e(TAG, "signOut: cannot find plugin for account " + accountId); - return; - } - - try { - if (Log.isLoggable(TAG, Log.DEBUG)) log("sign out for account " + accountId); - pluginInfo.mPlugin.signOut(accountId); - } catch (RemoteException ex) { - Log.e(TAG, "signOut failed", ex); - } - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - menu.findItem(ID_SIGN_OUT_ALL).setVisible(!allAccountsSignedOut()); - return true; - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, ID_SIGN_OUT_ALL, 0, R.string.menu_sign_out_all) - .setIcon(android.R.drawable.ic_menu_close_clear_cancel); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case ID_SIGN_OUT_ALL: - signoutAll(); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { - AdapterView.AdapterContextMenuInfo info; - try { - info = (AdapterView.AdapterContextMenuInfo) menuInfo; - } catch (ClassCastException e) { - Log.e(TAG, "bad menuInfo", e); - return; - } - - Cursor providerCursor = (Cursor) getListAdapter().getItem(info.position); - menu.setHeaderTitle(providerCursor.getString(PROVIDER_FULLNAME_COLUMN)); - - if (providerCursor.isNull(ACTIVE_ACCOUNT_ID_COLUMN)) { - menu.add(0, ID_ADD_ACCOUNT, 0, R.string.menu_add_account); - return; - } - - long providerId = providerCursor.getLong(PROVIDER_ID_COLUMN); - boolean isLoggingIn = isSigningIn(providerCursor); - boolean isLoggedIn = isSignedIn(providerCursor); - - if (!isLoggedIn) { - menu.add(0, ID_SIGN_IN, 0, R.string.sign_in).setIcon(com.android.internal.R.drawable.ic_menu_login); - } else { - BrandingResources brandingRes = getBrandingResource(providerId); - menu.add(0, ID_VIEW_CONTACT_LIST, 0, - brandingRes.getString(BrandingResourceIDs.STRING_MENU_CONTACT_LIST)); - menu.add(0, ID_SIGN_OUT, 0, R.string.menu_sign_out) - .setIcon(android.R.drawable.ic_menu_close_clear_cancel); - } - - boolean isAccountEditible = providerCursor.getInt(ACTIVE_ACCOUNT_LOCKED) == 0; - if (isAccountEditible && !isLoggingIn && !isLoggedIn) { - menu.add(0, ID_EDIT_ACCOUNT, 0, R.string.menu_edit_account) - .setIcon(android.R.drawable.ic_menu_edit); - menu.add(0, ID_REMOVE_ACCOUNT, 0, R.string.menu_remove_account) - .setIcon(android.R.drawable.ic_menu_delete); - } - - // always add a settings menu item - menu.add(0, ID_SETTINGS, 0, R.string.menu_settings); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterView.AdapterContextMenuInfo info; - try { - info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); - } catch (ClassCastException e) { - Log.e(TAG, "bad menuInfo", e); - return false; - } - long providerId = info.id; - Cursor providerCursor = (Cursor) getListAdapter().getItem(info.position); - long accountId = providerCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN); - - switch (item.getItemId()) { - case ID_EDIT_ACCOUNT: - { - startActivity(getEditAccountIntent()); - return true; - } - - case ID_REMOVE_ACCOUNT: - { - Uri accountUri = ContentUris.withAppendedId(Im.Account.CONTENT_URI, accountId); - getContentResolver().delete(accountUri, null, null); - // Requery the cursor to force refreshing screen - providerCursor.requery(); - return true; - } - - case ID_VIEW_CONTACT_LIST: - { - Intent intent = getViewContactsIntent(); - startActivity(intent); - return true; - } - case ID_ADD_ACCOUNT: - { - startActivity(getCreateAccountIntent()); - return true; - } - - case ID_SIGN_IN: - { - signIn(accountId); - return true; - } - - case ID_SIGN_OUT: - { - // TODO: progress bar - signOut(accountId); - return true; - } - - case ID_SETTINGS: - { - Intent intent = new Intent(Intent.ACTION_VIEW, Im.ProviderSettings.CONTENT_URI); - intent.addCategory(getProviderCategory(providerCursor)); - intent.putExtra("providerId", providerId); - startActivity(intent); - return true; - } - - } - - return false; - } - - @Override - protected void onListItemClick(ListView l, View v, int position, long id) { - Intent intent = null; - mProviderCursor.moveToPosition(position); - - if (mProviderCursor.isNull(ACTIVE_ACCOUNT_ID_COLUMN)) { - // add account - intent = getCreateAccountIntent(); - } else { - int state = mProviderCursor.getInt(ACCOUNT_CONNECTION_STATUS); - - if (state == Im.ConnectionStatus.OFFLINE || state == Im.ConnectionStatus.CONNECTING) { - boolean isAccountEditible = mProviderCursor.getInt(ACTIVE_ACCOUNT_LOCKED) == 0; - if (isAccountEditible && mProviderCursor.isNull(ACTIVE_ACCOUNT_PW_COLUMN)) { - // no password, edit the account - intent = getEditAccountIntent(); - } else { - long accountId = mProviderCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN); - signIn(accountId); - } - } else { - intent = getViewContactsIntent(); - } - } - - if (intent != null) { - startActivity(intent); - } - } - - Intent getCreateAccountIntent() { - Intent intent = new Intent(); - intent.setAction(Intent.ACTION_INSERT); - - long providerId = mProviderCursor.getLong(PROVIDER_ID_COLUMN); - intent.setData(ContentUris.withAppendedId(Im.Provider.CONTENT_URI, providerId)); - intent.addCategory(getProviderCategory(mProviderCursor)); - return intent; - } - - Intent getEditAccountIntent() { - Intent intent = new Intent(Intent.ACTION_EDIT, - ContentUris.withAppendedId(Im.Account.CONTENT_URI, - mProviderCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN))); - intent.addCategory(getProviderCategory(mProviderCursor)); - return intent; - } - - Intent getViewContactsIntent() { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Im.Contacts.CONTENT_URI); - intent.addCategory(getProviderCategory(mProviderCursor)); - intent.putExtra("accountId", mProviderCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN)); - return intent; - } - - private String getProviderCategory(Cursor cursor) { - return cursor.getString(PROVIDER_CATEGORY_COLUMN); - } - - - static void log(String msg) { - Log.d(TAG, "[LandingPage]" + msg); - } - - private class ProviderListItemFactory implements LayoutInflater.Factory { - public View onCreateView(String name, Context context, AttributeSet attrs) { - if (name != null && name.equals(ProviderListItem.class.getName())) { - return new ProviderListItem(context, LandingPage.this); - } - return null; - } - } - - private final class ProviderAdapter extends CursorAdapter { - private LayoutInflater mInflater; - - public ProviderAdapter(Context context, Cursor c) { - super(context, c); - mInflater = LayoutInflater.from(context).cloneInContext(context); - mInflater.setFactory(new ProviderListItemFactory()); - } - - @Override - public View newView(Context context, Cursor cursor, ViewGroup parent) { - // create a custom view, so we can manage it ourselves. Mainly, we want to - // initialize the widget views (by calling getViewById()) in newView() instead of in - // bindView(), which can be called more often. - ProviderListItem view = (ProviderListItem) mInflater.inflate( - R.layout.account_view, parent, false); - view.init(cursor); - return view; - } - - @Override - public void bindView(View view, Context context, Cursor cursor) { - ((ProviderListItem) view).bindView(cursor); - } - } - -} diff --git a/src/com/android/providers/im/ProviderListItem.java b/src/com/android/providers/im/ProviderListItem.java deleted file mode 100644 index 9032e94..0000000 --- a/src/com/android/providers/im/ProviderListItem.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.providers.im; - -import android.graphics.drawable.Drawable; -import android.widget.LinearLayout; -import android.widget.ImageView; -import android.widget.TextView; -import android.content.Context; -import android.content.ContentResolver; -import android.content.res.Resources; -import android.database.Cursor; -import android.im.BrandingResourceIDs; -import android.provider.Im; -import android.content.res.ColorStateList; -import android.view.View; -import android.util.Log; -import com.android.providers.im.R; - -public class ProviderListItem extends LinearLayout { - private static final String TAG = "IM"; - private static final boolean LOCAL_DEBUG = false; - - private LandingPage mActivity; - private ImageView mProviderIcon; - private ImageView mStatusIcon; - private TextView mProviderName; - private TextView mLoginName; - private TextView mChatView; - private View mUnderBubble; - private Drawable mBubbleDrawable, mDefaultBackground; - - private int mProviderIdColumn; - private int mProviderFullnameColumn; - private int mActiveAccountIdColumn; - private int mActiveAccountUserNameColumn; - private int mAccountPresenceStatusColumn; - private int mAccountConnectionStatusColumn; - - private ColorStateList mProviderNameColors; - private ColorStateList mLoginNameColors; - private ColorStateList mChatViewColors; - - public ProviderListItem(Context context, LandingPage activity) { - super(context); - mActivity = activity; - } - - public void init(Cursor c) { - mProviderIcon = (ImageView) findViewById(R.id.providerIcon); - mStatusIcon = (ImageView) findViewById(R.id.statusIcon); - mProviderName = (TextView) findViewById(R.id.providerName); - mLoginName = (TextView) findViewById(R.id.loginName); - mChatView = (TextView) findViewById(R.id.conversations); - mUnderBubble = (View) findViewById(R.id.underBubble); - mBubbleDrawable = getResources().getDrawable(R.drawable.bubble); - mDefaultBackground = getResources().getDrawable(R.drawable.default_background); - - mProviderIdColumn = c.getColumnIndexOrThrow(Im.Provider._ID); - mProviderFullnameColumn = c.getColumnIndexOrThrow(Im.Provider.FULLNAME); - mActiveAccountIdColumn = c.getColumnIndexOrThrow( - Im.Provider.ACTIVE_ACCOUNT_ID); - mActiveAccountUserNameColumn = c.getColumnIndexOrThrow( - Im.Provider.ACTIVE_ACCOUNT_USERNAME); - mAccountPresenceStatusColumn = c.getColumnIndexOrThrow( - Im.Provider.ACCOUNT_PRESENCE_STATUS); - mAccountConnectionStatusColumn = c.getColumnIndexOrThrow( - Im.Provider.ACCOUNT_CONNECTION_STATUS); - - mProviderNameColors = mProviderName.getTextColors(); - mLoginNameColors = mLoginName.getTextColors(); - mChatViewColors = mChatView.getTextColors(); - } - - public void bindView(Cursor cursor) { - Resources r = getResources(); - ImageView providerIcon = mProviderIcon; - ImageView statusIcon = mStatusIcon; - TextView providerName = mProviderName; - TextView loginName = mLoginName; - TextView chatView = mChatView; - - int providerId = cursor.getInt(mProviderIdColumn); - String providerDisplayName = cursor.getString(mProviderFullnameColumn); - - BrandingResources brandingRes = mActivity.getBrandingResource(providerId); - providerIcon.setImageDrawable( - brandingRes.getDrawable(BrandingResourceIDs.DRAWABLE_LOGO)); - - mUnderBubble.setBackgroundDrawable(mDefaultBackground); - statusIcon.setVisibility(View.GONE); - - providerName.setTextColor(mProviderNameColors); - loginName.setTextColor(mLoginNameColors); - chatView.setTextColor(mChatViewColors); - - if (!cursor.isNull(mActiveAccountIdColumn)) { - mLoginName.setVisibility(View.VISIBLE); - providerName.setVisibility(View.VISIBLE); - providerName.setText(providerDisplayName); - - long accountId = cursor.getLong(mActiveAccountIdColumn); - int connectionStatus = cursor.getInt(mAccountConnectionStatusColumn); - - String secondRowText; - - chatView.setVisibility(View.GONE); - - switch (connectionStatus) { - case Im.ConnectionStatus.CONNECTING: - secondRowText = r.getString(R.string.signing_in_wait); - break; - - case Im.ConnectionStatus.ONLINE: - int presenceIconId = getPresenceIconId(cursor); - statusIcon.setImageDrawable( - brandingRes.getDrawable(presenceIconId)); - statusIcon.setVisibility(View.VISIBLE); - ContentResolver cr = mActivity.getContentResolver(); - - int count = getConversationCount(cr, accountId); - if (count > 0) { - mUnderBubble.setBackgroundDrawable(mBubbleDrawable); - chatView.setVisibility(View.VISIBLE); - chatView.setText(r.getString(R.string.conversations, count)); - - providerName.setTextColor(0xff000000); - loginName.setTextColor(0xff000000); - chatView.setTextColor(0xff000000); - } else { - chatView.setVisibility(View.GONE); - } - - secondRowText = cursor.getString(mActiveAccountUserNameColumn); - break; - - default: - secondRowText = cursor.getString(mActiveAccountUserNameColumn); - break; - } - - loginName.setText(secondRowText); - - } else { - // No active account, show add account - mLoginName.setVisibility(View.GONE); - - mProviderName.setText(providerDisplayName); - } - } - - private int getConversationCount(ContentResolver cr, long accountId) { - // TODO: this is code used to get Google Talk's chat count. Not sure if this will work - // for IMPS chat count. - StringBuilder where = new StringBuilder(); - where.append(Im.Chats.CONTACT_ID); - where.append(" in (select _id from contacts where "); - where.append(Im.Contacts.ACCOUNT); - where.append("="); - where.append(accountId); - where.append(")"); - - Cursor cursor = cr.query(Im.Chats.CONTENT_URI, null, where.toString(), null, null); - - try { - return cursor.getCount(); - } finally { - cursor.close(); - } - } - - private int getPresenceIconId(Cursor cursor) { - int presenceStatus = cursor.getInt(mAccountPresenceStatusColumn); - - if (LOCAL_DEBUG) log("getPresenceIconId: presenceStatus=" + presenceStatus); - - switch (presenceStatus) { - case Im.Presence.AVAILABLE: - return BrandingResourceIDs.DRAWABLE_PRESENCE_ONLINE; - - case Im.Presence.IDLE: - case Im.Presence.AWAY: - return BrandingResourceIDs.DRAWABLE_PRESENCE_AWAY; - - case Im.Presence.DO_NOT_DISTURB: - return BrandingResourceIDs.DRAWABLE_PRESENCE_BUSY; - - case Im.Presence.INVISIBLE: - return BrandingResourceIDs.DRAWABLE_PRESENCE_INVISIBLE; - - default: - return BrandingResourceIDs.DRAWABLE_PRESENCE_OFFLINE; - } - } - - private void log(String msg) { - Log.d(TAG, msg); - } -} diff --git a/tests/Android.mk b/tests/Android.mk deleted file mode 100644 index e9e3a87..0000000 --- a/tests/Android.mk +++ /dev/null @@ -1,10 +0,0 @@ -LOCAL_PATH:= $(call my-dir) - -######################## - -include $(CLEAR_VARS) - -# no tests to build for now - -# additionally, build sub-tests in a separate .apk -include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file diff --git a/tests/permission/Android.mk b/tests/permission/Android.mk deleted file mode 100644 index 554ad62..0000000 --- a/tests/permission/Android.mk +++ /dev/null @@ -1,14 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -# We only want this apk build for tests. -LOCAL_MODULE_TAGS := tests - -# Include all test java files. -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_JAVA_LIBRARIES := android.test.runner -LOCAL_PACKAGE_NAME := ImProviderPermissionTests - -include $(BUILD_PACKAGE) - diff --git a/tests/permission/AndroidManifest.xml b/tests/permission/AndroidManifest.xml deleted file mode 100644 index fe83af1..0000000 --- a/tests/permission/AndroidManifest.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - * Copyright (C) 2009 Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - --> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.providers.im.permission.tests"> - - <application> - <uses-library android:name="android.test.runner" /> - </application> - - <!-- - The tests in this package are intended to verify that protected APIs or data - cannot be accessed without the necessary permissions. Thus this manifest should not - include any uses-permissions tags - --> - - <!-- - The test declared in this instrumentation can be run via this command - "adb shell am instrument -w com.android.providers.im.permission.tests/android.test.InstrumentationTestRunner" - --> - <instrumentation android:name="android.test.InstrumentationTestRunner" - android:targetPackage="com.android.providers.im.permission.tests" - android:label="Tests for IM provider permissions"/> - -</manifest> diff --git a/tests/permission/src/com/android/providers/im/permission/tests/ImProviderPermissionsTest.java b/tests/permission/src/com/android/providers/im/permission/tests/ImProviderPermissionsTest.java deleted file mode 100644 index 0f2f0ae..0000000 --- a/tests/permission/src/com/android/providers/im/permission/tests/ImProviderPermissionsTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.providers.im.permission.tests; - -import java.io.IOException; - -import android.net.Uri; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; - -/** - * Verify that protected Im provider actions require specific permissions. - */ -public class ImProviderPermissionsTest extends AndroidTestCase { - - private static final String CONTENT_IM = "content://im"; - - /** - * Test that an untrusted app cannot read from the im provider - * <p>Tests Permission: - * {@link com.android.providers.im.Manifest.permission#READ_ONLY} - */ - @MediumTest - public void testReadImProvider() throws Exception { - assertReadingContentUriRequiresPermission(Uri.parse(CONTENT_IM), - "com.android.providers.im.permission.READ_ONLY"); - } - - /** - * Test that an untrusted app cannot write to the download provider - * <p>Tests Permission: - * {@link com.android.providers.downloads.Manifest.permission#ACCESS_DOWNLOAD_MANAGER} - */ - @MediumTest - public void testWriteImProvider() throws IOException { - assertWritingContentUriRequiresPermission(Uri.parse(CONTENT_IM), - "com.android.providers.im.permission.WRITE_ONLY"); - } -} |