am c8c2ad85: (-s ours) am bdd65f5e: (-s ours) am 38ae6989: am ce2b95ae: Fix AudioEngine to allow re-initialization - DO NOT MERGE
* commit 'c8c2ad85474da63f5d70669b223f7a69f204956d':
diff --git a/camera2/public/src/com/android/ex/camera2/blocking/BlockingStateListener.java b/camera2/public/src/com/android/ex/camera2/blocking/BlockingStateListener.java
index 619ba0a..1f173eb 100644
--- a/camera2/public/src/com/android/ex/camera2/blocking/BlockingStateListener.java
+++ b/camera2/public/src/com/android/ex/camera2/blocking/BlockingStateListener.java
@@ -133,50 +133,50 @@
@Override
public void onOpened(CameraDevice camera) {
- setCurrentState(STATE_OPENED);
if (mProxy != null) mProxy.onOpened(camera);
+ setCurrentState(STATE_OPENED);
}
@Override
public void onDisconnected(CameraDevice camera) {
- setCurrentState(STATE_DISCONNECTED);
if (mProxy != null) mProxy.onDisconnected(camera);
+ setCurrentState(STATE_DISCONNECTED);
}
@Override
public void onError(CameraDevice camera, int error) {
- setCurrentState(STATE_ERROR);
if (mProxy != null) mProxy.onError(camera, error);
+ setCurrentState(STATE_ERROR);
}
@Override
public void onUnconfigured(CameraDevice camera) {
- setCurrentState(STATE_UNCONFIGURED);
if (mProxy != null) mProxy.onUnconfigured(camera);
+ setCurrentState(STATE_UNCONFIGURED);
}
@Override
public void onIdle(CameraDevice camera) {
- setCurrentState(STATE_IDLE);
if (mProxy != null) mProxy.onIdle(camera);
+ setCurrentState(STATE_IDLE);
}
@Override
public void onActive(CameraDevice camera) {
- setCurrentState(STATE_ACTIVE);
if (mProxy != null) mProxy.onActive(camera);
+ setCurrentState(STATE_ACTIVE);
}
@Override
public void onBusy(CameraDevice camera) {
- setCurrentState(STATE_BUSY);
if (mProxy != null) mProxy.onBusy(camera);
+ setCurrentState(STATE_BUSY);
}
@Override
public void onClosed(CameraDevice camera) {
- setCurrentState(STATE_CLOSED);
if (mProxy != null) mProxy.onClosed(camera);
+ setCurrentState(STATE_CLOSED);
}
/**
diff --git a/carousel/test/res/values-am/strings.xml b/carousel/test/res/values-am/strings.xml
index 5f4b961..f1e8da2 100644
--- a/carousel/test/res/values-am/strings.xml
+++ b/carousel/test/res/values-am/strings.xml
@@ -21,7 +21,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="music_demo_activity_label" msgid="4382090808250495841">"የሙዚቃ Carousel"</string>
<string name="carousel_test_activity_label" msgid="6014624482213318747">"የCarousel ፍተሻ"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"የCarouselን ጥቅም የሚያሳይ ትግበራ"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"የCarouselን ጥቅም የሚያሳይ መተግበሪያ"</string>
<string name="task_switcher_activity_label" msgid="714620143340933546">"ክንውን ቀያያሪ"</string>
<string name="recent_tasks_title" msgid="1030287226205477117">"የቅርብ ጊዜ ትግበራዎች"</string>
<string name="no_recent_tasks" msgid="6884096266670555780">"ምንም የቅርብ ጊዜ ክንውን የለም"</string>
diff --git a/carousel/test/res/values-be/strings.xml b/carousel/test/res/values-az-rAZ/strings.xml
similarity index 85%
copy from carousel/test/res/values-be/strings.xml
copy to carousel/test/res/values-az-rAZ/strings.xml
index 631a815..634f926 100644
--- a/carousel/test/res/values-be/strings.xml
+++ b/carousel/test/res/values-az-rAZ/strings.xml
@@ -21,8 +21,8 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
<string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Прыкладанне, якое адлюстроўвае выкарыстанне Carousel"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"Carousel istifadəsini göstərmək üçün tətbiq"</string>
<string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Апошнія прыкладанні"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма апошніх задач"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"Son Tətbiqlər"</string>
+ <string name="no_recent_tasks" msgid="6884096266670555780">"Son tapşırıqlar yoxdur"</string>
</resources>
diff --git a/carousel/test/res/values-be/strings.xml b/carousel/test/res/values-az/strings.xml
similarity index 85%
copy from carousel/test/res/values-be/strings.xml
copy to carousel/test/res/values-az/strings.xml
index 631a815..634f926 100644
--- a/carousel/test/res/values-be/strings.xml
+++ b/carousel/test/res/values-az/strings.xml
@@ -21,8 +21,8 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
<string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Прыкладанне, якое адлюстроўвае выкарыстанне Carousel"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"Carousel istifadəsini göstərmək üçün tətbiq"</string>
<string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Апошнія прыкладанні"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма апошніх задач"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"Son Tətbiqlər"</string>
+ <string name="no_recent_tasks" msgid="6884096266670555780">"Son tapşırıqlar yoxdur"</string>
</resources>
diff --git a/carousel/test/res/values-ca/strings.xml b/carousel/test/res/values-ca/strings.xml
index 15d758c..9f85f5e 100644
--- a/carousel/test/res/values-ca/strings.xml
+++ b/carousel/test/res/values-ca/strings.xml
@@ -21,7 +21,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
<string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Una aplicació per mostrar l\'ús de Carousel"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"Una aplicació per mostrar com es fa servir l\'expositor giratori"</string>
<string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
<string name="recent_tasks_title" msgid="1030287226205477117">"Aplicacions usades recentment"</string>
<string name="no_recent_tasks" msgid="6884096266670555780">"No hi ha tasques recents"</string>
diff --git a/carousel/test/res/values-be/strings.xml b/carousel/test/res/values-en-rIN/strings.xml
similarity index 78%
copy from carousel/test/res/values-be/strings.xml
copy to carousel/test/res/values-en-rIN/strings.xml
index 631a815..86ea2cb 100644
--- a/carousel/test/res/values-be/strings.xml
+++ b/carousel/test/res/values-en-rIN/strings.xml
@@ -19,10 +19,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Прыкладанне, якое адлюстроўвае выкарыстанне Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Апошнія прыкладанні"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма апошніх задач"</string>
+ <string name="music_demo_activity_label" msgid="4382090808250495841">"Music Carousel"</string>
+ <string name="carousel_test_activity_label" msgid="6014624482213318747">"Carousel Test"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"An application to show the use of Carousel"</string>
+ <string name="task_switcher_activity_label" msgid="714620143340933546">"Task Switcher"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"Recent Applications"</string>
+ <string name="no_recent_tasks" msgid="6884096266670555780">"No recent tasks"</string>
</resources>
diff --git a/carousel/test/res/values-et/strings.xml b/carousel/test/res/values-et-rEE/strings.xml
similarity index 100%
rename from carousel/test/res/values-et/strings.xml
rename to carousel/test/res/values-et-rEE/strings.xml
diff --git a/carousel/test/res/values-be/strings.xml b/carousel/test/res/values-fr-rCA/strings.xml
similarity index 85%
rename from carousel/test/res/values-be/strings.xml
rename to carousel/test/res/values-fr-rCA/strings.xml
index 631a815..87aeb34 100644
--- a/carousel/test/res/values-be/strings.xml
+++ b/carousel/test/res/values-fr-rCA/strings.xml
@@ -21,8 +21,8 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
<string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Прыкладанне, якое адлюстроўвае выкарыстанне Carousel"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"Une application expliquant l\'utilisation de Carousel"</string>
<string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Апошнія прыкладанні"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма апошніх задач"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"Applications récentes"</string>
+ <string name="no_recent_tasks" msgid="6884096266670555780">"Aucune tâche récente"</string>
</resources>
diff --git a/carousel/test/res/values-be/strings.xml b/carousel/test/res/values-hy-rAM/strings.xml
similarity index 84%
copy from carousel/test/res/values-be/strings.xml
copy to carousel/test/res/values-hy-rAM/strings.xml
index 631a815..39bf205 100644
--- a/carousel/test/res/values-be/strings.xml
+++ b/carousel/test/res/values-hy-rAM/strings.xml
@@ -21,8 +21,8 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
<string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Прыкладанне, якое адлюстроўвае выкарыстанне Carousel"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"Հավելված` Carousel-ի օգտագործումը ցույց տալու համար"</string>
<string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Апошнія прыкладанні"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма апошніх задач"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"Վերջին հավելվածները"</string>
+ <string name="no_recent_tasks" msgid="6884096266670555780">"Վերջին առաջադրանքներ չկան"</string>
</resources>
diff --git a/carousel/test/res/values-iw/strings.xml b/carousel/test/res/values-iw/strings.xml
index 53fa5d2..a4163c5 100644
--- a/carousel/test/res/values-iw/strings.xml
+++ b/carousel/test/res/values-iw/strings.xml
@@ -21,8 +21,8 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
<string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"יישום להצגת השימוש בקרוסלה"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"אפליקציה להצגת השימוש בקרוסלה"</string>
<string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"יישומים אחרונים"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"אפליקציות אחרונות"</string>
<string name="no_recent_tasks" msgid="6884096266670555780">"אין משימות אחרונות"</string>
</resources>
diff --git a/carousel/test/res/values-be/strings.xml b/carousel/test/res/values-ka-rGE/strings.xml
similarity index 79%
copy from carousel/test/res/values-be/strings.xml
copy to carousel/test/res/values-ka-rGE/strings.xml
index 631a815..0764f3f 100644
--- a/carousel/test/res/values-be/strings.xml
+++ b/carousel/test/res/values-ka-rGE/strings.xml
@@ -21,8 +21,8 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
<string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Прыкладанне, якое адлюстроўвае выкарыстанне Carousel"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"Carousel-ის გამოყენების მაჩვენებელი აპლიკაცია"</string>
<string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Апошнія прыкладанні"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма апошніх задач"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"ბოლოდროინდელი აპლიკაციები"</string>
+ <string name="no_recent_tasks" msgid="6884096266670555780">"ბოლოდროინდელი ამოცანები არ არის."</string>
</resources>
diff --git a/carousel/test/res/values-be/strings.xml b/carousel/test/res/values-km-rKH/strings.xml
similarity index 83%
copy from carousel/test/res/values-be/strings.xml
copy to carousel/test/res/values-km-rKH/strings.xml
index 631a815..5bb198d 100644
--- a/carousel/test/res/values-be/strings.xml
+++ b/carousel/test/res/values-km-rKH/strings.xml
@@ -21,8 +21,8 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
<string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Прыкладанне, якое адлюстроўвае выкарыстанне Carousel"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"កម្មវិធីត្រូវបង្ហាញការប្រើ Carousel"</string>
<string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Апошнія прыкладанні"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма апошніх задач"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"កម្មវិធីថ្មីៗ"</string>
+ <string name="no_recent_tasks" msgid="6884096266670555780">"គ្មានភារកិច្ចថ្មីៗ"</string>
</resources>
diff --git a/carousel/test/res/values-be/strings.xml b/carousel/test/res/values-lo-rLA/strings.xml
similarity index 80%
copy from carousel/test/res/values-be/strings.xml
copy to carousel/test/res/values-lo-rLA/strings.xml
index 631a815..83a4cbd 100644
--- a/carousel/test/res/values-be/strings.xml
+++ b/carousel/test/res/values-lo-rLA/strings.xml
@@ -21,8 +21,8 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
<string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Прыкладанне, якое адлюстроўвае выкарыстанне Carousel"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"ແອັບພລິເຄຊັນທີ່ໃຊ້ສະແດງປະໂຫຍດຂອງ Carousel"</string>
<string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Апошнія прыкладанні"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма апошніх задач"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"ແອັບຯພລິເຄຊັນທີ່ຫາກໍໃຊ້"</string>
+ <string name="no_recent_tasks" msgid="6884096266670555780">"ບໍ່ມີວຽກເມື່ອໄວໆນີ້ເທື່ອ"</string>
</resources>
diff --git a/carousel/test/res/values-be/strings.xml b/carousel/test/res/values-mn-rMN/strings.xml
similarity index 76%
copy from carousel/test/res/values-be/strings.xml
copy to carousel/test/res/values-mn-rMN/strings.xml
index 631a815..20d9f8d 100644
--- a/carousel/test/res/values-be/strings.xml
+++ b/carousel/test/res/values-mn-rMN/strings.xml
@@ -19,10 +19,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Прыкладанне, якое адлюстроўвае выкарыстанне Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Апошнія прыкладанні"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма апошніх задач"</string>
+ <string name="music_demo_activity_label" msgid="4382090808250495841">"Хөгжмийн тойруулга"</string>
+ <string name="carousel_test_activity_label" msgid="6014624482213318747">"Тойруулга тест"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"Тойруулга ашиглалтыг харуулах аппликешн"</string>
+ <string name="task_switcher_activity_label" msgid="714620143340933546">"Даалгавар солигч"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"Сүүлийн аппликешн"</string>
+ <string name="no_recent_tasks" msgid="6884096266670555780">"Сүүлийн даалгавар хоосон"</string>
</resources>
diff --git a/carousel/test/res/values-ms/strings.xml b/carousel/test/res/values-ms-rMY/strings.xml
similarity index 100%
rename from carousel/test/res/values-ms/strings.xml
rename to carousel/test/res/values-ms-rMY/strings.xml
diff --git a/carousel/test/res/values-nb/strings.xml b/carousel/test/res/values-nb/strings.xml
index 8cddca0..751baf9 100644
--- a/carousel/test/res/values-nb/strings.xml
+++ b/carousel/test/res/values-nb/strings.xml
@@ -21,8 +21,8 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
<string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"En applikasjon som viser bruken av Carousel"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"En app som viser bruken av Carousel"</string>
<string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Nylige applikasjoner"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"Nylige apper"</string>
<string name="no_recent_tasks" msgid="6884096266670555780">"Ingen nylige oppgaver"</string>
</resources>
diff --git a/carousel/test/res/values-be/strings.xml b/carousel/test/res/values-ne-rNP/strings.xml
similarity index 70%
copy from carousel/test/res/values-be/strings.xml
copy to carousel/test/res/values-ne-rNP/strings.xml
index 631a815..838502f 100644
--- a/carousel/test/res/values-be/strings.xml
+++ b/carousel/test/res/values-ne-rNP/strings.xml
@@ -19,10 +19,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Прыкладанне, якое адлюстроўвае выкарыстанне Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Апошнія прыкладанні"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма апошніх задач"</string>
+ <string name="music_demo_activity_label" msgid="4382090808250495841">"संगीत करउसेल"</string>
+ <string name="carousel_test_activity_label" msgid="6014624482213318747">"करउसेल परीक्षण"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"कारउसेलको प्रयोग देखाउन एउटा अनुप्रयोग"</string>
+ <string name="task_switcher_activity_label" msgid="714620143340933546">"कार्य स्विच गर्ने"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"भर्खरैका अनुप्रयोगहरू"</string>
+ <string name="no_recent_tasks" msgid="6884096266670555780">"कुनै भरखरका कार्यहरू छैनन्।"</string>
</resources>
diff --git a/carousel/test/res/values-be/strings.xml b/carousel/test/res/values-ne/strings.xml
similarity index 70%
copy from carousel/test/res/values-be/strings.xml
copy to carousel/test/res/values-ne/strings.xml
index 631a815..838502f 100644
--- a/carousel/test/res/values-be/strings.xml
+++ b/carousel/test/res/values-ne/strings.xml
@@ -19,10 +19,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Прыкладанне, якое адлюстроўвае выкарыстанне Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Апошнія прыкладанні"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма апошніх задач"</string>
+ <string name="music_demo_activity_label" msgid="4382090808250495841">"संगीत करउसेल"</string>
+ <string name="carousel_test_activity_label" msgid="6014624482213318747">"करउसेल परीक्षण"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"कारउसेलको प्रयोग देखाउन एउटा अनुप्रयोग"</string>
+ <string name="task_switcher_activity_label" msgid="714620143340933546">"कार्य स्विच गर्ने"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"भर्खरैका अनुप्रयोगहरू"</string>
+ <string name="no_recent_tasks" msgid="6884096266670555780">"कुनै भरखरका कार्यहरू छैनन्।"</string>
</resources>
diff --git a/carousel/test/res/values-be/strings.xml b/carousel/test/res/values-si-rLK/strings.xml
similarity index 75%
copy from carousel/test/res/values-be/strings.xml
copy to carousel/test/res/values-si-rLK/strings.xml
index 631a815..5a1aa48 100644
--- a/carousel/test/res/values-be/strings.xml
+++ b/carousel/test/res/values-si-rLK/strings.xml
@@ -19,10 +19,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Прыкладанне, якое адлюстроўвае выкарыстанне Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Апошнія прыкладанні"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма апошніх задач"</string>
+ <string name="music_demo_activity_label" msgid="4382090808250495841">"සංගීත Carousel"</string>
+ <string name="carousel_test_activity_label" msgid="6014624482213318747">"Carousel පරීක්ෂණය"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"Carousel භාවිතය පෙන්වීමට යෙදුමකි"</string>
+ <string name="task_switcher_activity_label" msgid="714620143340933546">"කාර්ය ස්විචය"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"මෑත කාලීන යෙදුම්"</string>
+ <string name="no_recent_tasks" msgid="6884096266670555780">"මෑත කාර්යයන් නැත"</string>
</resources>
diff --git a/carousel/test/res/values-be/strings.xml b/carousel/test/res/values-si/strings.xml
similarity index 75%
copy from carousel/test/res/values-be/strings.xml
copy to carousel/test/res/values-si/strings.xml
index 631a815..5a1aa48 100644
--- a/carousel/test/res/values-be/strings.xml
+++ b/carousel/test/res/values-si/strings.xml
@@ -19,10 +19,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Прыкладанне, якое адлюстроўвае выкарыстанне Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Апошнія прыкладанні"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма апошніх задач"</string>
+ <string name="music_demo_activity_label" msgid="4382090808250495841">"සංගීත Carousel"</string>
+ <string name="carousel_test_activity_label" msgid="6014624482213318747">"Carousel පරීක්ෂණය"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"Carousel භාවිතය පෙන්වීමට යෙදුමකි"</string>
+ <string name="task_switcher_activity_label" msgid="714620143340933546">"කාර්ය ස්විචය"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"මෑත කාලීන යෙදුම්"</string>
+ <string name="no_recent_tasks" msgid="6884096266670555780">"මෑත කාර්යයන් නැත"</string>
</resources>
diff --git a/carousel/test/res/values-be/strings.xml b/carousel/test/res/values-zh-rHK/strings.xml
similarity index 85%
copy from carousel/test/res/values-be/strings.xml
copy to carousel/test/res/values-zh-rHK/strings.xml
index 631a815..193cb4a 100644
--- a/carousel/test/res/values-be/strings.xml
+++ b/carousel/test/res/values-zh-rHK/strings.xml
@@ -21,8 +21,8 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
<string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Прыкладанне, якое адлюстроўвае выкарыстанне Carousel"</string>
+ <string name="carousel_test_activity_description" msgid="1632693812604375483">"展示輪轉使用方法的應用程式"</string>
<string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Апошнія прыкладанні"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма апошніх задач"</string>
+ <string name="recent_tasks_title" msgid="1030287226205477117">"最近使用的應用程式"</string>
+ <string name="no_recent_tasks" msgid="6884096266670555780">"最近沒有任務"</string>
</resources>
diff --git a/chips/Android.mk b/chips/Android.mk
deleted file mode 100644
index 2bca597..0000000
--- a/chips/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2011 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android-common-chips
-LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4
-LOCAL_SDK_VERSION := 19
-LOCAL_SRC_FILES := \
- $(call all-java-files-under, src) \
- $(call all-logtags-files-under, src)
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-##################################################
-# Build all sub-directories
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/chips/AndroidManifest.xml b/chips/AndroidManifest.xml
deleted file mode 100644
index 02ea564..0000000
--- a/chips/AndroidManifest.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.ex.chips"
- android:versionCode="1">
-
- <uses-sdk
- android:minSdkVersion="11"
- android:targetSdkVersion="19" />
-
-</manifest>
\ No newline at end of file
diff --git a/chips/project.properties b/chips/project.properties
deleted file mode 100644
index 91d2b02..0000000
--- a/chips/project.properties
+++ /dev/null
@@ -1,15 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-19
-android.library=true
diff --git a/chips/res/drawable-hdpi/chip_background.9.png b/chips/res/drawable-hdpi/chip_background.9.png
deleted file mode 100644
index 3988da5..0000000
--- a/chips/res/drawable-hdpi/chip_background.9.png
+++ /dev/null
Binary files differ
diff --git a/chips/res/drawable-hdpi/chip_background_invalid.9.png b/chips/res/drawable-hdpi/chip_background_invalid.9.png
deleted file mode 100644
index 01a3d95..0000000
--- a/chips/res/drawable-hdpi/chip_background_invalid.9.png
+++ /dev/null
Binary files differ
diff --git a/chips/res/drawable-hdpi/chip_background_selected.9.png b/chips/res/drawable-hdpi/chip_background_selected.9.png
deleted file mode 100644
index e05657f..0000000
--- a/chips/res/drawable-hdpi/chip_background_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/chips/res/drawable-hdpi/chip_delete.png b/chips/res/drawable-hdpi/chip_delete.png
deleted file mode 100644
index 75cde4a..0000000
--- a/chips/res/drawable-hdpi/chip_delete.png
+++ /dev/null
Binary files differ
diff --git a/chips/res/drawable-hdpi/ic_contact_picture.png b/chips/res/drawable-hdpi/ic_contact_picture.png
deleted file mode 100644
index 4c0e35e..0000000
--- a/chips/res/drawable-hdpi/ic_contact_picture.png
+++ /dev/null
Binary files differ
diff --git a/chips/res/drawable-mdpi/chip_background.9.png b/chips/res/drawable-mdpi/chip_background.9.png
deleted file mode 100644
index 99fd037..0000000
--- a/chips/res/drawable-mdpi/chip_background.9.png
+++ /dev/null
Binary files differ
diff --git a/chips/res/drawable-mdpi/chip_background_invalid.9.png b/chips/res/drawable-mdpi/chip_background_invalid.9.png
deleted file mode 100644
index f90bec5..0000000
--- a/chips/res/drawable-mdpi/chip_background_invalid.9.png
+++ /dev/null
Binary files differ
diff --git a/chips/res/drawable-mdpi/chip_background_selected.9.png b/chips/res/drawable-mdpi/chip_background_selected.9.png
deleted file mode 100644
index 308fa03..0000000
--- a/chips/res/drawable-mdpi/chip_background_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/chips/res/drawable-mdpi/chip_delete.png b/chips/res/drawable-mdpi/chip_delete.png
deleted file mode 100644
index 75cde4a..0000000
--- a/chips/res/drawable-mdpi/chip_delete.png
+++ /dev/null
Binary files differ
diff --git a/chips/res/drawable-mdpi/ic_contact_picture.png b/chips/res/drawable-mdpi/ic_contact_picture.png
deleted file mode 100644
index ead9718..0000000
--- a/chips/res/drawable-mdpi/ic_contact_picture.png
+++ /dev/null
Binary files differ
diff --git a/chips/res/drawable-xhdpi/chip_background.9.png b/chips/res/drawable-xhdpi/chip_background.9.png
deleted file mode 100644
index 72b0f22..0000000
--- a/chips/res/drawable-xhdpi/chip_background.9.png
+++ /dev/null
Binary files differ
diff --git a/chips/res/drawable-xhdpi/chip_background_invalid.9.png b/chips/res/drawable-xhdpi/chip_background_invalid.9.png
deleted file mode 100644
index a9195ea..0000000
--- a/chips/res/drawable-xhdpi/chip_background_invalid.9.png
+++ /dev/null
Binary files differ
diff --git a/chips/res/drawable-xhdpi/chip_background_selected.9.png b/chips/res/drawable-xhdpi/chip_background_selected.9.png
deleted file mode 100644
index abed86a..0000000
--- a/chips/res/drawable-xhdpi/chip_background_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/chips/res/drawable-xhdpi/ic_contact_picture.png b/chips/res/drawable-xhdpi/ic_contact_picture.png
deleted file mode 100644
index 05a65f6..0000000
--- a/chips/res/drawable-xhdpi/ic_contact_picture.png
+++ /dev/null
Binary files differ
diff --git a/chips/res/drawable/list_item_font_primary.xml b/chips/res/drawable/list_item_font_primary.xml
deleted file mode 100644
index 4351905..0000000
--- a/chips/res/drawable/list_item_font_primary.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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_activated="true" android:color="@android:color/white" />
- <item android:state_checked="true" android:color="@android:color/white" />
- <item android:state_selected="true" android:color="@android:color/white" />
- <item android:color="#333333"/>
- </selector>
\ No newline at end of file
diff --git a/chips/res/drawable/list_item_font_secondary.xml b/chips/res/drawable/list_item_font_secondary.xml
deleted file mode 100644
index 78c4066..0000000
--- a/chips/res/drawable/list_item_font_secondary.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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_activated="true" android:color="@android:color/white" />
- <item android:state_checked="true" android:color="@android:color/white" />
- <item android:state_selected="true" android:color="@android:color/white" />
- <item android:color="#777777"/>
- </selector>
\ No newline at end of file
diff --git a/chips/res/layout/chips_alternate_item.xml b/chips/res/layout/chips_alternate_item.xml
deleted file mode 100644
index 9bc7b6d..0000000
--- a/chips/res/layout/chips_alternate_item.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <include layout="@layout/chips_recipient_dropdown_item"/>
-
-</FrameLayout>
diff --git a/chips/res/layout/chips_recipient_dropdown_item.xml b/chips/res/layout/chips_recipient_dropdown_item.xml
deleted file mode 100644
index b02b197..0000000
--- a/chips/res/layout/chips_recipient_dropdown_item.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="48dip"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- android:background="?android:attr/activatedBackgroundIndicator">
- <LinearLayout
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:orientation="vertical"
- android:layout_weight="1">
- <TextView android:id="@android:id/title"
- android:textColor="@drawable/list_item_font_primary"
- android:textSize="18sp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:ellipsize="end"
- style="@style/ChipTitleStyle" />
- <TextView android:id="@android:id/text1"
- android:textColor="@drawable/list_item_font_secondary"
- android:textSize="14sp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:ellipsize="end"
- android:layout_marginTop="-4dip"
- style="@style/ChipSubtitleStyle" />
- </LinearLayout>
- <ImageView
- android:id="@android:id/icon"
- android:layout_width="48dip"
- android:layout_height="48dip"
- android:src="@drawable/ic_contact_picture"
- android:cropToPadding="true"
- android:scaleType="centerCrop"
- style="@style/ChipIconStyle" />
-</LinearLayout>
diff --git a/chips/res/layout/copy_chip_dialog_layout.xml b/chips/res/layout/copy_chip_dialog_layout.xml
deleted file mode 100644
index f131626..0000000
--- a/chips/res/layout/copy_chip_dialog_layout.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<Button xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/copy_email"
- android:id="@+android:id/button1"
- android:background="@null"
- android:layout_gravity="left"/>
diff --git a/chips/res/layout/more_item.xml b/chips/res/layout/more_item.xml
deleted file mode 100644
index 20693d6..0000000
--- a/chips/res/layout/more_item.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/text1"
- android:textColor="#aaaaaa"
- android:textSize="18sp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/more_string"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
- />
\ No newline at end of file
diff --git a/chips/res/values-af/strings.xml b/chips/res/values-af/strings.xml
deleted file mode 100644
index 3ccbcba..0000000
--- a/chips/res/values-af/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopieer e-posadres"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopieer foonnommer"</string>
- <string name="done" msgid="2356320650733788862">"Terugkeer"</string>
-</resources>
diff --git a/chips/res/values-am/strings.xml b/chips/res/values-am/strings.xml
deleted file mode 100644
index 0537868..0000000
--- a/chips/res/values-am/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"የኢሜይል አድራሻ ቅዳ"</string>
- <string name="copy_number" msgid="530057841276106843">"የስልክ ቁጥር ቅዳ"</string>
- <string name="done" msgid="2356320650733788862">"መልስ"</string>
-</resources>
diff --git a/chips/res/values-ar/strings.xml b/chips/res/values-ar/strings.xml
deleted file mode 100644
index 3398641..0000000
--- a/chips/res/values-ar/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"<xliff:g id="COUNT">%1$s</xliff:g>+"</string>
- <string name="copy_email" msgid="7869435992461603532">"نسخ عنوان البريد الإلكتروني"</string>
- <string name="copy_number" msgid="530057841276106843">"نسخ رقم الهاتف"</string>
- <string name="done" msgid="2356320650733788862">"رجوع"</string>
-</resources>
diff --git a/chips/res/values-be/strings.xml b/chips/res/values-be/strings.xml
deleted file mode 100644
index e71f0e2..0000000
--- a/chips/res/values-be/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Скапіраваць адрас электроннай пошты"</string>
- <string name="copy_number" msgid="530057841276106843">"Скапіраваць нумар тэлефона"</string>
- <string name="done" msgid="2356320650733788862">"Назад"</string>
-</resources>
diff --git a/chips/res/values-bg/strings.xml b/chips/res/values-bg/strings.xml
deleted file mode 100644
index 06ed49e..0000000
--- a/chips/res/values-bg/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+ <xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Копиране на имейл адреса"</string>
- <string name="copy_number" msgid="530057841276106843">"Копиране на телефонния номер"</string>
- <string name="done" msgid="2356320650733788862">"Enter"</string>
-</resources>
diff --git a/chips/res/values-ca/strings.xml b/chips/res/values-ca/strings.xml
deleted file mode 100644
index 77d2196..0000000
--- a/chips/res/values-ca/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Copia l\'adreça electrònica"</string>
- <string name="copy_number" msgid="530057841276106843">"Copia el número de telèfon"</string>
- <string name="done" msgid="2356320650733788862">"Retorn"</string>
-</resources>
diff --git a/chips/res/values-cs/strings.xml b/chips/res/values-cs/strings.xml
deleted file mode 100644
index 212d734..0000000
--- a/chips/res/values-cs/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopírovat e-mailovou adresu"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopírovat telefonní číslo"</string>
- <string name="done" msgid="2356320650733788862">"Enter"</string>
-</resources>
diff --git a/chips/res/values-da/strings.xml b/chips/res/values-da/strings.xml
deleted file mode 100644
index 8196fee..0000000
--- a/chips/res/values-da/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopiér e-mailadressen"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopiér telefonnummeret"</string>
- <string name="done" msgid="2356320650733788862">"Tilbage"</string>
-</resources>
diff --git a/chips/res/values-de/strings.xml b/chips/res/values-de/strings.xml
deleted file mode 100644
index d4c2fe4..0000000
--- a/chips/res/values-de/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"E-Mail-Adresse kopieren"</string>
- <string name="copy_number" msgid="530057841276106843">"Telefonnummer kopieren"</string>
- <string name="done" msgid="2356320650733788862">"Eingabe"</string>
-</resources>
diff --git a/chips/res/values-el/strings.xml b/chips/res/values-el/strings.xml
deleted file mode 100644
index 51b5ac3..0000000
--- a/chips/res/values-el/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Αντιγραφή διεύθυνσης ηλεκτρονικού ταχυδρομείου"</string>
- <string name="copy_number" msgid="530057841276106843">"Αντιγραφή αριθμού τηλεφώνου"</string>
- <string name="done" msgid="2356320650733788862">"Πλήκτρο Return"</string>
-</resources>
diff --git a/chips/res/values-en-rGB/strings.xml b/chips/res/values-en-rGB/strings.xml
deleted file mode 100644
index 1ae784b..0000000
--- a/chips/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Copy email address"</string>
- <string name="copy_number" msgid="530057841276106843">"Copy phone number"</string>
- <string name="done" msgid="2356320650733788862">"Return"</string>
-</resources>
diff --git a/chips/res/values-es-rUS/strings.xml b/chips/res/values-es-rUS/strings.xml
deleted file mode 100644
index c63e6cb..0000000
--- a/chips/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Copiar la dirección de correo"</string>
- <string name="copy_number" msgid="530057841276106843">"Copiar el número de teléfono"</string>
- <string name="done" msgid="2356320650733788862">"Volver"</string>
-</resources>
diff --git a/chips/res/values-es/strings.xml b/chips/res/values-es/strings.xml
deleted file mode 100644
index 74478a8..0000000
--- a/chips/res/values-es/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Copiar dirección de correo electrónico"</string>
- <string name="copy_number" msgid="530057841276106843">"Copiar número de teléfono"</string>
- <string name="done" msgid="2356320650733788862">"Intro"</string>
-</resources>
diff --git a/chips/res/values-et/strings.xml b/chips/res/values-et/strings.xml
deleted file mode 100644
index f32e66d..0000000
--- a/chips/res/values-et/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopeeri e-posti aadress"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopeeri telefoninumber"</string>
- <string name="done" msgid="2356320650733788862">"Sisestus"</string>
-</resources>
diff --git a/chips/res/values-fa/strings.xml b/chips/res/values-fa/strings.xml
deleted file mode 100644
index e5b32ba..0000000
--- a/chips/res/values-fa/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"کپی آدرس ایمیل"</string>
- <string name="copy_number" msgid="530057841276106843">"کپی شماره تلفن"</string>
- <string name="done" msgid="2356320650733788862">"بازگشت"</string>
-</resources>
diff --git a/chips/res/values-fi/strings.xml b/chips/res/values-fi/strings.xml
deleted file mode 100644
index 9893923..0000000
--- a/chips/res/values-fi/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"yli <xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopioi sähköpostiosoite"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopioi puhelinnumero"</string>
- <string name="done" msgid="2356320650733788862">"Enter"</string>
-</resources>
diff --git a/chips/res/values-fr/strings.xml b/chips/res/values-fr/strings.xml
deleted file mode 100644
index 3d13b5f..0000000
--- a/chips/res/values-fr/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+ <xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Copier l\'adresse e-mail"</string>
- <string name="copy_number" msgid="530057841276106843">"Copier le numéro de téléphone"</string>
- <string name="done" msgid="2356320650733788862">"Entrée"</string>
-</resources>
diff --git a/chips/res/values-hi/strings.xml b/chips/res/values-hi/strings.xml
deleted file mode 100644
index 8368c0d..0000000
--- a/chips/res/values-hi/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"ईमेल पते की प्रतिलिपि बनाएं"</string>
- <string name="copy_number" msgid="530057841276106843">"फोन नंबर की प्रतिलिपि बनाएं"</string>
- <string name="done" msgid="2356320650733788862">"वापस लौटें"</string>
-</resources>
diff --git a/chips/res/values-hr/strings.xml b/chips/res/values-hr/strings.xml
deleted file mode 100644
index 65f2c12..0000000
--- a/chips/res/values-hr/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopiranje e-adrese"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopiranje telefonskog broja"</string>
- <string name="done" msgid="2356320650733788862">"Vrati"</string>
-</resources>
diff --git a/chips/res/values-hu/strings.xml b/chips/res/values-hu/strings.xml
deleted file mode 100644
index a18f811..0000000
--- a/chips/res/values-hu/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"E-mail cím másolása"</string>
- <string name="copy_number" msgid="530057841276106843">"Telefonszám másolása"</string>
- <string name="done" msgid="2356320650733788862">"Enter"</string>
-</resources>
diff --git a/chips/res/values-in/strings.xml b/chips/res/values-in/strings.xml
deleted file mode 100644
index 9c1cbe6..0000000
--- a/chips/res/values-in/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Salin alamat email"</string>
- <string name="copy_number" msgid="530057841276106843">"Salin nomor telepon"</string>
- <string name="done" msgid="2356320650733788862">"Kembali"</string>
-</resources>
diff --git a/chips/res/values-it/strings.xml b/chips/res/values-it/strings.xml
deleted file mode 100644
index 3f87ec0..0000000
--- a/chips/res/values-it/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Copia indirizzo email"</string>
- <string name="copy_number" msgid="530057841276106843">"Copia numero di telefono"</string>
- <string name="done" msgid="2356320650733788862">"Invio"</string>
-</resources>
diff --git a/chips/res/values-iw/strings.xml b/chips/res/values-iw/strings.xml
deleted file mode 100644
index d7be75a..0000000
--- a/chips/res/values-iw/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"העתק כתובת דוא\"ל"</string>
- <string name="copy_number" msgid="530057841276106843">"העתק מספר טלפון"</string>
- <string name="done" msgid="2356320650733788862">"חזור"</string>
-</resources>
diff --git a/chips/res/values-ja/strings.xml b/chips/res/values-ja/strings.xml
deleted file mode 100644
index 543eb8a..0000000
--- a/chips/res/values-ja/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"メールアドレスをコピー"</string>
- <string name="copy_number" msgid="530057841276106843">"電話番号をコピー"</string>
- <string name="done" msgid="2356320650733788862">"戻る"</string>
-</resources>
diff --git a/chips/res/values-ko/strings.xml b/chips/res/values-ko/strings.xml
deleted file mode 100644
index f7884bd..0000000
--- a/chips/res/values-ko/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"<xliff:g id="COUNT">%1$s</xliff:g>명 이상"</string>
- <string name="copy_email" msgid="7869435992461603532">"이메일 주소 복사"</string>
- <string name="copy_number" msgid="530057841276106843">"전화번호 복사"</string>
- <string name="done" msgid="2356320650733788862">"입력"</string>
-</resources>
diff --git a/chips/res/values-land/dimen.xml b/chips/res/values-land/dimen.xml
deleted file mode 100644
index 1ee6608..0000000
--- a/chips/res/values-land/dimen.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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>
- <dimen name="chip_height">26dip</dimen>
-</resources>
\ No newline at end of file
diff --git a/chips/res/values-lt/strings.xml b/chips/res/values-lt/strings.xml
deleted file mode 100644
index e85eba3..0000000
--- a/chips/res/values-lt/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+ <xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopijuoti el. pašto adresą"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopijuoti telefono numerį"</string>
- <string name="done" msgid="2356320650733788862">"Grįžti"</string>
-</resources>
diff --git a/chips/res/values-lv/strings.xml b/chips/res/values-lv/strings.xml
deleted file mode 100644
index f06e4fc..0000000
--- a/chips/res/values-lv/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"Vairāk nekā <xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopēt e-pasta adresi"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopēt tālruņa numuru"</string>
- <string name="done" msgid="2356320650733788862">"Iev. taust."</string>
-</resources>
diff --git a/chips/res/values-ms/strings.xml b/chips/res/values-ms/strings.xml
deleted file mode 100644
index 76320f9..0000000
--- a/chips/res/values-ms/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Salin alamat e-mel"</string>
- <string name="copy_number" msgid="530057841276106843">"Salin nombor telefon"</string>
- <string name="done" msgid="2356320650733788862">"Kembali"</string>
-</resources>
diff --git a/chips/res/values-nb/strings.xml b/chips/res/values-nb/strings.xml
deleted file mode 100644
index a71348e..0000000
--- a/chips/res/values-nb/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopiér e-postadressen"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopiér telefonnummeret"</string>
- <string name="done" msgid="2356320650733788862">"Gå tilbake"</string>
-</resources>
diff --git a/chips/res/values-nl/strings.xml b/chips/res/values-nl/strings.xml
deleted file mode 100644
index c4289c6..0000000
--- a/chips/res/values-nl/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"E-mailadres kopiëren"</string>
- <string name="copy_number" msgid="530057841276106843">"Telefoonnummer kopiëren"</string>
- <string name="done" msgid="2356320650733788862">"Return"</string>
-</resources>
diff --git a/chips/res/values-pl/strings.xml b/chips/res/values-pl/strings.xml
deleted file mode 100644
index 8746e48..0000000
--- a/chips/res/values-pl/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopiuj adres e-mail"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopiuj numer telefonu"</string>
- <string name="done" msgid="2356320650733788862">"Enter"</string>
-</resources>
diff --git a/chips/res/values-pt-rPT/strings.xml b/chips/res/values-pt-rPT/strings.xml
deleted file mode 100644
index fc991b1..0000000
--- a/chips/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Copiar endereço de email"</string>
- <string name="copy_number" msgid="530057841276106843">"Copiar número de telefone"</string>
- <string name="done" msgid="2356320650733788862">"Voltar"</string>
-</resources>
diff --git a/chips/res/values-pt/strings.xml b/chips/res/values-pt/strings.xml
deleted file mode 100644
index 58a23e3..0000000
--- a/chips/res/values-pt/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Copiar endereço de e-mail"</string>
- <string name="copy_number" msgid="530057841276106843">"Copiar número de telefone"</string>
- <string name="done" msgid="2356320650733788862">"Enter"</string>
-</resources>
diff --git a/chips/res/values-ro/strings.xml b/chips/res/values-ro/strings.xml
deleted file mode 100644
index 6bd8a36..0000000
--- a/chips/res/values-ro/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Copiaţi adresa de e-mail"</string>
- <string name="copy_number" msgid="530057841276106843">"Copiaţi numărul de telefon"</string>
- <string name="done" msgid="2356320650733788862">"Enter"</string>
-</resources>
diff --git a/chips/res/values-ru/strings.xml b/chips/res/values-ru/strings.xml
deleted file mode 100644
index 0d6a2d7..0000000
--- a/chips/res/values-ru/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"ещё <xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Скопировать адрес эл. почты"</string>
- <string name="copy_number" msgid="530057841276106843">"Скопировать номер телефона"</string>
- <string name="done" msgid="2356320650733788862">"Назад"</string>
-</resources>
diff --git a/chips/res/values-sk/strings.xml b/chips/res/values-sk/strings.xml
deleted file mode 100644
index 155da99..0000000
--- a/chips/res/values-sk/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopírovať e-mailovú adresu"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopírovať telefónne číslo"</string>
- <string name="done" msgid="2356320650733788862">"Enter"</string>
-</resources>
diff --git a/chips/res/values-sl/strings.xml b/chips/res/values-sl/strings.xml
deleted file mode 100644
index e9877dd..0000000
--- a/chips/res/values-sl/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopiranje e-poštnega naslova"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopiranje telefonske številke"</string>
- <string name="done" msgid="2356320650733788862">"Vračalka"</string>
-</resources>
diff --git a/chips/res/values-sr/strings.xml b/chips/res/values-sr/strings.xml
deleted file mode 100644
index 578ca42..0000000
--- a/chips/res/values-sr/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Копирај адресу е-поште"</string>
- <string name="copy_number" msgid="530057841276106843">"Копирај број телефона"</string>
- <string name="done" msgid="2356320650733788862">"Врати"</string>
-</resources>
diff --git a/chips/res/values-sv/strings.xml b/chips/res/values-sv/strings.xml
deleted file mode 100644
index a2a9f40..0000000
--- a/chips/res/values-sv/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopiera e-postadress"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopiera telefonnummer"</string>
- <string name="done" msgid="2356320650733788862">"Retur"</string>
-</resources>
diff --git a/chips/res/values-sw/strings.xml b/chips/res/values-sw/strings.xml
deleted file mode 100644
index edea133..0000000
--- a/chips/res/values-sw/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Nakili anwani ya barua pepe"</string>
- <string name="copy_number" msgid="530057841276106843">"Nakili namba ya simu"</string>
- <string name="done" msgid="2356320650733788862">"Inayofuata"</string>
-</resources>
diff --git a/chips/res/values-sw600dp-land/dimen.xml b/chips/res/values-sw600dp-land/dimen.xml
deleted file mode 100644
index dc3aadf..0000000
--- a/chips/res/values-sw600dp-land/dimen.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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>
- <dimen name="chip_padding">8dip</dimen>
- <dimen name="chip_height">32dip</dimen>
- <dimen name="chip_text_size">14sp</dimen>
-</resources>
\ No newline at end of file
diff --git a/chips/res/values-sw600dp/styles.xml b/chips/res/values-sw600dp/styles.xml
deleted file mode 100644
index 00988a9..0000000
--- a/chips/res/values-sw600dp/styles.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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:tools="http://schemas.android.com/tools"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <style name="RecipientEditTextView" parent="@android:attr/autoCompleteTextViewStyle">
- <item name="android:paddingLeft">8dip</item>
- <item name="android:paddingRight">4dip</item>
- <item name="android:inputType">textEmailAddress|textMultiLine</item>
- <item name="android:imeOptions">actionNext</item>
- <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
- <item name="android:background">@null</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:layout_width">match_parent</item>
- <item name="android:dropDownVerticalOffset">0dip</item>
- <item name="android:dropDownHorizontalOffset">-4dip</item>
- <item name="android:textAlignment" tools:ignore="NewApi">viewStart</item>
- <item name="android:textDirection" tools:ignore="NewApi">locale</item>
- </style>
-</resources>
diff --git a/chips/res/values-th/strings.xml b/chips/res/values-th/strings.xml
deleted file mode 100644
index fffafd0..0000000
--- a/chips/res/values-th/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"คัดลอกที่อยู่อีเมล"</string>
- <string name="copy_number" msgid="530057841276106843">"คัดลอกหมายเลขโทรศัพท์"</string>
- <string name="done" msgid="2356320650733788862">"ส่งคืน"</string>
-</resources>
diff --git a/chips/res/values-tl/strings.xml b/chips/res/values-tl/strings.xml
deleted file mode 100644
index db846ca..0000000
--- a/chips/res/values-tl/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopyahin ang email address"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopyahin ang numero ng telepono"</string>
- <string name="done" msgid="2356320650733788862">"Bumalik"</string>
-</resources>
diff --git a/chips/res/values-tr/strings.xml b/chips/res/values-tr/strings.xml
deleted file mode 100644
index 1e099a4..0000000
--- a/chips/res/values-tr/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"E-posta adresini kopyala"</string>
- <string name="copy_number" msgid="530057841276106843">"Telefon numarasını kopyala"</string>
- <string name="done" msgid="2356320650733788862">"Enter"</string>
-</resources>
diff --git a/chips/res/values-uk/strings.xml b/chips/res/values-uk/strings.xml
deleted file mode 100644
index 820183e..0000000
--- a/chips/res/values-uk/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Копіювати електронну адресу"</string>
- <string name="copy_number" msgid="530057841276106843">"Копіювати номер телефону"</string>
- <string name="done" msgid="2356320650733788862">"Return"</string>
-</resources>
diff --git a/chips/res/values-v17/styles-v17.xml b/chips/res/values-v17/styles-v17.xml
deleted file mode 100644
index d151a75..0000000
--- a/chips/res/values-v17/styles-v17.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
- <style name="ChipTitleStyle">
- <item name="android:paddingStart">@dimen/chip_title_padding_start</item>
- </style>
-
- <style name="ChipSubtitleStyle">
- <item name="android:paddingStart">@dimen/chip_subtitle_padding_start</item>
- </style>
-
- <style name="ChipIconStyle">
- <item name="android:layout_marginStart">@dimen/chip_icon_margin_start</item>
- </style>
-</resources>
diff --git a/chips/res/values-vi/strings.xml b/chips/res/values-vi/strings.xml
deleted file mode 100644
index f42d837..0000000
--- a/chips/res/values-vi/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Sao chép địa chỉ email"</string>
- <string name="copy_number" msgid="530057841276106843">"Sao chép số điện thoại"</string>
- <string name="done" msgid="2356320650733788862">"Quay lại"</string>
-</resources>
diff --git a/chips/res/values-zh-rCN/strings.xml b/chips/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 2283f75..0000000
--- a/chips/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"复制电子邮件地址"</string>
- <string name="copy_number" msgid="530057841276106843">"复制电话号码"</string>
- <string name="done" msgid="2356320650733788862">"上一步"</string>
-</resources>
diff --git a/chips/res/values-zh-rTW/strings.xml b/chips/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 62d71cf..0000000
--- a/chips/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g> 人"</string>
- <string name="copy_email" msgid="7869435992461603532">"複製電子郵件地址"</string>
- <string name="copy_number" msgid="530057841276106843">"複製電話號碼"</string>
- <string name="done" msgid="2356320650733788862">"返回"</string>
-</resources>
diff --git a/chips/res/values-zu/strings.xml b/chips/res/values-zu/strings.xml
deleted file mode 100644
index 9ae03ed..0000000
--- a/chips/res/values-zu/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2011 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="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="copy_email" msgid="7869435992461603532">"Kopisha ikheli le-imeyli"</string>
- <string name="copy_number" msgid="530057841276106843">"Kopisha inombolo yefoni"</string>
- <string name="done" msgid="2356320650733788862">"Buyela"</string>
-</resources>
diff --git a/chips/res/values/attrs.xml b/chips/res/values/attrs.xml
deleted file mode 100644
index d3500aa..0000000
--- a/chips/res/values/attrs.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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>
- <declare-styleable name="RecipientEditTextView">
- <attr name="avatarPosition">
- <enum name="end" value="0" />
- <enum name="start" value="1" />
- </attr>
- <attr name="chipBackground" format="reference" />
- <attr name="chipBackgroundPressed" format="reference" />
- <attr name="chipDelete" format="reference" />
- <attr name="chipFontSize" format="reference" />
- <attr name="chipHeight" format="reference" />
- <attr name="chipPadding" format="reference" />
- <attr name="disableDelete" format="boolean" />
- <attr name="invalidChipBackground" format="reference" />
- <attr name="imageSpanAlignment">
- <enum name="bottom" value = "0"/>
- <enum name="baseline" value = "1"/>
- </attr>
- </declare-styleable>
-</resources>
\ No newline at end of file
diff --git a/chips/res/values/dimen.xml b/chips/res/values/dimen.xml
deleted file mode 100644
index f989c86..0000000
--- a/chips/res/values/dimen.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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>
- <dimen name="chip_padding">8dip</dimen>
- <dimen name="chip_height">32dip</dimen>
- <dimen name="chip_text_size">14sp</dimen>
- <dimen name="line_spacing_extra">4dip</dimen>
- <integer name="chips_max_lines">-1</integer>
-
- <dimen name="chip_title_padding_start">8dip</dimen>
- <dimen name="chip_subtitle_padding_start">16dip</dimen>
- <dimen name="chip_icon_margin_start">12dip</dimen>
-</resources>
diff --git a/chips/res/values/strings.xml b/chips/res/values/strings.xml
deleted file mode 100644
index 3588ec3..0000000
--- a/chips/res/values/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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">
- <!-- Text displayed when the recipientedittextview is not focused. Displays the total number of recipients since the field is shrunk to just display a portion -->
- <string name="more_string">\u002B<xliff:g id="count">%1$s</xliff:g></string>
-
- <!-- Text displayed when the user long presses on a chip to copy the recipients email address.
- [CHAR LIMIT=200] -->
- <string name="copy_email">Copy email address</string>
- <!-- Text displayed when the user long presses on a chip to copy the recipient's phone number.
- [CHAR LIMIT=200] -->
- <string name="copy_number">Copy phone number</string>
- <!-- Text displayed in the enter key slot when the recipientedittextview has focus.
- [CHAR LIMIT=12] -->
- <string name="done">Return</string>
-</resources>
diff --git a/chips/res/values/styles.xml b/chips/res/values/styles.xml
deleted file mode 100644
index 9b60cde..0000000
--- a/chips/res/values/styles.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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:tools="http://schemas.android.com/tools"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <style name="RecipientEditTextView" parent="@android:attr/autoCompleteTextViewStyle">
- <item name="android:inputType">textEmailAddress|textMultiLine</item>
- <item name="android:imeOptions">actionNext|flagNoFullscreen</item>
- <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
- <item name="android:background">@null</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:layout_width">match_parent</item>
- <item name="android:dropDownVerticalOffset">-6dip</item>
- <item name="android:dropDownHorizontalOffset">-16dip</item>
- <item name="android:minHeight">48dip</item>
- <item name="android:lineSpacingExtra">@dimen/line_spacing_extra</item>
- <item name="android:textAlignment" tools:ignore="NewApi">viewStart</item>
- <item name="android:textDirection" tools:ignore="NewApi">locale</item>
- </style>
-
- <style name="ChipTitleStyle">
- <item name="android:paddingLeft">@dimen/chip_title_padding_start</item>
- </style>
-
- <style name="ChipSubtitleStyle">
- <item name="android:paddingLeft">@dimen/chip_subtitle_padding_start</item>
- </style>
-
- <style name="ChipIconStyle">
- <item name="android:layout_marginLeft">@dimen/chip_icon_margin_start</item>
- </style>
-</resources>
diff --git a/chips/sample/Android.mk b/chips/sample/Android.mk
deleted file mode 100644
index 978aa7f..0000000
--- a/chips/sample/Android.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 2013 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-# Include res dir from chips
-chips_dir := ../res
-res_dirs := res $(chips_dir)
-
-##################################################
-# Build APK
-include $(CLEAR_VARS)
-
-src_dirs := src
-LOCAL_PACKAGE_NAME := ChipsSample
-
-LOCAL_STATIC_JAVA_LIBRARIES += android-common-chips
-
-LOCAL_SDK_VERSION := 18
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
- $(call all-logtags-files-under, $(src_dirs))
-LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dirs))
-LOCAL_AAPT_FLAGS := --auto-add-overlay
-LOCAL_AAPT_FLAGS += --extra-packages com.android.ex.chips
-
-include $(BUILD_PACKAGE)
-
-
-##################################################
-# Build all sub-directories
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/chips/sample/AndroidManifest.xml b/chips/sample/AndroidManifest.xml
deleted file mode 100644
index a490e29..0000000
--- a/chips/sample/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.ex.chips.sample"
- android:versionCode="1"
- android:versionName="1.0" >
-
- <uses-sdk
- android:minSdkVersion="11"
- android:targetSdkVersion="18" />
-
- <uses-permission android:name="android.permission.READ_CONTACTS" />
-
- <application
- android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:theme="@android:style/Theme.Holo.Light" >
- <activity
- android:name="com.android.ex.chips.sample.MainActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
\ No newline at end of file
diff --git a/chips/sample/res/drawable-hdpi/ic_launcher.png b/chips/sample/res/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index 96a442e..0000000
--- a/chips/sample/res/drawable-hdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/chips/sample/res/drawable-mdpi/ic_launcher.png b/chips/sample/res/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index 359047d..0000000
--- a/chips/sample/res/drawable-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/chips/sample/res/drawable-xhdpi/ic_launcher.png b/chips/sample/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index 71c6d76..0000000
--- a/chips/sample/res/drawable-xhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/chips/sample/res/layout/activity_main.xml b/chips/sample/res/layout/activity_main.xml
deleted file mode 100644
index 01a9ff3..0000000
--- a/chips/sample/res/layout/activity_main.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<!-- Copyright (C) 2013 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context=".MainActivity" >
-
- <com.android.ex.chips.RecipientEditTextView
- android:id="@+id/email_retv"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="@string/email_addresses"
- android:minHeight="58dp" />
-
- <com.android.ex.chips.RecipientEditTextView
- android:id="@+id/phone_retv"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="@string/phone_numbers"
- android:minHeight="58dp" />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/chips/sample/res/values-af/strings.xml b/chips/sample/res/values-af/strings.xml
deleted file mode 100644
index e4c4945..0000000
--- a/chips/sample/res/values-af/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips-voorbeeld"</string>
- <string name="email_addresses" msgid="5320415175940315400">"E-posadresse"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Foonnommers"</string>
-</resources>
diff --git a/chips/sample/res/values-am/strings.xml b/chips/sample/res/values-am/strings.xml
deleted file mode 100644
index d19c4e8..0000000
--- a/chips/sample/res/values-am/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"የቺፕስ ናሙና"</string>
- <string name="email_addresses" msgid="5320415175940315400">"የኢሜይል አድራሻዎች"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"ስልክ ቁጥሮች"</string>
-</resources>
diff --git a/chips/sample/res/values-ar/strings.xml b/chips/sample/res/values-ar/strings.xml
deleted file mode 100644
index 4492ec7..0000000
--- a/chips/sample/res/values-ar/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"عينة شرائح"</string>
- <string name="email_addresses" msgid="5320415175940315400">"عناوين البريد الإلكتروني"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"أرقام الهواتف"</string>
-</resources>
diff --git a/chips/sample/res/values-bg/strings.xml b/chips/sample/res/values-bg/strings.xml
deleted file mode 100644
index 4c118c1..0000000
--- a/chips/sample/res/values-bg/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Имейл адреси"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Телефонни номера"</string>
-</resources>
diff --git a/chips/sample/res/values-ca/strings.xml b/chips/sample/res/values-ca/strings.xml
deleted file mode 100644
index 847cc6f..0000000
--- a/chips/sample/res/values-ca/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Mostra de xips"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Adreces electròniques"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Números de telèfon"</string>
-</resources>
diff --git a/chips/sample/res/values-cs/strings.xml b/chips/sample/res/values-cs/strings.xml
deleted file mode 100644
index 3e0a928..0000000
--- a/chips/sample/res/values-cs/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Vzorové čipy"</string>
- <string name="email_addresses" msgid="5320415175940315400">"E-mailové adresy"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Telefonní čísla"</string>
-</resources>
diff --git a/chips/sample/res/values-da/strings.xml b/chips/sample/res/values-da/strings.xml
deleted file mode 100644
index e55fcc6..0000000
--- a/chips/sample/res/values-da/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Eksempel på chips"</string>
- <string name="email_addresses" msgid="5320415175940315400">"E-mailadresser"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Telefonnumre"</string>
-</resources>
diff --git a/chips/sample/res/values-de/strings.xml b/chips/sample/res/values-de/strings.xml
deleted file mode 100644
index 614081c..0000000
--- a/chips/sample/res/values-de/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"E-Mail-Adressen"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Telefonnummern"</string>
-</resources>
diff --git a/chips/sample/res/values-el/strings.xml b/chips/sample/res/values-el/strings.xml
deleted file mode 100644
index a90018a..0000000
--- a/chips/sample/res/values-el/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Δείγμα τσιπ"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Διευθύνσεις ηλεκτρονικού ταχυδρομείου"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Αριθμοί τηλεφώνου"</string>
-</resources>
diff --git a/chips/sample/res/values-en-rGB/strings.xml b/chips/sample/res/values-en-rGB/strings.xml
deleted file mode 100644
index aaccb10..0000000
--- a/chips/sample/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Email Addresses"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Phone Numbers"</string>
-</resources>
diff --git a/chips/sample/res/values-en-rIN/strings.xml b/chips/sample/res/values-en-rIN/strings.xml
deleted file mode 100644
index aaccb10..0000000
--- a/chips/sample/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Email Addresses"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Phone Numbers"</string>
-</resources>
diff --git a/chips/sample/res/values-es-rUS/strings.xml b/chips/sample/res/values-es-rUS/strings.xml
deleted file mode 100644
index e314778..0000000
--- a/chips/sample/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Muestra de chips"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Direcciones de correo electrónico"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Números de teléfono"</string>
-</resources>
diff --git a/chips/sample/res/values-es/strings.xml b/chips/sample/res/values-es/strings.xml
deleted file mode 100644
index dd64514..0000000
--- a/chips/sample/res/values-es/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Muestra de Chips"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Direcciones de correo electrónico"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Números de teléfono"</string>
-</resources>
diff --git a/chips/sample/res/values-et-rEE/strings.xml b/chips/sample/res/values-et-rEE/strings.xml
deleted file mode 100644
index 5c7d6e5..0000000
--- a/chips/sample/res/values-et-rEE/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"E-posti aadressid"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Telefoninumbrid"</string>
-</resources>
diff --git a/chips/sample/res/values-fa/strings.xml b/chips/sample/res/values-fa/strings.xml
deleted file mode 100644
index 8ee4162..0000000
--- a/chips/sample/res/values-fa/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"نمونه تراشهها"</string>
- <string name="email_addresses" msgid="5320415175940315400">"آدرسهای ایمیل"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"شماره تلفنها"</string>
-</resources>
diff --git a/chips/sample/res/values-fi/strings.xml b/chips/sample/res/values-fi/strings.xml
deleted file mode 100644
index c72df4d..0000000
--- a/chips/sample/res/values-fi/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Sähköpostiosoitteet"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Puhelinnumerot"</string>
-</resources>
diff --git a/chips/sample/res/values-fr-rCA/strings.xml b/chips/sample/res/values-fr-rCA/strings.xml
deleted file mode 100644
index e88de2d..0000000
--- a/chips/sample/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Échantillon Chips"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Adresses de courriel"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Numéros de téléphone"</string>
-</resources>
diff --git a/chips/sample/res/values-fr/strings.xml b/chips/sample/res/values-fr/strings.xml
deleted file mode 100644
index 2b1c18e..0000000
--- a/chips/sample/res/values-fr/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Échantillon Chips"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Adresses e-mail"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Numéros de téléphone"</string>
-</resources>
diff --git a/chips/sample/res/values-hi/strings.xml b/chips/sample/res/values-hi/strings.xml
deleted file mode 100644
index bae6585..0000000
--- a/chips/sample/res/values-hi/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"चिप्स नमूने"</string>
- <string name="email_addresses" msgid="5320415175940315400">"ईमेल पते"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"फ़ोन नंबर"</string>
-</resources>
diff --git a/chips/sample/res/values-hr/strings.xml b/chips/sample/res/values-hr/strings.xml
deleted file mode 100644
index 6eb8a8e..0000000
--- a/chips/sample/res/values-hr/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"E-adrese"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Telefonski brojevi"</string>
-</resources>
diff --git a/chips/sample/res/values-hu/strings.xml b/chips/sample/res/values-hu/strings.xml
deleted file mode 100644
index 1d00752..0000000
--- a/chips/sample/res/values-hu/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"„Chips” minta"</string>
- <string name="email_addresses" msgid="5320415175940315400">"E-mail címek"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Telefonszámok"</string>
-</resources>
diff --git a/chips/sample/res/values-hy-rAM/strings.xml b/chips/sample/res/values-hy-rAM/strings.xml
deleted file mode 100644
index fbdcb21..0000000
--- a/chips/sample/res/values-hy-rAM/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Չիպերի նմուշ"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Էլփոստի հասցեներ"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Հեռախոսահամարներ"</string>
-</resources>
diff --git a/chips/sample/res/values-in/strings.xml b/chips/sample/res/values-in/strings.xml
deleted file mode 100644
index 1ebd148..0000000
--- a/chips/sample/res/values-in/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Contoh Chip"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Alamat Email"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Nomor Telepon"</string>
-</resources>
diff --git a/chips/sample/res/values-it/strings.xml b/chips/sample/res/values-it/strings.xml
deleted file mode 100644
index aefbd01..0000000
--- a/chips/sample/res/values-it/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Indirizzi email"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Numeri di telefono"</string>
-</resources>
diff --git a/chips/sample/res/values-iw/strings.xml b/chips/sample/res/values-iw/strings.xml
deleted file mode 100644
index 24c7e69..0000000
--- a/chips/sample/res/values-iw/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"דוגמאות שבבים"</string>
- <string name="email_addresses" msgid="5320415175940315400">"כתובות דוא\"ל"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"מספרי טלפון"</string>
-</resources>
diff --git a/chips/sample/res/values-ja/strings.xml b/chips/sample/res/values-ja/strings.xml
deleted file mode 100644
index c75120a..0000000
--- a/chips/sample/res/values-ja/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"チップサンプル"</string>
- <string name="email_addresses" msgid="5320415175940315400">"メールアドレス"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"電話番号"</string>
-</resources>
diff --git a/chips/sample/res/values-ka-rGE/strings.xml b/chips/sample/res/values-ka-rGE/strings.xml
deleted file mode 100644
index a21dab5..0000000
--- a/chips/sample/res/values-ka-rGE/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"ჩიპების ნიმუში"</string>
- <string name="email_addresses" msgid="5320415175940315400">"ელფოსტის მისამართები"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"ტელეფონის ნომრები"</string>
-</resources>
diff --git a/chips/sample/res/values-km-rKH/strings.xml b/chips/sample/res/values-km-rKH/strings.xml
deleted file mode 100644
index 3730a7d..0000000
--- a/chips/sample/res/values-km-rKH/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"គំរូបន្ទះសៀគ្វី"</string>
- <string name="email_addresses" msgid="5320415175940315400">"អាសយដ្ឋានអ៊ីមែល"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"លេខទូរស័ព្ទ"</string>
-</resources>
diff --git a/chips/sample/res/values-ko/strings.xml b/chips/sample/res/values-ko/strings.xml
deleted file mode 100644
index 24d2793..0000000
--- a/chips/sample/res/values-ko/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"칩 샘플"</string>
- <string name="email_addresses" msgid="5320415175940315400">"이메일 주소"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"전화번호"</string>
-</resources>
diff --git a/chips/sample/res/values-lo-rLA/strings.xml b/chips/sample/res/values-lo-rLA/strings.xml
deleted file mode 100644
index 6357807..0000000
--- a/chips/sample/res/values-lo-rLA/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"ທີ່ຢູ່ອີເມວ"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"ເບີໂທລະສັບ:"</string>
-</resources>
diff --git a/chips/sample/res/values-lt/strings.xml b/chips/sample/res/values-lt/strings.xml
deleted file mode 100644
index b966062..0000000
--- a/chips/sample/res/values-lt/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Lustų pavyzdžiai"</string>
- <string name="email_addresses" msgid="5320415175940315400">"El. pašto adresai"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Telefonų numeriai"</string>
-</resources>
diff --git a/chips/sample/res/values-lv/strings.xml b/chips/sample/res/values-lv/strings.xml
deleted file mode 100644
index fec05b5..0000000
--- a/chips/sample/res/values-lv/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"E-pasta adreses"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Tālruņa numuri"</string>
-</resources>
diff --git a/chips/sample/res/values-mn-rMN/strings.xml b/chips/sample/res/values-mn-rMN/strings.xml
deleted file mode 100644
index 5289e5c..0000000
--- a/chips/sample/res/values-mn-rMN/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Чипний дээж"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Имэйл хаягууд"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Утасны дугаарууд"</string>
-</resources>
diff --git a/chips/sample/res/values-ms-rMY/strings.xml b/chips/sample/res/values-ms-rMY/strings.xml
deleted file mode 100644
index 12ab807..0000000
--- a/chips/sample/res/values-ms-rMY/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Sampel Cip"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Alamat E-mel"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Nombor Telefon"</string>
-</resources>
diff --git a/chips/sample/res/values-nb/strings.xml b/chips/sample/res/values-nb/strings.xml
deleted file mode 100644
index 3bff3e2..0000000
--- a/chips/sample/res/values-nb/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips-eksempel"</string>
- <string name="email_addresses" msgid="5320415175940315400">"E-postadresser"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Telefonnumre"</string>
-</resources>
diff --git a/chips/sample/res/values-nl/strings.xml b/chips/sample/res/values-nl/strings.xml
deleted file mode 100644
index 8951311..0000000
--- a/chips/sample/res/values-nl/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chipsvoorbeeld"</string>
- <string name="email_addresses" msgid="5320415175940315400">"E-mailadressen"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Telefoonnummers"</string>
-</resources>
diff --git a/chips/sample/res/values-pl/strings.xml b/chips/sample/res/values-pl/strings.xml
deleted file mode 100644
index fedec0d..0000000
--- a/chips/sample/res/values-pl/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Próbka chipsów"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Adresy e-mail"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Numery telefonów"</string>
-</resources>
diff --git a/chips/sample/res/values-pt-rPT/strings.xml b/chips/sample/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 951d30a..0000000
--- a/chips/sample/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Amostra de Chips"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Endereços de email"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Números de telefone"</string>
-</resources>
diff --git a/chips/sample/res/values-pt/strings.xml b/chips/sample/res/values-pt/strings.xml
deleted file mode 100644
index 9d2e732..0000000
--- a/chips/sample/res/values-pt/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Amostra de chips"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Endereços de e-mail"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Números de telefone"</string>
-</resources>
diff --git a/chips/sample/res/values-ro/strings.xml b/chips/sample/res/values-ro/strings.xml
deleted file mode 100644
index bcffb5e..0000000
--- a/chips/sample/res/values-ro/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Mostră Chips"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Adrese de e-mail"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Numere de telefon"</string>
-</resources>
diff --git a/chips/sample/res/values-ru/strings.xml b/chips/sample/res/values-ru/strings.xml
deleted file mode 100644
index 10f052e..0000000
--- a/chips/sample/res/values-ru/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Адреса эл. почты"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Номера телефонов"</string>
-</resources>
diff --git a/chips/sample/res/values-sk/strings.xml b/chips/sample/res/values-sk/strings.xml
deleted file mode 100644
index 1297298..0000000
--- a/chips/sample/res/values-sk/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Ukážka čipov"</string>
- <string name="email_addresses" msgid="5320415175940315400">"E-mailové adresy"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Telefónne čísla"</string>
-</resources>
diff --git a/chips/sample/res/values-sl/strings.xml b/chips/sample/res/values-sl/strings.xml
deleted file mode 100644
index 0e1c855..0000000
--- a/chips/sample/res/values-sl/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Vzorec čipov"</string>
- <string name="email_addresses" msgid="5320415175940315400">"E-poštni naslovi"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Telefonske številke"</string>
-</resources>
diff --git a/chips/sample/res/values-sr/strings.xml b/chips/sample/res/values-sr/strings.xml
deleted file mode 100644
index dbd91a5..0000000
--- a/chips/sample/res/values-sr/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Пример чипова"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Адресе е-поште"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Бројеви телефона"</string>
-</resources>
diff --git a/chips/sample/res/values-sv/strings.xml b/chips/sample/res/values-sv/strings.xml
deleted file mode 100644
index d787c85..0000000
--- a/chips/sample/res/values-sv/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chipsprov"</string>
- <string name="email_addresses" msgid="5320415175940315400">"E-postadresser"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Telefonnummer"</string>
-</resources>
diff --git a/chips/sample/res/values-sw/strings.xml b/chips/sample/res/values-sw/strings.xml
deleted file mode 100644
index 5afd792..0000000
--- a/chips/sample/res/values-sw/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Sampuli ya Chips"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Anwani za Barua Pepe"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Nambari za Simu"</string>
-</resources>
diff --git a/chips/sample/res/values-th/strings.xml b/chips/sample/res/values-th/strings.xml
deleted file mode 100644
index 80bf67d..0000000
--- a/chips/sample/res/values-th/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"ตัวอย่างชิป"</string>
- <string name="email_addresses" msgid="5320415175940315400">"ที่อยู่อีเมล"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"หมายเลขโทรศัพท์"</string>
-</resources>
diff --git a/chips/sample/res/values-tl/strings.xml b/chips/sample/res/values-tl/strings.xml
deleted file mode 100644
index 411e0d4..0000000
--- a/chips/sample/res/values-tl/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Sample ng Mga Chip"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Mga Email Address"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Mga Numero ng Telepono"</string>
-</resources>
diff --git a/chips/sample/res/values-tr/strings.xml b/chips/sample/res/values-tr/strings.xml
deleted file mode 100644
index dad01bb..0000000
--- a/chips/sample/res/values-tr/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Fiş Örneği"</string>
- <string name="email_addresses" msgid="5320415175940315400">"E-posta Adresleri"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Telefon Numaraları"</string>
-</resources>
diff --git a/chips/sample/res/values-uk/strings.xml b/chips/sample/res/values-uk/strings.xml
deleted file mode 100644
index f09cb8c..0000000
--- a/chips/sample/res/values-uk/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Електронні адреси"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Номери телефонів"</string>
-</resources>
diff --git a/chips/sample/res/values-vi/strings.xml b/chips/sample/res/values-vi/strings.xml
deleted file mode 100644
index b9bc474..0000000
--- a/chips/sample/res/values-vi/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Mẫu chip"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Địa chỉ email"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Số điện thoại"</string>
-</resources>
diff --git a/chips/sample/res/values-zh-rCN/strings.xml b/chips/sample/res/values-zh-rCN/strings.xml
deleted file mode 100644
index ebee45c..0000000
--- a/chips/sample/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"电子邮件地址"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"电话号码"</string>
-</resources>
diff --git a/chips/sample/res/values-zh-rHK/strings.xml b/chips/sample/res/values-zh-rHK/strings.xml
deleted file mode 100644
index d2c3bb0..0000000
--- a/chips/sample/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"電郵地址"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"電話號碼"</string>
-</resources>
diff --git a/chips/sample/res/values-zh-rTW/strings.xml b/chips/sample/res/values-zh-rTW/strings.xml
deleted file mode 100644
index b502833..0000000
--- a/chips/sample/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Chips Sample"</string>
- <string name="email_addresses" msgid="5320415175940315400">"電子郵件地址"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"電話號碼"</string>
-</resources>
diff --git a/chips/sample/res/values-zu/strings.xml b/chips/sample/res/values-zu/strings.xml
deleted file mode 100644
index 6a106b7..0000000
--- a/chips/sample/res/values-zu/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 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="app_name" msgid="4076638519189386225">"Isempula yama-chip"</string>
- <string name="email_addresses" msgid="5320415175940315400">"Amakheli we-imeyili"</string>
- <string name="phone_numbers" msgid="7836326833170390688">"Izinombolo zefoni"</string>
-</resources>
diff --git a/chips/sample/res/values/strings.xml b/chips/sample/res/values/strings.xml
deleted file mode 100644
index a40b20d..0000000
--- a/chips/sample/res/values/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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>
-
- <string name="app_name" translatable="false">Chips Sample</string>
- <string name="email_addresses">Email Addresses</string>
- <string name="phone_numbers">Phone Numbers</string>
-
-</resources>
diff --git a/chips/sample/src/com/android/ex/chips/sample/MainActivity.java b/chips/sample/src/com/android/ex/chips/sample/MainActivity.java
deleted file mode 100644
index 0622e65..0000000
--- a/chips/sample/src/com/android/ex/chips/sample/MainActivity.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2013 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.ex.chips.sample;
-
-import android.os.Bundle;
-import android.text.util.Rfc822Tokenizer;
-import android.widget.MultiAutoCompleteTextView;
-import android.app.Activity;
-
-import com.android.ex.chips.BaseRecipientAdapter;
-import com.android.ex.chips.RecipientEditTextView;
-
-public class MainActivity extends Activity {
-
- @Override
- protected void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- final RecipientEditTextView emailRetv =
- (RecipientEditTextView) findViewById(R.id.email_retv);
- emailRetv.setTokenizer(new Rfc822Tokenizer());
- emailRetv.setAdapter(new BaseRecipientAdapter(this) { });
-
- final RecipientEditTextView phoneRetv =
- (RecipientEditTextView) findViewById(R.id.phone_retv);
- phoneRetv.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
- phoneRetv.setAdapter(
- new BaseRecipientAdapter(BaseRecipientAdapter.QUERY_TYPE_PHONE, this) { });
- }
-
-}
diff --git a/chips/src/com/android/ex/chips/AccountSpecifier.java b/chips/src/com/android/ex/chips/AccountSpecifier.java
deleted file mode 100644
index 5eb8314..0000000
--- a/chips/src/com/android/ex/chips/AccountSpecifier.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2011 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.ex.chips;
-
-import android.accounts.Account;
-
-/**
- * The AccountSpecificAdapter interface describes an Adapter
- * that can take an account to retrieve information tied to
- * a specific account.
- */
-public interface AccountSpecifier {
- public void setAccount(Account account);
-}
diff --git a/chips/src/com/android/ex/chips/BaseRecipientAdapter.java b/chips/src/com/android/ex/chips/BaseRecipientAdapter.java
deleted file mode 100644
index 468e168..0000000
--- a/chips/src/com/android/ex/chips/BaseRecipientAdapter.java
+++ /dev/null
@@ -1,1005 +0,0 @@
-/*
- * Copyright (C) 2011 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.ex.chips;
-
-import android.accounts.Account;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Photo;
-import android.provider.ContactsContract.Directory;
-import android.support.v4.util.LruCache;
-import android.text.TextUtils;
-import android.text.util.Rfc822Token;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AutoCompleteTextView;
-import android.widget.BaseAdapter;
-import android.widget.Filter;
-import android.widget.Filterable;
-
-import com.android.ex.chips.DropdownChipLayouter.AdapterType;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Adapter for showing a recipient list.
- */
-public class BaseRecipientAdapter extends BaseAdapter implements Filterable, AccountSpecifier {
- private static final String TAG = "BaseRecipientAdapter";
-
- private static final boolean DEBUG = false;
-
- /**
- * The preferred number of results to be retrieved. This number may be
- * exceeded if there are several directories configured, because we will use
- * the same limit for all directories.
- */
- private static final int DEFAULT_PREFERRED_MAX_RESULT_COUNT = 10;
-
- /**
- * The number of extra entries requested to allow for duplicates. Duplicates
- * are removed from the overall result.
- */
- static final int ALLOWANCE_FOR_DUPLICATES = 5;
-
- // This is ContactsContract.PRIMARY_ACCOUNT_NAME. Available from ICS as hidden
- static final String PRIMARY_ACCOUNT_NAME = "name_for_primary_account";
- // This is ContactsContract.PRIMARY_ACCOUNT_TYPE. Available from ICS as hidden
- static final String PRIMARY_ACCOUNT_TYPE = "type_for_primary_account";
-
- /** The number of photos cached in this Adapter. */
- private static final int PHOTO_CACHE_SIZE = 20;
-
- /**
- * The "Waiting for more contacts" message will be displayed if search is not complete
- * within this many milliseconds.
- */
- private static final int MESSAGE_SEARCH_PENDING_DELAY = 1000;
- /** Used to prepare "Waiting for more contacts" message. */
- private static final int MESSAGE_SEARCH_PENDING = 1;
-
- public static final int QUERY_TYPE_EMAIL = 0;
- public static final int QUERY_TYPE_PHONE = 1;
-
- private final Queries.Query mQuery;
- private final int mQueryType;
-
- /**
- * Model object for a {@link Directory} row.
- */
- public final static class DirectorySearchParams {
- public long directoryId;
- public String directoryType;
- public String displayName;
- public String accountName;
- public String accountType;
- public CharSequence constraint;
- public DirectoryFilter filter;
- }
-
- private static class PhotoQuery {
- public static final String[] PROJECTION = {
- Photo.PHOTO
- };
-
- public static final int PHOTO = 0;
- }
-
- protected static class DirectoryListQuery {
-
- public static final Uri URI =
- Uri.withAppendedPath(ContactsContract.AUTHORITY_URI, "directories");
- public static final String[] PROJECTION = {
- Directory._ID, // 0
- Directory.ACCOUNT_NAME, // 1
- Directory.ACCOUNT_TYPE, // 2
- Directory.DISPLAY_NAME, // 3
- Directory.PACKAGE_NAME, // 4
- Directory.TYPE_RESOURCE_ID, // 5
- };
-
- public static final int ID = 0;
- public static final int ACCOUNT_NAME = 1;
- public static final int ACCOUNT_TYPE = 2;
- public static final int DISPLAY_NAME = 3;
- public static final int PACKAGE_NAME = 4;
- public static final int TYPE_RESOURCE_ID = 5;
- }
-
- /** Used to temporarily hold results in Cursor objects. */
- protected static class TemporaryEntry {
- public final String displayName;
- public final String destination;
- public final int destinationType;
- public final String destinationLabel;
- public final long contactId;
- public final Long directoryId;
- public final long dataId;
- public final String thumbnailUriString;
- public final int displayNameSource;
- public final String lookupKey;
-
- public TemporaryEntry(
- String displayName,
- String destination,
- int destinationType,
- String destinationLabel,
- long contactId,
- Long directoryId,
- long dataId,
- String thumbnailUriString,
- int displayNameSource,
- String lookupKey) {
- this.displayName = displayName;
- this.destination = destination;
- this.destinationType = destinationType;
- this.destinationLabel = destinationLabel;
- this.contactId = contactId;
- this.directoryId = directoryId;
- this.dataId = dataId;
- this.thumbnailUriString = thumbnailUriString;
- this.displayNameSource = displayNameSource;
- this.lookupKey = lookupKey;
- }
-
- public TemporaryEntry(Cursor cursor, Long directoryId) {
- this.displayName = cursor.getString(Queries.Query.NAME);
- this.destination = cursor.getString(Queries.Query.DESTINATION);
- this.destinationType = cursor.getInt(Queries.Query.DESTINATION_TYPE);
- this.destinationLabel = cursor.getString(Queries.Query.DESTINATION_LABEL);
- this.contactId = cursor.getLong(Queries.Query.CONTACT_ID);
- this.directoryId = directoryId;
- this.dataId = cursor.getLong(Queries.Query.DATA_ID);
- this.thumbnailUriString = cursor.getString(Queries.Query.PHOTO_THUMBNAIL_URI);
- this.displayNameSource = cursor.getInt(Queries.Query.DISPLAY_NAME_SOURCE);
- this.lookupKey = cursor.getString(Queries.Query.LOOKUP_KEY);
- }
- }
-
- /**
- * Used to pass results from {@link DefaultFilter#performFiltering(CharSequence)} to
- * {@link DefaultFilter#publishResults(CharSequence, android.widget.Filter.FilterResults)}
- */
- private static class DefaultFilterResult {
- public final List<RecipientEntry> entries;
- public final LinkedHashMap<Long, List<RecipientEntry>> entryMap;
- public final List<RecipientEntry> nonAggregatedEntries;
- public final Set<String> existingDestinations;
- public final List<DirectorySearchParams> paramsList;
-
- public DefaultFilterResult(List<RecipientEntry> entries,
- LinkedHashMap<Long, List<RecipientEntry>> entryMap,
- List<RecipientEntry> nonAggregatedEntries,
- Set<String> existingDestinations,
- List<DirectorySearchParams> paramsList) {
- this.entries = entries;
- this.entryMap = entryMap;
- this.nonAggregatedEntries = nonAggregatedEntries;
- this.existingDestinations = existingDestinations;
- this.paramsList = paramsList;
- }
- }
-
- /**
- * An asynchronous filter used for loading two data sets: email rows from the local
- * contact provider and the list of {@link Directory}'s.
- */
- private final class DefaultFilter extends Filter {
-
- @Override
- protected FilterResults performFiltering(CharSequence constraint) {
- if (DEBUG) {
- Log.d(TAG, "start filtering. constraint: " + constraint + ", thread:"
- + Thread.currentThread());
- }
-
- final FilterResults results = new FilterResults();
- Cursor defaultDirectoryCursor = null;
- Cursor directoryCursor = null;
-
- if (TextUtils.isEmpty(constraint)) {
- clearTempEntries();
- // Return empty results.
- return results;
- }
-
- try {
- defaultDirectoryCursor = doQuery(constraint, mPreferredMaxResultCount,
- null /* directoryId */);
-
- if (defaultDirectoryCursor == null) {
- if (DEBUG) {
- Log.w(TAG, "null cursor returned for default Email filter query.");
- }
- } else {
- // These variables will become mEntries, mEntryMap, mNonAggregatedEntries, and
- // mExistingDestinations. Here we shouldn't use those member variables directly
- // since this method is run outside the UI thread.
- final LinkedHashMap<Long, List<RecipientEntry>> entryMap =
- new LinkedHashMap<Long, List<RecipientEntry>>();
- final List<RecipientEntry> nonAggregatedEntries =
- new ArrayList<RecipientEntry>();
- final Set<String> existingDestinations = new HashSet<String>();
-
- while (defaultDirectoryCursor.moveToNext()) {
- // Note: At this point each entry doesn't contain any photo
- // (thus getPhotoBytes() returns null).
- putOneEntry(new TemporaryEntry(defaultDirectoryCursor,
- null /* directoryId */),
- true, entryMap, nonAggregatedEntries, existingDestinations);
- }
-
- // We'll copy this result to mEntry in publicResults() (run in the UX thread).
- final List<RecipientEntry> entries = constructEntryList(
- entryMap, nonAggregatedEntries);
-
- // After having local results, check the size of results. If the results are
- // not enough, we search remote directories, which will take longer time.
- final int limit = mPreferredMaxResultCount - existingDestinations.size();
- final List<DirectorySearchParams> paramsList;
- if (limit > 0) {
- if (DEBUG) {
- Log.d(TAG, "More entries should be needed (current: "
- + existingDestinations.size()
- + ", remaining limit: " + limit + ") ");
- }
- directoryCursor = mContentResolver.query(
- DirectoryListQuery.URI, DirectoryListQuery.PROJECTION,
- null, null, null);
- paramsList = setupOtherDirectories(mContext, directoryCursor, mAccount);
- } else {
- // We don't need to search other directories.
- paramsList = null;
- }
-
- results.values = new DefaultFilterResult(
- entries, entryMap, nonAggregatedEntries,
- existingDestinations, paramsList);
- results.count = 1;
- }
- } finally {
- if (defaultDirectoryCursor != null) {
- defaultDirectoryCursor.close();
- }
- if (directoryCursor != null) {
- directoryCursor.close();
- }
- }
- return results;
- }
-
- @Override
- protected void publishResults(final CharSequence constraint, FilterResults results) {
- // If a user types a string very quickly and database is slow, "constraint" refers to
- // an older text which shows inconsistent results for users obsolete (b/4998713).
- // TODO: Fix it.
- mCurrentConstraint = constraint;
-
- clearTempEntries();
-
- if (results.values != null) {
- DefaultFilterResult defaultFilterResult = (DefaultFilterResult) results.values;
- mEntryMap = defaultFilterResult.entryMap;
- mNonAggregatedEntries = defaultFilterResult.nonAggregatedEntries;
- mExistingDestinations = defaultFilterResult.existingDestinations;
-
- // If there are no local results, in the new result set, cache off what had been
- // shown to the user for use until the first directory result is returned
- if (defaultFilterResult.entries.size() == 0 &&
- defaultFilterResult.paramsList != null) {
- cacheCurrentEntries();
- }
-
- updateEntries(defaultFilterResult.entries);
-
- // We need to search other remote directories, doing other Filter requests.
- if (defaultFilterResult.paramsList != null) {
- final int limit = mPreferredMaxResultCount -
- defaultFilterResult.existingDestinations.size();
- startSearchOtherDirectories(constraint, defaultFilterResult.paramsList, limit);
- }
- }
-
- }
-
- @Override
- public CharSequence convertResultToString(Object resultValue) {
- final RecipientEntry entry = (RecipientEntry)resultValue;
- final String displayName = entry.getDisplayName();
- final String emailAddress = entry.getDestination();
- if (TextUtils.isEmpty(displayName) || TextUtils.equals(displayName, emailAddress)) {
- return emailAddress;
- } else {
- return new Rfc822Token(displayName, emailAddress, null).toString();
- }
- }
- }
-
- /**
- * An asynchronous filter that performs search in a particular directory.
- */
- protected class DirectoryFilter extends Filter {
- private final DirectorySearchParams mParams;
- private int mLimit;
-
- public DirectoryFilter(DirectorySearchParams params) {
- mParams = params;
- }
-
- public synchronized void setLimit(int limit) {
- this.mLimit = limit;
- }
-
- public synchronized int getLimit() {
- return this.mLimit;
- }
-
- @Override
- protected FilterResults performFiltering(CharSequence constraint) {
- if (DEBUG) {
- Log.d(TAG, "DirectoryFilter#performFiltering. directoryId: " + mParams.directoryId
- + ", constraint: " + constraint + ", thread: " + Thread.currentThread());
- }
- final FilterResults results = new FilterResults();
- results.values = null;
- results.count = 0;
-
- if (!TextUtils.isEmpty(constraint)) {
- final ArrayList<TemporaryEntry> tempEntries = new ArrayList<TemporaryEntry>();
-
- Cursor cursor = null;
- try {
- // We don't want to pass this Cursor object to UI thread (b/5017608).
- // Assuming the result should contain fairly small results (at most ~10),
- // We just copy everything to local structure.
- cursor = doQuery(constraint, getLimit(), mParams.directoryId);
-
- if (cursor != null) {
- while (cursor.moveToNext()) {
- tempEntries.add(new TemporaryEntry(cursor, mParams.directoryId));
- }
- }
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- if (!tempEntries.isEmpty()) {
- results.values = tempEntries;
- results.count = 1;
- }
- }
-
- if (DEBUG) {
- Log.v(TAG, "finished loading directory \"" + mParams.displayName + "\"" +
- " with query " + constraint);
- }
-
- return results;
- }
-
- @Override
- protected void publishResults(final CharSequence constraint, FilterResults results) {
- if (DEBUG) {
- Log.d(TAG, "DirectoryFilter#publishResult. constraint: " + constraint
- + ", mCurrentConstraint: " + mCurrentConstraint);
- }
- mDelayedMessageHandler.removeDelayedLoadMessage();
- // Check if the received result matches the current constraint
- // If not - the user must have continued typing after the request was issued, which
- // means several member variables (like mRemainingDirectoryLoad) are already
- // overwritten so shouldn't be touched here anymore.
- if (TextUtils.equals(constraint, mCurrentConstraint)) {
- if (results.count > 0) {
- @SuppressWarnings("unchecked")
- final ArrayList<TemporaryEntry> tempEntries =
- (ArrayList<TemporaryEntry>) results.values;
-
- for (TemporaryEntry tempEntry : tempEntries) {
- putOneEntry(tempEntry, mParams.directoryId == Directory.DEFAULT,
- mEntryMap, mNonAggregatedEntries, mExistingDestinations);
- }
- }
-
- // If there are remaining directories, set up delayed message again.
- mRemainingDirectoryCount--;
- if (mRemainingDirectoryCount > 0) {
- if (DEBUG) {
- Log.d(TAG, "Resend delayed load message. Current mRemainingDirectoryLoad: "
- + mRemainingDirectoryCount);
- }
- mDelayedMessageHandler.sendDelayedLoadMessage();
- }
-
- // If this directory result has some items, or there are no more directories that
- // we are waiting for, clear the temp results
- if (results.count > 0 || mRemainingDirectoryCount == 0) {
- // Clear the temp entries
- clearTempEntries();
- }
- }
-
- // Show the list again without "waiting" message.
- updateEntries(constructEntryList(mEntryMap, mNonAggregatedEntries));
- }
- }
-
- private final Context mContext;
- private final ContentResolver mContentResolver;
- private final LayoutInflater mInflater;
- private Account mAccount;
- private final int mPreferredMaxResultCount;
- private DropdownChipLayouter mDropdownChipLayouter;
-
- /**
- * {@link #mEntries} is responsible for showing every result for this Adapter. To
- * construct it, we use {@link #mEntryMap}, {@link #mNonAggregatedEntries}, and
- * {@link #mExistingDestinations}.
- *
- * First, each destination (an email address or a phone number) with a valid contactId is
- * inserted into {@link #mEntryMap} and grouped by the contactId. Destinations without valid
- * contactId (possible if they aren't in local storage) are stored in
- * {@link #mNonAggregatedEntries}.
- * Duplicates are removed using {@link #mExistingDestinations}.
- *
- * After having all results from Cursor objects, all destinations in mEntryMap are copied to
- * {@link #mEntries}. If the number of destinations is not enough (i.e. less than
- * {@link #mPreferredMaxResultCount}), destinations in mNonAggregatedEntries are also used.
- *
- * These variables are only used in UI thread, thus should not be touched in
- * performFiltering() methods.
- */
- private LinkedHashMap<Long, List<RecipientEntry>> mEntryMap;
- private List<RecipientEntry> mNonAggregatedEntries;
- private Set<String> mExistingDestinations;
- /** Note: use {@link #updateEntries(List)} to update this variable. */
- private List<RecipientEntry> mEntries;
- private List<RecipientEntry> mTempEntries;
-
- /** The number of directories this adapter is waiting for results. */
- private int mRemainingDirectoryCount;
-
- /**
- * Used to ignore asynchronous queries with a different constraint, which may happen when
- * users type characters quickly.
- */
- private CharSequence mCurrentConstraint;
-
- private final LruCache<Uri, byte[]> mPhotoCacheMap;
-
- /**
- * Handler specific for maintaining "Waiting for more contacts" message, which will be shown
- * when:
- * - there are directories to be searched
- * - results from directories are slow to come
- */
- private final class DelayedMessageHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- if (mRemainingDirectoryCount > 0) {
- updateEntries(constructEntryList(mEntryMap, mNonAggregatedEntries));
- }
- }
-
- public void sendDelayedLoadMessage() {
- sendMessageDelayed(obtainMessage(MESSAGE_SEARCH_PENDING, 0, 0, null),
- MESSAGE_SEARCH_PENDING_DELAY);
- }
-
- public void removeDelayedLoadMessage() {
- removeMessages(MESSAGE_SEARCH_PENDING);
- }
- }
-
- private final DelayedMessageHandler mDelayedMessageHandler = new DelayedMessageHandler();
-
- private EntriesUpdatedObserver mEntriesUpdatedObserver;
-
- /**
- * Constructor for email queries.
- */
- public BaseRecipientAdapter(Context context) {
- this(context, DEFAULT_PREFERRED_MAX_RESULT_COUNT, QUERY_TYPE_EMAIL);
- }
-
- public BaseRecipientAdapter(Context context, int preferredMaxResultCount) {
- this(context, preferredMaxResultCount, QUERY_TYPE_EMAIL);
- }
-
- public BaseRecipientAdapter(int queryMode, Context context) {
- this(context, DEFAULT_PREFERRED_MAX_RESULT_COUNT, queryMode);
- }
-
- public BaseRecipientAdapter(int queryMode, Context context, int preferredMaxResultCount) {
- this(context, preferredMaxResultCount, queryMode);
- }
-
- public BaseRecipientAdapter(Context context, int preferredMaxResultCount, int queryMode) {
- mContext = context;
- mContentResolver = context.getContentResolver();
- mInflater = LayoutInflater.from(context);
- mPreferredMaxResultCount = preferredMaxResultCount;
- mPhotoCacheMap = new LruCache<Uri, byte[]>(PHOTO_CACHE_SIZE);
- mQueryType = queryMode;
-
- if (queryMode == QUERY_TYPE_EMAIL) {
- mQuery = Queries.EMAIL;
- } else if (queryMode == QUERY_TYPE_PHONE) {
- mQuery = Queries.PHONE;
- } else {
- mQuery = Queries.EMAIL;
- Log.e(TAG, "Unsupported query type: " + queryMode);
- }
- }
-
- public Context getContext() {
- return mContext;
- }
-
- public int getQueryType() {
- return mQueryType;
- }
-
- public void setDropdownChipLayouter(DropdownChipLayouter dropdownChipLayouter) {
- mDropdownChipLayouter = dropdownChipLayouter;
- mDropdownChipLayouter.setQuery(mQuery);
- }
-
- public DropdownChipLayouter getDropdownChipLayouter() {
- return mDropdownChipLayouter;
- }
-
- /**
- * Set the account when known. Causes the search to prioritize contacts from that account.
- */
- @Override
- public void setAccount(Account account) {
- mAccount = account;
- }
-
- /** Will be called from {@link AutoCompleteTextView} to prepare auto-complete list. */
- @Override
- public Filter getFilter() {
- return new DefaultFilter();
- }
-
- /**
- * An extesion to {@link RecipientAlternatesAdapter#getMatchingRecipients} that allows
- * additional sources of contacts to be considered as matching recipients.
- * @param addresses A set of addresses to be matched
- * @return A list of matches or null if none found
- */
- public Map<String, RecipientEntry> getMatchingRecipients(Set<String> addresses) {
- return null;
- }
-
- public static List<DirectorySearchParams> setupOtherDirectories(Context context,
- Cursor directoryCursor, Account account) {
- final PackageManager packageManager = context.getPackageManager();
- final List<DirectorySearchParams> paramsList = new ArrayList<DirectorySearchParams>();
- DirectorySearchParams preferredDirectory = null;
- while (directoryCursor.moveToNext()) {
- final long id = directoryCursor.getLong(DirectoryListQuery.ID);
-
- // Skip the local invisible directory, because the default directory already includes
- // all local results.
- if (id == Directory.LOCAL_INVISIBLE) {
- continue;
- }
-
- final DirectorySearchParams params = new DirectorySearchParams();
- final String packageName = directoryCursor.getString(DirectoryListQuery.PACKAGE_NAME);
- final int resourceId = directoryCursor.getInt(DirectoryListQuery.TYPE_RESOURCE_ID);
- params.directoryId = id;
- params.displayName = directoryCursor.getString(DirectoryListQuery.DISPLAY_NAME);
- params.accountName = directoryCursor.getString(DirectoryListQuery.ACCOUNT_NAME);
- params.accountType = directoryCursor.getString(DirectoryListQuery.ACCOUNT_TYPE);
- if (packageName != null && resourceId != 0) {
- try {
- final Resources resources =
- packageManager.getResourcesForApplication(packageName);
- params.directoryType = resources.getString(resourceId);
- if (params.directoryType == null) {
- Log.e(TAG, "Cannot resolve directory name: "
- + resourceId + "@" + packageName);
- }
- } catch (NameNotFoundException e) {
- Log.e(TAG, "Cannot resolve directory name: "
- + resourceId + "@" + packageName, e);
- }
- }
-
- // If an account has been provided and we found a directory that
- // corresponds to that account, place that directory second, directly
- // underneath the local contacts.
- if (account != null && account.name.equals(params.accountName) &&
- account.type.equals(params.accountType)) {
- preferredDirectory = params;
- } else {
- paramsList.add(params);
- }
- }
-
- if (preferredDirectory != null) {
- paramsList.add(1, preferredDirectory);
- }
-
- return paramsList;
- }
-
- /**
- * Starts search in other directories using {@link Filter}. Results will be handled in
- * {@link DirectoryFilter}.
- */
- protected void startSearchOtherDirectories(
- CharSequence constraint, List<DirectorySearchParams> paramsList, int limit) {
- final int count = paramsList.size();
- // Note: skipping the default partition (index 0), which has already been loaded
- for (int i = 1; i < count; i++) {
- final DirectorySearchParams params = paramsList.get(i);
- params.constraint = constraint;
- if (params.filter == null) {
- params.filter = new DirectoryFilter(params);
- }
- params.filter.setLimit(limit);
- params.filter.filter(constraint);
- }
-
- // Directory search started. We may show "waiting" message if directory results are slow
- // enough.
- mRemainingDirectoryCount = count - 1;
- mDelayedMessageHandler.sendDelayedLoadMessage();
- }
-
- private static void putOneEntry(TemporaryEntry entry, boolean isAggregatedEntry,
- LinkedHashMap<Long, List<RecipientEntry>> entryMap,
- List<RecipientEntry> nonAggregatedEntries,
- Set<String> existingDestinations) {
- if (existingDestinations.contains(entry.destination)) {
- return;
- }
-
- existingDestinations.add(entry.destination);
-
- if (!isAggregatedEntry) {
- nonAggregatedEntries.add(RecipientEntry.constructTopLevelEntry(
- entry.displayName,
- entry.displayNameSource,
- entry.destination, entry.destinationType, entry.destinationLabel,
- entry.contactId, entry.directoryId, entry.dataId, entry.thumbnailUriString,
- true, entry.lookupKey));
- } else if (entryMap.containsKey(entry.contactId)) {
- // We already have a section for the person.
- final List<RecipientEntry> entryList = entryMap.get(entry.contactId);
- entryList.add(RecipientEntry.constructSecondLevelEntry(
- entry.displayName,
- entry.displayNameSource,
- entry.destination, entry.destinationType, entry.destinationLabel,
- entry.contactId, entry.directoryId, entry.dataId, entry.thumbnailUriString,
- true, entry.lookupKey));
- } else {
- final List<RecipientEntry> entryList = new ArrayList<RecipientEntry>();
- entryList.add(RecipientEntry.constructTopLevelEntry(
- entry.displayName,
- entry.displayNameSource,
- entry.destination, entry.destinationType, entry.destinationLabel,
- entry.contactId, entry.directoryId, entry.dataId, entry.thumbnailUriString,
- true, entry.lookupKey));
- entryMap.put(entry.contactId, entryList);
- }
- }
-
- /**
- * Constructs an actual list for this Adapter using {@link #mEntryMap}. Also tries to
- * fetch a cached photo for each contact entry (other than separators), or request another
- * thread to get one from directories.
- */
- private List<RecipientEntry> constructEntryList(
- LinkedHashMap<Long, List<RecipientEntry>> entryMap,
- List<RecipientEntry> nonAggregatedEntries) {
- final List<RecipientEntry> entries = new ArrayList<RecipientEntry>();
- int validEntryCount = 0;
- for (Map.Entry<Long, List<RecipientEntry>> mapEntry : entryMap.entrySet()) {
- final List<RecipientEntry> entryList = mapEntry.getValue();
- final int size = entryList.size();
- for (int i = 0; i < size; i++) {
- RecipientEntry entry = entryList.get(i);
- entries.add(entry);
- tryFetchPhoto(entry);
- validEntryCount++;
- }
- if (validEntryCount > mPreferredMaxResultCount) {
- break;
- }
- }
- if (validEntryCount <= mPreferredMaxResultCount) {
- for (RecipientEntry entry : nonAggregatedEntries) {
- if (validEntryCount > mPreferredMaxResultCount) {
- break;
- }
- entries.add(entry);
- tryFetchPhoto(entry);
-
- validEntryCount++;
- }
- }
-
- return entries;
- }
-
-
- public interface EntriesUpdatedObserver {
- public void onChanged(List<RecipientEntry> entries);
- }
-
- public void registerUpdateObserver(EntriesUpdatedObserver observer) {
- mEntriesUpdatedObserver = observer;
- }
-
- /** Resets {@link #mEntries} and notify the event to its parent ListView. */
- private void updateEntries(List<RecipientEntry> newEntries) {
- mEntries = newEntries;
- mEntriesUpdatedObserver.onChanged(newEntries);
- notifyDataSetChanged();
- }
-
- private void cacheCurrentEntries() {
- mTempEntries = mEntries;
- }
-
- private void clearTempEntries() {
- mTempEntries = null;
- }
-
- protected List<RecipientEntry> getEntries() {
- return mTempEntries != null ? mTempEntries : mEntries;
- }
-
- private void tryFetchPhoto(final RecipientEntry entry) {
- final Uri photoThumbnailUri = entry.getPhotoThumbnailUri();
- if (photoThumbnailUri != null) {
- final byte[] photoBytes = mPhotoCacheMap.get(photoThumbnailUri);
- if (photoBytes != null) {
- entry.setPhotoBytes(photoBytes);
- // notifyDataSetChanged() should be called by a caller.
- } else {
- if (DEBUG) {
- Log.d(TAG, "No photo cache for " + entry.getDisplayName()
- + ". Fetch one asynchronously");
- }
- fetchPhotoAsync(entry, photoThumbnailUri);
- }
- }
- }
-
- // For reading photos for directory contacts, this is the chunksize for
- // copying from the inputstream to the output stream.
- private static final int BUFFER_SIZE = 1024*16;
-
- private void fetchPhotoAsync(final RecipientEntry entry, final Uri photoThumbnailUri) {
- final AsyncTask<Void, Void, byte[]> photoLoadTask = new AsyncTask<Void, Void, byte[]>() {
- @Override
- protected byte[] doInBackground(Void... params) {
- // First try running a query. Images for local contacts are
- // loaded by sending a query to the ContactsProvider.
- final Cursor photoCursor = mContentResolver.query(
- photoThumbnailUri, PhotoQuery.PROJECTION, null, null, null);
- if (photoCursor != null) {
- try {
- if (photoCursor.moveToFirst()) {
- return photoCursor.getBlob(PhotoQuery.PHOTO);
- }
- } finally {
- photoCursor.close();
- }
- } else {
- // If the query fails, try streaming the URI directly.
- // For remote directory images, this URI resolves to the
- // directory provider and the images are loaded by sending
- // an openFile call to the provider.
- try {
- InputStream is = mContentResolver.openInputStream(
- photoThumbnailUri);
- if (is != null) {
- byte[] buffer = new byte[BUFFER_SIZE];
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try {
- int size;
- while ((size = is.read(buffer)) != -1) {
- baos.write(buffer, 0, size);
- }
- } finally {
- is.close();
- }
- return baos.toByteArray();
- }
- } catch (IOException ex) {
- // ignore
- }
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(final byte[] photoBytes) {
- entry.setPhotoBytes(photoBytes);
- if (photoBytes != null) {
- mPhotoCacheMap.put(photoThumbnailUri, photoBytes);
- notifyDataSetChanged();
- }
- }
- };
- photoLoadTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
- }
-
- protected void fetchPhoto(final RecipientEntry entry, final Uri photoThumbnailUri) {
- byte[] photoBytes = mPhotoCacheMap.get(photoThumbnailUri);
- if (photoBytes != null) {
- entry.setPhotoBytes(photoBytes);
- return;
- }
- final Cursor photoCursor = mContentResolver.query(photoThumbnailUri, PhotoQuery.PROJECTION,
- null, null, null);
- if (photoCursor != null) {
- try {
- if (photoCursor.moveToFirst()) {
- photoBytes = photoCursor.getBlob(PhotoQuery.PHOTO);
- entry.setPhotoBytes(photoBytes);
- mPhotoCacheMap.put(photoThumbnailUri, photoBytes);
- }
- } finally {
- photoCursor.close();
- }
- } else {
- InputStream inputStream = null;
- ByteArrayOutputStream outputStream = null;
- try {
- inputStream = mContentResolver.openInputStream(photoThumbnailUri);
- final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
-
- if (bitmap != null) {
- outputStream = new ByteArrayOutputStream();
- bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
- photoBytes = outputStream.toByteArray();
-
- entry.setPhotoBytes(photoBytes);
- mPhotoCacheMap.put(photoThumbnailUri, photoBytes);
- }
- } catch (final FileNotFoundException e) {
- Log.w(TAG, "Error opening InputStream for photo", e);
- } finally {
- try {
- if (inputStream != null) {
- inputStream.close();
- }
- } catch (IOException e) {
- Log.e(TAG, "Error closing photo input stream", e);
- }
- try {
- if (outputStream != null) {
- outputStream.close();
- }
- } catch (IOException e) {
- Log.e(TAG, "Error closing photo output stream", e);
- }
- }
- }
- }
-
- private Cursor doQuery(CharSequence constraint, int limit, Long directoryId) {
- final Uri.Builder builder = mQuery.getContentFilterUri().buildUpon()
- .appendPath(constraint.toString())
- .appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY,
- String.valueOf(limit + ALLOWANCE_FOR_DUPLICATES));
- if (directoryId != null) {
- builder.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
- String.valueOf(directoryId));
- }
- if (mAccount != null) {
- builder.appendQueryParameter(PRIMARY_ACCOUNT_NAME, mAccount.name);
- builder.appendQueryParameter(PRIMARY_ACCOUNT_TYPE, mAccount.type);
- }
- final long start = System.currentTimeMillis();
- final Cursor cursor = mContentResolver.query(
- builder.build(), mQuery.getProjection(), null, null, null);
- final long end = System.currentTimeMillis();
- if (DEBUG) {
- Log.d(TAG, "Time for autocomplete (query: " + constraint
- + ", directoryId: " + directoryId + ", num_of_results: "
- + (cursor != null ? cursor.getCount() : "null") + "): "
- + (end - start) + " ms");
- }
- return cursor;
- }
-
- // TODO: This won't be used at all. We should find better way to quit the thread..
- /*public void close() {
- mEntries = null;
- mPhotoCacheMap.evictAll();
- if (!sPhotoHandlerThread.quit()) {
- Log.w(TAG, "Failed to quit photo handler thread, ignoring it.");
- }
- }*/
-
- @Override
- public int getCount() {
- final List<RecipientEntry> entries = getEntries();
- return entries != null ? entries.size() : 0;
- }
-
- @Override
- public RecipientEntry getItem(int position) {
- return getEntries().get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public int getViewTypeCount() {
- return RecipientEntry.ENTRY_TYPE_SIZE;
- }
-
- @Override
- public int getItemViewType(int position) {
- return getEntries().get(position).getEntryType();
- }
-
- @Override
- public boolean isEnabled(int position) {
- return getEntries().get(position).isSelectable();
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- final RecipientEntry entry = getEntries().get(position);
-
- final String constraint = mCurrentConstraint == null ? null :
- mCurrentConstraint.toString();
-
- return mDropdownChipLayouter.bindView(convertView, parent, entry, position,
- AdapterType.BASE_RECIPIENT, constraint);
- }
-
- public Account getAccount() {
- return mAccount;
- }
-}
diff --git a/chips/src/com/android/ex/chips/ChipsUtil.java b/chips/src/com/android/ex/chips/ChipsUtil.java
deleted file mode 100644
index 559b2c9..0000000
--- a/chips/src/com/android/ex/chips/ChipsUtil.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2011 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.ex.chips;
-
-import android.os.Build;
-
-public class ChipsUtil {
-
- /**
- * @return true when the caller can use Chips UI in its environment.
- */
- public static boolean supportsChipsUi() {
- return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
- }
-}
\ No newline at end of file
diff --git a/chips/src/com/android/ex/chips/DropdownChipLayouter.java b/chips/src/com/android/ex/chips/DropdownChipLayouter.java
deleted file mode 100644
index 6b0e78e..0000000
--- a/chips/src/com/android/ex/chips/DropdownChipLayouter.java
+++ /dev/null
@@ -1,274 +0,0 @@
-package com.android.ex.chips;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.Uri;
-import android.text.TextUtils;
-import android.text.util.Rfc822Tokenizer;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.ex.chips.Queries.Query;
-
-/**
- * A class that inflates and binds the views in the dropdown list from
- * RecipientEditTextView.
- */
-public class DropdownChipLayouter {
- /**
- * The type of adapter that is requesting a chip layout.
- */
- public enum AdapterType {
- BASE_RECIPIENT,
- RECIPIENT_ALTERNATES,
- SINGLE_RECIPIENT
- }
-
- private final LayoutInflater mInflater;
- private final Context mContext;
- private Query mQuery;
-
- public DropdownChipLayouter(LayoutInflater inflater, Context context) {
- mInflater = inflater;
- mContext = context;
- }
-
- public void setQuery(Query query) {
- mQuery = query;
- }
-
-
- /**
- * Layouts and binds recipient information to the view. If convertView is null, inflates a new
- * view with getItemLaytout().
- *
- * @param convertView The view to bind information to.
- * @param parent The parent to bind the view to if we inflate a new view.
- * @param entry The recipient entry to get information from.
- * @param position The position in the list.
- * @param type The adapter type that is requesting the bind.
- * @param constraint The constraint typed in the auto complete view.
- *
- * @return A view ready to be shown in the drop down list.
- */
- public View bindView(View convertView, ViewGroup parent, RecipientEntry entry, int position,
- AdapterType type, String constraint) {
- // Default to show all the information
- String displayName = entry.getDisplayName();
- String destination = entry.getDestination();
- boolean showImage = true;
- CharSequence destinationType = getDestinationType(entry);
-
- final View itemView = reuseOrInflateView(convertView, parent, type);
-
- final ViewHolder viewHolder = new ViewHolder(itemView);
-
- // Hide some information depending on the entry type and adapter type
- switch (type) {
- case BASE_RECIPIENT:
- if (TextUtils.isEmpty(displayName) || TextUtils.equals(displayName, destination)) {
- displayName = destination;
-
- // We only show the destination for secondary entries, so clear it only for the
- // first level.
- if (entry.isFirstLevel()) {
- destination = null;
- }
- }
-
- if (!entry.isFirstLevel()) {
- displayName = null;
- showImage = false;
- }
- break;
- case RECIPIENT_ALTERNATES:
- if (position != 0) {
- displayName = null;
- showImage = false;
- }
- break;
- case SINGLE_RECIPIENT:
- destination = Rfc822Tokenizer.tokenize(entry.getDestination())[0].getAddress();
- destinationType = null;
- }
-
- // Bind the information to the view
- bindTextToView(displayName, viewHolder.displayNameView);
- bindTextToView(destination, viewHolder.destinationView);
- bindTextToView(destinationType, viewHolder.destinationTypeView);
- bindIconToView(showImage, entry, viewHolder.imageView, type);
-
- return itemView;
- }
-
- /**
- * Returns a new view with {@link #getItemLayoutResId()}.
- */
- public View newView() {
- return mInflater.inflate(getItemLayoutResId(), null);
- }
-
- /**
- * Returns the same view, or inflates a new one if the given view was null.
- */
- protected View reuseOrInflateView(View convertView, ViewGroup parent, AdapterType type) {
- int itemLayout = getItemLayoutResId();
- switch (type) {
- case BASE_RECIPIENT:
- case RECIPIENT_ALTERNATES:
- break;
- case SINGLE_RECIPIENT:
- itemLayout = getAlternateItemLayoutResId();
- break;
- }
- return convertView != null ? convertView : mInflater.inflate(itemLayout, parent, false);
- }
-
- /**
- * Binds the text to the given text view. If the text was null, hides the text view.
- */
- protected void bindTextToView(CharSequence text, TextView view) {
- if (view == null) {
- return;
- }
-
- if (text != null) {
- view.setText(text);
- view.setVisibility(View.VISIBLE);
- } else {
- view.setVisibility(View.GONE);
- }
- }
-
- /**
- * Binds the avatar icon to the image view. If we don't want to show the image, hides the
- * image view.
- */
- protected void bindIconToView(boolean showImage, RecipientEntry entry, ImageView view,
- AdapterType type) {
- if (view == null) {
- return;
- }
-
- if (showImage) {
- switch (type) {
- case BASE_RECIPIENT:
- byte[] photoBytes = entry.getPhotoBytes();
- if (photoBytes != null && photoBytes.length > 0) {
- final Bitmap photo = BitmapFactory.decodeByteArray(photoBytes, 0,
- photoBytes.length);
- view.setImageBitmap(photo);
- } else {
- view.setImageResource(getDefaultPhotoResId());
- }
- break;
- case RECIPIENT_ALTERNATES:
- Uri thumbnailUri = entry.getPhotoThumbnailUri();
- if (thumbnailUri != null) {
- // TODO: see if this needs to be done outside the main thread
- // as it may be too slow to get immediately.
- view.setImageURI(thumbnailUri);
- } else {
- view.setImageResource(getDefaultPhotoResId());
- }
- break;
- case SINGLE_RECIPIENT:
- default:
- break;
- }
- view.setVisibility(View.VISIBLE);
- } else {
- view.setVisibility(View.GONE);
- }
- }
-
- protected CharSequence getDestinationType(RecipientEntry entry) {
- return mQuery.getTypeLabel(mContext.getResources(), entry.getDestinationType(),
- entry.getDestinationLabel()).toString().toUpperCase();
- }
-
- /**
- * Returns a layout id for each item inside auto-complete list.
- *
- * Each View must contain two TextViews (for display name and destination) and one ImageView
- * (for photo). Ids for those should be available via {@link #getDisplayNameResId()},
- * {@link #getDestinationResId()}, and {@link #getPhotoResId()}.
- */
- protected int getItemLayoutResId() {
- return R.layout.chips_recipient_dropdown_item;
- }
-
- /**
- * Returns a layout id for each item inside alternate auto-complete list.
- *
- * Each View must contain two TextViews (for display name and destination) and one ImageView
- * (for photo). Ids for those should be available via {@link #getDisplayNameResId()},
- * {@link #getDestinationResId()}, and {@link #getPhotoResId()}.
- */
- protected int getAlternateItemLayoutResId() {
- return R.layout.chips_alternate_item;
- }
-
- /**
- * Returns a resource ID representing an image which should be shown when ther's no relevant
- * photo is available.
- */
- protected int getDefaultPhotoResId() {
- return R.drawable.ic_contact_picture;
- }
-
- /**
- * Returns an id for TextView in an item View for showing a display name. By default
- * {@link android.R.id#title} is returned.
- */
- protected int getDisplayNameResId() {
- return android.R.id.title;
- }
-
- /**
- * Returns an id for TextView in an item View for showing a destination
- * (an email address or a phone number).
- * By default {@link android.R.id#text1} is returned.
- */
- protected int getDestinationResId() {
- return android.R.id.text1;
- }
-
- /**
- * Returns an id for TextView in an item View for showing the type of the destination.
- * By default {@link android.R.id#text2} is returned.
- */
- protected int getDestinationTypeResId() {
- return android.R.id.text2;
- }
-
- /**
- * Returns an id for ImageView in an item View for showing photo image for a person. In default
- * {@link android.R.id#icon} is returned.
- */
- protected int getPhotoResId() {
- return android.R.id.icon;
- }
-
- /**
- * A holder class the view. Uses the getters in DropdownChipLayouter to find the id of the
- * corresponding views.
- */
- protected class ViewHolder {
- public final TextView displayNameView;
- public final TextView destinationView;
- public final TextView destinationTypeView;
- public final ImageView imageView;
-
- public ViewHolder(View view) {
- displayNameView = (TextView) view.findViewById(getDisplayNameResId());
- destinationView = (TextView) view.findViewById(getDestinationResId());
- destinationTypeView = (TextView) view.findViewById(getDestinationTypeResId());
- imageView = (ImageView) view.findViewById(getPhotoResId());
- }
- }
-}
diff --git a/chips/src/com/android/ex/chips/Queries.java b/chips/src/com/android/ex/chips/Queries.java
deleted file mode 100644
index 1e66b96..0000000
--- a/chips/src/com/android/ex/chips/Queries.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2012 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.ex.chips;
-
-import android.content.res.Resources;
-import android.net.Uri;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.Contacts;
-
-/**
- * Phone and Email queries for supporting Chips UI.
- */
-/* package */ class Queries {
-
- public static final Query PHONE = new Query(new String[] {
- Contacts.DISPLAY_NAME, // 0
- Phone.NUMBER, // 1
- Phone.TYPE, // 2
- Phone.LABEL, // 3
- Phone.CONTACT_ID, // 4
- Phone._ID, // 5
- Contacts.PHOTO_THUMBNAIL_URI, // 6
- Contacts.DISPLAY_NAME_SOURCE, // 7
- Contacts.LOOKUP_KEY, // 8
- ContactsContract.CommonDataKinds.Email.MIMETYPE // 9
- }, Phone.CONTENT_FILTER_URI, Phone.CONTENT_URI) {
-
- @Override
- public CharSequence getTypeLabel(Resources res, int type, CharSequence label) {
- return Phone.getTypeLabel(res, type, label);
- }
-
- };
-
- public static final Query EMAIL = new Query(new String[]{
- Contacts.DISPLAY_NAME, // 0
- Email.DATA, // 1
- Email.TYPE, // 2
- Email.LABEL, // 3
- Email.CONTACT_ID, // 4
- Email._ID, // 5
- Contacts.PHOTO_THUMBNAIL_URI, // 6
- Contacts.DISPLAY_NAME_SOURCE, // 7
- Contacts.LOOKUP_KEY, // 8
- ContactsContract.CommonDataKinds.Email.MIMETYPE // 9
- }, Email.CONTENT_FILTER_URI, Email.CONTENT_URI) {
-
- @Override
- public CharSequence getTypeLabel(Resources res, int type, CharSequence label) {
- return Email.getTypeLabel(res, type, label);
- }
-
- };
-
- static abstract class Query {
- private final String[] mProjection;
- private final Uri mContentFilterUri;
- private final Uri mContentUri;
-
- public static final int NAME = 0; // String
- public static final int DESTINATION = 1; // String
- public static final int DESTINATION_TYPE = 2; // int
- public static final int DESTINATION_LABEL = 3; // String
- public static final int CONTACT_ID = 4; // long
- public static final int DATA_ID = 5; // long
- public static final int PHOTO_THUMBNAIL_URI = 6; // String
- public static final int DISPLAY_NAME_SOURCE = 7; // int
- public static final int LOOKUP_KEY = 8; // String
- public static final int MIME_TYPE = 9; // String
-
- public Query(String[] projection, Uri contentFilter, Uri content) {
- mProjection = projection;
- mContentFilterUri = contentFilter;
- mContentUri = content;
- }
-
- public String[] getProjection() {
- return mProjection;
- }
-
- public Uri getContentFilterUri() {
- return mContentFilterUri;
- }
-
- public Uri getContentUri() {
- return mContentUri;
- }
-
- public abstract CharSequence getTypeLabel(Resources res, int type, CharSequence label);
- }
-}
diff --git a/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java b/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java
deleted file mode 100644
index f6f662d..0000000
--- a/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (C) 2011 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.ex.chips;
-
-import android.accounts.Account;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.Uri;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Contacts;
-import android.text.TextUtils;
-import android.text.util.Rfc822Token;
-import android.text.util.Rfc822Tokenizer;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CursorAdapter;
-
-import com.android.ex.chips.BaseRecipientAdapter.DirectoryListQuery;
-import com.android.ex.chips.BaseRecipientAdapter.DirectorySearchParams;
-import com.android.ex.chips.DropdownChipLayouter.AdapterType;
-import com.android.ex.chips.Queries.Query;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * RecipientAlternatesAdapter backs the RecipientEditTextView for managing contacts
- * queried by email or by phone number.
- */
-public class RecipientAlternatesAdapter extends CursorAdapter {
- static final int MAX_LOOKUPS = 50;
-
- private final long mCurrentId;
-
- private int mCheckedItemPosition = -1;
-
- private OnCheckedItemChangedListener mCheckedItemChangedListener;
-
- private static final String TAG = "RecipAlternates";
-
- public static final int QUERY_TYPE_EMAIL = 0;
- public static final int QUERY_TYPE_PHONE = 1;
- private final Long mDirectoryId;
- private DropdownChipLayouter mDropdownChipLayouter;
-
- private static final Map<String, String> sCorrectedPhotoUris = new HashMap<String, String>();
-
- public interface RecipientMatchCallback {
- public void matchesFound(Map<String, RecipientEntry> results);
- /**
- * Called with all addresses that could not be resolved to valid recipients.
- */
- public void matchesNotFound(Set<String> unfoundAddresses);
- }
-
- public static void getMatchingRecipients(Context context, BaseRecipientAdapter adapter,
- ArrayList<String> inAddresses, Account account, RecipientMatchCallback callback) {
- getMatchingRecipients(context, adapter, inAddresses, QUERY_TYPE_EMAIL, account, callback);
- }
-
- /**
- * Get a HashMap of address to RecipientEntry that contains all contact
- * information for a contact with the provided address, if one exists. This
- * may block the UI, so run it in an async task.
- *
- * @param context Context.
- * @param inAddresses Array of addresses on which to perform the lookup.
- * @param callback RecipientMatchCallback called when a match or matches are found.
- * @return HashMap<String,RecipientEntry>
- */
- public static void getMatchingRecipients(Context context, BaseRecipientAdapter adapter,
- ArrayList<String> inAddresses, int addressType, Account account,
- RecipientMatchCallback callback) {
- Queries.Query query;
- if (addressType == QUERY_TYPE_EMAIL) {
- query = Queries.EMAIL;
- } else {
- query = Queries.PHONE;
- }
- int addressesSize = Math.min(MAX_LOOKUPS, inAddresses.size());
- HashSet<String> addresses = new HashSet<String>();
- StringBuilder bindString = new StringBuilder();
- // Create the "?" string and set up arguments.
- for (int i = 0; i < addressesSize; i++) {
- Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(inAddresses.get(i).toLowerCase());
- addresses.add(tokens.length > 0 ? tokens[0].getAddress() : inAddresses.get(i));
- bindString.append("?");
- if (i < addressesSize - 1) {
- bindString.append(",");
- }
- }
-
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Doing reverse lookup for " + addresses.toString());
- }
-
- String[] addressArray = new String[addresses.size()];
- addresses.toArray(addressArray);
- HashMap<String, RecipientEntry> recipientEntries = null;
- Cursor c = null;
-
- try {
- c = context.getContentResolver().query(
- query.getContentUri(),
- query.getProjection(),
- query.getProjection()[Queries.Query.DESTINATION] + " IN ("
- + bindString.toString() + ")", addressArray, null);
- recipientEntries = processContactEntries(c, null /* directoryId */);
- callback.matchesFound(recipientEntries);
- } finally {
- if (c != null) {
- c.close();
- }
- }
- // See if any entries did not resolve; if so, we need to check other
- // directories
- final Set<String> matchesNotFound = new HashSet<String>();
- if (recipientEntries.size() < addresses.size()) {
- final List<DirectorySearchParams> paramsList;
- Cursor directoryCursor = null;
- try {
- directoryCursor = context.getContentResolver().query(DirectoryListQuery.URI,
- DirectoryListQuery.PROJECTION, null, null, null);
- if (directoryCursor == null) {
- paramsList = null;
- } else {
- paramsList = BaseRecipientAdapter.setupOtherDirectories(context,
- directoryCursor, account);
- }
- } finally {
- if (directoryCursor != null) {
- directoryCursor.close();
- }
- }
- // Run a directory query for each unmatched recipient.
- HashSet<String> unresolvedAddresses = new HashSet<String>();
- for (String address : addresses) {
- if (!recipientEntries.containsKey(address)) {
- unresolvedAddresses.add(address);
- }
- }
-
- matchesNotFound.addAll(unresolvedAddresses);
-
- if (paramsList != null) {
- Cursor directoryContactsCursor = null;
- for (String unresolvedAddress : unresolvedAddresses) {
- Long directoryId = null;
- for (int i = 0; i < paramsList.size(); i++) {
- try {
- directoryContactsCursor = doQuery(unresolvedAddress, 1,
- paramsList.get(i).directoryId, account,
- context.getContentResolver(), query);
- } finally {
- if (directoryContactsCursor != null
- && directoryContactsCursor.getCount() == 0) {
- directoryContactsCursor.close();
- directoryContactsCursor = null;
- } else {
- directoryId = paramsList.get(i).directoryId;
- break;
- }
- }
- }
- if (directoryContactsCursor != null) {
- try {
- final Map<String, RecipientEntry> entries =
- processContactEntries(directoryContactsCursor, directoryId);
-
- for (final String address : entries.keySet()) {
- matchesNotFound.remove(address);
- }
-
- callback.matchesFound(entries);
- } finally {
- directoryContactsCursor.close();
- }
- }
- }
- }
- }
-
- // If no matches found in contact provider or the directories, try the extension
- // matcher.
- // todo (aalbert): This whole method needs to be in the adapter?
- if (adapter != null) {
- final Map<String, RecipientEntry> entries =
- adapter.getMatchingRecipients(matchesNotFound);
- if (entries != null && entries.size() > 0) {
- callback.matchesFound(entries);
- for (final String address : entries.keySet()) {
- matchesNotFound.remove(address);
- }
- }
- }
- callback.matchesNotFound(matchesNotFound);
- }
-
- private static HashMap<String, RecipientEntry> processContactEntries(Cursor c,
- Long directoryId) {
- HashMap<String, RecipientEntry> recipientEntries = new HashMap<String, RecipientEntry>();
- if (c != null && c.moveToFirst()) {
- do {
- String address = c.getString(Queries.Query.DESTINATION);
-
- final RecipientEntry newRecipientEntry = RecipientEntry.constructTopLevelEntry(
- c.getString(Queries.Query.NAME),
- c.getInt(Queries.Query.DISPLAY_NAME_SOURCE),
- c.getString(Queries.Query.DESTINATION),
- c.getInt(Queries.Query.DESTINATION_TYPE),
- c.getString(Queries.Query.DESTINATION_LABEL),
- c.getLong(Queries.Query.CONTACT_ID),
- directoryId,
- c.getLong(Queries.Query.DATA_ID),
- c.getString(Queries.Query.PHOTO_THUMBNAIL_URI),
- true,
- c.getString(Queries.Query.LOOKUP_KEY));
-
- /*
- * In certain situations, we may have two results for one address, where one of the
- * results is just the email address, and the other has a name and photo, so we want
- * to use the better one.
- */
- final RecipientEntry recipientEntry =
- getBetterRecipient(recipientEntries.get(address), newRecipientEntry);
-
- recipientEntries.put(address, recipientEntry);
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Received reverse look up information for " + address
- + " RESULTS: "
- + " NAME : " + c.getString(Queries.Query.NAME)
- + " CONTACT ID : " + c.getLong(Queries.Query.CONTACT_ID)
- + " ADDRESS :" + c.getString(Queries.Query.DESTINATION));
- }
- } while (c.moveToNext());
- }
- return recipientEntries;
- }
-
- /**
- * Given two {@link RecipientEntry}s for the same email address, this will return the one that
- * contains more complete information for display purposes. Defaults to <code>entry2</code> if
- * no significant differences are found.
- */
- static RecipientEntry getBetterRecipient(final RecipientEntry entry1,
- final RecipientEntry entry2) {
- // If only one has passed in, use it
- if (entry2 == null) {
- return entry1;
- }
-
- if (entry1 == null) {
- return entry2;
- }
-
- // If only one has a display name, use it
- if (!TextUtils.isEmpty(entry1.getDisplayName())
- && TextUtils.isEmpty(entry2.getDisplayName())) {
- return entry1;
- }
-
- if (!TextUtils.isEmpty(entry2.getDisplayName())
- && TextUtils.isEmpty(entry1.getDisplayName())) {
- return entry2;
- }
-
- // If only one has a display name that is not the same as the destination, use it
- if (!TextUtils.equals(entry1.getDisplayName(), entry1.getDestination())
- && TextUtils.equals(entry2.getDisplayName(), entry2.getDestination())) {
- return entry1;
- }
-
- if (!TextUtils.equals(entry2.getDisplayName(), entry2.getDestination())
- && TextUtils.equals(entry1.getDisplayName(), entry1.getDestination())) {
- return entry2;
- }
-
- // If only one has a photo, use it
- if ((entry1.getPhotoThumbnailUri() != null || entry1.getPhotoBytes() != null)
- && (entry2.getPhotoThumbnailUri() == null && entry2.getPhotoBytes() == null)) {
- return entry1;
- }
-
- if ((entry2.getPhotoThumbnailUri() != null || entry2.getPhotoBytes() != null)
- && (entry1.getPhotoThumbnailUri() == null && entry1.getPhotoBytes() == null)) {
- return entry2;
- }
-
- // Go with the second option as a default
- return entry2;
- }
-
- private static Cursor doQuery(CharSequence constraint, int limit, Long directoryId,
- Account account, ContentResolver resolver, Query query) {
- final Uri.Builder builder = query
- .getContentFilterUri()
- .buildUpon()
- .appendPath(constraint.toString())
- .appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY,
- String.valueOf(limit + BaseRecipientAdapter.ALLOWANCE_FOR_DUPLICATES));
- if (directoryId != null) {
- builder.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
- String.valueOf(directoryId));
- }
- if (account != null) {
- builder.appendQueryParameter(BaseRecipientAdapter.PRIMARY_ACCOUNT_NAME, account.name);
- builder.appendQueryParameter(BaseRecipientAdapter.PRIMARY_ACCOUNT_TYPE, account.type);
- }
- final Cursor cursor = resolver.query(builder.build(), query.getProjection(), null, null,
- null);
- return cursor;
- }
-
- public RecipientAlternatesAdapter(Context context, long contactId, Long directoryId,
- String lookupKey, long currentId, int queryMode, OnCheckedItemChangedListener listener,
- DropdownChipLayouter dropdownChipLayouter) {
- super(context,
- getCursorForConstruction(context, contactId, directoryId, lookupKey, queryMode), 0);
- mCurrentId = currentId;
- mDirectoryId = directoryId;
- mCheckedItemChangedListener = listener;
-
- mDropdownChipLayouter = dropdownChipLayouter;
- }
-
- private static Cursor getCursorForConstruction(Context context, long contactId,
- Long directoryId, String lookupKey, int queryType) {
- final Cursor cursor;
- final String desiredMimeType;
- if (queryType == QUERY_TYPE_EMAIL) {
- final Uri uri;
- final StringBuilder selection = new StringBuilder();
- selection.append(Queries.EMAIL.getProjection()[Queries.Query.CONTACT_ID]);
- selection.append(" = ?");
-
- if (directoryId == null || lookupKey == null) {
- uri = Queries.EMAIL.getContentUri();
- desiredMimeType = null;
- } else {
- final Uri.Builder builder = Contacts.getLookupUri(contactId, lookupKey).buildUpon();
- builder.appendPath(Contacts.Entity.CONTENT_DIRECTORY)
- .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
- String.valueOf(directoryId));
- uri = builder.build();
- desiredMimeType = ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE;
- }
- cursor = context.getContentResolver().query(
- uri,
- Queries.EMAIL.getProjection(),
- selection.toString(), new String[] {
- String.valueOf(contactId)
- }, null);
- } else {
- final Uri uri;
- final StringBuilder selection = new StringBuilder();
- selection.append(Queries.PHONE.getProjection()[Queries.Query.CONTACT_ID]);
- selection.append(" = ?");
-
- if (lookupKey == null) {
- uri = Queries.PHONE.getContentUri();
- desiredMimeType = null;
- } else {
- final Uri.Builder builder = Contacts.getLookupUri(contactId, lookupKey).buildUpon();
- builder.appendPath(Contacts.Entity.CONTENT_DIRECTORY)
- .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
- String.valueOf(directoryId));
- uri = builder.build();
- desiredMimeType = ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;
- }
- cursor = context.getContentResolver().query(
- uri,
- Queries.PHONE.getProjection(),
- selection.toString(), new String[] {
- String.valueOf(contactId)
- }, null);
- }
-
- final Cursor resultCursor = removeUndesiredDestinations(cursor, desiredMimeType, lookupKey);
- cursor.close();
-
- return resultCursor;
- }
-
- /**
- * @return a new cursor based on the given cursor with all duplicate destinations removed.
- *
- * It's only intended to use for the alternate list, so...
- * - This method ignores all other fields and dedupe solely on the destination. Normally,
- * if a cursor contains multiple contacts and they have the same destination, we'd still want
- * to show both.
- * - This method creates a MatrixCursor, so all data will be kept in memory. We wouldn't want
- * to do this if the original cursor is large, but it's okay here because the alternate list
- * won't be that big.
- *
- * @param desiredMimeType If this is non-<code>null</code>, only entries with this mime type
- * will be added to the cursor
- * @param lookupKey The lookup key used for this contact if there isn't one in the cursor. This
- * should be the same one used in the query that returned the cursor
- */
- // Visible for testing
- static Cursor removeUndesiredDestinations(final Cursor original, final String desiredMimeType,
- final String lookupKey) {
- final MatrixCursor result = new MatrixCursor(
- original.getColumnNames(), original.getCount());
- final HashSet<String> destinationsSeen = new HashSet<String>();
-
- String defaultDisplayName = null;
- String defaultPhotoThumbnailUri = null;
- int defaultDisplayNameSource = 0;
-
- // Find some nice defaults in case we need them
- original.moveToPosition(-1);
- while (original.moveToNext()) {
- final String mimeType = original.getString(Query.MIME_TYPE);
-
- if (ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE.equals(
- mimeType)) {
- // Store this data
- defaultDisplayName = original.getString(Query.NAME);
- defaultPhotoThumbnailUri = original.getString(Query.PHOTO_THUMBNAIL_URI);
- defaultDisplayNameSource = original.getInt(Query.DISPLAY_NAME_SOURCE);
- break;
- }
- }
-
- original.moveToPosition(-1);
- while (original.moveToNext()) {
- if (desiredMimeType != null) {
- final String mimeType = original.getString(Query.MIME_TYPE);
- if (!desiredMimeType.equals(mimeType)) {
- continue;
- }
- }
- final String destination = original.getString(Query.DESTINATION);
- if (destinationsSeen.contains(destination)) {
- continue;
- }
- destinationsSeen.add(destination);
-
- final Object[] row = new Object[] {
- original.getString(Query.NAME),
- original.getString(Query.DESTINATION),
- original.getInt(Query.DESTINATION_TYPE),
- original.getString(Query.DESTINATION_LABEL),
- original.getLong(Query.CONTACT_ID),
- original.getLong(Query.DATA_ID),
- original.getString(Query.PHOTO_THUMBNAIL_URI),
- original.getInt(Query.DISPLAY_NAME_SOURCE),
- original.getString(Query.LOOKUP_KEY),
- original.getString(Query.MIME_TYPE)
- };
-
- if (row[Query.NAME] == null) {
- row[Query.NAME] = defaultDisplayName;
- }
- if (row[Query.PHOTO_THUMBNAIL_URI] == null) {
- row[Query.PHOTO_THUMBNAIL_URI] = defaultPhotoThumbnailUri;
- }
- if ((Integer) row[Query.DISPLAY_NAME_SOURCE] == 0) {
- row[Query.DISPLAY_NAME_SOURCE] = defaultDisplayNameSource;
- }
- if (row[Query.LOOKUP_KEY] == null) {
- row[Query.LOOKUP_KEY] = lookupKey;
- }
-
- // Ensure we don't have two '?' like content://.../...?account_name=...?sz=...
- final String photoThumbnailUri = (String) row[Query.PHOTO_THUMBNAIL_URI];
- if (photoThumbnailUri != null) {
- if (sCorrectedPhotoUris.containsKey(photoThumbnailUri)) {
- row[Query.PHOTO_THUMBNAIL_URI] = sCorrectedPhotoUris.get(photoThumbnailUri);
- } else if (photoThumbnailUri.indexOf('?') != photoThumbnailUri.lastIndexOf('?')) {
- final String[] parts = photoThumbnailUri.split("\\?");
- final StringBuilder correctedUriBuilder = new StringBuilder();
- for (int i = 0; i < parts.length; i++) {
- if (i == 1) {
- correctedUriBuilder.append("?"); // We only want one of these
- } else if (i > 1) {
- correctedUriBuilder.append("&"); // And we want these elsewhere
- }
- correctedUriBuilder.append(parts[i]);
- }
-
- final String correctedUri = correctedUriBuilder.toString();
- sCorrectedPhotoUris.put(photoThumbnailUri, correctedUri);
- row[Query.PHOTO_THUMBNAIL_URI] = correctedUri;
- }
- }
-
- result.addRow(row);
- }
-
- return result;
- }
-
- @Override
- public long getItemId(int position) {
- Cursor c = getCursor();
- if (c.moveToPosition(position)) {
- c.getLong(Queries.Query.DATA_ID);
- }
- return -1;
- }
-
- public RecipientEntry getRecipientEntry(int position) {
- Cursor c = getCursor();
- c.moveToPosition(position);
- return RecipientEntry.constructTopLevelEntry(
- c.getString(Queries.Query.NAME),
- c.getInt(Queries.Query.DISPLAY_NAME_SOURCE),
- c.getString(Queries.Query.DESTINATION),
- c.getInt(Queries.Query.DESTINATION_TYPE),
- c.getString(Queries.Query.DESTINATION_LABEL),
- c.getLong(Queries.Query.CONTACT_ID),
- mDirectoryId,
- c.getLong(Queries.Query.DATA_ID),
- c.getString(Queries.Query.PHOTO_THUMBNAIL_URI),
- true,
- c.getString(Queries.Query.LOOKUP_KEY));
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- Cursor cursor = getCursor();
- cursor.moveToPosition(position);
- if (convertView == null) {
- convertView = mDropdownChipLayouter.newView();
- }
- if (cursor.getLong(Queries.Query.DATA_ID) == mCurrentId) {
- mCheckedItemPosition = position;
- if (mCheckedItemChangedListener != null) {
- mCheckedItemChangedListener.onCheckedItemChanged(mCheckedItemPosition);
- }
- }
- bindView(convertView, convertView.getContext(), cursor);
- return convertView;
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- int position = cursor.getPosition();
- RecipientEntry entry = getRecipientEntry(position);
-
- mDropdownChipLayouter.bindView(view, null, entry, position,
- AdapterType.RECIPIENT_ALTERNATES, null);
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mDropdownChipLayouter.newView();
- }
-
- /*package*/ static interface OnCheckedItemChangedListener {
- public void onCheckedItemChanged(int position);
- }
-}
diff --git a/chips/src/com/android/ex/chips/RecipientEditTextView.java b/chips/src/com/android/ex/chips/RecipientEditTextView.java
deleted file mode 100644
index 4339b9e..0000000
--- a/chips/src/com/android/ex/chips/RecipientEditTextView.java
+++ /dev/null
@@ -1,2988 +0,0 @@
-/*
-
- * Copyright (C) 2011 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.ex.chips;
-
-import android.app.Dialog;
-import android.content.ClipData;
-import android.content.ClipDescription;
-import android.content.ClipboardManager;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnDismissListener;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Parcelable;
-import android.text.Editable;
-import android.text.InputType;
-import android.text.Layout;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
-import android.text.TextPaint;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.text.method.QwertyKeyListener;
-import android.text.style.ImageSpan;
-import android.text.util.Rfc822Token;
-import android.text.util.Rfc822Tokenizer;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.ActionMode;
-import android.view.ActionMode.Callback;
-import android.view.DragEvent;
-import android.view.GestureDetector;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewParent;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.Button;
-import android.widget.Filterable;
-import android.widget.ListAdapter;
-import android.widget.ListPopupWindow;
-import android.widget.ListView;
-import android.widget.MultiAutoCompleteTextView;
-import android.widget.ScrollView;
-import android.widget.TextView;
-
-import com.android.ex.chips.RecipientAlternatesAdapter.RecipientMatchCallback;
-import com.android.ex.chips.recipientchip.DrawableRecipientChip;
-import com.android.ex.chips.recipientchip.InvisibleRecipientChip;
-import com.android.ex.chips.recipientchip.VisibleRecipientChip;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * RecipientEditTextView is an auto complete text view for use with applications
- * that use the new Chips UI for addressing a message to recipients.
- */
-public class RecipientEditTextView extends MultiAutoCompleteTextView implements
- OnItemClickListener, Callback, RecipientAlternatesAdapter.OnCheckedItemChangedListener,
- GestureDetector.OnGestureListener, OnDismissListener, OnClickListener,
- TextView.OnEditorActionListener {
-
- private static final char COMMIT_CHAR_COMMA = ',';
-
- private static final char COMMIT_CHAR_SEMICOLON = ';';
-
- private static final char COMMIT_CHAR_SPACE = ' ';
-
- private static final String SEPARATOR = String.valueOf(COMMIT_CHAR_COMMA)
- + String.valueOf(COMMIT_CHAR_SPACE);
-
- private static final String TAG = "RecipientEditTextView";
-
- private static int DISMISS = "dismiss".hashCode();
-
- private static final long DISMISS_DELAY = 300;
-
- // TODO: get correct number/ algorithm from with UX.
- // Visible for testing.
- /*package*/ static final int CHIP_LIMIT = 2;
-
- private static final int MAX_CHIPS_PARSED = 50;
-
- private static int sSelectedTextColor = -1;
-
- // Resources for displaying chips.
- private Drawable mChipBackground = null;
-
- private Drawable mChipDelete = null;
-
- private Drawable mInvalidChipBackground;
-
- private Drawable mChipBackgroundPressed;
-
- private float mChipHeight;
-
- private float mChipFontSize;
-
- private float mLineSpacingExtra;
-
- private int mChipPadding;
-
- /**
- * Enumerator for avatar position. See attr.xml for more details.
- * 0 for end, 1 for start.
- */
- private int mAvatarPosition;
-
- private static final int AVATAR_POSITION_END = 0;
-
- private static final int AVATAR_POSITION_START = 1;
-
- /**
- * Enumerator for image span alignment. See attr.xml for more details.
- * 0 for bottom, 1 for baseline.
- */
- private int mImageSpanAlignment;
-
- private static final int IMAGE_SPAN_ALIGNMENT_BOTTOM = 0;
-
- private static final int IMAGE_SPAN_ALIGNMENT_BASELINE = 1;
-
-
- private boolean mDisableDelete;
-
- private Tokenizer mTokenizer;
-
- private Validator mValidator;
-
- private DrawableRecipientChip mSelectedChip;
-
- private Bitmap mDefaultContactPhoto;
-
- private ImageSpan mMoreChip;
-
- private TextView mMoreItem;
-
- // VisibleForTesting
- final ArrayList<String> mPendingChips = new ArrayList<String>();
-
- private Handler mHandler;
-
- private int mPendingChipsCount = 0;
-
- private boolean mNoChips = false;
-
- private ListPopupWindow mAlternatesPopup;
-
- private ListPopupWindow mAddressPopup;
-
- // VisibleForTesting
- ArrayList<DrawableRecipientChip> mTemporaryRecipients;
-
- private ArrayList<DrawableRecipientChip> mRemovedSpans;
-
- private boolean mShouldShrink = true;
-
- // Chip copy fields.
- private GestureDetector mGestureDetector;
-
- private Dialog mCopyDialog;
-
- private String mCopyAddress;
-
- /**
- * Used with {@link #mAlternatesPopup}. Handles clicks to alternate addresses for a
- * selected chip.
- */
- private OnItemClickListener mAlternatesListener;
-
- private int mCheckedItem;
-
- private TextWatcher mTextWatcher;
-
- // Obtain the enclosing scroll view, if it exists, so that the view can be
- // scrolled to show the last line of chips content.
- private ScrollView mScrollView;
-
- private boolean mTriedGettingScrollView;
-
- private boolean mDragEnabled = false;
-
- // This pattern comes from android.util.Patterns. It has been tweaked to handle a "1" before
- // parens, so numbers such as "1 (425) 222-2342" match.
- private static final Pattern PHONE_PATTERN
- = Pattern.compile( // sdd = space, dot, or dash
- "(\\+[0-9]+[\\- \\.]*)?" // +<digits><sdd>*
- + "(1?[ ]*\\([0-9]+\\)[\\- \\.]*)?" // 1(<digits>)<sdd>*
- + "([0-9][0-9\\- \\.][0-9\\- \\.]+[0-9])"); // <digit><digit|sdd>+<digit>
-
- private final Runnable mAddTextWatcher = new Runnable() {
- @Override
- public void run() {
- if (mTextWatcher == null) {
- mTextWatcher = new RecipientTextWatcher();
- addTextChangedListener(mTextWatcher);
- }
- }
- };
-
- private IndividualReplacementTask mIndividualReplacements;
-
- private Runnable mHandlePendingChips = new Runnable() {
-
- @Override
- public void run() {
- handlePendingChips();
- }
-
- };
-
- private Runnable mDelayedShrink = new Runnable() {
-
- @Override
- public void run() {
- shrink();
- }
-
- };
-
- private int mMaxLines;
-
- private static int sExcessTopPadding = -1;
-
- private int mActionBarHeight;
-
- private boolean mAttachedToWindow;
-
- private DropdownChipLayouter mDropdownChipLayouter;
-
- public RecipientEditTextView(Context context, AttributeSet attrs) {
- super(context, attrs);
- setChipDimensions(context, attrs);
- if (sSelectedTextColor == -1) {
- sSelectedTextColor = context.getResources().getColor(android.R.color.white);
- }
- mAlternatesPopup = new ListPopupWindow(context);
- mAddressPopup = new ListPopupWindow(context);
- mCopyDialog = new Dialog(context);
- mAlternatesListener = new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> adapterView,View view, int position,
- long rowId) {
- mAlternatesPopup.setOnItemClickListener(null);
- replaceChip(mSelectedChip, ((RecipientAlternatesAdapter) adapterView.getAdapter())
- .getRecipientEntry(position));
- Message delayed = Message.obtain(mHandler, DISMISS);
- delayed.obj = mAlternatesPopup;
- mHandler.sendMessageDelayed(delayed, DISMISS_DELAY);
- clearComposingText();
- }
- };
- setInputType(getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
- setOnItemClickListener(this);
- setCustomSelectionActionModeCallback(this);
- mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == DISMISS) {
- ((ListPopupWindow) msg.obj).dismiss();
- return;
- }
- super.handleMessage(msg);
- }
- };
- mTextWatcher = new RecipientTextWatcher();
- addTextChangedListener(mTextWatcher);
- mGestureDetector = new GestureDetector(context, this);
- setOnEditorActionListener(this);
-
- setDropdownChipLayouter(new DropdownChipLayouter(LayoutInflater.from(context), context));
- }
-
- protected void setDropdownChipLayouter(DropdownChipLayouter dropdownChipLayouter) {
- mDropdownChipLayouter = dropdownChipLayouter;
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- mAttachedToWindow = false;
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- mAttachedToWindow = true;
- }
-
- @Override
- public boolean onEditorAction(TextView view, int action, KeyEvent keyEvent) {
- if (action == EditorInfo.IME_ACTION_DONE) {
- if (commitDefault()) {
- return true;
- }
- if (mSelectedChip != null) {
- clearSelectedChip();
- return true;
- } else if (focusNext()) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
- InputConnection connection = super.onCreateInputConnection(outAttrs);
- int imeActions = outAttrs.imeOptions&EditorInfo.IME_MASK_ACTION;
- if ((imeActions&EditorInfo.IME_ACTION_DONE) != 0) {
- // clear the existing action
- outAttrs.imeOptions ^= imeActions;
- // set the DONE action
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_DONE;
- }
- if ((outAttrs.imeOptions&EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
- outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
- }
-
- outAttrs.actionId = EditorInfo.IME_ACTION_DONE;
- outAttrs.actionLabel = getContext().getString(R.string.done);
- return connection;
- }
-
- /*package*/ DrawableRecipientChip getLastChip() {
- DrawableRecipientChip last = null;
- DrawableRecipientChip[] chips = getSortedRecipients();
- if (chips != null && chips.length > 0) {
- last = chips[chips.length - 1];
- }
- return last;
- }
-
- @Override
- public void onSelectionChanged(int start, int end) {
- // When selection changes, see if it is inside the chips area.
- // If so, move the cursor back after the chips again.
- DrawableRecipientChip last = getLastChip();
- if (last != null && start < getSpannable().getSpanEnd(last)) {
- // Grab the last chip and set the cursor to after it.
- setSelection(Math.min(getSpannable().getSpanEnd(last) + 1, getText().length()));
- }
- super.onSelectionChanged(start, end);
- }
-
- @Override
- public void onRestoreInstanceState(Parcelable state) {
- if (!TextUtils.isEmpty(getText())) {
- super.onRestoreInstanceState(null);
- } else {
- super.onRestoreInstanceState(state);
- }
- }
-
- @Override
- public Parcelable onSaveInstanceState() {
- // If the user changes orientation while they are editing, just roll back the selection.
- clearSelectedChip();
- return super.onSaveInstanceState();
- }
-
- /**
- * Convenience method: Append the specified text slice to the TextView's
- * display buffer, upgrading it to BufferType.EDITABLE if it was
- * not already editable. Commas are excluded as they are added automatically
- * by the view.
- */
- @Override
- public void append(CharSequence text, int start, int end) {
- // We don't care about watching text changes while appending.
- if (mTextWatcher != null) {
- removeTextChangedListener(mTextWatcher);
- }
- super.append(text, start, end);
- if (!TextUtils.isEmpty(text) && TextUtils.getTrimmedLength(text) > 0) {
- String displayString = text.toString();
-
- if (!displayString.trim().endsWith(String.valueOf(COMMIT_CHAR_COMMA))) {
- // We have no separator, so we should add it
- super.append(SEPARATOR, 0, SEPARATOR.length());
- displayString += SEPARATOR;
- }
-
- if (!TextUtils.isEmpty(displayString)
- && TextUtils.getTrimmedLength(displayString) > 0) {
- mPendingChipsCount++;
- mPendingChips.add(displayString);
- }
- }
- // Put a message on the queue to make sure we ALWAYS handle pending
- // chips.
- if (mPendingChipsCount > 0) {
- postHandlePendingChips();
- }
- mHandler.post(mAddTextWatcher);
- }
-
- @Override
- public void onFocusChanged(boolean hasFocus, int direction, Rect previous) {
- super.onFocusChanged(hasFocus, direction, previous);
- if (!hasFocus) {
- shrink();
- } else {
- expand();
- }
- }
-
- private int getExcessTopPadding() {
- if (sExcessTopPadding == -1) {
- sExcessTopPadding = (int) (mChipHeight + mLineSpacingExtra);
- }
- return sExcessTopPadding;
- }
-
- @Override
- public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
- super.setAdapter(adapter);
- BaseRecipientAdapter baseAdapter = (BaseRecipientAdapter) adapter;
- baseAdapter.registerUpdateObserver(new BaseRecipientAdapter.EntriesUpdatedObserver() {
- @Override
- public void onChanged(List<RecipientEntry> entries) {
- // Scroll the chips field to the top of the screen so
- // that the user can see as many results as possible.
- if (entries != null && entries.size() > 0) {
- scrollBottomIntoView();
- }
- }
- });
- baseAdapter.setDropdownChipLayouter(mDropdownChipLayouter);
- }
-
- protected void scrollBottomIntoView() {
- if (mScrollView != null && mShouldShrink) {
- int[] location = new int[2];
- getLocationOnScreen(location);
- int height = getHeight();
- int currentPos = location[1] + height;
- // Desired position shows at least 1 line of chips below the action
- // bar. We add excess padding to make sure this is always below other
- // content.
- int desiredPos = (int) mChipHeight + mActionBarHeight + getExcessTopPadding();
- if (currentPos > desiredPos) {
- mScrollView.scrollBy(0, currentPos - desiredPos);
- }
- }
- }
-
- protected ScrollView getScrollView() {
- return mScrollView;
- }
-
- @Override
- public void performValidation() {
- // Do nothing. Chips handles its own validation.
- }
-
- private void shrink() {
- if (mTokenizer == null) {
- return;
- }
- long contactId = mSelectedChip != null ? mSelectedChip.getEntry().getContactId() : -1;
- if (mSelectedChip != null && contactId != RecipientEntry.INVALID_CONTACT
- && (!isPhoneQuery() && contactId != RecipientEntry.GENERATED_CONTACT)) {
- clearSelectedChip();
- } else {
- if (getWidth() <= 0) {
- // We don't have the width yet which means the view hasn't been drawn yet
- // and there is no reason to attempt to commit chips yet.
- // This focus lost must be the result of an orientation change
- // or an initial rendering.
- // Re-post the shrink for later.
- mHandler.removeCallbacks(mDelayedShrink);
- mHandler.post(mDelayedShrink);
- return;
- }
- // Reset any pending chips as they would have been handled
- // when the field lost focus.
- if (mPendingChipsCount > 0) {
- postHandlePendingChips();
- } else {
- Editable editable = getText();
- int end = getSelectionEnd();
- int start = mTokenizer.findTokenStart(editable, end);
- DrawableRecipientChip[] chips =
- getSpannable().getSpans(start, end, DrawableRecipientChip.class);
- if ((chips == null || chips.length == 0)) {
- Editable text = getText();
- int whatEnd = mTokenizer.findTokenEnd(text, start);
- // This token was already tokenized, so skip past the ending token.
- if (whatEnd < text.length() && text.charAt(whatEnd) == ',') {
- whatEnd = movePastTerminators(whatEnd);
- }
- // In the middle of chip; treat this as an edit
- // and commit the whole token.
- int selEnd = getSelectionEnd();
- if (whatEnd != selEnd) {
- handleEdit(start, whatEnd);
- } else {
- commitChip(start, end, editable);
- }
- }
- }
- mHandler.post(mAddTextWatcher);
- }
- createMoreChip();
- }
-
- private void expand() {
- if (mShouldShrink) {
- setMaxLines(Integer.MAX_VALUE);
- }
- removeMoreChip();
- setCursorVisible(true);
- Editable text = getText();
- setSelection(text != null && text.length() > 0 ? text.length() : 0);
- // If there are any temporary chips, try replacing them now that the user
- // has expanded the field.
- if (mTemporaryRecipients != null && mTemporaryRecipients.size() > 0) {
- new RecipientReplacementTask().execute();
- mTemporaryRecipients = null;
- }
- }
-
- private CharSequence ellipsizeText(CharSequence text, TextPaint paint, float maxWidth) {
- paint.setTextSize(mChipFontSize);
- if (maxWidth <= 0 && Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Max width is negative: " + maxWidth);
- }
- return TextUtils.ellipsize(text, paint, maxWidth,
- TextUtils.TruncateAt.END);
- }
-
- /**
- * Creates a bitmap of the given contact on a selected chip.
- *
- * @param contact The recipient entry to pull data from.
- * @param paint The paint to use to draw the bitmap.
- */
- private Bitmap createSelectedChip(RecipientEntry contact, TextPaint paint) {
- paint.setColor(sSelectedTextColor);
- Bitmap photo;
- if (mDisableDelete) {
- // Show the avatar instead if we don't want to delete
- photo = getAvatarIcon(contact);
- } else {
- photo = ((BitmapDrawable) mChipDelete).getBitmap();
- }
- return createChipBitmap(contact, paint, photo, mChipBackgroundPressed);
- }
-
- /**
- * Creates a bitmap of the given contact on a selected chip.
- *
- * @param contact The recipient entry to pull data from.
- * @param paint The paint to use to draw the bitmap.
- */
- // TODO: Is leaveBlankIconSpacer obsolete now that we have left and right attributes?
- private Bitmap createUnselectedChip(RecipientEntry contact, TextPaint paint,
- boolean leaveBlankIconSpacer) {
- Drawable background = getChipBackground(contact);
- Bitmap photo = getAvatarIcon(contact);
- paint.setColor(getContext().getResources().getColor(android.R.color.black));
- return createChipBitmap(contact, paint, photo, background);
- }
-
- private Bitmap createChipBitmap(RecipientEntry contact, TextPaint paint, Bitmap icon,
- Drawable background) {
- if (background == null) {
- Log.w(TAG, "Unable to draw a background for the chips as it was never set");
- return Bitmap.createBitmap(
- (int) mChipHeight * 2, (int) mChipHeight, Bitmap.Config.ARGB_8888);
- }
-
- Rect backgroundPadding = new Rect();
- background.getPadding(backgroundPadding);
-
- // Ellipsize the text so that it takes AT MOST the entire width of the
- // autocomplete text entry area. Make sure to leave space for padding
- // on the sides.
- int height = (int) mChipHeight;
- // Since the icon is a square, it's width is equal to the maximum height it can be inside
- // the chip.
- int iconWidth = height - backgroundPadding.top - backgroundPadding.bottom;
- float[] widths = new float[1];
- paint.getTextWidths(" ", widths);
- CharSequence ellipsizedText = ellipsizeText(createChipDisplayText(contact), paint,
- calculateAvailableWidth() - iconWidth - widths[0] - backgroundPadding.left
- - backgroundPadding.right);;
- int textWidth = (int) paint.measureText(ellipsizedText, 0, ellipsizedText.length());
-
- // Make sure there is a minimum chip width so the user can ALWAYS
- // tap a chip without difficulty.
- int width = Math.max(iconWidth * 2, textWidth + (mChipPadding * 2) + iconWidth
- + backgroundPadding.left + backgroundPadding.right);
-
- // Create the background of the chip.
- Bitmap tmpBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(tmpBitmap);
-
- // Draw the background drawable
- background.setBounds(0, 0, width, height);
- background.draw(canvas);
- // Draw the text vertically aligned
- int textX = shouldPositionAvatarOnRight() ?
- mChipPadding + backgroundPadding.left :
- width - backgroundPadding.right - mChipPadding - textWidth;
- canvas.drawText(ellipsizedText, 0, ellipsizedText.length(),
- textX, getTextYOffset(ellipsizedText.toString(), paint, height), paint);
- if (icon != null) {
- // Draw the icon
- int iconX = shouldPositionAvatarOnRight() ?
- width - backgroundPadding.right - iconWidth :
- backgroundPadding.left;
- RectF src = new RectF(0, 0, icon.getWidth(), icon.getHeight());
- RectF dst = new RectF(iconX,
- 0 + backgroundPadding.top,
- iconX + iconWidth,
- height - backgroundPadding.bottom);
- drawIconOnCanvas(icon, canvas, paint, src, dst);
- }
- return tmpBitmap;
- }
-
- /**
- * Returns true if the avatar should be positioned at the right edge of the chip.
- * Takes into account both the set avatar position (start or end) as well as whether
- * the layout direction is LTR or RTL.
- */
- private boolean shouldPositionAvatarOnRight() {
- final boolean isRtl = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 ?
- getLayoutDirection() == LAYOUT_DIRECTION_RTL : false;
- final boolean assignedPosition = mAvatarPosition == AVATAR_POSITION_END;
- // If in Rtl mode, the position should be flipped.
- return isRtl ? !assignedPosition : assignedPosition;
- }
-
- /**
- * Returns the avatar icon to use for this recipient entry. Returns null if we don't want to
- * draw an icon for this recipient.
- */
- private Bitmap getAvatarIcon(RecipientEntry contact) {
- // Don't draw photos for recipients that have been typed in OR generated on the fly.
- long contactId = contact.getContactId();
- boolean drawPhotos = isPhoneQuery() ?
- contactId != RecipientEntry.INVALID_CONTACT
- : (contactId != RecipientEntry.INVALID_CONTACT
- && (contactId != RecipientEntry.GENERATED_CONTACT &&
- !TextUtils.isEmpty(contact.getDisplayName())));
-
- if (drawPhotos) {
- byte[] photoBytes = contact.getPhotoBytes();
- // There may not be a photo yet if anything but the first contact address
- // was selected.
- if (photoBytes == null && contact.getPhotoThumbnailUri() != null) {
- // TODO: cache this in the recipient entry?
- getAdapter().fetchPhoto(contact, contact.getPhotoThumbnailUri());
- photoBytes = contact.getPhotoBytes();
- }
- if (photoBytes != null) {
- return BitmapFactory.decodeByteArray(photoBytes, 0, photoBytes.length);
- } else {
- // TODO: can the scaled down default photo be cached?
- return mDefaultContactPhoto;
- }
- }
-
- return null;
- }
-
- /**
- * Get the background drawable for a RecipientChip.
- */
- // Visible for testing.
- /* package */Drawable getChipBackground(RecipientEntry contact) {
- return contact.isValid() ? mChipBackground : mInvalidChipBackground;
- }
-
- /**
- * Given a height, returns a Y offset that will draw the text in the middle of the height.
- */
- protected float getTextYOffset(String text, TextPaint paint, int height) {
- Rect bounds = new Rect();
- paint.getTextBounds(text, 0, text.length(), bounds);
- int textHeight = bounds.bottom - bounds.top ;
- return height - ((height - textHeight) / 2) - (int)paint.descent();
- }
-
- /**
- * Draws the icon onto the canvas given the source rectangle of the bitmap and the destination
- * rectangle of the canvas.
- */
- protected void drawIconOnCanvas(Bitmap icon, Canvas canvas, Paint paint, RectF src, RectF dst) {
- Matrix matrix = new Matrix();
- matrix.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
- canvas.drawBitmap(icon, matrix, paint);
- }
-
- private DrawableRecipientChip constructChipSpan(RecipientEntry contact, boolean pressed,
- boolean leaveIconSpace) throws NullPointerException {
- if (mChipBackground == null) {
- throw new NullPointerException(
- "Unable to render any chips as setChipDimensions was not called.");
- }
-
- TextPaint paint = getPaint();
- float defaultSize = paint.getTextSize();
- int defaultColor = paint.getColor();
-
- Bitmap tmpBitmap;
- if (pressed) {
- tmpBitmap = createSelectedChip(contact, paint);
-
- } else {
- tmpBitmap = createUnselectedChip(contact, paint, leaveIconSpace);
- }
-
- // Pass the full text, un-ellipsized, to the chip.
- Drawable result = new BitmapDrawable(getResources(), tmpBitmap);
- result.setBounds(0, 0, tmpBitmap.getWidth(), tmpBitmap.getHeight());
- DrawableRecipientChip recipientChip =
- new VisibleRecipientChip(result, contact, getImageSpanAlignment());
- // Return text to the original size.
- paint.setTextSize(defaultSize);
- paint.setColor(defaultColor);
- return recipientChip;
- }
-
- private int getImageSpanAlignment() {
- switch (mImageSpanAlignment) {
- case IMAGE_SPAN_ALIGNMENT_BASELINE:
- return ImageSpan.ALIGN_BASELINE;
- case IMAGE_SPAN_ALIGNMENT_BOTTOM:
- return ImageSpan.ALIGN_BOTTOM;
- default:
- return ImageSpan.ALIGN_BOTTOM;
- }
- }
-
- /**
- * Calculate the bottom of the line the chip will be located on using:
- * 1) which line the chip appears on
- * 2) the height of a chip
- * 3) padding built into the edit text view
- */
- private int calculateOffsetFromBottom(int line) {
- // Line offsets start at zero.
- int actualLine = getLineCount() - (line + 1);
- return -((actualLine * ((int) mChipHeight) + getPaddingBottom()) + getPaddingTop())
- + getDropDownVerticalOffset();
- }
-
- /**
- * Get the max amount of space a chip can take up. The formula takes into
- * account the width of the EditTextView, any view padding, and padding
- * that will be added to the chip.
- */
- private float calculateAvailableWidth() {
- return getWidth() - getPaddingLeft() - getPaddingRight() - (mChipPadding * 2);
- }
-
-
- private void setChipDimensions(Context context, AttributeSet attrs) {
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecipientEditTextView, 0,
- 0);
- Resources r = getContext().getResources();
-
- mChipBackground = a.getDrawable(R.styleable.RecipientEditTextView_chipBackground);
- if (mChipBackground == null) {
- mChipBackground = r.getDrawable(R.drawable.chip_background);
- }
- mChipBackgroundPressed = a
- .getDrawable(R.styleable.RecipientEditTextView_chipBackgroundPressed);
- if (mChipBackgroundPressed == null) {
- mChipBackgroundPressed = r.getDrawable(R.drawable.chip_background_selected);
- }
- mChipDelete = a.getDrawable(R.styleable.RecipientEditTextView_chipDelete);
- if (mChipDelete == null) {
- mChipDelete = r.getDrawable(R.drawable.chip_delete);
- }
- mChipPadding = a.getDimensionPixelSize(R.styleable.RecipientEditTextView_chipPadding, -1);
- if (mChipPadding == -1) {
- mChipPadding = (int) r.getDimension(R.dimen.chip_padding);
- }
-
- mDefaultContactPhoto = BitmapFactory.decodeResource(r, R.drawable.ic_contact_picture);
-
- mMoreItem = (TextView) LayoutInflater.from(getContext()).inflate(R.layout.more_item, null);
-
- mChipHeight = a.getDimensionPixelSize(R.styleable.RecipientEditTextView_chipHeight, -1);
- if (mChipHeight == -1) {
- mChipHeight = r.getDimension(R.dimen.chip_height);
- }
- mChipFontSize = a.getDimensionPixelSize(R.styleable.RecipientEditTextView_chipFontSize, -1);
- if (mChipFontSize == -1) {
- mChipFontSize = r.getDimension(R.dimen.chip_text_size);
- }
- mInvalidChipBackground = a
- .getDrawable(R.styleable.RecipientEditTextView_invalidChipBackground);
- if (mInvalidChipBackground == null) {
- mInvalidChipBackground = r.getDrawable(R.drawable.chip_background_invalid);
- }
- mAvatarPosition = a.getInt(R.styleable.RecipientEditTextView_avatarPosition, 0);
- mImageSpanAlignment = a.getInt(R.styleable.RecipientEditTextView_imageSpanAlignment, 0);
- mDisableDelete = a.getBoolean(R.styleable.RecipientEditTextView_disableDelete, false);
-
- mLineSpacingExtra = r.getDimension(R.dimen.line_spacing_extra);
- mMaxLines = r.getInteger(R.integer.chips_max_lines);
- TypedValue tv = new TypedValue();
- if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
- mActionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources()
- .getDisplayMetrics());
- }
-
- a.recycle();
- }
-
- // Visible for testing.
- /* package */ void setMoreItem(TextView moreItem) {
- mMoreItem = moreItem;
- }
-
-
- // Visible for testing.
- /* package */ void setChipBackground(Drawable chipBackground) {
- mChipBackground = chipBackground;
- }
-
- // Visible for testing.
- /* package */ void setChipHeight(int height) {
- mChipHeight = height;
- }
-
- public float getChipHeight() {
- return mChipHeight;
- }
-
- /**
- * Set whether to shrink the recipients field such that at most
- * one line of recipients chips are shown when the field loses
- * focus. By default, the number of displayed recipients will be
- * limited and a "more" chip will be shown when focus is lost.
- * @param shrink
- */
- public void setOnFocusListShrinkRecipients(boolean shrink) {
- mShouldShrink = shrink;
- }
-
- @Override
- public void onSizeChanged(int width, int height, int oldw, int oldh) {
- super.onSizeChanged(width, height, oldw, oldh);
- if (width != 0 && height != 0) {
- if (mPendingChipsCount > 0) {
- postHandlePendingChips();
- } else {
- checkChipWidths();
- }
- }
- // Try to find the scroll view parent, if it exists.
- if (mScrollView == null && !mTriedGettingScrollView) {
- ViewParent parent = getParent();
- while (parent != null && !(parent instanceof ScrollView)) {
- parent = parent.getParent();
- }
- if (parent != null) {
- mScrollView = (ScrollView) parent;
- }
- mTriedGettingScrollView = true;
- }
- }
-
- private void postHandlePendingChips() {
- mHandler.removeCallbacks(mHandlePendingChips);
- mHandler.post(mHandlePendingChips);
- }
-
- private void checkChipWidths() {
- // Check the widths of the associated chips.
- DrawableRecipientChip[] chips = getSortedRecipients();
- if (chips != null) {
- Rect bounds;
- for (DrawableRecipientChip chip : chips) {
- bounds = chip.getBounds();
- if (getWidth() > 0 && bounds.right - bounds.left >
- getWidth() - getPaddingLeft() - getPaddingRight()) {
- // Need to redraw that chip.
- replaceChip(chip, chip.getEntry());
- }
- }
- }
- }
-
- // Visible for testing.
- /*package*/ void handlePendingChips() {
- if (getViewWidth() <= 0) {
- // The widget has not been sized yet.
- // This will be called as a result of onSizeChanged
- // at a later point.
- return;
- }
- if (mPendingChipsCount <= 0) {
- return;
- }
-
- synchronized (mPendingChips) {
- Editable editable = getText();
- // Tokenize!
- if (mPendingChipsCount <= MAX_CHIPS_PARSED) {
- for (int i = 0; i < mPendingChips.size(); i++) {
- String current = mPendingChips.get(i);
- int tokenStart = editable.toString().indexOf(current);
- // Always leave a space at the end between tokens.
- int tokenEnd = tokenStart + current.length() - 1;
- if (tokenStart >= 0) {
- // When we have a valid token, include it with the token
- // to the left.
- if (tokenEnd < editable.length() - 2
- && editable.charAt(tokenEnd) == COMMIT_CHAR_COMMA) {
- tokenEnd++;
- }
- createReplacementChip(tokenStart, tokenEnd, editable, i < CHIP_LIMIT
- || !mShouldShrink);
- }
- mPendingChipsCount--;
- }
- sanitizeEnd();
- } else {
- mNoChips = true;
- }
-
- if (mTemporaryRecipients != null && mTemporaryRecipients.size() > 0
- && mTemporaryRecipients.size() <= RecipientAlternatesAdapter.MAX_LOOKUPS) {
- if (hasFocus() || mTemporaryRecipients.size() < CHIP_LIMIT) {
- new RecipientReplacementTask().execute();
- mTemporaryRecipients = null;
- } else {
- // Create the "more" chip
- mIndividualReplacements = new IndividualReplacementTask();
- mIndividualReplacements.execute(new ArrayList<DrawableRecipientChip>(
- mTemporaryRecipients.subList(0, CHIP_LIMIT)));
- if (mTemporaryRecipients.size() > CHIP_LIMIT) {
- mTemporaryRecipients = new ArrayList<DrawableRecipientChip>(
- mTemporaryRecipients.subList(CHIP_LIMIT,
- mTemporaryRecipients.size()));
- } else {
- mTemporaryRecipients = null;
- }
- createMoreChip();
- }
- } else {
- // There are too many recipients to look up, so just fall back
- // to showing addresses for all of them.
- mTemporaryRecipients = null;
- createMoreChip();
- }
- mPendingChipsCount = 0;
- mPendingChips.clear();
- }
- }
-
- // Visible for testing.
- /*package*/ int getViewWidth() {
- return getWidth();
- }
-
- /**
- * Remove any characters after the last valid chip.
- */
- // Visible for testing.
- /*package*/ void sanitizeEnd() {
- // Don't sanitize while we are waiting for pending chips to complete.
- if (mPendingChipsCount > 0) {
- return;
- }
- // Find the last chip; eliminate any commit characters after it.
- DrawableRecipientChip[] chips = getSortedRecipients();
- Spannable spannable = getSpannable();
- if (chips != null && chips.length > 0) {
- int end;
- mMoreChip = getMoreChip();
- if (mMoreChip != null) {
- end = spannable.getSpanEnd(mMoreChip);
- } else {
- end = getSpannable().getSpanEnd(getLastChip());
- }
- Editable editable = getText();
- int length = editable.length();
- if (length > end) {
- // See what characters occur after that and eliminate them.
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "There were extra characters after the last tokenizable entry."
- + editable);
- }
- editable.delete(end + 1, length);
- }
- }
- }
-
- /**
- * Create a chip that represents just the email address of a recipient. At some later
- * point, this chip will be attached to a real contact entry, if one exists.
- */
- // VisibleForTesting
- void createReplacementChip(int tokenStart, int tokenEnd, Editable editable,
- boolean visible) {
- if (alreadyHasChip(tokenStart, tokenEnd)) {
- // There is already a chip present at this location.
- // Don't recreate it.
- return;
- }
- String token = editable.toString().substring(tokenStart, tokenEnd);
- final String trimmedToken = token.trim();
- int commitCharIndex = trimmedToken.lastIndexOf(COMMIT_CHAR_COMMA);
- if (commitCharIndex != -1 && commitCharIndex == trimmedToken.length() - 1) {
- token = trimmedToken.substring(0, trimmedToken.length() - 1);
- }
- RecipientEntry entry = createTokenizedEntry(token);
- if (entry != null) {
- DrawableRecipientChip chip = null;
- try {
- if (!mNoChips) {
- /*
- * leave space for the contact icon if this is not just an
- * email address
- */
- boolean leaveSpace = TextUtils.isEmpty(entry.getDisplayName())
- || TextUtils.equals(entry.getDisplayName(),
- entry.getDestination());
- chip = visible ?
- constructChipSpan(entry, false, leaveSpace)
- : new InvisibleRecipientChip(entry);
- }
- } catch (NullPointerException e) {
- Log.e(TAG, e.getMessage(), e);
- }
- editable.setSpan(chip, tokenStart, tokenEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- // Add this chip to the list of entries "to replace"
- if (chip != null) {
- if (mTemporaryRecipients == null) {
- mTemporaryRecipients = new ArrayList<DrawableRecipientChip>();
- }
- chip.setOriginalText(token);
- mTemporaryRecipients.add(chip);
- }
- }
- }
-
- private static boolean isPhoneNumber(String number) {
- // TODO: replace this function with libphonenumber's isPossibleNumber (see
- // PhoneNumberUtil). One complication is that it requires the sender's region which
- // comes from the CurrentCountryIso. For now, let's just do this simple match.
- if (TextUtils.isEmpty(number)) {
- return false;
- }
-
- Matcher match = PHONE_PATTERN.matcher(number);
- return match.matches();
- }
-
- // VisibleForTesting
- RecipientEntry createTokenizedEntry(final String token) {
- if (TextUtils.isEmpty(token)) {
- return null;
- }
- if (isPhoneQuery() && isPhoneNumber(token)) {
- return RecipientEntry.constructFakePhoneEntry(token, true);
- }
- Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(token);
- String display = null;
- boolean isValid = isValid(token);
- if (isValid && tokens != null && tokens.length > 0) {
- // If we can get a name from tokenizing, then generate an entry from
- // this.
- display = tokens[0].getName();
- if (!TextUtils.isEmpty(display)) {
- return RecipientEntry.constructGeneratedEntry(display, tokens[0].getAddress(),
- isValid);
- } else {
- display = tokens[0].getAddress();
- if (!TextUtils.isEmpty(display)) {
- return RecipientEntry.constructFakeEntry(display, isValid);
- }
- }
- }
- // Unable to validate the token or to create a valid token from it.
- // Just create a chip the user can edit.
- String validatedToken = null;
- if (mValidator != null && !isValid) {
- // Try fixing up the entry using the validator.
- validatedToken = mValidator.fixText(token).toString();
- if (!TextUtils.isEmpty(validatedToken)) {
- if (validatedToken.contains(token)) {
- // protect against the case of a validator with a null
- // domain,
- // which doesn't add a domain to the token
- Rfc822Token[] tokenized = Rfc822Tokenizer.tokenize(validatedToken);
- if (tokenized.length > 0) {
- validatedToken = tokenized[0].getAddress();
- isValid = true;
- }
- } else {
- // We ran into a case where the token was invalid and
- // removed
- // by the validator. In this case, just use the original
- // token
- // and let the user sort out the error chip.
- validatedToken = null;
- isValid = false;
- }
- }
- }
- // Otherwise, fallback to just creating an editable email address chip.
- return RecipientEntry.constructFakeEntry(
- !TextUtils.isEmpty(validatedToken) ? validatedToken : token, isValid);
- }
-
- private boolean isValid(String text) {
- return mValidator == null ? true : mValidator.isValid(text);
- }
-
- private static String tokenizeAddress(String destination) {
- Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(destination);
- if (tokens != null && tokens.length > 0) {
- return tokens[0].getAddress();
- }
- return destination;
- }
-
- @Override
- public void setTokenizer(Tokenizer tokenizer) {
- mTokenizer = tokenizer;
- super.setTokenizer(mTokenizer);
- }
-
- @Override
- public void setValidator(Validator validator) {
- mValidator = validator;
- super.setValidator(validator);
- }
-
- /**
- * We cannot use the default mechanism for replaceText. Instead,
- * we override onItemClickListener so we can get all the associated
- * contact information including display text, address, and id.
- */
- @Override
- protected void replaceText(CharSequence text) {
- return;
- }
-
- /**
- * Dismiss any selected chips when the back key is pressed.
- */
- @Override
- public boolean onKeyPreIme(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK && mSelectedChip != null) {
- clearSelectedChip();
- return true;
- }
- return super.onKeyPreIme(keyCode, event);
- }
-
- /**
- * Monitor key presses in this view to see if the user types
- * any commit keys, which consist of ENTER, TAB, or DPAD_CENTER.
- * If the user has entered text that has contact matches and types
- * a commit key, create a chip from the topmost matching contact.
- * If the user has entered text that has no contact matches and types
- * a commit key, then create a chip from the text they have entered.
- */
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_TAB:
- if (event.hasNoModifiers()) {
- if (mSelectedChip != null) {
- clearSelectedChip();
- } else {
- commitDefault();
- }
- }
- break;
- }
- return super.onKeyUp(keyCode, event);
- }
-
- private boolean focusNext() {
- View next = focusSearch(View.FOCUS_DOWN);
- if (next != null) {
- next.requestFocus();
- return true;
- }
- return false;
- }
-
- /**
- * Create a chip from the default selection. If the popup is showing, the
- * default is the first item in the popup suggestions list. Otherwise, it is
- * whatever the user had typed in. End represents where the the tokenizer
- * should search for a token to turn into a chip.
- * @return If a chip was created from a real contact.
- */
- private boolean commitDefault() {
- // If there is no tokenizer, don't try to commit.
- if (mTokenizer == null) {
- return false;
- }
- Editable editable = getText();
- int end = getSelectionEnd();
- int start = mTokenizer.findTokenStart(editable, end);
-
- if (shouldCreateChip(start, end)) {
- int whatEnd = mTokenizer.findTokenEnd(getText(), start);
- // In the middle of chip; treat this as an edit
- // and commit the whole token.
- whatEnd = movePastTerminators(whatEnd);
- if (whatEnd != getSelectionEnd()) {
- handleEdit(start, whatEnd);
- return true;
- }
- return commitChip(start, end , editable);
- }
- return false;
- }
-
- private void commitByCharacter() {
- // We can't possibly commit by character if we can't tokenize.
- if (mTokenizer == null) {
- return;
- }
- Editable editable = getText();
- int end = getSelectionEnd();
- int start = mTokenizer.findTokenStart(editable, end);
- if (shouldCreateChip(start, end)) {
- commitChip(start, end, editable);
- }
- setSelection(getText().length());
- }
-
- private boolean commitChip(int start, int end, Editable editable) {
- ListAdapter adapter = getAdapter();
- if (adapter != null && adapter.getCount() > 0 && enoughToFilter()
- && end == getSelectionEnd() && !isPhoneQuery()) {
- // choose the first entry.
- submitItemAtPosition(0);
- dismissDropDown();
- return true;
- } else {
- int tokenEnd = mTokenizer.findTokenEnd(editable, start);
- if (editable.length() > tokenEnd + 1) {
- char charAt = editable.charAt(tokenEnd + 1);
- if (charAt == COMMIT_CHAR_COMMA || charAt == COMMIT_CHAR_SEMICOLON) {
- tokenEnd++;
- }
- }
- String text = editable.toString().substring(start, tokenEnd).trim();
- clearComposingText();
- if (text != null && text.length() > 0 && !text.equals(" ")) {
- RecipientEntry entry = createTokenizedEntry(text);
- if (entry != null) {
- QwertyKeyListener.markAsReplaced(editable, start, end, "");
- CharSequence chipText = createChip(entry, false);
- if (chipText != null && start > -1 && end > -1) {
- editable.replace(start, end, chipText);
- }
- }
- // Only dismiss the dropdown if it is related to the text we
- // just committed.
- // For paste, it may not be as there are possibly multiple
- // tokens being added.
- if (end == getSelectionEnd()) {
- dismissDropDown();
- }
- sanitizeBetween();
- return true;
- }
- }
- return false;
- }
-
- // Visible for testing.
- /* package */ void sanitizeBetween() {
- // Don't sanitize while we are waiting for content to chipify.
- if (mPendingChipsCount > 0) {
- return;
- }
- // Find the last chip.
- DrawableRecipientChip[] recips = getSortedRecipients();
- if (recips != null && recips.length > 0) {
- DrawableRecipientChip last = recips[recips.length - 1];
- DrawableRecipientChip beforeLast = null;
- if (recips.length > 1) {
- beforeLast = recips[recips.length - 2];
- }
- int startLooking = 0;
- int end = getSpannable().getSpanStart(last);
- if (beforeLast != null) {
- startLooking = getSpannable().getSpanEnd(beforeLast);
- Editable text = getText();
- if (startLooking == -1 || startLooking > text.length() - 1) {
- // There is nothing after this chip.
- return;
- }
- if (text.charAt(startLooking) == ' ') {
- startLooking++;
- }
- }
- if (startLooking >= 0 && end >= 0 && startLooking < end) {
- getText().delete(startLooking, end);
- }
- }
- }
-
- private boolean shouldCreateChip(int start, int end) {
- return !mNoChips && hasFocus() && enoughToFilter() && !alreadyHasChip(start, end);
- }
-
- private boolean alreadyHasChip(int start, int end) {
- if (mNoChips) {
- return true;
- }
- DrawableRecipientChip[] chips =
- getSpannable().getSpans(start, end, DrawableRecipientChip.class);
- if ((chips == null || chips.length == 0)) {
- return false;
- }
- return true;
- }
-
- private void handleEdit(int start, int end) {
- if (start == -1 || end == -1) {
- // This chip no longer exists in the field.
- dismissDropDown();
- return;
- }
- // This is in the middle of a chip, so select out the whole chip
- // and commit it.
- Editable editable = getText();
- setSelection(end);
- String text = getText().toString().substring(start, end);
- if (!TextUtils.isEmpty(text)) {
- RecipientEntry entry = RecipientEntry.constructFakeEntry(text, isValid(text));
- QwertyKeyListener.markAsReplaced(editable, start, end, "");
- CharSequence chipText = createChip(entry, false);
- int selEnd = getSelectionEnd();
- if (chipText != null && start > -1 && selEnd > -1) {
- editable.replace(start, selEnd, chipText);
- }
- }
- dismissDropDown();
- }
-
- /**
- * If there is a selected chip, delegate the key events
- * to the selected chip.
- */
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (mSelectedChip != null && keyCode == KeyEvent.KEYCODE_DEL) {
- if (mAlternatesPopup != null && mAlternatesPopup.isShowing()) {
- mAlternatesPopup.dismiss();
- }
- removeChip(mSelectedChip);
- }
-
- switch (keyCode) {
- case KeyEvent.KEYCODE_ENTER:
- case KeyEvent.KEYCODE_DPAD_CENTER:
- if (event.hasNoModifiers()) {
- if (commitDefault()) {
- return true;
- }
- if (mSelectedChip != null) {
- clearSelectedChip();
- return true;
- } else if (focusNext()) {
- return true;
- }
- }
- break;
- }
-
- return super.onKeyDown(keyCode, event);
- }
-
- // Visible for testing.
- /* package */ Spannable getSpannable() {
- return getText();
- }
-
- private int getChipStart(DrawableRecipientChip chip) {
- return getSpannable().getSpanStart(chip);
- }
-
- private int getChipEnd(DrawableRecipientChip chip) {
- return getSpannable().getSpanEnd(chip);
- }
-
- /**
- * Instead of filtering on the entire contents of the edit box,
- * this subclass method filters on the range from
- * {@link Tokenizer#findTokenStart} to {@link #getSelectionEnd}
- * if the length of that range meets or exceeds {@link #getThreshold}
- * and makes sure that the range is not already a Chip.
- */
- @Override
- protected void performFiltering(CharSequence text, int keyCode) {
- boolean isCompletedToken = isCompletedToken(text);
- if (enoughToFilter() && !isCompletedToken) {
- int end = getSelectionEnd();
- int start = mTokenizer.findTokenStart(text, end);
- // If this is a RecipientChip, don't filter
- // on its contents.
- Spannable span = getSpannable();
- DrawableRecipientChip[] chips = span.getSpans(start, end, DrawableRecipientChip.class);
- if (chips != null && chips.length > 0) {
- dismissDropDown();
- return;
- }
- } else if (isCompletedToken) {
- dismissDropDown();
- return;
- }
- super.performFiltering(text, keyCode);
- }
-
- // Visible for testing.
- /*package*/ boolean isCompletedToken(CharSequence text) {
- if (TextUtils.isEmpty(text)) {
- return false;
- }
- // Check to see if this is a completed token before filtering.
- int end = text.length();
- int start = mTokenizer.findTokenStart(text, end);
- String token = text.toString().substring(start, end).trim();
- if (!TextUtils.isEmpty(token)) {
- char atEnd = token.charAt(token.length() - 1);
- return atEnd == COMMIT_CHAR_COMMA || atEnd == COMMIT_CHAR_SEMICOLON;
- }
- return false;
- }
-
- private void clearSelectedChip() {
- if (mSelectedChip != null) {
- unselectChip(mSelectedChip);
- mSelectedChip = null;
- }
- setCursorVisible(true);
- }
-
- /**
- * Monitor touch events in the RecipientEditTextView.
- * If the view does not have focus, any tap on the view
- * will just focus the view. If the view has focus, determine
- * if the touch target is a recipient chip. If it is and the chip
- * is not selected, select it and clear any other selected chips.
- * If it isn't, then select that chip.
- */
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (!isFocused()) {
- // Ignore any chip taps until this view is focused.
- return super.onTouchEvent(event);
- }
- boolean handled = super.onTouchEvent(event);
- int action = event.getAction();
- boolean chipWasSelected = false;
- if (mSelectedChip == null) {
- mGestureDetector.onTouchEvent(event);
- }
- if (mCopyAddress == null && action == MotionEvent.ACTION_UP) {
- float x = event.getX();
- float y = event.getY();
- int offset = putOffsetInRange(x, y);
- DrawableRecipientChip currentChip = findChip(offset);
- if (currentChip != null) {
- if (action == MotionEvent.ACTION_UP) {
- if (mSelectedChip != null && mSelectedChip != currentChip) {
- clearSelectedChip();
- mSelectedChip = selectChip(currentChip);
- } else if (mSelectedChip == null) {
- setSelection(getText().length());
- commitDefault();
- mSelectedChip = selectChip(currentChip);
- } else {
- onClick(mSelectedChip, offset, x, y);
- }
- }
- chipWasSelected = true;
- handled = true;
- } else if (mSelectedChip != null && shouldShowEditableText(mSelectedChip)) {
- chipWasSelected = true;
- }
- }
- if (action == MotionEvent.ACTION_UP && !chipWasSelected) {
- clearSelectedChip();
- }
- return handled;
- }
-
- private void scrollLineIntoView(int line) {
- if (mScrollView != null) {
- mScrollView.smoothScrollBy(0, calculateOffsetFromBottom(line));
- }
- }
-
- private void showAlternates(final DrawableRecipientChip currentChip,
- final ListPopupWindow alternatesPopup, final int width) {
- new AsyncTask<Void, Void, ListAdapter>() {
- @Override
- protected ListAdapter doInBackground(final Void... params) {
- return createAlternatesAdapter(currentChip);
- }
-
- @Override
- protected void onPostExecute(final ListAdapter result) {
- if (!mAttachedToWindow) {
- return;
- }
- int line = getLayout().getLineForOffset(getChipStart(currentChip));
- int bottom;
- if (line == getLineCount() -1) {
- bottom = 0;
- } else {
- bottom = -(int) ((mChipHeight + (2 * mLineSpacingExtra)) * (Math
- .abs(getLineCount() - 1 - line)));
- }
- // Align the alternates popup with the left side of the View,
- // regardless of the position of the chip tapped.
- alternatesPopup.setWidth(width);
- alternatesPopup.setAnchorView(RecipientEditTextView.this);
- alternatesPopup.setVerticalOffset(bottom);
- alternatesPopup.setAdapter(result);
- alternatesPopup.setOnItemClickListener(mAlternatesListener);
- // Clear the checked item.
- mCheckedItem = -1;
- alternatesPopup.show();
- ListView listView = alternatesPopup.getListView();
- listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
- // Checked item would be -1 if the adapter has not
- // loaded the view that should be checked yet. The
- // variable will be set correctly when onCheckedItemChanged
- // is called in a separate thread.
- if (mCheckedItem != -1) {
- listView.setItemChecked(mCheckedItem, true);
- mCheckedItem = -1;
- }
- }
- }.execute((Void[]) null);
- }
-
- private ListAdapter createAlternatesAdapter(DrawableRecipientChip chip) {
- return new RecipientAlternatesAdapter(getContext(), chip.getContactId(),
- chip.getDirectoryId(), chip.getLookupKey(), chip.getDataId(),
- getAdapter().getQueryType(), this, mDropdownChipLayouter);
- }
-
- private ListAdapter createSingleAddressAdapter(DrawableRecipientChip currentChip) {
- return new SingleRecipientArrayAdapter(getContext(), currentChip.getEntry(),
- mDropdownChipLayouter);
- }
-
- @Override
- public void onCheckedItemChanged(int position) {
- ListView listView = mAlternatesPopup.getListView();
- if (listView != null && listView.getCheckedItemCount() == 0) {
- listView.setItemChecked(position, true);
- }
- mCheckedItem = position;
- }
-
- private int putOffsetInRange(final float x, final float y) {
- final int offset;
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
- offset = getOffsetForPosition(x, y);
- } else {
- offset = supportGetOffsetForPosition(x, y);
- }
-
- return putOffsetInRange(offset);
- }
-
- // TODO: This algorithm will need a lot of tweaking after more people have used
- // the chips ui. This attempts to be "forgiving" to fat finger touches by favoring
- // what comes before the finger.
- private int putOffsetInRange(int o) {
- int offset = o;
- Editable text = getText();
- int length = text.length();
- // Remove whitespace from end to find "real end"
- int realLength = length;
- for (int i = length - 1; i >= 0; i--) {
- if (text.charAt(i) == ' ') {
- realLength--;
- } else {
- break;
- }
- }
-
- // If the offset is beyond or at the end of the text,
- // leave it alone.
- if (offset >= realLength) {
- return offset;
- }
- Editable editable = getText();
- while (offset >= 0 && findText(editable, offset) == -1 && findChip(offset) == null) {
- // Keep walking backward!
- offset--;
- }
- return offset;
- }
-
- private static int findText(Editable text, int offset) {
- if (text.charAt(offset) != ' ') {
- return offset;
- }
- return -1;
- }
-
- private DrawableRecipientChip findChip(int offset) {
- DrawableRecipientChip[] chips =
- getSpannable().getSpans(0, getText().length(), DrawableRecipientChip.class);
- // Find the chip that contains this offset.
- for (int i = 0; i < chips.length; i++) {
- DrawableRecipientChip chip = chips[i];
- int start = getChipStart(chip);
- int end = getChipEnd(chip);
- if (offset >= start && offset <= end) {
- return chip;
- }
- }
- return null;
- }
-
- // Visible for testing.
- // Use this method to generate text to add to the list of addresses.
- /* package */String createAddressText(RecipientEntry entry) {
- String display = entry.getDisplayName();
- String address = entry.getDestination();
- if (TextUtils.isEmpty(display) || TextUtils.equals(display, address)) {
- display = null;
- }
- String trimmedDisplayText;
- if (isPhoneQuery() && isPhoneNumber(address)) {
- trimmedDisplayText = address.trim();
- } else {
- if (address != null) {
- // Tokenize out the address in case the address already
- // contained the username as well.
- Rfc822Token[] tokenized = Rfc822Tokenizer.tokenize(address);
- if (tokenized != null && tokenized.length > 0) {
- address = tokenized[0].getAddress();
- }
- }
- Rfc822Token token = new Rfc822Token(display, address, null);
- trimmedDisplayText = token.toString().trim();
- }
- int index = trimmedDisplayText.indexOf(",");
- return mTokenizer != null && !TextUtils.isEmpty(trimmedDisplayText)
- && index < trimmedDisplayText.length() - 1 ? (String) mTokenizer
- .terminateToken(trimmedDisplayText) : trimmedDisplayText;
- }
-
- // Visible for testing.
- // Use this method to generate text to display in a chip.
- /*package*/ String createChipDisplayText(RecipientEntry entry) {
- String display = entry.getDisplayName();
- String address = entry.getDestination();
- if (TextUtils.isEmpty(display) || TextUtils.equals(display, address)) {
- display = null;
- }
- if (!TextUtils.isEmpty(display)) {
- return display;
- } else if (!TextUtils.isEmpty(address)){
- return address;
- } else {
- return new Rfc822Token(display, address, null).toString();
- }
- }
-
- private CharSequence createChip(RecipientEntry entry, boolean pressed) {
- String displayText = createAddressText(entry);
- if (TextUtils.isEmpty(displayText)) {
- return null;
- }
- SpannableString chipText = null;
- // Always leave a blank space at the end of a chip.
- int textLength = displayText.length() - 1;
- chipText = new SpannableString(displayText);
- if (!mNoChips) {
- try {
- DrawableRecipientChip chip = constructChipSpan(entry, pressed,
- false /* leave space for contact icon */);
- chipText.setSpan(chip, 0, textLength,
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- chip.setOriginalText(chipText.toString());
- } catch (NullPointerException e) {
- Log.e(TAG, e.getMessage(), e);
- return null;
- }
- }
- return chipText;
- }
-
- /**
- * When an item in the suggestions list has been clicked, create a chip from the
- * contact information of the selected item.
- */
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- if (position < 0) {
- return;
- }
- submitItemAtPosition(position);
- }
-
- private void submitItemAtPosition(int position) {
- RecipientEntry entry = createValidatedEntry(getAdapter().getItem(position));
- if (entry == null) {
- return;
- }
- clearComposingText();
-
- int end = getSelectionEnd();
- int start = mTokenizer.findTokenStart(getText(), end);
-
- Editable editable = getText();
- QwertyKeyListener.markAsReplaced(editable, start, end, "");
- CharSequence chip = createChip(entry, false);
- if (chip != null && start >= 0 && end >= 0) {
- editable.replace(start, end, chip);
- }
- sanitizeBetween();
- }
-
- private RecipientEntry createValidatedEntry(RecipientEntry item) {
- if (item == null) {
- return null;
- }
- final RecipientEntry entry;
- // If the display name and the address are the same, or if this is a
- // valid contact, but the destination is invalid, then make this a fake
- // recipient that is editable.
- String destination = item.getDestination();
- if (!isPhoneQuery() && item.getContactId() == RecipientEntry.GENERATED_CONTACT) {
- entry = RecipientEntry.constructGeneratedEntry(item.getDisplayName(),
- destination, item.isValid());
- } else if (RecipientEntry.isCreatedRecipient(item.getContactId())
- && (TextUtils.isEmpty(item.getDisplayName())
- || TextUtils.equals(item.getDisplayName(), destination)
- || (mValidator != null && !mValidator.isValid(destination)))) {
- entry = RecipientEntry.constructFakeEntry(destination, item.isValid());
- } else {
- entry = item;
- }
- return entry;
- }
-
- /** Returns a collection of contact Id for each chip inside this View. */
- /* package */ Collection<Long> getContactIds() {
- final Set<Long> result = new HashSet<Long>();
- DrawableRecipientChip[] chips = getSortedRecipients();
- if (chips != null) {
- for (DrawableRecipientChip chip : chips) {
- result.add(chip.getContactId());
- }
- }
- return result;
- }
-
-
- /** Returns a collection of data Id for each chip inside this View. May be null. */
- /* package */ Collection<Long> getDataIds() {
- final Set<Long> result = new HashSet<Long>();
- DrawableRecipientChip [] chips = getSortedRecipients();
- if (chips != null) {
- for (DrawableRecipientChip chip : chips) {
- result.add(chip.getDataId());
- }
- }
- return result;
- }
-
- // Visible for testing.
- /* package */DrawableRecipientChip[] getSortedRecipients() {
- DrawableRecipientChip[] recips = getSpannable()
- .getSpans(0, getText().length(), DrawableRecipientChip.class);
- ArrayList<DrawableRecipientChip> recipientsList = new ArrayList<DrawableRecipientChip>(
- Arrays.asList(recips));
- final Spannable spannable = getSpannable();
- Collections.sort(recipientsList, new Comparator<DrawableRecipientChip>() {
-
- @Override
- public int compare(DrawableRecipientChip first, DrawableRecipientChip second) {
- int firstStart = spannable.getSpanStart(first);
- int secondStart = spannable.getSpanStart(second);
- if (firstStart < secondStart) {
- return -1;
- } else if (firstStart > secondStart) {
- return 1;
- } else {
- return 0;
- }
- }
- });
- return recipientsList.toArray(new DrawableRecipientChip[recipientsList.size()]);
- }
-
- @Override
- public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- return false;
- }
-
- @Override
- public void onDestroyActionMode(ActionMode mode) {
- }
-
- @Override
- public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
- return false;
- }
-
- /**
- * No chips are selectable.
- */
- @Override
- public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- return false;
- }
-
- // Visible for testing.
- /* package */ImageSpan getMoreChip() {
- MoreImageSpan[] moreSpans = getSpannable().getSpans(0, getText().length(),
- MoreImageSpan.class);
- return moreSpans != null && moreSpans.length > 0 ? moreSpans[0] : null;
- }
-
- private MoreImageSpan createMoreSpan(int count) {
- String moreText = String.format(mMoreItem.getText().toString(), count);
- TextPaint morePaint = new TextPaint(getPaint());
- morePaint.setTextSize(mMoreItem.getTextSize());
- morePaint.setColor(mMoreItem.getCurrentTextColor());
- int width = (int)morePaint.measureText(moreText) + mMoreItem.getPaddingLeft()
- + mMoreItem.getPaddingRight();
- int height = getLineHeight();
- Bitmap drawable = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(drawable);
- int adjustedHeight = height;
- Layout layout = getLayout();
- if (layout != null) {
- adjustedHeight -= layout.getLineDescent(0);
- }
- canvas.drawText(moreText, 0, moreText.length(), 0, adjustedHeight, morePaint);
-
- Drawable result = new BitmapDrawable(getResources(), drawable);
- result.setBounds(0, 0, width, height);
- return new MoreImageSpan(result);
- }
-
- // Visible for testing.
- /*package*/ void createMoreChipPlainText() {
- // Take the first <= CHIP_LIMIT addresses and get to the end of the second one.
- Editable text = getText();
- int start = 0;
- int end = start;
- for (int i = 0; i < CHIP_LIMIT; i++) {
- end = movePastTerminators(mTokenizer.findTokenEnd(text, start));
- start = end; // move to the next token and get its end.
- }
- // Now, count total addresses.
- start = 0;
- int tokenCount = countTokens(text);
- MoreImageSpan moreSpan = createMoreSpan(tokenCount - CHIP_LIMIT);
- SpannableString chipText = new SpannableString(text.subSequence(end, text.length()));
- chipText.setSpan(moreSpan, 0, chipText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- text.replace(end, text.length(), chipText);
- mMoreChip = moreSpan;
- }
-
- // Visible for testing.
- /* package */int countTokens(Editable text) {
- int tokenCount = 0;
- int start = 0;
- while (start < text.length()) {
- start = movePastTerminators(mTokenizer.findTokenEnd(text, start));
- tokenCount++;
- if (start >= text.length()) {
- break;
- }
- }
- return tokenCount;
- }
-
- /**
- * Create the more chip. The more chip is text that replaces any chips that
- * do not fit in the pre-defined available space when the
- * RecipientEditTextView loses focus.
- */
- // Visible for testing.
- /* package */ void createMoreChip() {
- if (mNoChips) {
- createMoreChipPlainText();
- return;
- }
-
- if (!mShouldShrink) {
- return;
- }
- ImageSpan[] tempMore = getSpannable().getSpans(0, getText().length(), MoreImageSpan.class);
- if (tempMore.length > 0) {
- getSpannable().removeSpan(tempMore[0]);
- }
- DrawableRecipientChip[] recipients = getSortedRecipients();
-
- if (recipients == null || recipients.length <= CHIP_LIMIT) {
- mMoreChip = null;
- return;
- }
- Spannable spannable = getSpannable();
- int numRecipients = recipients.length;
- int overage = numRecipients - CHIP_LIMIT;
- MoreImageSpan moreSpan = createMoreSpan(overage);
- mRemovedSpans = new ArrayList<DrawableRecipientChip>();
- int totalReplaceStart = 0;
- int totalReplaceEnd = 0;
- Editable text = getText();
- for (int i = numRecipients - overage; i < recipients.length; i++) {
- mRemovedSpans.add(recipients[i]);
- if (i == numRecipients - overage) {
- totalReplaceStart = spannable.getSpanStart(recipients[i]);
- }
- if (i == recipients.length - 1) {
- totalReplaceEnd = spannable.getSpanEnd(recipients[i]);
- }
- if (mTemporaryRecipients == null || !mTemporaryRecipients.contains(recipients[i])) {
- int spanStart = spannable.getSpanStart(recipients[i]);
- int spanEnd = spannable.getSpanEnd(recipients[i]);
- recipients[i].setOriginalText(text.toString().substring(spanStart, spanEnd));
- }
- spannable.removeSpan(recipients[i]);
- }
- if (totalReplaceEnd < text.length()) {
- totalReplaceEnd = text.length();
- }
- int end = Math.max(totalReplaceStart, totalReplaceEnd);
- int start = Math.min(totalReplaceStart, totalReplaceEnd);
- SpannableString chipText = new SpannableString(text.subSequence(start, end));
- chipText.setSpan(moreSpan, 0, chipText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- text.replace(start, end, chipText);
- mMoreChip = moreSpan;
- // If adding the +more chip goes over the limit, resize accordingly.
- if (!isPhoneQuery() && getLineCount() > mMaxLines) {
- setMaxLines(getLineCount());
- }
- }
-
- /**
- * Replace the more chip, if it exists, with all of the recipient chips it had
- * replaced when the RecipientEditTextView gains focus.
- */
- // Visible for testing.
- /*package*/ void removeMoreChip() {
- if (mMoreChip != null) {
- Spannable span = getSpannable();
- span.removeSpan(mMoreChip);
- mMoreChip = null;
- // Re-add the spans that were removed.
- if (mRemovedSpans != null && mRemovedSpans.size() > 0) {
- // Recreate each removed span.
- DrawableRecipientChip[] recipients = getSortedRecipients();
- // Start the search for tokens after the last currently visible
- // chip.
- if (recipients == null || recipients.length == 0) {
- return;
- }
- int end = span.getSpanEnd(recipients[recipients.length - 1]);
- Editable editable = getText();
- for (DrawableRecipientChip chip : mRemovedSpans) {
- int chipStart;
- int chipEnd;
- String token;
- // Need to find the location of the chip, again.
- token = (String) chip.getOriginalText();
- // As we find the matching recipient for the remove spans,
- // reduce the size of the string we need to search.
- // That way, if there are duplicates, we always find the correct
- // recipient.
- chipStart = editable.toString().indexOf(token, end);
- end = chipEnd = Math.min(editable.length(), chipStart + token.length());
- // Only set the span if we found a matching token.
- if (chipStart != -1) {
- editable.setSpan(chip, chipStart, chipEnd,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- }
- mRemovedSpans.clear();
- }
- }
- }
-
- /**
- * Show specified chip as selected. If the RecipientChip is just an email address,
- * selecting the chip will take the contents of the chip and place it at
- * the end of the RecipientEditTextView for inline editing. If the
- * RecipientChip is a complete contact, then selecting the chip
- * will change the background color of the chip, show the delete icon,
- * and a popup window with the address in use highlighted and any other
- * alternate addresses for the contact.
- * @param currentChip Chip to select.
- * @return A RecipientChip in the selected state or null if the chip
- * just contained an email address.
- */
- private DrawableRecipientChip selectChip(DrawableRecipientChip currentChip) {
- if (shouldShowEditableText(currentChip)) {
- CharSequence text = currentChip.getValue();
- Editable editable = getText();
- Spannable spannable = getSpannable();
- int spanStart = spannable.getSpanStart(currentChip);
- int spanEnd = spannable.getSpanEnd(currentChip);
- spannable.removeSpan(currentChip);
- editable.delete(spanStart, spanEnd);
- setCursorVisible(true);
- setSelection(editable.length());
- editable.append(text);
- return constructChipSpan(
- RecipientEntry.constructFakeEntry((String) text, isValid(text.toString())),
- true, false);
- } else if (currentChip.getContactId() == RecipientEntry.GENERATED_CONTACT) {
- int start = getChipStart(currentChip);
- int end = getChipEnd(currentChip);
- getSpannable().removeSpan(currentChip);
- DrawableRecipientChip newChip;
- try {
- if (mNoChips) {
- return null;
- }
- newChip = constructChipSpan(currentChip.getEntry(), true, false);
- } catch (NullPointerException e) {
- Log.e(TAG, e.getMessage(), e);
- return null;
- }
- Editable editable = getText();
- QwertyKeyListener.markAsReplaced(editable, start, end, "");
- if (start == -1 || end == -1) {
- Log.d(TAG, "The chip being selected no longer exists but should.");
- } else {
- editable.setSpan(newChip, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- newChip.setSelected(true);
- if (shouldShowEditableText(newChip)) {
- scrollLineIntoView(getLayout().getLineForOffset(getChipStart(newChip)));
- }
- showAddress(newChip, mAddressPopup, getWidth());
- setCursorVisible(false);
- return newChip;
- } else {
- int start = getChipStart(currentChip);
- int end = getChipEnd(currentChip);
- getSpannable().removeSpan(currentChip);
- DrawableRecipientChip newChip;
- try {
- newChip = constructChipSpan(currentChip.getEntry(), true, false);
- } catch (NullPointerException e) {
- Log.e(TAG, e.getMessage(), e);
- return null;
- }
- Editable editable = getText();
- QwertyKeyListener.markAsReplaced(editable, start, end, "");
- if (start == -1 || end == -1) {
- Log.d(TAG, "The chip being selected no longer exists but should.");
- } else {
- editable.setSpan(newChip, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- newChip.setSelected(true);
- if (shouldShowEditableText(newChip)) {
- scrollLineIntoView(getLayout().getLineForOffset(getChipStart(newChip)));
- }
- showAlternates(newChip, mAlternatesPopup, getWidth());
- setCursorVisible(false);
- return newChip;
- }
- }
-
- private boolean shouldShowEditableText(DrawableRecipientChip currentChip) {
- long contactId = currentChip.getContactId();
- return contactId == RecipientEntry.INVALID_CONTACT
- || (!isPhoneQuery() && contactId == RecipientEntry.GENERATED_CONTACT);
- }
-
- private void showAddress(final DrawableRecipientChip currentChip, final ListPopupWindow popup,
- int width) {
- if (!mAttachedToWindow) {
- return;
- }
- int line = getLayout().getLineForOffset(getChipStart(currentChip));
- int bottom = calculateOffsetFromBottom(line);
- // Align the alternates popup with the left side of the View,
- // regardless of the position of the chip tapped.
- popup.setWidth(width);
- popup.setAnchorView(this);
- popup.setVerticalOffset(bottom);
- popup.setAdapter(createSingleAddressAdapter(currentChip));
- popup.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- unselectChip(currentChip);
- popup.dismiss();
- }
- });
- popup.show();
- ListView listView = popup.getListView();
- listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
- listView.setItemChecked(0, true);
- }
-
- /**
- * Remove selection from this chip. Unselecting a RecipientChip will render
- * the chip without a delete icon and with an unfocused background. This is
- * called when the RecipientChip no longer has focus.
- */
- private void unselectChip(DrawableRecipientChip chip) {
- int start = getChipStart(chip);
- int end = getChipEnd(chip);
- Editable editable = getText();
- mSelectedChip = null;
- if (start == -1 || end == -1) {
- Log.w(TAG, "The chip doesn't exist or may be a chip a user was editing");
- setSelection(editable.length());
- commitDefault();
- } else {
- getSpannable().removeSpan(chip);
- QwertyKeyListener.markAsReplaced(editable, start, end, "");
- editable.removeSpan(chip);
- try {
- if (!mNoChips) {
- editable.setSpan(constructChipSpan(chip.getEntry(), false, false),
- start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- } catch (NullPointerException e) {
- Log.e(TAG, e.getMessage(), e);
- }
- }
- setCursorVisible(true);
- setSelection(editable.length());
- if (mAlternatesPopup != null && mAlternatesPopup.isShowing()) {
- mAlternatesPopup.dismiss();
- }
- }
-
- /**
- * Return whether a touch event was inside the delete target of
- * a selected chip. It is in the delete target if:
- * 1) the x and y points of the event are within the
- * delete assset.
- * 2) the point tapped would have caused a cursor to appear
- * right after the selected chip.
- * @return boolean
- */
- private boolean isInDelete(DrawableRecipientChip chip, int offset, float x, float y) {
- // Figure out the bounds of this chip and whether or not
- // the user clicked in the X portion.
- // TODO: Should x and y be used, or removed?
- if (mDisableDelete) {
- return false;
- }
-
- return chip.isSelected() &&
- ((mAvatarPosition == AVATAR_POSITION_END && offset == getChipEnd(chip)) ||
- (mAvatarPosition != AVATAR_POSITION_END && offset == getChipStart(chip)));
- }
-
- /**
- * Remove the chip and any text associated with it from the RecipientEditTextView.
- */
- // Visible for testing.
- /* package */void removeChip(DrawableRecipientChip chip) {
- Spannable spannable = getSpannable();
- int spanStart = spannable.getSpanStart(chip);
- int spanEnd = spannable.getSpanEnd(chip);
- Editable text = getText();
- int toDelete = spanEnd;
- boolean wasSelected = chip == mSelectedChip;
- // Clear that there is a selected chip before updating any text.
- if (wasSelected) {
- mSelectedChip = null;
- }
- // Always remove trailing spaces when removing a chip.
- while (toDelete >= 0 && toDelete < text.length() && text.charAt(toDelete) == ' ') {
- toDelete++;
- }
- spannable.removeSpan(chip);
- if (spanStart >= 0 && toDelete > 0) {
- text.delete(spanStart, toDelete);
- }
- if (wasSelected) {
- clearSelectedChip();
- }
- }
-
- /**
- * Replace this currently selected chip with a new chip
- * that uses the contact data provided.
- */
- // Visible for testing.
- /*package*/ void replaceChip(DrawableRecipientChip chip, RecipientEntry entry) {
- boolean wasSelected = chip == mSelectedChip;
- if (wasSelected) {
- mSelectedChip = null;
- }
- int start = getChipStart(chip);
- int end = getChipEnd(chip);
- getSpannable().removeSpan(chip);
- Editable editable = getText();
- CharSequence chipText = createChip(entry, false);
- if (chipText != null) {
- if (start == -1 || end == -1) {
- Log.e(TAG, "The chip to replace does not exist but should.");
- editable.insert(0, chipText);
- } else {
- if (!TextUtils.isEmpty(chipText)) {
- // There may be a space to replace with this chip's new
- // associated space. Check for it
- int toReplace = end;
- while (toReplace >= 0 && toReplace < editable.length()
- && editable.charAt(toReplace) == ' ') {
- toReplace++;
- }
- editable.replace(start, toReplace, chipText);
- }
- }
- }
- setCursorVisible(true);
- if (wasSelected) {
- clearSelectedChip();
- }
- }
-
- /**
- * Handle click events for a chip. When a selected chip receives a click
- * event, see if that event was in the delete icon. If so, delete it.
- * Otherwise, unselect the chip.
- */
- public void onClick(DrawableRecipientChip chip, int offset, float x, float y) {
- if (chip.isSelected()) {
- if (isInDelete(chip, offset, x, y)) {
- removeChip(chip);
- } else {
- clearSelectedChip();
- }
- }
- }
-
- private boolean chipsPending() {
- return mPendingChipsCount > 0 || (mRemovedSpans != null && mRemovedSpans.size() > 0);
- }
-
- @Override
- public void removeTextChangedListener(TextWatcher watcher) {
- mTextWatcher = null;
- super.removeTextChangedListener(watcher);
- }
-
- private class RecipientTextWatcher implements TextWatcher {
-
- @Override
- public void afterTextChanged(Editable s) {
- // If the text has been set to null or empty, make sure we remove
- // all the spans we applied.
- if (TextUtils.isEmpty(s)) {
- // Remove all the chips spans.
- Spannable spannable = getSpannable();
- DrawableRecipientChip[] chips = spannable.getSpans(0, getText().length(),
- DrawableRecipientChip.class);
- for (DrawableRecipientChip chip : chips) {
- spannable.removeSpan(chip);
- }
- if (mMoreChip != null) {
- spannable.removeSpan(mMoreChip);
- }
- clearSelectedChip();
- return;
- }
- // Get whether there are any recipients pending addition to the
- // view. If there are, don't do anything in the text watcher.
- if (chipsPending()) {
- return;
- }
- // If the user is editing a chip, don't clear it.
- if (mSelectedChip != null) {
- if (!isGeneratedContact(mSelectedChip)) {
- setCursorVisible(true);
- setSelection(getText().length());
- clearSelectedChip();
- } else {
- return;
- }
- }
- int length = s.length();
- // Make sure there is content there to parse and that it is
- // not just the commit character.
- if (length > 1) {
- if (lastCharacterIsCommitCharacter(s)) {
- commitByCharacter();
- return;
- }
- char last;
- int end = getSelectionEnd() == 0 ? 0 : getSelectionEnd() - 1;
- int len = length() - 1;
- if (end != len) {
- last = s.charAt(end);
- } else {
- last = s.charAt(len);
- }
- if (last == COMMIT_CHAR_SPACE) {
- if (!isPhoneQuery()) {
- // Check if this is a valid email address. If it is,
- // commit it.
- String text = getText().toString();
- int tokenStart = mTokenizer.findTokenStart(text, getSelectionEnd());
- String sub = text.substring(tokenStart, mTokenizer.findTokenEnd(text,
- tokenStart));
- if (!TextUtils.isEmpty(sub) && mValidator != null &&
- mValidator.isValid(sub)) {
- commitByCharacter();
- }
- }
- }
- }
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- // The user deleted some text OR some text was replaced; check to
- // see if the insertion point is on a space
- // following a chip.
- if (before - count == 1) {
- // If the item deleted is a space, and the thing before the
- // space is a chip, delete the entire span.
- int selStart = getSelectionStart();
- DrawableRecipientChip[] repl = getSpannable().getSpans(selStart, selStart,
- DrawableRecipientChip.class);
- if (repl.length > 0) {
- // There is a chip there! Just remove it.
- Editable editable = getText();
- // Add the separator token.
- int tokenStart = mTokenizer.findTokenStart(editable, selStart);
- int tokenEnd = mTokenizer.findTokenEnd(editable, tokenStart);
- tokenEnd = tokenEnd + 1;
- if (tokenEnd > editable.length()) {
- tokenEnd = editable.length();
- }
- editable.delete(tokenStart, tokenEnd);
- getSpannable().removeSpan(repl[0]);
- }
- } else if (count > before) {
- if (mSelectedChip != null
- && isGeneratedContact(mSelectedChip)) {
- if (lastCharacterIsCommitCharacter(s)) {
- commitByCharacter();
- return;
- }
- }
- }
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- // Do nothing.
- }
- }
-
- public boolean lastCharacterIsCommitCharacter(CharSequence s) {
- char last;
- int end = getSelectionEnd() == 0 ? 0 : getSelectionEnd() - 1;
- int len = length() - 1;
- if (end != len) {
- last = s.charAt(end);
- } else {
- last = s.charAt(len);
- }
- return last == COMMIT_CHAR_COMMA || last == COMMIT_CHAR_SEMICOLON;
- }
-
- public boolean isGeneratedContact(DrawableRecipientChip chip) {
- long contactId = chip.getContactId();
- return contactId == RecipientEntry.INVALID_CONTACT
- || (!isPhoneQuery() && contactId == RecipientEntry.GENERATED_CONTACT);
- }
-
- /**
- * Handles pasting a {@link ClipData} to this {@link RecipientEditTextView}.
- */
- private void handlePasteClip(ClipData clip) {
- removeTextChangedListener(mTextWatcher);
-
- if (clip != null && clip.getDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)){
- for (int i = 0; i < clip.getItemCount(); i++) {
- CharSequence paste = clip.getItemAt(i).getText();
- if (paste != null) {
- int start = getSelectionStart();
- int end = getSelectionEnd();
- Editable editable = getText();
- if (start >= 0 && end >= 0 && start != end) {
- editable.append(paste, start, end);
- } else {
- editable.insert(end, paste);
- }
- handlePasteAndReplace();
- }
- }
- }
-
- mHandler.post(mAddTextWatcher);
- }
-
- @Override
- public boolean onTextContextMenuItem(int id) {
- if (id == android.R.id.paste) {
- ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(
- Context.CLIPBOARD_SERVICE);
- handlePasteClip(clipboard.getPrimaryClip());
- return true;
- }
- return super.onTextContextMenuItem(id);
- }
-
- private void handlePasteAndReplace() {
- ArrayList<DrawableRecipientChip> created = handlePaste();
- if (created != null && created.size() > 0) {
- // Perform reverse lookups on the pasted contacts.
- IndividualReplacementTask replace = new IndividualReplacementTask();
- replace.execute(created);
- }
- }
-
- // Visible for testing.
- /* package */ArrayList<DrawableRecipientChip> handlePaste() {
- String text = getText().toString();
- int originalTokenStart = mTokenizer.findTokenStart(text, getSelectionEnd());
- String lastAddress = text.substring(originalTokenStart);
- int tokenStart = originalTokenStart;
- int prevTokenStart = 0;
- DrawableRecipientChip findChip = null;
- ArrayList<DrawableRecipientChip> created = new ArrayList<DrawableRecipientChip>();
- if (tokenStart != 0) {
- // There are things before this!
- while (tokenStart != 0 && findChip == null && tokenStart != prevTokenStart) {
- prevTokenStart = tokenStart;
- tokenStart = mTokenizer.findTokenStart(text, tokenStart);
- findChip = findChip(tokenStart);
- if (tokenStart == originalTokenStart && findChip == null) {
- break;
- }
- }
- if (tokenStart != originalTokenStart) {
- if (findChip != null) {
- tokenStart = prevTokenStart;
- }
- int tokenEnd;
- DrawableRecipientChip createdChip;
- while (tokenStart < originalTokenStart) {
- tokenEnd = movePastTerminators(mTokenizer.findTokenEnd(getText().toString(),
- tokenStart));
- commitChip(tokenStart, tokenEnd, getText());
- createdChip = findChip(tokenStart);
- if (createdChip == null) {
- break;
- }
- // +1 for the space at the end.
- tokenStart = getSpannable().getSpanEnd(createdChip) + 1;
- created.add(createdChip);
- }
- }
- }
- // Take a look at the last token. If the token has been completed with a
- // commit character, create a chip.
- if (isCompletedToken(lastAddress)) {
- Editable editable = getText();
- tokenStart = editable.toString().indexOf(lastAddress, originalTokenStart);
- commitChip(tokenStart, editable.length(), editable);
- created.add(findChip(tokenStart));
- }
- return created;
- }
-
- // Visible for testing.
- /* package */int movePastTerminators(int tokenEnd) {
- if (tokenEnd >= length()) {
- return tokenEnd;
- }
- char atEnd = getText().toString().charAt(tokenEnd);
- if (atEnd == COMMIT_CHAR_COMMA || atEnd == COMMIT_CHAR_SEMICOLON) {
- tokenEnd++;
- }
- // This token had not only an end token character, but also a space
- // separating it from the next token.
- if (tokenEnd < length() && getText().toString().charAt(tokenEnd) == ' ') {
- tokenEnd++;
- }
- return tokenEnd;
- }
-
- private class RecipientReplacementTask extends AsyncTask<Void, Void, Void> {
- private DrawableRecipientChip createFreeChip(RecipientEntry entry) {
- try {
- if (mNoChips) {
- return null;
- }
- return constructChipSpan(entry, false,
- false /*leave space for contact icon */);
- } catch (NullPointerException e) {
- Log.e(TAG, e.getMessage(), e);
- return null;
- }
- }
-
- @Override
- protected void onPreExecute() {
- // Ensure everything is in chip-form already, so we don't have text that slowly gets
- // replaced
- final List<DrawableRecipientChip> originalRecipients =
- new ArrayList<DrawableRecipientChip>();
- final DrawableRecipientChip[] existingChips = getSortedRecipients();
- for (int i = 0; i < existingChips.length; i++) {
- originalRecipients.add(existingChips[i]);
- }
- if (mRemovedSpans != null) {
- originalRecipients.addAll(mRemovedSpans);
- }
-
- final List<DrawableRecipientChip> replacements =
- new ArrayList<DrawableRecipientChip>(originalRecipients.size());
-
- for (final DrawableRecipientChip chip : originalRecipients) {
- if (RecipientEntry.isCreatedRecipient(chip.getEntry().getContactId())
- && getSpannable().getSpanStart(chip) != -1) {
- replacements.add(createFreeChip(chip.getEntry()));
- } else {
- replacements.add(null);
- }
- }
-
- processReplacements(originalRecipients, replacements);
- }
-
- @Override
- protected Void doInBackground(Void... params) {
- if (mIndividualReplacements != null) {
- mIndividualReplacements.cancel(true);
- }
- // For each chip in the list, look up the matching contact.
- // If there is a match, replace that chip with the matching
- // chip.
- final ArrayList<DrawableRecipientChip> recipients =
- new ArrayList<DrawableRecipientChip>();
- DrawableRecipientChip[] existingChips = getSortedRecipients();
- for (int i = 0; i < existingChips.length; i++) {
- recipients.add(existingChips[i]);
- }
- if (mRemovedSpans != null) {
- recipients.addAll(mRemovedSpans);
- }
- ArrayList<String> addresses = new ArrayList<String>();
- DrawableRecipientChip chip;
- for (int i = 0; i < recipients.size(); i++) {
- chip = recipients.get(i);
- if (chip != null) {
- addresses.add(createAddressText(chip.getEntry()));
- }
- }
- final BaseRecipientAdapter adapter = getAdapter();
- RecipientAlternatesAdapter.getMatchingRecipients(getContext(), adapter, addresses,
- adapter.getAccount(), new RecipientMatchCallback() {
- @Override
- public void matchesFound(Map<String, RecipientEntry> entries) {
- final ArrayList<DrawableRecipientChip> replacements =
- new ArrayList<DrawableRecipientChip>();
- for (final DrawableRecipientChip temp : recipients) {
- RecipientEntry entry = null;
- if (temp != null && RecipientEntry.isCreatedRecipient(
- temp.getEntry().getContactId())
- && getSpannable().getSpanStart(temp) != -1) {
- // Replace this.
- entry = createValidatedEntry(
- entries.get(tokenizeAddress(temp.getEntry()
- .getDestination())));
- }
- if (entry != null) {
- replacements.add(createFreeChip(entry));
- } else {
- replacements.add(null);
- }
- }
- processReplacements(recipients, replacements);
- }
-
- @Override
- public void matchesNotFound(final Set<String> unfoundAddresses) {
- final List<DrawableRecipientChip> replacements =
- new ArrayList<DrawableRecipientChip>(unfoundAddresses.size());
-
- for (final DrawableRecipientChip temp : recipients) {
- if (temp != null && RecipientEntry.isCreatedRecipient(
- temp.getEntry().getContactId())
- && getSpannable().getSpanStart(temp) != -1) {
- if (unfoundAddresses.contains(
- temp.getEntry().getDestination())) {
- replacements.add(createFreeChip(temp.getEntry()));
- } else {
- replacements.add(null);
- }
- } else {
- replacements.add(null);
- }
- }
-
- processReplacements(recipients, replacements);
- }
- });
- return null;
- }
-
- private void processReplacements(final List<DrawableRecipientChip> recipients,
- final List<DrawableRecipientChip> replacements) {
- if (replacements != null && replacements.size() > 0) {
- final Runnable runnable = new Runnable() {
- @Override
- public void run() {
- final Editable text = new SpannableStringBuilder(getText());
- int i = 0;
- for (final DrawableRecipientChip chip : recipients) {
- final DrawableRecipientChip replacement = replacements.get(i);
- if (replacement != null) {
- final RecipientEntry oldEntry = chip.getEntry();
- final RecipientEntry newEntry = replacement.getEntry();
- final boolean isBetter =
- RecipientAlternatesAdapter.getBetterRecipient(
- oldEntry, newEntry) == newEntry;
-
- if (isBetter) {
- // Find the location of the chip in the text currently shown.
- final int start = text.getSpanStart(chip);
- if (start != -1) {
- // Replacing the entirety of what the chip represented,
- // including the extra space dividing it from other chips.
- final int end =
- Math.min(text.getSpanEnd(chip) + 1, text.length());
- text.removeSpan(chip);
- // Make sure we always have just 1 space at the end to
- // separate this chip from the next chip.
- final SpannableString displayText =
- new SpannableString(createAddressText(
- replacement.getEntry()).trim() + " ");
- displayText.setSpan(replacement, 0,
- displayText.length() - 1,
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- // Replace the old text we found with with the new display
- // text, which now may also contain the display name of the
- // recipient.
- text.replace(start, end, displayText);
- replacement.setOriginalText(displayText.toString());
- replacements.set(i, null);
-
- recipients.set(i, replacement);
- }
- }
- }
- i++;
- }
- setText(text);
- }
- };
-
- if (Looper.myLooper() == Looper.getMainLooper()) {
- runnable.run();
- } else {
- mHandler.post(runnable);
- }
- }
- }
- }
-
- private class IndividualReplacementTask
- extends AsyncTask<ArrayList<DrawableRecipientChip>, Void, Void> {
- @Override
- protected Void doInBackground(ArrayList<DrawableRecipientChip>... params) {
- // For each chip in the list, look up the matching contact.
- // If there is a match, replace that chip with the matching
- // chip.
- final ArrayList<DrawableRecipientChip> originalRecipients = params[0];
- ArrayList<String> addresses = new ArrayList<String>();
- DrawableRecipientChip chip;
- for (int i = 0; i < originalRecipients.size(); i++) {
- chip = originalRecipients.get(i);
- if (chip != null) {
- addresses.add(createAddressText(chip.getEntry()));
- }
- }
- final BaseRecipientAdapter adapter = getAdapter();
- RecipientAlternatesAdapter.getMatchingRecipients(getContext(), adapter, addresses,
- adapter.getAccount(),
- new RecipientMatchCallback() {
-
- @Override
- public void matchesFound(Map<String, RecipientEntry> entries) {
- for (final DrawableRecipientChip temp : originalRecipients) {
- if (RecipientEntry.isCreatedRecipient(temp.getEntry()
- .getContactId())
- && getSpannable().getSpanStart(temp) != -1) {
- // Replace this.
- final RecipientEntry entry = createValidatedEntry(entries
- .get(tokenizeAddress(temp.getEntry().getDestination())
- .toLowerCase()));
- if (entry != null) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- replaceChip(temp, entry);
- }
- });
- }
- }
- }
- }
-
- @Override
- public void matchesNotFound(final Set<String> unfoundAddresses) {
- // No action required
- }
- });
- return null;
- }
- }
-
-
- /**
- * MoreImageSpan is a simple class created for tracking the existence of a
- * more chip across activity restarts/
- */
- private class MoreImageSpan extends ImageSpan {
- public MoreImageSpan(Drawable b) {
- super(b);
- }
- }
-
- @Override
- public boolean onDown(MotionEvent e) {
- return false;
- }
-
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- // Do nothing.
- return false;
- }
-
- @Override
- public void onLongPress(MotionEvent event) {
- if (mSelectedChip != null) {
- return;
- }
- float x = event.getX();
- float y = event.getY();
- final int offset = putOffsetInRange(x, y);
- DrawableRecipientChip currentChip = findChip(offset);
- if (currentChip != null) {
- if (mDragEnabled) {
- // Start drag-and-drop for the selected chip.
- startDrag(currentChip);
- } else {
- // Copy the selected chip email address.
- showCopyDialog(currentChip.getEntry().getDestination());
- }
- }
- }
-
- // The following methods are used to provide some functionality on older versions of Android
- // These methods were copied out of JB MR2's TextView
- /////////////////////////////////////////////////
- private int supportGetOffsetForPosition(float x, float y) {
- if (getLayout() == null) return -1;
- final int line = supportGetLineAtCoordinate(y);
- final int offset = supportGetOffsetAtCoordinate(line, x);
- return offset;
- }
-
- private float supportConvertToLocalHorizontalCoordinate(float x) {
- x -= getTotalPaddingLeft();
- // Clamp the position to inside of the view.
- x = Math.max(0.0f, x);
- x = Math.min(getWidth() - getTotalPaddingRight() - 1, x);
- x += getScrollX();
- return x;
- }
-
- private int supportGetLineAtCoordinate(float y) {
- y -= getTotalPaddingLeft();
- // Clamp the position to inside of the view.
- y = Math.max(0.0f, y);
- y = Math.min(getHeight() - getTotalPaddingBottom() - 1, y);
- y += getScrollY();
- return getLayout().getLineForVertical((int) y);
- }
-
- private int supportGetOffsetAtCoordinate(int line, float x) {
- x = supportConvertToLocalHorizontalCoordinate(x);
- return getLayout().getOffsetForHorizontal(line, x);
- }
- /////////////////////////////////////////////////
-
- /**
- * Enables drag-and-drop for chips.
- */
- public void enableDrag() {
- mDragEnabled = true;
- }
-
- /**
- * Starts drag-and-drop for the selected chip.
- */
- private void startDrag(DrawableRecipientChip currentChip) {
- String address = currentChip.getEntry().getDestination();
- ClipData data = ClipData.newPlainText(address, address + COMMIT_CHAR_COMMA);
-
- // Start drag mode.
- startDrag(data, new RecipientChipShadow(currentChip), null, 0);
-
- // Remove the current chip, so drag-and-drop will result in a move.
- // TODO (phamm): consider readd this chip if it's dropped outside a target.
- removeChip(currentChip);
- }
-
- /**
- * Handles drag event.
- */
- @Override
- public boolean onDragEvent(DragEvent event) {
- switch (event.getAction()) {
- case DragEvent.ACTION_DRAG_STARTED:
- // Only handle plain text drag and drop.
- return event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN);
- case DragEvent.ACTION_DRAG_ENTERED:
- requestFocus();
- return true;
- case DragEvent.ACTION_DROP:
- handlePasteClip(event.getClipData());
- return true;
- }
- return false;
- }
-
- /**
- * Drag shadow for a {@link RecipientChip}.
- */
- private final class RecipientChipShadow extends DragShadowBuilder {
- private final DrawableRecipientChip mChip;
-
- public RecipientChipShadow(DrawableRecipientChip chip) {
- mChip = chip;
- }
-
- @Override
- public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
- Rect rect = mChip.getBounds();
- shadowSize.set(rect.width(), rect.height());
- shadowTouchPoint.set(rect.centerX(), rect.centerY());
- }
-
- @Override
- public void onDrawShadow(Canvas canvas) {
- mChip.draw(canvas);
- }
- }
-
- private void showCopyDialog(final String address) {
- if (!mAttachedToWindow) {
- return;
- }
- mCopyAddress = address;
- mCopyDialog.setTitle(address);
- mCopyDialog.setContentView(R.layout.copy_chip_dialog_layout);
- mCopyDialog.setCancelable(true);
- mCopyDialog.setCanceledOnTouchOutside(true);
- Button button = (Button)mCopyDialog.findViewById(android.R.id.button1);
- button.setOnClickListener(this);
- int btnTitleId;
- if (isPhoneQuery()) {
- btnTitleId = R.string.copy_number;
- } else {
- btnTitleId = R.string.copy_email;
- }
- String buttonTitle = getContext().getResources().getString(btnTitleId);
- button.setText(buttonTitle);
- mCopyDialog.setOnDismissListener(this);
- mCopyDialog.show();
- }
-
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- // Do nothing.
- return false;
- }
-
- @Override
- public void onShowPress(MotionEvent e) {
- // Do nothing.
- }
-
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- // Do nothing.
- return false;
- }
-
- @Override
- public void onDismiss(DialogInterface dialog) {
- mCopyAddress = null;
- }
-
- @Override
- public void onClick(View v) {
- // Copy this to the clipboard.
- ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(
- Context.CLIPBOARD_SERVICE);
- clipboard.setPrimaryClip(ClipData.newPlainText("", mCopyAddress));
- mCopyDialog.dismiss();
- }
-
- protected boolean isPhoneQuery() {
- return getAdapter() != null
- && getAdapter().getQueryType() == BaseRecipientAdapter.QUERY_TYPE_PHONE;
- }
-
- @Override
- public BaseRecipientAdapter getAdapter() {
- return (BaseRecipientAdapter) super.getAdapter();
- }
-}
diff --git a/chips/src/com/android/ex/chips/RecipientEntry.java b/chips/src/com/android/ex/chips/RecipientEntry.java
deleted file mode 100644
index 7d9b87f..0000000
--- a/chips/src/com/android/ex/chips/RecipientEntry.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2011 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.ex.chips;
-
-import android.net.Uri;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.DisplayNameSources;
-import android.text.util.Rfc822Token;
-import android.text.util.Rfc822Tokenizer;
-
-/**
- * Represents one entry inside recipient auto-complete list.
- */
-public class RecipientEntry {
- /* package */ static final int INVALID_CONTACT = -1;
- /**
- * A GENERATED_CONTACT is one that was created based entirely on
- * information passed in to the RecipientEntry from an external source
- * that is not a real contact.
- */
- /* package */ static final int GENERATED_CONTACT = -2;
-
- /** Used when {@link #mDestinationType} is invalid and thus shouldn't be used for display. */
- /* package */ static final int INVALID_DESTINATION_TYPE = -1;
-
- public static final int ENTRY_TYPE_PERSON = 0;
-
- public static final int ENTRY_TYPE_SIZE = 1;
-
- private final int mEntryType;
-
- /**
- * True when this entry is the first entry in a group, which should have a photo and display
- * name, while the second or later entries won't.
- */
- private boolean mIsFirstLevel;
- private final String mDisplayName;
-
- /** Destination for this contact entry. Would be an email address or a phone number. */
- private final String mDestination;
- /** Type of the destination like {@link Email#TYPE_HOME} */
- private final int mDestinationType;
- /**
- * Label of the destination which will be used when type was {@link Email#TYPE_CUSTOM}.
- * Can be null when {@link #mDestinationType} is {@link #INVALID_DESTINATION_TYPE}.
- */
- private final String mDestinationLabel;
- /** ID for the person */
- private final long mContactId;
- /** ID for the directory this contact came from, or <code>null</code> */
- private final Long mDirectoryId;
- /** ID for the destination */
- private final long mDataId;
- private final boolean mIsDivider;
-
- private final Uri mPhotoThumbnailUri;
-
- private boolean mIsValid;
- /**
- * This can be updated after this object being constructed, when the photo is fetched
- * from remote directories.
- */
- private byte[] mPhotoBytes;
-
- /** See {@link ContactsContract.Contacts#LOOKUP_KEY} */
- private final String mLookupKey;
-
- private RecipientEntry(int entryType, String displayName, String destination,
- int destinationType, String destinationLabel, long contactId, Long directoryId,
- long dataId, Uri photoThumbnailUri, boolean isFirstLevel, boolean isValid,
- String lookupKey) {
- mEntryType = entryType;
- mIsFirstLevel = isFirstLevel;
- mDisplayName = displayName;
- mDestination = destination;
- mDestinationType = destinationType;
- mDestinationLabel = destinationLabel;
- mContactId = contactId;
- mDirectoryId = directoryId;
- mDataId = dataId;
- mPhotoThumbnailUri = photoThumbnailUri;
- mPhotoBytes = null;
- mIsDivider = false;
- mIsValid = isValid;
- mLookupKey = lookupKey;
- }
-
- public boolean isValid() {
- return mIsValid;
- }
-
- /**
- * Determine if this was a RecipientEntry created from recipient info or
- * an entry from contacts.
- */
- public static boolean isCreatedRecipient(long id) {
- return id == RecipientEntry.INVALID_CONTACT || id == RecipientEntry.GENERATED_CONTACT;
- }
-
- /**
- * Construct a RecipientEntry from just an address that has been entered.
- * This address has not been resolved to a contact and therefore does not
- * have a contact id or photo.
- */
- public static RecipientEntry constructFakeEntry(final String address, final boolean isValid) {
- final Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(address);
- final String tokenizedAddress = tokens.length > 0 ? tokens[0].getAddress() : address;
-
- return new RecipientEntry(ENTRY_TYPE_PERSON, tokenizedAddress, tokenizedAddress,
- INVALID_DESTINATION_TYPE, null, INVALID_CONTACT, null /* directoryId */,
- INVALID_CONTACT, null, true, isValid, null /* lookupKey */);
- }
-
- /**
- * Construct a RecipientEntry from just a phone number.
- */
- public static RecipientEntry constructFakePhoneEntry(final String phoneNumber,
- final boolean isValid) {
- return new RecipientEntry(ENTRY_TYPE_PERSON, phoneNumber, phoneNumber,
- INVALID_DESTINATION_TYPE, null, INVALID_CONTACT, null /* directoryId */,
- INVALID_CONTACT, null, true, isValid, null /* lookupKey */);
- }
-
- /**
- * @return the display name for the entry. If the display name source is larger than
- * {@link DisplayNameSources#PHONE} we use the contact's display name, but if not,
- * i.e. the display name came from an email address or a phone number, we don't use it
- * to avoid confusion and just use the destination instead.
- */
- private static String pickDisplayName(int displayNameSource, String displayName,
- String destination) {
- return (displayNameSource > DisplayNameSources.PHONE) ? displayName : destination;
- }
-
- /**
- * Construct a RecipientEntry from just an address that has been entered
- * with both an associated display name. This address has not been resolved
- * to a contact and therefore does not have a contact id or photo.
- */
- public static RecipientEntry constructGeneratedEntry(String display, String address,
- boolean isValid) {
- return new RecipientEntry(ENTRY_TYPE_PERSON, display, address, INVALID_DESTINATION_TYPE,
- null, GENERATED_CONTACT, null /* directoryId */, GENERATED_CONTACT, null, true,
- isValid, null /* lookupKey */);
- }
-
- public static RecipientEntry constructTopLevelEntry(String displayName, int displayNameSource,
- String destination, int destinationType, String destinationLabel, long contactId,
- Long directoryId, long dataId, Uri photoThumbnailUri, boolean isValid,
- String lookupKey) {
- return new RecipientEntry(ENTRY_TYPE_PERSON, pickDisplayName(displayNameSource,
- displayName, destination), destination, destinationType, destinationLabel,
- contactId, directoryId, dataId, photoThumbnailUri, true, isValid, lookupKey);
- }
-
- public static RecipientEntry constructTopLevelEntry(String displayName, int displayNameSource,
- String destination, int destinationType, String destinationLabel, long contactId,
- Long directoryId, long dataId, String thumbnailUriAsString, boolean isValid,
- String lookupKey) {
- return new RecipientEntry(ENTRY_TYPE_PERSON, pickDisplayName(displayNameSource,
- displayName, destination), destination, destinationType, destinationLabel,
- contactId, directoryId, dataId, (thumbnailUriAsString != null
- ? Uri.parse(thumbnailUriAsString) : null), true, isValid, lookupKey);
- }
-
- public static RecipientEntry constructSecondLevelEntry(String displayName,
- int displayNameSource, String destination, int destinationType,
- String destinationLabel, long contactId, Long directoryId, long dataId,
- String thumbnailUriAsString, boolean isValid, String lookupKey) {
- return new RecipientEntry(ENTRY_TYPE_PERSON, pickDisplayName(displayNameSource,
- displayName, destination), destination, destinationType, destinationLabel,
- contactId, directoryId, dataId, (thumbnailUriAsString != null
- ? Uri.parse(thumbnailUriAsString) : null), false, isValid, lookupKey);
- }
-
- public int getEntryType() {
- return mEntryType;
- }
-
- public String getDisplayName() {
- return mDisplayName;
- }
-
- public String getDestination() {
- return mDestination;
- }
-
- public int getDestinationType() {
- return mDestinationType;
- }
-
- public String getDestinationLabel() {
- return mDestinationLabel;
- }
-
- public long getContactId() {
- return mContactId;
- }
-
- public Long getDirectoryId() {
- return mDirectoryId;
- }
-
- public long getDataId() {
- return mDataId;
- }
-
- public boolean isFirstLevel() {
- return mIsFirstLevel;
- }
-
- public Uri getPhotoThumbnailUri() {
- return mPhotoThumbnailUri;
- }
-
- /** This can be called outside main Looper thread. */
- public synchronized void setPhotoBytes(byte[] photoBytes) {
- mPhotoBytes = photoBytes;
- }
-
- /** This can be called outside main Looper thread. */
- public synchronized byte[] getPhotoBytes() {
- return mPhotoBytes;
- }
-
- public boolean isSeparator() {
- return mIsDivider;
- }
-
- public boolean isSelectable() {
- return mEntryType == ENTRY_TYPE_PERSON;
- }
-
- public String getLookupKey() {
- return mLookupKey;
- }
-
- @Override
- public String toString() {
- return mDisplayName + " <" + mDestination + ">, isValid=" + mIsValid;
- }
-}
\ No newline at end of file
diff --git a/chips/src/com/android/ex/chips/SingleRecipientArrayAdapter.java b/chips/src/com/android/ex/chips/SingleRecipientArrayAdapter.java
deleted file mode 100644
index 985953f..0000000
--- a/chips/src/com/android/ex/chips/SingleRecipientArrayAdapter.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2011 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.ex.chips;
-
-import android.content.Context;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-
-import com.android.ex.chips.DropdownChipLayouter.AdapterType;
-
-class SingleRecipientArrayAdapter extends ArrayAdapter<RecipientEntry> {
- private final DropdownChipLayouter mDropdownChipLayouter;
-
- public SingleRecipientArrayAdapter(Context context, RecipientEntry entry,
- DropdownChipLayouter dropdownChipLayouter) {
- super(context, dropdownChipLayouter.getAlternateItemLayoutResId(), new RecipientEntry[] {
- entry
- });
-
- mDropdownChipLayouter = dropdownChipLayouter;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- return mDropdownChipLayouter.bindView(convertView, parent, getItem(position), position,
- AdapterType.SINGLE_RECIPIENT, null);
- }
-}
diff --git a/chips/src/com/android/ex/chips/recipientchip/BaseRecipientChip.java b/chips/src/com/android/ex/chips/recipientchip/BaseRecipientChip.java
deleted file mode 100644
index 8012b5c..0000000
--- a/chips/src/com/android/ex/chips/recipientchip/BaseRecipientChip.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2013 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.ex.chips.recipientchip;
-
-import com.android.ex.chips.RecipientEntry;
-
-/**
- * BaseRecipientChip defines an object that contains information relevant to a
- * particular recipient.
- */
-interface BaseRecipientChip {
-
- /**
- * Set the selected state of the chip.
- */
- void setSelected(boolean selected);
-
- /**
- * Return true if the chip is selected.
- */
- boolean isSelected();
-
- /**
- * Get the text displayed in the chip.
- */
- CharSequence getDisplay();
-
- /**
- * Get the text value this chip represents.
- */
- CharSequence getValue();
-
- /**
- * Get the id of the contact associated with this chip.
- */
- long getContactId();
-
- /**
- * Get the directory id of the contact associated with this chip.
- */
- Long getDirectoryId();
-
- /**
- * Get the directory lookup key associated with this chip, or <code>null</code>.
- */
- String getLookupKey();
-
- /**
- * Get the id of the data associated with this chip.
- */
- long getDataId();
-
- /**
- * Get associated RecipientEntry.
- */
- RecipientEntry getEntry();
-
- /**
- * Set the text in the edittextview originally associated with this chip
- * before any reverse lookups.
- */
- void setOriginalText(String text);
-
- /**
- * Set the text in the edittextview originally associated with this chip
- * before any reverse lookups.
- */
- CharSequence getOriginalText();
-}
diff --git a/chips/src/com/android/ex/chips/recipientchip/DrawableRecipientChip.java b/chips/src/com/android/ex/chips/recipientchip/DrawableRecipientChip.java
deleted file mode 100644
index 396a8ac..0000000
--- a/chips/src/com/android/ex/chips/recipientchip/DrawableRecipientChip.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2011 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.ex.chips.recipientchip;
-
-import android.graphics.Canvas;
-import android.graphics.Rect;
-
-/**
- * RecipientChip defines a drawable object that contains information relevant to a
- * particular recipient.
- */
-public interface DrawableRecipientChip extends BaseRecipientChip {
- /**
- * Get the bounds of the chip; may be 0,0 if it is not visibly rendered.
- */
- Rect getBounds();
-
- /**
- * Draw the chip.
- */
- void draw(Canvas canvas);
-}
diff --git a/chips/src/com/android/ex/chips/recipientchip/InvisibleRecipientChip.java b/chips/src/com/android/ex/chips/recipientchip/InvisibleRecipientChip.java
deleted file mode 100644
index 455f2cb..0000000
--- a/chips/src/com/android/ex/chips/recipientchip/InvisibleRecipientChip.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2011 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.ex.chips.recipientchip;
-
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.text.style.ReplacementSpan;
-
-import com.android.ex.chips.RecipientEntry;
-
-/**
- * RecipientChip defines a span that contains information relevant to a
- * particular recipient.
- */
-public class InvisibleRecipientChip extends ReplacementSpan implements DrawableRecipientChip {
- private final SimpleRecipientChip mDelegate;
-
- public InvisibleRecipientChip(final RecipientEntry entry) {
- super();
-
- mDelegate = new SimpleRecipientChip(entry);
- }
-
- @Override
- public void setSelected(final boolean selected) {
- mDelegate.setSelected(selected);
- }
-
- @Override
- public boolean isSelected() {
- return mDelegate.isSelected();
- }
-
- @Override
- public CharSequence getDisplay() {
- return mDelegate.getDisplay();
- }
-
- @Override
- public CharSequence getValue() {
- return mDelegate.getValue();
- }
-
- @Override
- public long getContactId() {
- return mDelegate.getContactId();
- }
-
- @Override
- public Long getDirectoryId() {
- return mDelegate.getDirectoryId();
- }
-
- @Override
- public String getLookupKey() {
- return mDelegate.getLookupKey();
- }
-
- @Override
- public long getDataId() {
- return mDelegate.getDataId();
- }
-
- @Override
- public RecipientEntry getEntry() {
- return mDelegate.getEntry();
- }
-
- @Override
- public void setOriginalText(final String text) {
- mDelegate.setOriginalText(text);
- }
-
- @Override
- public CharSequence getOriginalText() {
- return mDelegate.getOriginalText();
- }
-
- @Override
- public void draw(final Canvas canvas, final CharSequence text, final int start, final int end,
- final float x, final int top, final int y, final int bottom, final Paint paint) {
- // Do nothing.
- }
-
- @Override
- public int getSize(final Paint paint, final CharSequence text, final int start, final int end,
- final Paint.FontMetricsInt fm) {
- return 0;
- }
-
- @Override
- public Rect getBounds() {
- return new Rect(0, 0, 0, 0);
- }
-
- @Override
- public void draw(final Canvas canvas) {
- // do nothing.
- }
-}
diff --git a/chips/src/com/android/ex/chips/recipientchip/SimpleRecipientChip.java b/chips/src/com/android/ex/chips/recipientchip/SimpleRecipientChip.java
deleted file mode 100644
index 533f53f..0000000
--- a/chips/src/com/android/ex/chips/recipientchip/SimpleRecipientChip.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2013 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.ex.chips.recipientchip;
-
-import com.android.ex.chips.RecipientEntry;
-
-import android.text.TextUtils;
-
-class SimpleRecipientChip implements BaseRecipientChip {
- private final CharSequence mDisplay;
-
- private final CharSequence mValue;
-
- private final long mContactId;
-
- private final Long mDirectoryId;
-
- private final String mLookupKey;
-
- private final long mDataId;
-
- private final RecipientEntry mEntry;
-
- private boolean mSelected = false;
-
- private CharSequence mOriginalText;
-
- public SimpleRecipientChip(final RecipientEntry entry) {
- mDisplay = entry.getDisplayName();
- mValue = entry.getDestination().trim();
- mContactId = entry.getContactId();
- mDirectoryId = entry.getDirectoryId();
- mLookupKey = entry.getLookupKey();
- mDataId = entry.getDataId();
- mEntry = entry;
- }
-
- @Override
- public void setSelected(final boolean selected) {
- mSelected = selected;
- }
-
- @Override
- public boolean isSelected() {
- return mSelected;
- }
-
- @Override
- public CharSequence getDisplay() {
- return mDisplay;
- }
-
- @Override
- public CharSequence getValue() {
- return mValue;
- }
-
- @Override
- public long getContactId() {
- return mContactId;
- }
-
- @Override
- public Long getDirectoryId() {
- return mDirectoryId;
- }
-
- @Override
- public String getLookupKey() {
- return mLookupKey;
- }
-
- @Override
- public long getDataId() {
- return mDataId;
- }
-
- @Override
- public RecipientEntry getEntry() {
- return mEntry;
- }
-
- @Override
- public void setOriginalText(final String text) {
- if (TextUtils.isEmpty(text)) {
- mOriginalText = text;
- } else {
- mOriginalText = text.trim();
- }
- }
-
- @Override
- public CharSequence getOriginalText() {
- return !TextUtils.isEmpty(mOriginalText) ? mOriginalText : mEntry.getDestination();
- }
-
- @Override
- public String toString() {
- return mDisplay + " <" + mValue + ">";
- }
-}
\ No newline at end of file
diff --git a/chips/src/com/android/ex/chips/recipientchip/VisibleRecipientChip.java b/chips/src/com/android/ex/chips/recipientchip/VisibleRecipientChip.java
deleted file mode 100644
index 6d3d27d..0000000
--- a/chips/src/com/android/ex/chips/recipientchip/VisibleRecipientChip.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2011 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.ex.chips.recipientchip;
-
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.text.style.DynamicDrawableSpan;
-import android.text.style.ImageSpan;
-
-import com.android.ex.chips.RecipientEntry;
-
-/**
- * VisibleRecipientChip defines an ImageSpan that contains information relevant to a
- * particular recipient and renders a background asset to go with it.
- */
-public class VisibleRecipientChip extends ImageSpan implements DrawableRecipientChip {
- private final SimpleRecipientChip mDelegate;
-
- public VisibleRecipientChip(final Drawable drawable, final RecipientEntry entry) {
- this(drawable, entry, DynamicDrawableSpan.ALIGN_BOTTOM);
- }
-
- public VisibleRecipientChip(final Drawable drawable, final RecipientEntry entry,
- final int verticalAlignment) {
- super(drawable, verticalAlignment);
-
- mDelegate = new SimpleRecipientChip(entry);
- }
-
- @Override
- public void setSelected(final boolean selected) {
- mDelegate.setSelected(selected);
- }
-
- @Override
- public boolean isSelected() {
- return mDelegate.isSelected();
- }
-
- @Override
- public CharSequence getDisplay() {
- return mDelegate.getDisplay();
- }
-
- @Override
- public CharSequence getValue() {
- return mDelegate.getValue();
- }
-
- @Override
- public long getContactId() {
- return mDelegate.getContactId();
- }
-
- @Override
- public Long getDirectoryId() {
- return mDelegate.getDirectoryId();
- }
-
- @Override
- public String getLookupKey() {
- return mDelegate.getLookupKey();
- }
-
- @Override
- public long getDataId() {
- return mDelegate.getDataId();
- }
-
- @Override
- public RecipientEntry getEntry() {
- return mDelegate.getEntry();
- }
-
- @Override
- public void setOriginalText(final String text) {
- mDelegate.setOriginalText(text);
- }
-
- @Override
- public CharSequence getOriginalText() {
- return mDelegate.getOriginalText();
- }
-
- @Override
- public Rect getBounds() {
- return getDrawable().getBounds();
- }
-
- @Override
- public void draw(final Canvas canvas) {
- getDrawable().draw(canvas);
- }
-
- @Override
- public String toString() {
- return mDelegate.toString();
- }
-}
diff --git a/chips/tests/Android.mk b/chips/tests/Android.mk
deleted file mode 100644
index b01aa0c..0000000
--- a/chips/tests/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2011 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.
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := ChipsTests
-LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
-LOCAL_CERTIFICATE := platform
-LOCAL_STATIC_JAVA_LIBRARIES += android-common-chips
-LOCAL_RESOURCE_DIR := frameworks/ex/chips/res/
-LOCAL_AAPT_FLAGS := --auto-add-overlay
-LOCAL_AAPT_FLAGS += --extra-packages com.android.ex.chips
-
-include $(BUILD_PACKAGE)
-
diff --git a/chips/tests/AndroidManifest.xml b/chips/tests/AndroidManifest.xml
deleted file mode 100644
index b2b307e..0000000
--- a/chips/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.ex.chips.tests"
- android:sharedUserId="com.android.uid.test">
-
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <!-- Run tests with "runtest android-common" -->
- <instrumentation android:name="android.test.InstrumentationTestRunner"
- android:targetPackage="com.android.ex.chips.tests"
- android:label="Chips Tests" />
-
-</manifest>
diff --git a/chips/tests/src/com/android/ex/chips/ChipsTest.java b/chips/tests/src/com/android/ex/chips/ChipsTest.java
deleted file mode 100644
index 9116e26..0000000
--- a/chips/tests/src/com/android/ex/chips/ChipsTest.java
+++ /dev/null
@@ -1,1028 +0,0 @@
-/*
- * Copyright (C) 2011 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.ex.chips;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.Editable;
-import android.text.SpannableStringBuilder;
-import android.text.style.ImageSpan;
-import android.text.util.Rfc822Tokenizer;
-import android.widget.TextView;
-
-import com.android.ex.chips.BaseRecipientAdapter;
-import com.android.ex.chips.RecipientEditTextView;
-import com.android.ex.chips.RecipientEntry;
-import com.android.ex.chips.recipientchip.DrawableRecipientChip;
-import com.android.ex.chips.recipientchip.VisibleRecipientChip;
-
-import java.util.regex.Pattern;
-
-@SmallTest
-public class ChipsTest extends AndroidTestCase {
- private DrawableRecipientChip[] mMockRecips;
-
- private RecipientEntry[] mMockEntries;
-
- private Rfc822Tokenizer mTokenizer;
-
- private Editable mEditable;
-
- class BaseMockRecipientEditTextView extends RecipientEditTextView {
-
- public BaseMockRecipientEditTextView(Context context) {
- super(context, null);
- mTokenizer = new Rfc822Tokenizer();
- setTokenizer(mTokenizer);
- }
-
- @Override
- public DrawableRecipientChip[] getSortedRecipients() {
- return mMockRecips;
- }
-
- @Override
- public int getLineHeight() {
- return 48;
- }
-
- @Override
- Drawable getChipBackground(RecipientEntry contact) {
- return createChipBackground();
- }
-
- @Override
- public int getViewWidth() {
- return 100;
- }
- }
-
- class MockRecipientEditTextView extends BaseMockRecipientEditTextView {
-
- public MockRecipientEditTextView(Context context) {
- super(context);
- mTokenizer = new Rfc822Tokenizer();
- setTokenizer(mTokenizer);
- }
-
- @Override
- public DrawableRecipientChip[] getSortedRecipients() {
- return mMockRecips;
- }
-
- @Override
- public Editable getText() {
- return mEditable;
- }
-
- @Override
- public Editable getSpannable() {
- return mEditable;
- }
-
- @Override
- public int getLineHeight() {
- return 48;
- }
-
- @Override
- Drawable getChipBackground(RecipientEntry contact) {
- return createChipBackground();
- }
-
- @Override
- public int length() {
- return mEditable != null ? mEditable.length() : 0;
- }
-
- @Override
- public String toString() {
- return mEditable != null ? mEditable.toString() : "";
- }
-
- @Override
- public int getViewWidth() {
- return 100;
- }
- }
-
- private class TestBaseRecipientAdapter extends BaseRecipientAdapter {
- public TestBaseRecipientAdapter(final Context context) {
- super(context);
- }
-
- public TestBaseRecipientAdapter(final Context context, final int preferredMaxResultCount,
- final int queryMode) {
- super(context, preferredMaxResultCount, queryMode);
- }
- }
-
- private MockRecipientEditTextView createViewForTesting() {
- mEditable = new SpannableStringBuilder();
- MockRecipientEditTextView view = new MockRecipientEditTextView(getContext());
- view.setAdapter(new TestBaseRecipientAdapter(getContext()));
- return view;
- }
-
- public void testCreateDisplayText() {
- RecipientEditTextView view = createViewForTesting();
- RecipientEntry entry = RecipientEntry.constructGeneratedEntry("User Name, Jr",
- "user@username.com", true);
- String testAddress = view.createAddressText(entry);
- String testDisplay = view.createChipDisplayText(entry);
- assertEquals("Expected a properly formatted RFC email address",
- "\"User Name, Jr\" <user@username.com>, ", testAddress);
- assertEquals("Expected a displayable name", "User Name, Jr", testDisplay);
-
- RecipientEntry alreadyFormatted =
- RecipientEntry.constructFakeEntry("user@username.com, ", true);
- testAddress = view.createAddressText(alreadyFormatted);
- testDisplay = view.createChipDisplayText(alreadyFormatted);
- assertEquals("Expected a properly formatted RFC email address", "<user@username.com>, ",
- testAddress);
- assertEquals("Expected a displayable name", "user@username.com", testDisplay);
-
- RecipientEntry alreadyFormattedNoSpace = RecipientEntry
- .constructFakeEntry("user@username.com,", true);
- testAddress = view.createAddressText(alreadyFormattedNoSpace);
- assertEquals("Expected a properly formatted RFC email address", "<user@username.com>, ",
- testAddress);
-
- RecipientEntry alreadyNamed = RecipientEntry.constructGeneratedEntry("User Name",
- "\"User Name, Jr\" <user@username.com>", true);
- testAddress = view.createAddressText(alreadyNamed);
- testDisplay = view.createChipDisplayText(alreadyNamed);
- assertEquals(
- "Expected address that used the name not the excess address name",
- "User Name <user@username.com>, ", testAddress);
- assertEquals("Expected a displayable name", "User Name", testDisplay);
- }
-
- public void testSanitizeBetween() {
- // First, add 2 chips and then make sure we remove
- // the extra content between them correctly.
- populateMocks(2);
- MockRecipientEditTextView view = createViewForTesting();
- String first = (String) mTokenizer.terminateToken("FIRST");
- String second = (String) mTokenizer.terminateToken("SECOND");
- String extra = "EXTRA";
- mEditable = new SpannableStringBuilder();
- mEditable.append(first + extra + second);
- int firstStart = mEditable.toString().indexOf(first);
- int firstEnd = firstStart + first.trim().length();
- int secondStart = mEditable.toString().indexOf(second);
- int secondEnd = secondStart + second.trim().length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], secondStart, secondEnd, 0);
- view.sanitizeBetween();
- String editableString = mEditable.toString();
- assertEquals(editableString.indexOf(extra), -1);
- assertEquals(editableString.indexOf(first), firstStart);
- assertEquals(editableString.indexOf(second), secondStart - extra.length());
- assertEquals(editableString, (first + second));
-
- // Add 1 chip and make sure that we remove the extra stuff before it correctly.
- mEditable = new SpannableStringBuilder();
- populateMocks(1);
- mEditable.append(extra);
- mEditable.append(first);
- firstStart = mEditable.toString().indexOf(first);
- firstEnd = firstStart + first.length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], firstStart, firstEnd, 0);
- view.sanitizeBetween();
- assertEquals(mEditable.toString(), first);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), firstStart
- - extra.length());
- }
-
- public void testSanitizeEnd() {
- // First, add 2 chips and then make sure we remove
- // the extra content between them correctly.
- populateMocks(2);
- MockRecipientEditTextView view = createViewForTesting();
- String first = (String) mTokenizer.terminateToken("FIRST");
- String second = (String) mTokenizer.terminateToken("SECOND");
- String extra = "EXTRA";
- mEditable = new SpannableStringBuilder();
- mEditable.append(first + second);
- int firstStart = mEditable.toString().indexOf(first);
- int firstEnd = firstStart + first.trim().length();
- int secondStart = mEditable.toString().indexOf(second);
- int secondEnd = secondStart + second.trim().length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], secondStart, secondEnd, 0);
- view.sanitizeEnd();
- String editableString = mEditable.toString();
- assertEquals(editableString.indexOf(extra), -1);
- assertEquals(editableString.indexOf(first), firstStart);
- assertEquals(editableString.indexOf(second), secondStart);
- assertEquals(editableString, (first + second));
- mEditable.append(extra);
- editableString = mEditable.toString();
- assertEquals(mEditable.toString(), (first + second + extra));
- view.sanitizeEnd();
- assertEquals(mEditable.toString(), (first + second));
- }
-
- public void testMoreChipPlainText() {
- MockRecipientEditTextView view = createViewForTesting();
- view.setMoreItem(createTestMoreItem());
- String first = (String) mTokenizer.terminateToken("FIRST");
- String second = (String) mTokenizer.terminateToken("SECOND");
- String third = (String) mTokenizer.terminateToken("THIRD");
- mEditable = new SpannableStringBuilder();
- mEditable.append(first+second+third);
- int thirdStart = mEditable.toString().indexOf(third);
- int thirdEnd = thirdStart + third.trim().length();
- view.createMoreChipPlainText();
- ImageSpan moreChip = view.getMoreChip();
- assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
- assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
- }
-
- public void testCountTokens() {
- MockRecipientEditTextView view = createViewForTesting();
- view.setMoreItem(createTestMoreItem());
- String first = (String) mTokenizer.terminateToken("FIRST");
- String second = (String) mTokenizer.terminateToken("SECOND");
- String third = (String) mTokenizer.terminateToken("THIRD");
- String fourth = "FOURTH,";
- String fifth = "FIFTH,";
- mEditable = new SpannableStringBuilder();
- mEditable.append(first+second+third+fourth+fifth);
- assertEquals(view.countTokens(mEditable), 5);
- }
-
- public void testTooManyRecips() {
- BaseMockRecipientEditTextView view = new BaseMockRecipientEditTextView(getContext());
- view.setMoreItem(createTestMoreItem());
- for (int i = 0; i < 100; i++) {
- view.append(mTokenizer.terminateToken(i + ""));
- }
- assertEquals(view.countTokens(view.getText()), 100);
- view.handlePendingChips();
- view.createMoreChip();
- ImageSpan moreChip = view.getMoreChip();
- // We show 2 chips then place a more chip.
- int secondStart = view.getText().toString().indexOf(
- (String) mTokenizer.terminateToken(RecipientEditTextView.CHIP_LIMIT + ""));
- assertEquals(view.getText().getSpanStart(moreChip), secondStart);
- assertEquals(view.getText().getSpanEnd(moreChip), view.length());
- assertEquals(view.getSortedRecipients(), null);
- }
-
- public void testMoreChip() {
- // Add 3 chips: this is the trigger point at which the more chip will be created.
- // Test that adding the chips and then creating and removing the more chip, as if
- // the user were focusing/ removing focus from the chips field.
- populateMocks(3);
- MockRecipientEditTextView view = createViewForTesting();
- view.setMoreItem(createTestMoreItem());
- String first = (String) mTokenizer.terminateToken("FIRST");
- String second = (String) mTokenizer.terminateToken("SECOND");
- String third = (String) mTokenizer.terminateToken("THIRD");
- mEditable = new SpannableStringBuilder();
- mEditable.append(first+second+third);
-
- int firstStart = mEditable.toString().indexOf(first);
- int firstEnd = firstStart + first.trim().length();
- int secondStart = mEditable.toString().indexOf(second);
- int secondEnd = secondStart + second.trim().length();
- int thirdStart = mEditable.toString().indexOf(third);
- int thirdEnd = thirdStart + third.trim().length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
-
- view.createMoreChip();
- assertEquals(mEditable.toString(), first+second+third);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
- // Find the more chip.
- ImageSpan moreChip = view.getMoreChip();
- assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
- assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
-
- view.removeMoreChip();
- assertEquals(mEditable.toString(), first+second+third);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
- moreChip = view.getMoreChip();
- assertEquals(mEditable.getSpanStart(moreChip), -1);
-
- // Rinse and repeat, just in case!
- view.createMoreChip();
- assertEquals(mEditable.toString(), first+second+third);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
- // Find the more chip.
- moreChip = view.getMoreChip();
- assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
- assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
-
- view.removeMoreChip();
- assertEquals(mEditable.toString(), first+second+third);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
- moreChip = view.getMoreChip();
- assertEquals(mEditable.getSpanStart(moreChip), -1);
- }
-
- public void testMoreChipLotsOfUsers() {
- // Test adding and removing the more chip in the case where we have a lot of users.
- populateMocks(10);
- MockRecipientEditTextView view = createViewForTesting();
- view.setMoreItem(createTestMoreItem());
- String first = (String) mTokenizer.terminateToken("FIRST");
- String second = (String) mTokenizer.terminateToken("SECOND");
- String third = (String) mTokenizer.terminateToken("THIRD");
- String fourth = (String) mTokenizer.terminateToken("FOURTH");
- String fifth = (String) mTokenizer.terminateToken("FIFTH");
- String sixth = (String) mTokenizer.terminateToken("SIXTH");
- String seventh = (String) mTokenizer.terminateToken("SEVENTH");
- String eigth = (String) mTokenizer.terminateToken("EIGHTH");
- String ninth = (String) mTokenizer.terminateToken("NINTH");
- String tenth = (String) mTokenizer.terminateToken("TENTH");
- mEditable = new SpannableStringBuilder();
- mEditable.append(first+second+third+fourth+fifth+sixth+seventh+eigth+ninth+tenth);
-
- int firstStart = mEditable.toString().indexOf(first);
- int firstEnd = firstStart + first.trim().length();
- int secondStart = mEditable.toString().indexOf(second);
- int secondEnd = secondStart + second.trim().length();
- int thirdStart = mEditable.toString().indexOf(third);
- int thirdEnd = thirdStart + third.trim().length();
- int fourthStart = mEditable.toString().indexOf(fourth);
- int fourthEnd = fourthStart + fourth.trim().length();
- int fifthStart = mEditable.toString().indexOf(fifth);
- int fifthEnd = fifthStart + fifth.trim().length();
- int sixthStart = mEditable.toString().indexOf(sixth);
- int sixthEnd = sixthStart + sixth.trim().length();
- int seventhStart = mEditable.toString().indexOf(seventh);
- int seventhEnd = seventhStart + seventh.trim().length();
- int eighthStart = mEditable.toString().indexOf(eigth);
- int eighthEnd = eighthStart + eigth.trim().length();
- int ninthStart = mEditable.toString().indexOf(ninth);
- int ninthEnd = ninthStart + ninth.trim().length();
- int tenthStart = mEditable.toString().indexOf(tenth);
- int tenthEnd = tenthStart + tenth.trim().length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 10], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 9], secondStart, secondEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 8], thirdStart, thirdEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 7], fourthStart, fourthEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 6], fifthStart, fifthEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 5], sixthStart, sixthEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 4], seventhStart, seventhEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 3], eighthStart, eighthEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], ninthStart, ninthEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], tenthStart, tenthEnd, 0);
-
- view.createMoreChip();
- assertEquals(mEditable.toString(), first + second + third + fourth + fifth + sixth
- + seventh + eigth + ninth + tenth);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 10]), firstStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 9]), secondStart);
- // Find the more chip.
- ImageSpan moreChip = view.getMoreChip();
- assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
- assertEquals(mEditable.getSpanEnd(moreChip), tenthEnd + 1);
-
- view.removeMoreChip();
- assertEquals(mEditable.toString(), first + second + third + fourth + fifth + sixth
- + seventh + eigth + ninth + tenth);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 10]), firstStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 9]), secondStart);
-
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 8]), thirdStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 7]), fourthStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 6]), fifthStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 5]), sixthStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), seventhStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), eighthStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), ninthStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), tenthStart);
- moreChip = view.getMoreChip();
- assertEquals(mEditable.getSpanStart(moreChip), -1);
-
- }
-
- public void testMoreChipSpecialChars() {
- // Make sure the more chip correctly handles extra tokenizer characters in the middle
- // of chip text.
- populateMocks(3);
- MockRecipientEditTextView view = createViewForTesting();
- view.setMoreItem(createTestMoreItem());
- String first = (String) mTokenizer.terminateToken("FI,RST");
- String second = (String) mTokenizer.terminateToken("SE,COND");
- String third = (String) mTokenizer.terminateToken("THI,RD");
- mEditable = new SpannableStringBuilder();
- mEditable.append(first+second+third);
-
- int firstStart = mEditable.toString().indexOf(first);
- int firstEnd = firstStart + first.trim().length();
- int secondStart = mEditable.toString().indexOf(second);
- int secondEnd = secondStart + second.trim().length();
- int thirdStart = mEditable.toString().indexOf(third);
- int thirdEnd = thirdStart + third.trim().length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
-
- view.createMoreChip();
- assertEquals(mEditable.toString(), first+second+third);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
- // Find the more chip.
- ImageSpan moreChip = view.getMoreChip();
- assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
- assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
-
- view.removeMoreChip();
- assertEquals(mEditable.toString(), first+second+third);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
- moreChip = view.getMoreChip();
- assertEquals(mEditable.getSpanStart(moreChip), -1);
- }
-
- public void testMoreChipDupes() {
- // Make sure the more chip is correctly added and removed when we have duplicate chips.
- populateMocks(4);
- MockRecipientEditTextView view = createViewForTesting();
- view.setMoreItem(createTestMoreItem());
- String first = (String) mTokenizer.terminateToken("FIRST");
- String second = (String) mTokenizer.terminateToken("SECOND");
- String third = (String) mTokenizer.terminateToken("THIRD");
- mEditable = new SpannableStringBuilder();
- mEditable.append(first+second+third+third);
-
- int firstStart = mEditable.toString().indexOf(first);
- int firstEnd = firstStart + first.trim().length();
- int secondStart = mEditable.toString().indexOf(second);
- int secondEnd = secondStart + second.trim().length();
- int thirdStart = mEditable.toString().indexOf(third);
- int thirdEnd = thirdStart + third.trim().length();
- int thirdNextStart = mEditable.toString().indexOf(third, thirdEnd);
- int thirdNextEnd = thirdNextStart + third.trim().length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 4], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 3], secondStart, secondEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], thirdStart, thirdEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdNextStart, thirdNextEnd, 0);
-
- view.createMoreChip();
- assertEquals(mEditable.toString(), first+second+third+third);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), firstStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), secondStart);
- // Find the more chip.
- ImageSpan moreChip = view.getMoreChip();
- assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
- assertEquals(mEditable.getSpanEnd(moreChip), thirdNextEnd + 1);
-
- view.removeMoreChip();
- assertEquals(mEditable.toString(), first+second+third+third);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), firstStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 4]), firstEnd);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), secondStart);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), thirdStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), thirdEnd);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdNextStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdNextEnd);
- moreChip = view.getMoreChip();
- assertEquals(mEditable.getSpanStart(moreChip), -1);
- }
-
- public void testRemoveChip() {
- // Create 3 chips to start and test removing chips in various postions.
- populateMocks(3);
- MockRecipientEditTextView view = createViewForTesting();
- view.setMoreItem(createTestMoreItem());
- String first = (String) mTokenizer.terminateToken("FIRST");
- String second = (String) mTokenizer.terminateToken("SECOND");
- String third = (String) mTokenizer.terminateToken("THIRD");
- mEditable = new SpannableStringBuilder();
- mEditable.append(first + second + third);
-
- int firstStart = mEditable.toString().indexOf(first);
- int firstEnd = firstStart + first.length();
- int secondStart = mEditable.toString().indexOf(second);
- int secondEnd = secondStart + second.length();
- int thirdStart = mEditable.toString().indexOf(third);
- int thirdEnd = thirdStart + third.length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
- assertEquals(mEditable.toString(), first + second + third);
- // Test removing the middle chip.
- view.removeChip(mMockRecips[mMockRecips.length - 2]);
- assertEquals(mEditable.toString(), first + third);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), -1);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), -1);
- int newThirdStart = mEditable.toString().indexOf(third);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), newThirdStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), newThirdStart
- + third.length());
-
- // Test removing the first chip.
- populateMocks(3);
- view = createViewForTesting();
- view.setMoreItem(createTestMoreItem());
- mEditable = new SpannableStringBuilder();
- mEditable.append(first + second + third);
-
- firstStart = mEditable.toString().indexOf(first);
- firstEnd = firstStart + first.length();
- secondStart = mEditable.toString().indexOf(second);
- secondEnd = secondStart + second.length();
- thirdStart = mEditable.toString().indexOf(third);
- thirdEnd = thirdStart + third.length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
- assertEquals(mEditable.toString(), first + second + third);
- view.removeChip(mMockRecips[mMockRecips.length - 3]);
- assertEquals(mEditable.toString(), second + third);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), -1);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), -1);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), 0);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), second.length());
- newThirdStart = mEditable.toString().indexOf(third);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), newThirdStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), newThirdStart
- + third.length());
-
- // Test removing the last chip.
- populateMocks(3);
- view = createViewForTesting();
- view.setMoreItem(createTestMoreItem());
- mEditable = new SpannableStringBuilder();
- mEditable.append(first + second + third);
-
- firstStart = mEditable.toString().indexOf(first);
- firstEnd = firstStart + first.length();
- secondStart = mEditable.toString().indexOf(second);
- secondEnd = secondStart + second.length();
- thirdStart = mEditable.toString().indexOf(third);
- thirdEnd = thirdStart + third.length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
- assertEquals(mEditable.toString(), first + second + third);
- view.removeChip(mMockRecips[mMockRecips.length - 1]);
- assertEquals(mEditable.toString(), first + second);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), secondEnd);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), -1);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), -1);
- }
-
- public void testReplaceChip() {
- populateMocks(3);
- MockRecipientEditTextView view = createViewForTesting();
- view.setMoreItem(createTestMoreItem());
- view.setChipBackground(createChipBackground());
- view.setChipHeight(48);
- String first = (String) mTokenizer.terminateToken("FIRST");
- String second = (String) mTokenizer.terminateToken("SECOND");
- String third = (String) mTokenizer.terminateToken("THIRD");
- mEditable = new SpannableStringBuilder();
- mEditable.append(first + second + third);
-
- // Test replacing the first chip with a new chip.
- int firstStart = mEditable.toString().indexOf(first);
- int firstEnd = firstStart + first.trim().length();
- int secondStart = mEditable.toString().indexOf(second);
- int secondEnd = secondStart + second.trim().length();
- int thirdStart = mEditable.toString().indexOf(third);
- int thirdEnd = thirdStart + third.trim().length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
- assertEquals(mEditable.toString(), first + second + third);
- view.replaceChip(mMockRecips[mMockRecips.length - 3], RecipientEntry
- .constructGeneratedEntry("replacement", "replacement@replacement.com", true));
- assertEquals(mEditable.toString(), mTokenizer
- .terminateToken("replacement <replacement@replacement.com>")
- + second + third);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), -1);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), -1);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), mEditable
- .toString().indexOf(second));
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), mEditable
- .toString().indexOf(second)
- + second.trim().length());
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), mEditable
- .toString().indexOf(third));
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), mEditable
- .toString().indexOf(third)
- + third.trim().length());
- DrawableRecipientChip[] spans =
- mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class);
- assertEquals(spans.length, 3);
- spans = mEditable
- .getSpans(0, mEditable.toString().indexOf(second) - 1, DrawableRecipientChip.class);
- assertEquals((String) spans[0].getDisplay(), "replacement");
-
-
- // Test replacing the middle chip with a new chip.
- mEditable = new SpannableStringBuilder();
- mEditable.append(first + second + third);
- firstStart = mEditable.toString().indexOf(first);
- firstEnd = firstStart + first.trim().length();
- secondStart = mEditable.toString().indexOf(second);
- secondEnd = secondStart + second.trim().length();
- thirdStart = mEditable.toString().indexOf(third);
- thirdEnd = thirdStart + third.trim().length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
- assertEquals(mEditable.toString(), first + second + third);
- view.replaceChip(mMockRecips[mMockRecips.length - 2], RecipientEntry
- .constructGeneratedEntry("replacement", "replacement@replacement.com", true));
- assertEquals(mEditable.toString(), first + mTokenizer
- .terminateToken("replacement <replacement@replacement.com>") + third);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), -1);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), -1);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), mEditable
- .toString().indexOf(third));
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), mEditable
- .toString().indexOf(third)
- + third.trim().length());
- spans = mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class);
- assertEquals(spans.length, 3);
- spans = mEditable.getSpans(firstEnd, mEditable.toString().indexOf(third) - 1,
- DrawableRecipientChip.class);
- assertEquals((String) spans[0].getDisplay(), "replacement");
-
-
- // Test replacing the last chip with a new chip.
- mEditable = new SpannableStringBuilder();
- mEditable.append(first + second + third);
- firstStart = mEditable.toString().indexOf(first);
- firstEnd = firstStart + first.trim().length();
- secondStart = mEditable.toString().indexOf(second);
- secondEnd = secondStart + second.trim().length();
- thirdStart = mEditable.toString().indexOf(third);
- thirdEnd = thirdStart + third.trim().length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
- assertEquals(mEditable.toString(), first + second + third);
- view.replaceChip(mMockRecips[mMockRecips.length - 1], RecipientEntry
- .constructGeneratedEntry("replacement", "replacement@replacement.com", true));
- assertEquals(mEditable.toString(), first + second + mTokenizer
- .terminateToken("replacement <replacement@replacement.com>"));
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), secondEnd);
- assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), -1);
- assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), -1);
- spans = mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class);
- assertEquals(spans.length, 3);
- spans = mEditable
- .getSpans(secondEnd, mEditable.length(), DrawableRecipientChip.class);
- assertEquals((String) spans[0].getDisplay(), "replacement");
- }
-
- public void testHandlePaste() {
- // Start with an empty edit field.
- // Add an address; the text should be left as is.
- MockRecipientEditTextView view = createViewForTesting();
- view.setMoreItem(createTestMoreItem());
- view.setChipBackground(createChipBackground());
- view.setChipHeight(48);
- mEditable = new SpannableStringBuilder();
- mEditable.append("user@user.com");
- view.setSelection(mEditable.length());
- view.handlePaste();
- assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length, 0);
- assertEquals(mEditable.toString(), "user@user.com");
-
- // Test adding a single address to an empty chips field with a space at
- // the end of it. The address should stay as text.
- mEditable = new SpannableStringBuilder();
- String tokenizedUser = "user@user.com" + " ";
- mEditable.append(tokenizedUser);
- view.setSelection(mEditable.length());
- view.handlePaste();
- assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length, 0);
- assertEquals(mEditable.toString(), tokenizedUser);
-
- // Test adding a single address to an empty chips field with a semicolon at
- // the end of it. The address should become a chip
- mEditable = new SpannableStringBuilder();
- tokenizedUser = "user@user.com;";
- mEditable.append(tokenizedUser);
- view.setSelection(mEditable.length());
- view.handlePaste();
- assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length, 1);
-
- // Test adding 2 address to an empty chips field. The second to last
- // address should become a chip and the last address should stay as
- // text.
- mEditable = new SpannableStringBuilder();
- mEditable.append("user1,user2@user.com");
- view.setSelection(mEditable.length());
- view.handlePaste();
- assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length, 1);
- assertEquals(mEditable.getSpans(0, mEditable.toString().indexOf("user2@user.com"),
- DrawableRecipientChip.class).length, 1);
- assertEquals(mEditable.toString(), "<user1>, user2@user.com");
-
- // Test adding a single address to the end of existing chips. The existing
- // chips should remain, and the last address should stay as text.
- populateMocks(3);
- String first = (String) mTokenizer.terminateToken("FIRST");
- String second = (String) mTokenizer.terminateToken("SECOND");
- String third = (String) mTokenizer.terminateToken("THIRD");
- mEditable = new SpannableStringBuilder();
- mEditable.append(first + second + third);
- view.setSelection(mEditable.length());
- int firstStart = mEditable.toString().indexOf(first);
- int firstEnd = firstStart + first.trim().length();
- int secondStart = mEditable.toString().indexOf(second);
- int secondEnd = secondStart + second.trim().length();
- int thirdStart = mEditable.toString().indexOf(third);
- int thirdEnd = thirdStart + third.trim().length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
-
- mEditable.append("user@user.com");
- view.setSelection(mEditable.length());
- view.handlePaste();
- assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length,
- mMockRecips.length);
- assertEquals(mEditable.toString(), first + second + third + "user@user.com");
-
- // Paste 2 addresses after existing chips. We expect the first address to be turned into
- // a chip and the second to be left as text.
- populateMocks(3);
- mEditable = new SpannableStringBuilder();
- mEditable.append(first + second + third);
-
- mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
-
- mEditable.append("user1, user2@user.com");
- view.setSelection(mEditable.length());
- view.handlePaste();
- assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length,
- mMockRecips.length + 1);
- assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
- .toString().indexOf("user2@user.com") - 1, DrawableRecipientChip.class).length, 1);
- assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
- .length(), DrawableRecipientChip.class).length, 0);
- assertEquals(mEditable.toString(), first + second + third + "<user1>, user2@user.com");
-
- // Paste 2 addresses after existing chips. We expect the first address to be turned into
- // a chip and the second to be left as text. This removes the space seperator char between
- // addresses.
- populateMocks(3);
- mEditable = new SpannableStringBuilder();
- mEditable.append(first + second + third);
-
- mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
-
- mEditable.append("user1,user2@user.com");
- view.setSelection(mEditable.length());
- view.handlePaste();
- assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length,
- mMockRecips.length + 1);
- assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
- .toString().indexOf("user2@user.com") - 1, DrawableRecipientChip.class).length, 1);
- assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
- .length(), DrawableRecipientChip.class).length, 0);
- assertEquals(mEditable.toString(), first + second + third + "<user1>, user2@user.com");
-
- // Test a complete token pasted in at the end. It should be turned into a chip.
- mEditable = new SpannableStringBuilder();
- mEditable.append("user1, user2@user.com,");
- view.setSelection(mEditable.length());
- view.handlePaste();
- assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length, 2);
- assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
- .toString().indexOf("user2@user.com") - 1, DrawableRecipientChip.class).length, 1);
- assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
- .length(), DrawableRecipientChip.class).length, 1);
- assertEquals(mEditable.toString(), "<user1>, <user2@user.com>, ");
- }
-
- public void testGetPastTerminators() {
- MockRecipientEditTextView view = createViewForTesting();
- view.setMoreItem(createTestMoreItem());
- view.setChipBackground(createChipBackground());
- view.setChipHeight(48);
- String test = "test";
- mEditable = new SpannableStringBuilder();
- mEditable.append(test);
- assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
- test.length());
-
- test = "test,";
- mEditable = new SpannableStringBuilder();
- mEditable.append(test);
- assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
- test.length());
-
- test = "test, ";
- mEditable = new SpannableStringBuilder();
- mEditable.append(test);
- assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
- test.length());
-
- test = "test;";
- mEditable = new SpannableStringBuilder();
- mEditable.append(test);
- assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
- test.length());
-
- test = "test; ";
- mEditable = new SpannableStringBuilder();
- mEditable.append(test);
- assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
- test.length());
- }
-
- public void testIsCompletedToken() {
- MockRecipientEditTextView view = createViewForTesting();
- view.setMoreItem(createTestMoreItem());
- view.setChipBackground(createChipBackground());
- view.setChipHeight(48);
- assertTrue(view.isCompletedToken("test;"));
- assertTrue(view.isCompletedToken("test,"));
- assertFalse(view.isCompletedToken("test"));
- assertFalse(view.isCompletedToken("test "));
- }
-
- public void testGetLastChip() {
- populateMocks(3);
- MockRecipientEditTextView view = createViewForTesting();
- view.setMoreItem(createTestMoreItem());
- view.setChipBackground(createChipBackground());
- view.setChipHeight(48);
- String first = (String) mTokenizer.terminateToken("FIRST");
- String second = (String) mTokenizer.terminateToken("SECOND");
- String third = (String) mTokenizer.terminateToken("THIRD");
- mEditable = new SpannableStringBuilder();
- mEditable.append(first + second + third);
-
- // Test replacing the first chip with a new chip.
- int firstStart = mEditable.toString().indexOf(first);
- int firstEnd = firstStart + first.trim().length();
- int secondStart = mEditable.toString().indexOf(second);
- int secondEnd = secondStart + second.trim().length();
- int thirdStart = mEditable.toString().indexOf(third);
- int thirdEnd = thirdStart + third.trim().length();
- mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
- mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
- assertEquals(view.getLastChip(), mMockRecips[mMockRecips.length - 1]);
- mEditable.append("extra");
- assertEquals(view.getLastChip(), mMockRecips[mMockRecips.length - 1]);
- }
-
- private Drawable createChipBackground() {
- Bitmap drawable = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
- return new BitmapDrawable(getContext().getResources(), drawable);
- }
-
- private TextView createTestMoreItem() {
- TextView view = new TextView(getContext());
- view.setText("<xliff:g id='count'>%1$s</xliff:g> more...");
- return view;
- }
-
- private void populateMocks(int size) {
- mMockEntries = new RecipientEntry[size];
- for (int i = 0; i < size; i++) {
- mMockEntries[i] = RecipientEntry.constructGeneratedEntry("user",
- "user@username.com", true);
- }
- mMockRecips = new DrawableRecipientChip[size];
- for (int i = 0; i < size; i++) {
- mMockRecips[i] = new VisibleRecipientChip(null, mMockEntries[i]);
- }
- }
-
- /**
- * <p>
- * Ensure the original text is always accurate, regardless of the type of email. The original
- * text is used to determine where to display the chip span. If this test fails, it means some
- * text that should be turned into one whole chip may behave unexpectedly.
- * </p>
- * <p>
- * For example, a bug was seen where
- *
- * <pre>
- * "Android User" <android@example.com>
- * </pre>
- *
- * was converted to
- *
- * <pre>
- * Android User [android@example.com]
- * </pre>
- *
- * where text inside [] is a chip.
- * </p>
- */
- public void testCreateReplacementChipOriginalText() {
- // Name in quotes + email address
- testCreateReplacementChipOriginalText("\"Android User\" <android@example.com>,");
- // Name in quotes + email address without brackets
- testCreateReplacementChipOriginalText("\"Android User\" android@example.com,");
- // Name in quotes
- testCreateReplacementChipOriginalText("\"Android User\",");
- // Name without quotes + email address
- testCreateReplacementChipOriginalText("Android User <android@example.com>,");
- // Name without quotes
- testCreateReplacementChipOriginalText("Android User,");
- // Email address
- testCreateReplacementChipOriginalText("<android@example.com>,");
- // Email address without brackets
- testCreateReplacementChipOriginalText("android@example.com,");
- }
-
- private void testCreateReplacementChipOriginalText(final String email) {
- // No trailing space
- attemptCreateReplacementChipOriginalText(email.trim());
- // Trailing space
- attemptCreateReplacementChipOriginalText(email.trim() + " ");
- }
-
- private void attemptCreateReplacementChipOriginalText(final String email) {
- final RecipientEditTextView view = new RecipientEditTextView(getContext(), null);
-
- view.setText(email);
- view.mPendingChips.add(email);
-
- view.createReplacementChip(0, email.length(), view.getText(), true);
- // The "original text" should be the email without the comma or space(s)
- assertEquals(email.replaceAll(",\\s*$", ""),
- view.mTemporaryRecipients.get(0).getOriginalText().toString().trim());
- }
-
- public void testCreateTokenizedEntryForPhone() {
- final String phonePattern = "[^\\d]*888[^\\d]*555[^\\d]*1234[^\\d]*";
- final String phone1 = "8885551234";
- final String phone2 = "888-555-1234";
- final String phone3 = "(888) 555-1234";
-
- final RecipientEditTextView view = new RecipientEditTextView(getContext(), null);
- final BaseRecipientAdapter adapter = new TestBaseRecipientAdapter(getContext(), 10,
- BaseRecipientAdapter.QUERY_TYPE_PHONE);
- view.setAdapter(adapter);
-
- final RecipientEntry entry1 = view.createTokenizedEntry(phone1);
- final String destination1 = entry1.getDestination();
- assertTrue(phone1 + " failed with " + destination1,
- Pattern.matches(phonePattern, destination1));
-
- final RecipientEntry entry2 = view.createTokenizedEntry(phone2);
- final String destination2 = entry2.getDestination();
- assertTrue(phone2 + " failed with " + destination2,
- Pattern.matches(phonePattern, destination2));
-
- final RecipientEntry entry3 = view.createTokenizedEntry(phone3);
- final String destination3 = entry3.getDestination();
- assertTrue(phone3 + " failed with " + destination3,
- Pattern.matches(phonePattern, destination3));
- }
-}
diff --git a/chips/tests/src/com/android/ex/chips/RecipientAlternatesAdapterTest.java b/chips/tests/src/com/android/ex/chips/RecipientAlternatesAdapterTest.java
deleted file mode 100644
index afb6a00..0000000
--- a/chips/tests/src/com/android/ex/chips/RecipientAlternatesAdapterTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2012 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.ex.chips;
-
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.Uri;
-import android.provider.ContactsContract.DisplayNameSources;
-import android.test.AndroidTestCase;
-
-import com.android.ex.chips.RecipientAlternatesAdapter;
-import com.android.ex.chips.RecipientEntry;
-
-public class RecipientAlternatesAdapterTest extends AndroidTestCase {
-
- public void testRemoveUndesiredDestinations() {
- MatrixCursor c = new MatrixCursor(Queries.EMAIL.getProjection());
- Cursor result;
-
- // Test: Empty input
- assertEquals(0, RecipientAlternatesAdapter.removeUndesiredDestinations(c,
- null /* desiredMimeType */, null /* lookupKey */).getCount());
-
-
- // Test: One row
- addRow(c, "a", "1@android.com", 1, "home", 1000, 2000, "x", 0);
-
- result = RecipientAlternatesAdapter.removeUndesiredDestinations(c,
- null /* desiredMimeType */, null /* lookupKey */);
- assertEquals(1, result.getCount());
- assertRow(result, 0, "a", "1@android.com", 1, "home", 1000, 2000, "x", 0);
-
- // Test: two unique rows, different destinations
- addRow(c, "a", "2@android.com", 1, "home", 1000, 2000, "x", 0);
-
- result = RecipientAlternatesAdapter.removeUndesiredDestinations(c,
- null /* desiredMimeType */, null /* lookupKey */);
- assertEquals(2, result.getCount());
- assertRow(result, 0, "a", "1@android.com", 1, "home", 1000, 2000, "x", 0);
- assertRow(result, 1, "a", "2@android.com", 1, "home", 1000, 2000, "x", 0);
-
- // Test: add a third row with a non-unique destination.
- addRow(c, "ax", "1@android.com", 11, "homex", 10001, 2000, "xx", 1);
-
- // Third row should be removed.
- result = RecipientAlternatesAdapter.removeUndesiredDestinations(c,
- null /* desiredMimeType */, null /* lookupKey */);
- assertEquals(2, result.getCount());
- assertRow(result, 0, "a", "1@android.com", 1, "home", 1000, 2000, "x", 0);
- assertRow(result, 1, "a", "2@android.com", 1, "home", 1000, 2000, "x", 0);
-
- // Test: add a forth row with a non-unique destination again.
- addRow(c, "ax", "2@android.com", 11, "homex", 10001, 2000, "xx", 1);
-
- // Forth row should also be removed.
- result = RecipientAlternatesAdapter.removeUndesiredDestinations(c,
- null /* desiredMimeType */, null /* lookupKey */);
- assertEquals(2, result.getCount());
- assertRow(result, 0, "a", "1@android.com", 1, "home", 1000, 2000, "x", 0);
- assertRow(result, 1, "a", "2@android.com", 1, "home", 1000, 2000, "x", 0);
- }
-
- private static MatrixCursor addRow(MatrixCursor c,
- String displayName,
- String destination,
- int destinationType,
- String destinationLabel,
- long contactId,
- long dataId,
- String photoUri,
- int displayNameSource
- ) {
- c.addRow(new Object[] {displayName, destination, destinationType, destinationLabel,
- contactId, dataId, photoUri, displayNameSource});
- return c;
- }
-
- private static void assertRow(Cursor c, int position,
- String displayName,
- String destination,
- int destinationType,
- String destinationLabel,
- long contactId,
- long dataId,
- String photoUri,
- int displayNameSource
- ) {
- assertTrue(c.moveToPosition(position));
- assertEquals(displayName, c.getString(0));
- assertEquals(destination, c.getString(1));
- assertEquals(destinationType, c.getInt(2));
- assertEquals(destinationLabel, c.getString(3));
- assertEquals(contactId, c.getLong(4));
- assertEquals(dataId, c.getLong(5));
- assertEquals(photoUri, c.getString(6));
- assertEquals(displayNameSource, c.getInt(7));
- }
-
- public void testGetBetterRecipient() {
- // Ensure that if either (but not both) parameters are null, the other is returned
- {
- final RecipientEntry entry1 =
- RecipientEntry.constructFakeEntry("1@android.com", true);
- final RecipientEntry entry2 = null;
-
- assertEquals(RecipientAlternatesAdapter.getBetterRecipient(entry1, entry2), entry1);
- assertEquals(RecipientAlternatesAdapter.getBetterRecipient(entry2, entry1), entry1);
- }
-
- // Ensure that if only one has a display name, it is used
- {
- final RecipientEntry entry1 =
- RecipientEntry.constructTopLevelEntry("Android", DisplayNameSources.NICKNAME,
- "1@android.com", 0, null, 0, null /* directoryId */, 0, (Uri) null,
- true, null /* lookupKey */);
- final RecipientEntry entry2 = RecipientEntry.constructFakeEntry("1@android.com", true);
-
- assertEquals(RecipientAlternatesAdapter.getBetterRecipient(entry1, entry2), entry1);
- assertEquals(RecipientAlternatesAdapter.getBetterRecipient(entry2, entry1), entry1);
- }
-
- // Ensure that if one has a display name different from its destination, and the other's
- // is equal to its destination, we use the unique one
- {
- final RecipientEntry entry1 =
- RecipientEntry.constructTopLevelEntry("Android", DisplayNameSources.NICKNAME,
- "1@android.com", 0, null, 0, null /* directoryId */, 0, (Uri) null,
- true, null /* lookupKey */);
- final RecipientEntry entry2 =
- RecipientEntry.constructTopLevelEntry("2@android.com", DisplayNameSources.EMAIL,
- "2@android.com", 0, null, 0, null /* directoryId */, 0, (Uri) null,
- true, null /* lookupKey */);
-
- assertEquals(RecipientAlternatesAdapter.getBetterRecipient(entry1, entry2), entry1);
- assertEquals(RecipientAlternatesAdapter.getBetterRecipient(entry2, entry1), entry1);
- }
-
- // Ensure that if only one has a photo, it is used
- {
- final RecipientEntry entry1 =
- RecipientEntry.constructTopLevelEntry("Android", DisplayNameSources.NICKNAME,
- "1@android.com", 0, null, 0, null /* directoryId */, 0,
- Uri.parse("http://www.android.com"), true, null /* lookupKey */);
- final RecipientEntry entry2 =
- RecipientEntry.constructTopLevelEntry("Android", DisplayNameSources.EMAIL,
- "2@android.com", 0, null, 0, null /* directoryId */,
- 0, (Uri) null, true, null /* lookupKey */);
-
- assertEquals(RecipientAlternatesAdapter.getBetterRecipient(entry1, entry2), entry1);
- assertEquals(RecipientAlternatesAdapter.getBetterRecipient(entry2, entry1), entry1);
- }
- }
-}
diff --git a/common/build.gradle b/common/build.gradle
index d2612c5..fa1388c 100644
--- a/common/build.gradle
+++ b/common/build.gradle
@@ -1,36 +1,20 @@
apply plugin: 'android-library'
-
-buildDir = "$project.rootBuildDir/android-$project.name"
+apply plugin: 'logtags'
android {
- compileSdkVersion 17
- buildToolsVersion = 17
-
- logtags {
- srcDirs = ['java']
- genDir = "$buildDir/source/generated"
- }
+ compileSdkVersion 19
+ buildToolsVersion = '19.0.1'
sourceSets {
main {
- manifest {
- srcFile "AndroidManifest.xml"
- }
- java {
- srcDirs = [
- 'java',
- "$buildDir/source/generated"
- ]
- }
- resources.srcDirs = ['src']
- aidl.srcDirs = ['src']
- renderscript.srcDirs = ['src']
- res.srcDirs = ['res']
- assets.srcDirs = ['assets']
+ manifest.srcFile 'AndroidManifest.xml'
+ java.srcDirs = ['java']
+ logtags.srcDirs = ['java']
}
}
-}
-android.libraryVariants.each { variant ->
- variant.packageLibrary.baseName = "android-common"
-}
\ No newline at end of file
+ lintOptions {
+ // TODO: fix errors and reenable.
+ abortOnError false
+ }
+}
diff --git a/common/java/com/android/common/GoogleLogTags.logtags b/common/java/com/android/common/GoogleLogTags.logtags
index 8314368..4a86970 100644
--- a/common/java/com/android/common/GoogleLogTags.logtags
+++ b/common/java/com/android/common/GoogleLogTags.logtags
@@ -99,3 +99,8 @@
205009 gls_account_saved (status|1)
205010 gls_authenticate (status|1),(service|3)
205011 google_mail_switch (direction|1)
+
+# Event for Android SNet
+206001 snet (payload|3)
+# TODO(williamluh): Remove this once switch to snet completed.
+206003 exp_det_snet (payload|3)
diff --git a/framesequence/jni/Android.mk b/framesequence/jni/Android.mk
index ee86fc1..e9d0ec5 100644
--- a/framesequence/jni/Android.mk
+++ b/framesequence/jni/Android.mk
@@ -19,12 +19,13 @@
## Main library
-LOCAL_STATIC_LIBRARIES += libgif
+LOCAL_STATIC_LIBRARIES += libgif libwebp-decode
LOCAL_LDFLAGS := -llog -ljnigraphics
LOCAL_C_INCLUDES := \
- external/giflib
+ external/giflib \
+ external/webp/include
LOCAL_MODULE := libframesequence
LOCAL_SRC_FILES := \
@@ -32,6 +33,7 @@
FrameSequence.cpp \
FrameSequenceJNI.cpp \
FrameSequence_gif.cpp \
+ FrameSequence_webp.cpp \
JNIHelpers.cpp \
Registry.cpp \
Stream.cpp
diff --git a/framesequence/jni/FrameSequence_gif.cpp b/framesequence/jni/FrameSequence_gif.cpp
index daa097b..f3e94df 100644
--- a/framesequence/jni/FrameSequence_gif.cpp
+++ b/framesequence/jni/FrameSequence_gif.cpp
@@ -89,7 +89,7 @@
&& eb2->Function == CONTINUE_EXT_FUNC_CODE
&& eb2->ByteCount == 3
&& eb2->Bytes[0] == 1) {
- mLoopCount = (int)(eb2->Bytes[2] & 0xff) + (int)(eb2->Bytes[1] & 0xff);
+ mLoopCount = (int)(eb2->Bytes[2] << 8) + (int)(eb2->Bytes[1]);
}
}
diff --git a/framesequence/jni/FrameSequence_webp.cpp b/framesequence/jni/FrameSequence_webp.cpp
new file mode 100644
index 0000000..602feb7
--- /dev/null
+++ b/framesequence/jni/FrameSequence_webp.cpp
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#include <string.h>
+#include "JNIHelpers.h"
+#include "utils/log.h"
+#include "utils/math.h"
+#include "webp/format_constants.h"
+
+#include "FrameSequence_webp.h"
+
+#define WEBP_DEBUG 0
+
+////////////////////////////////////////////////////////////////////////////////
+// Frame sequence
+////////////////////////////////////////////////////////////////////////////////
+
+static uint32_t GetLE32(const uint8_t* const data) {
+ return MKFOURCC(data[0], data[1], data[2], data[3]);
+}
+
+// Returns true if the frame covers full canvas.
+static bool isFullFrame(const WebPIterator& frame, int canvasWidth, int canvasHeight) {
+ return (frame.width == canvasWidth && frame.height == canvasHeight);
+}
+
+// Returns true if the rectangle defined by 'frame' contains pixel (x, y).
+static bool FrameContainsPixel(const WebPIterator& frame, int x, int y) {
+ const int left = frame.x_offset;
+ const int right = left + frame.width;
+ const int top = frame.y_offset;
+ const int bottom = top + frame.height;
+ return x >= left && x < right && y >= top && y < bottom;
+}
+
+// Construct mIsKeyFrame array.
+void FrameSequence_webp::constructDependencyChain() {
+ const size_t frameCount = getFrameCount();
+ mIsKeyFrame = new bool[frameCount];
+ const int canvasWidth = getWidth();
+ const int canvasHeight = getHeight();
+
+ WebPIterator prev;
+ WebPIterator curr;
+
+ // Note: WebPDemuxGetFrame() uses base-1 counting.
+ int ok = WebPDemuxGetFrame(mDemux, 1, &curr);
+ ALOG_ASSERT(ok, "Could not retrieve frame# 0");
+ mIsKeyFrame[0] = true; // 0th frame is always a key frame.
+ for (size_t i = 1; i < frameCount; i++) {
+ prev = curr;
+ ok = WebPDemuxGetFrame(mDemux, i + 1, &curr); // Get ith frame.
+ ALOG_ASSERT(ok, "Could not retrieve frame# %d", i);
+
+ if ((!curr.has_alpha || curr.blend_method == WEBP_MUX_NO_BLEND) &&
+ isFullFrame(curr, canvasWidth, canvasHeight)) {
+ mIsKeyFrame[i] = true;
+ } else {
+ mIsKeyFrame[i] = (prev.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) &&
+ (isFullFrame(prev, canvasWidth, canvasHeight) || mIsKeyFrame[i - 1]);
+ }
+ }
+ WebPDemuxReleaseIterator(&prev);
+ WebPDemuxReleaseIterator(&curr);
+
+#if WEBP_DEBUG
+ ALOGD("Dependency chain:");
+ for (size_t i = 0; i < frameCount; i++) {
+ ALOGD("Frame# %zu: %s", i, mIsKeyFrame[i] ? "Key frame" : "NOT a key frame");
+ }
+#endif
+}
+
+FrameSequence_webp::FrameSequence_webp(Stream* stream) {
+ // Read RIFF header to get file size.
+ uint8_t riff_header[RIFF_HEADER_SIZE];
+ if (stream->read(riff_header, RIFF_HEADER_SIZE) != RIFF_HEADER_SIZE) {
+ ALOGE("WebP header load failed");
+ return;
+ }
+ mData.size = CHUNK_HEADER_SIZE + GetLE32(riff_header + TAG_SIZE);
+ mData.bytes = new uint8_t[mData.size];
+ memcpy((void*)mData.bytes, riff_header, RIFF_HEADER_SIZE);
+
+ // Read rest of the bytes.
+ void* remaining_bytes = (void*)(mData.bytes + RIFF_HEADER_SIZE);
+ size_t remaining_size = mData.size - RIFF_HEADER_SIZE;
+ if (stream->read(remaining_bytes, remaining_size) != remaining_size) {
+ ALOGE("WebP full load failed");
+ return;
+ }
+
+ // Construct demux.
+ mDemux = WebPDemux(&mData);
+ if (!mDemux) {
+ ALOGE("Parsing of WebP container file failed");
+ return;
+ }
+ mLoopCount = WebPDemuxGetI(mDemux, WEBP_FF_LOOP_COUNT);
+ mFormatFlags = WebPDemuxGetI(mDemux, WEBP_FF_FORMAT_FLAGS);
+#if WEBP_DEBUG
+ ALOGD("FrameSequence_webp created with size = %d x %d, number of frames = %d, flags = 0x%X",
+ getWidth(), getHeight(), getFrameCount(), mFormatFlags);
+#endif
+ constructDependencyChain();
+}
+
+FrameSequence_webp::~FrameSequence_webp() {
+ WebPDemuxDelete(mDemux);
+ delete[] mData.bytes;
+ delete[] mIsKeyFrame;
+}
+
+FrameSequenceState* FrameSequence_webp::createState() const {
+ return new FrameSequenceState_webp(*this);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// draw helpers
+////////////////////////////////////////////////////////////////////////////////
+
+static bool willBeCleared(const WebPIterator& iter) {
+ return iter.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND;
+}
+
+// return true if area of 'target' completely covers area of 'covered'
+static bool checkIfCover(const WebPIterator& target, const WebPIterator& covered) {
+ const int covered_x_max = covered.x_offset + covered.width;
+ const int target_x_max = target.x_offset + target.width;
+ const int covered_y_max = covered.y_offset + covered.height;
+ const int target_y_max = target.y_offset + target.height;
+ return target.x_offset <= covered.x_offset
+ && covered_x_max <= target_x_max
+ && target.y_offset <= covered.y_offset
+ && covered_y_max <= target_y_max;
+}
+
+// Clear all pixels in a line to transparent.
+static void clearLine(Color8888* dst, int width) {
+ memset(dst, 0, width * sizeof(*dst)); // Note: Assumes TRANSPARENT == 0x0.
+}
+
+// Copy all pixels from 'src' to 'dst'.
+static void copyFrame(const Color8888* src, int srcStride, Color8888* dst, int dstStride,
+ int width, int height) {
+ for (int y = 0; y < height; y++) {
+ memcpy(dst, src, width * sizeof(*dst));
+ src += srcStride;
+ dst += dstStride;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Frame sequence state
+////////////////////////////////////////////////////////////////////////////////
+
+FrameSequenceState_webp::FrameSequenceState_webp(const FrameSequence_webp& frameSequence) :
+ mFrameSequence(frameSequence) {
+ WebPInitDecoderConfig(&mDecoderConfig);
+ mDecoderConfig.output.is_external_memory = 1;
+ mDecoderConfig.output.colorspace = MODE_rgbA; // Pre-multiplied alpha mode.
+ const int canvasWidth = mFrameSequence.getWidth();
+ const int canvasHeight = mFrameSequence.getHeight();
+ mPreservedBuffer = new Color8888[canvasWidth * canvasHeight];
+}
+
+FrameSequenceState_webp::~FrameSequenceState_webp() {
+ delete[] mPreservedBuffer;
+}
+
+void FrameSequenceState_webp::initializeFrame(const WebPIterator& currIter, Color8888* currBuffer,
+ int currStride, const WebPIterator& prevIter, const Color8888* prevBuffer, int prevStride) {
+ const int canvasWidth = mFrameSequence.getWidth();
+ const int canvasHeight = mFrameSequence.getHeight();
+ const bool currFrameIsKeyFrame = mFrameSequence.isKeyFrame(currIter.frame_num - 1);
+
+ if (currFrameIsKeyFrame) { // Clear canvas.
+ for (int y = 0; y < canvasHeight; y++) {
+ Color8888* dst = currBuffer + y * currStride;
+ clearLine(dst, canvasWidth);
+ }
+ } else {
+ // Preserve previous frame as starting state of current frame.
+ copyFrame(prevBuffer, prevStride, currBuffer, currStride, canvasWidth, canvasHeight);
+
+ // Dispose previous frame rectangle to Background if needed.
+ bool prevFrameCompletelyCovered =
+ (!currIter.has_alpha || currIter.blend_method == WEBP_MUX_NO_BLEND) &&
+ checkIfCover(currIter, prevIter);
+ if ((prevIter.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) &&
+ !prevFrameCompletelyCovered) {
+ Color8888* dst = currBuffer + prevIter.x_offset + prevIter.y_offset * currStride;
+ for (int j = 0; j < prevIter.height; j++) {
+ clearLine(dst, prevIter.width);
+ dst += currStride;
+ }
+ }
+ }
+}
+
+bool FrameSequenceState_webp::decodeFrame(const WebPIterator& currIter, Color8888* currBuffer,
+ int currStride, const WebPIterator& prevIter, const Color8888* prevBuffer, int prevStride) {
+ Color8888* dst = currBuffer + currIter.x_offset + currIter.y_offset * currStride;
+ mDecoderConfig.output.u.RGBA.rgba = (uint8_t*)dst;
+ mDecoderConfig.output.u.RGBA.stride = currStride * 4;
+ mDecoderConfig.output.u.RGBA.size = mDecoderConfig.output.u.RGBA.stride * currIter.height;
+
+ const WebPData& currFrame = currIter.fragment;
+ if (WebPDecode(currFrame.bytes, currFrame.size, &mDecoderConfig) != VP8_STATUS_OK) {
+ return false;
+ }
+
+ const int canvasWidth = mFrameSequence.getWidth();
+ const int canvasHeight = mFrameSequence.getHeight();
+ const bool currFrameIsKeyFrame = mFrameSequence.isKeyFrame(currIter.frame_num - 1);
+ // During the decoding of current frame, we may have set some pixels to be transparent
+ // (i.e. alpha < 255). However, the value of each of these pixels should have been determined
+ // by blending it against the value of that pixel in the previous frame if WEBP_MUX_BLEND was
+ // specified. So, we correct these pixels based on disposal method of the previous frame and
+ // the previous frame buffer.
+ if (currIter.blend_method == WEBP_MUX_BLEND && !currFrameIsKeyFrame) {
+ if (prevIter.dispose_method == WEBP_MUX_DISPOSE_NONE) {
+ for (int y = 0; y < currIter.height; y++) {
+ const int canvasY = currIter.y_offset + y;
+ for (int x = 0; x < currIter.width; x++) {
+ const int canvasX = currIter.x_offset + x;
+ Color8888& currPixel = currBuffer[canvasY * currStride + canvasX];
+ // FIXME: Use alpha-blending when alpha is between 0 and 255.
+ if (!(currPixel & COLOR_8888_ALPHA_MASK)) {
+ const Color8888 prevPixel = prevBuffer[canvasY * prevStride + canvasX];
+ currPixel = prevPixel;
+ }
+ }
+ }
+ } else { // prevIter.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND
+ // Need to restore transparent pixels to as they were just after frame initialization.
+ // That is:
+ // * Transparent if it belongs to previous frame rectangle <-- This is a no-op.
+ // * Pixel in the previous canvas otherwise <-- Need to restore.
+ for (int y = 0; y < currIter.height; y++) {
+ const int canvasY = currIter.y_offset + y;
+ for (int x = 0; x < currIter.width; x++) {
+ const int canvasX = currIter.x_offset + x;
+ Color8888& currPixel = currBuffer[canvasY * currStride + canvasX];
+ // FIXME: Use alpha-blending when alpha is between 0 and 255.
+ if (!(currPixel & COLOR_8888_ALPHA_MASK)
+ && !FrameContainsPixel(prevIter, canvasX, canvasY)) {
+ const Color8888 prevPixel = prevBuffer[canvasY * prevStride + canvasX];
+ currPixel = prevPixel;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
+long FrameSequenceState_webp::drawFrame(int frameNr,
+ Color8888* outputPtr, int outputPixelStride, int previousFrameNr) {
+ WebPDemuxer* demux = mFrameSequence.getDemuxer();
+ ALOG_ASSERT(demux, "Cannot drawFrame, mDemux is NULL");
+
+#if WEBP_DEBUG
+ ALOGD(" drawFrame called for frame# %d, previous frame# %d", frameNr, previousFrameNr);
+#endif
+
+ const int canvasWidth = mFrameSequence.getWidth();
+ const int canvasHeight = mFrameSequence.getHeight();
+
+ // Find the first frame to be decoded.
+ int start = max(previousFrameNr + 1, 0);
+ int earliestRequired = frameNr;
+ while (earliestRequired > start) {
+ if (mFrameSequence.isKeyFrame(earliestRequired)) {
+ start = earliestRequired;
+ break;
+ }
+ earliestRequired--;
+ }
+
+ WebPIterator currIter;
+ WebPIterator prevIter;
+ int ok = WebPDemuxGetFrame(demux, start, &currIter); // Get frame number 'start - 1'.
+ ALOG_ASSERT(ok, "Could not retrieve frame# %d", start - 1);
+
+ // Use preserve buffer only if needed.
+ Color8888* prevBuffer = (frameNr == 0) ? outputPtr : mPreservedBuffer;
+ int prevStride = (frameNr == 0) ? outputPixelStride : canvasWidth;
+ Color8888* currBuffer = outputPtr;
+ int currStride = outputPixelStride;
+
+ for (int i = start; i <= frameNr; i++) {
+ prevIter = currIter;
+ ok = WebPDemuxGetFrame(demux, i + 1, &currIter); // Get ith frame.
+ ALOG_ASSERT(ok, "Could not retrieve frame# %d", i);
+#if WEBP_DEBUG
+ ALOGD(" producing frame %d (has_alpha = %d, dispose = %s, blend = %s, duration = %d)",
+ i, currIter.has_alpha,
+ (currIter.dispose_method == WEBP_MUX_DISPOSE_NONE) ? "none" : "background",
+ (currIter.blend_method == WEBP_MUX_BLEND) ? "yes" : "no", currIter.duration);
+#endif
+ // We swap the prev/curr buffers as we go.
+ Color8888* tmpBuffer = prevBuffer;
+ prevBuffer = currBuffer;
+ currBuffer = tmpBuffer;
+
+ int tmpStride = prevStride;
+ prevStride = currStride;
+ currStride = tmpStride;
+
+#if WEBP_DEBUG
+ ALOGD(" prev = %p, curr = %p, out = %p, tmp = %p",
+ prevBuffer, currBuffer, outputPtr, mPreservedBuffer);
+#endif
+ // Process this frame.
+ initializeFrame(currIter, currBuffer, currStride, prevIter, prevBuffer, prevStride);
+
+ if (i == frameNr || !willBeCleared(currIter)) {
+ if (!decodeFrame(currIter, currBuffer, currStride, prevIter, prevBuffer, prevStride)) {
+ ALOGE("Error decoding frame# %d", i);
+ return -1;
+ }
+ }
+ }
+
+ if (outputPtr != currBuffer) {
+ copyFrame(currBuffer, currStride, outputPtr, outputPixelStride, canvasWidth, canvasHeight);
+ }
+
+ // Return last frame's delay.
+ const int frameCount = mFrameSequence.getFrameCount();
+ const int lastFrame = (frameNr + frameCount - 1) % frameCount;
+ ok = WebPDemuxGetFrame(demux, lastFrame, &currIter);
+ ALOG_ASSERT(ok, "Could not retrieve frame# %d", lastFrame - 1);
+ const int lastFrameDelay = currIter.duration;
+
+ WebPDemuxReleaseIterator(&currIter);
+ WebPDemuxReleaseIterator(&prevIter);
+
+ return lastFrameDelay;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Registry
+////////////////////////////////////////////////////////////////////////////////
+
+#include "Registry.h"
+
+static bool isWebP(void* header, int header_size) {
+ const uint8_t* const header_str = (const uint8_t*)header;
+ return (header_size >= RIFF_HEADER_SIZE) &&
+ !memcmp("RIFF", header_str, 4) &&
+ !memcmp("WEBP", header_str + 8, 4);
+}
+
+static FrameSequence* createFramesequence(Stream* stream) {
+ return new FrameSequence_webp(stream);
+}
+
+static RegistryEntry gEntry = {
+ RIFF_HEADER_SIZE,
+ isWebP,
+ createFramesequence,
+ NULL,
+};
+static Registry gRegister(gEntry);
+
diff --git a/framesequence/jni/FrameSequence_webp.h b/framesequence/jni/FrameSequence_webp.h
new file mode 100644
index 0000000..f4fbec0
--- /dev/null
+++ b/framesequence/jni/FrameSequence_webp.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef RASTERMILL_FRAMESQUENCE_WEBP_H
+#define RASTERMILL_FRAMESQUENCE_WEBP_H
+
+#include "config.h"
+#include "webp/decode.h"
+#include "webp/demux.h"
+
+#include "Stream.h"
+#include "Color.h"
+#include "FrameSequence.h"
+
+// Parser for a possibly-animated WebP bitstream.
+class FrameSequence_webp : public FrameSequence {
+public:
+ FrameSequence_webp(Stream* stream);
+ virtual ~FrameSequence_webp();
+
+ virtual int getWidth() const {
+ return WebPDemuxGetI(mDemux, WEBP_FF_CANVAS_WIDTH);
+ }
+
+ virtual int getHeight() const {
+ return WebPDemuxGetI(mDemux, WEBP_FF_CANVAS_HEIGHT);
+ }
+
+ virtual bool isOpaque() const {
+ return !(mFormatFlags & ALPHA_FLAG);
+ }
+
+ virtual int getFrameCount() const {
+ return WebPDemuxGetI(mDemux, WEBP_FF_FRAME_COUNT);
+ }
+
+ virtual int getDefaultLoopCount() const {
+ return mLoopCount;
+ }
+
+ virtual FrameSequenceState* createState() const;
+
+ WebPDemuxer* getDemuxer() const { return mDemux; }
+
+ bool isKeyFrame(size_t frameNr) const { return mIsKeyFrame[frameNr]; }
+
+private:
+ void constructDependencyChain();
+
+ WebPData mData;
+ WebPDemuxer* mDemux;
+ int mLoopCount;
+ uint32_t mFormatFlags;
+ // mIsKeyFrame[i] is true if ith canvas can be constructed without decoding any prior frames.
+ bool* mIsKeyFrame;
+};
+
+// Produces frames of a possibly-animated WebP file for display.
+class FrameSequenceState_webp : public FrameSequenceState {
+public:
+ FrameSequenceState_webp(const FrameSequence_webp& frameSequence);
+ virtual ~FrameSequenceState_webp();
+
+ // Returns frame's delay time in milliseconds.
+ virtual long drawFrame(int frameNr,
+ Color8888* outputPtr, int outputPixelStride, int previousFrameNr);
+
+private:
+ void initializeFrame(const WebPIterator& currIter, Color8888* currBuffer, int currStride,
+ const WebPIterator& prevIter, const Color8888* prevBuffer, int prevStride);
+ bool decodeFrame(const WebPIterator& iter, Color8888* currBuffer, int currStride,
+ const WebPIterator& prevIter, const Color8888* prevBuffer, int prevStride);
+
+ const FrameSequence_webp& mFrameSequence;
+ WebPDecoderConfig mDecoderConfig;
+ Color8888* mPreservedBuffer;
+};
+
+#endif //RASTERMILL_FRAMESQUENCE_WEBP_H
diff --git a/framesequence/jni/utils/log.h b/framesequence/jni/utils/log.h
index 5e15f30..d8441dc 100644
--- a/framesequence/jni/utils/log.h
+++ b/framesequence/jni/utils/log.h
@@ -267,6 +267,20 @@
if (__android_log_assert(ANDROID_##priority, tag))
#endif
+/* Returns 2nd arg. Used to substitute default value if caller's vararg list
+ * is empty.
+ */
+#define __android_second(dummy, second, ...) second
+
+/* If passed multiple args, returns ',' followed by all but 1st arg, otherwise
+ * returns nothing.
+ */
+#define __android_rest(first, ...) , ## __VA_ARGS__
+
+#define android_printAssert(cond, tag, fmt...) \
+ __android_log_assert(cond, tag, \
+ __android_second(0, ## fmt, NULL) __android_rest(fmt))
+
#ifdef __cplusplus
}
#endif
diff --git a/variablespeed/jni/jni_entry.cc b/variablespeed/jni/jni_entry.cc
index 93c12ba..20bcf3c 100644
--- a/variablespeed/jni/jni_entry.cc
+++ b/variablespeed/jni/jni_entry.cc
@@ -81,9 +81,12 @@
jfloat initialRate, jint decodeInitialSize, jint decodeMaxSize,
jint startPositionMillis, jint audioStreamType) {
MethodLog _("initializeEngine");
- AudioEngine::SetEngine(new AudioEngine(targetFrames,
+ AudioEngine *engine = new AudioEngine(targetFrames,
windowDuration, windowOverlapDuration, maxPlayBufferCount, initialRate,
- decodeInitialSize, decodeMaxSize, startPositionMillis, audioStreamType));
+ decodeInitialSize, decodeMaxSize, startPositionMillis, audioStreamType);
+ if (!AudioEngine::CompareAndSetEngine(NULL, engine)) {
+ delete engine;
+ }
}
JNI_METHOD(shutdownEngine, void) (JNIEnv*, jclass) {
diff --git a/variablespeed/jni/variablespeed.cc b/variablespeed/jni/variablespeed.cc
index b5d9067..8e161fc 100644
--- a/variablespeed/jni/variablespeed.cc
+++ b/variablespeed/jni/variablespeed.cc
@@ -129,14 +129,21 @@
audioEngine_ = engine;
}
-void AudioEngine::DeleteEngine() {
- if (audioEngine_ == NULL) {
- LOGE("you haven't initialized the audio engine");
- CHECK(false);
- return;
+bool AudioEngine::CompareAndSetEngine(AudioEngine* expect, AudioEngine* update) {
+ android::Mutex::Autolock autoLock(publishEngineLock_);
+ if (audioEngine_ == expect) {
+ DeleteEngine();
+ audioEngine_ = update;
+ return true;
}
- delete audioEngine_;
- audioEngine_ = NULL;
+ return false;
+}
+
+void AudioEngine::DeleteEngine() {
+ if (audioEngine_ != NULL) {
+ delete audioEngine_;
+ audioEngine_ = NULL;
+ }
}
// ****************************************************************************
diff --git a/variablespeed/jni/variablespeed.h b/variablespeed/jni/variablespeed.h
index cf856da..74710e5 100644
--- a/variablespeed/jni/variablespeed.h
+++ b/variablespeed/jni/variablespeed.h
@@ -64,6 +64,7 @@
static AudioEngine* GetEngine();
static void SetEngine(AudioEngine* engine);
+ static bool CompareAndSetEngine(AudioEngine* expect, AudioEngine* update);
static void DeleteEngine();
private:
diff --git a/variablespeed/src/com/android/ex/variablespeed/MediaPlayerProxy.java b/variablespeed/src/com/android/ex/variablespeed/MediaPlayerProxy.java
index 8489dc1..3b7b576 100644
--- a/variablespeed/src/com/android/ex/variablespeed/MediaPlayerProxy.java
+++ b/variablespeed/src/com/android/ex/variablespeed/MediaPlayerProxy.java
@@ -42,6 +42,7 @@
int getDuration();
void seekTo(int startPosition);
void start();
+ boolean isReadyToPlay();
boolean isPlaying();
int getCurrentPosition();
void pause();
diff --git a/variablespeed/src/com/android/ex/variablespeed/SingleThreadedMediaPlayerProxy.java b/variablespeed/src/com/android/ex/variablespeed/SingleThreadedMediaPlayerProxy.java
index 17692f7..c9a9741 100644
--- a/variablespeed/src/com/android/ex/variablespeed/SingleThreadedMediaPlayerProxy.java
+++ b/variablespeed/src/com/android/ex/variablespeed/SingleThreadedMediaPlayerProxy.java
@@ -85,6 +85,11 @@
}
@Override
+ public synchronized boolean isReadyToPlay() {
+ return mDelegate.isReadyToPlay();
+ }
+
+ @Override
public synchronized boolean isPlaying() {
return mDelegate.isPlaying();
}
diff --git a/variablespeed/src/com/android/ex/variablespeed/VariableSpeed.java b/variablespeed/src/com/android/ex/variablespeed/VariableSpeed.java
index 5c93d26..e44a375 100644
--- a/variablespeed/src/com/android/ex/variablespeed/VariableSpeed.java
+++ b/variablespeed/src/com/android/ex/variablespeed/VariableSpeed.java
@@ -337,9 +337,16 @@
}
@Override
+ public boolean isReadyToPlay() {
+ synchronized (lock) {
+ return !mHasBeenReleased && mHasDuration;
+ }
+ }
+
+ @Override
public boolean isPlaying() {
synchronized (lock) {
- return mHasStartedPlayback && !hasPlaybackFinished();
+ return isReadyToPlay() && mHasStartedPlayback && !hasPlaybackFinished();
}
}