localization for recovery messages

Add images of text for all locales we support.  Make the progress bar
fill the correct way for RTL languages.  (Flip the direction the
spinner turns, too, just for good measure.)

Bug: 7064142
Change-Id: I5dddb26e02ee5275c57c4dc4a03c6d68432ac7ba
diff --git a/recovery.cpp b/recovery.cpp
index 6ced420..3b58138 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -781,7 +781,7 @@
     if (fp != NULL) {
         fgets(buffer, sizeof(buffer), fp);
         int j = 0;
-        int i;
+        unsigned int i;
         for (i = 0; i < sizeof(buffer) && buffer[i]; ++i) {
             if (!isspace(buffer[i])) {
                 buffer[j++] = buffer[i];
@@ -849,6 +849,7 @@
     ui = device->GetUI();
 
     ui->Init();
+    ui->SetLocale(locale);
     ui->SetBackground(RecoveryUI::NONE);
     if (show_text) ui->ShowText(true);
 
diff --git a/res/images/erasing_text.png b/res/images/erasing_text.png
index 2cd2e38..8b9f265 100644
--- a/res/images/erasing_text.png
+++ b/res/images/erasing_text.png
Binary files differ
diff --git a/res/images/error_text.png b/res/images/error_text.png
index 91be5fe..b64b3d7 100644
--- a/res/images/error_text.png
+++ b/res/images/error_text.png
Binary files differ
diff --git a/res/images/installing_text.png b/res/images/installing_text.png
index 42704b9..9c16c77 100644
--- a/res/images/installing_text.png
+++ b/res/images/installing_text.png
Binary files differ
diff --git a/res/images/no_command_text.png b/res/images/no_command_text.png
index fbc2074..2241259 100644
--- a/res/images/no_command_text.png
+++ b/res/images/no_command_text.png
Binary files differ
diff --git a/screen_ui.cpp b/screen_ui.cpp
index 0b34375..64a5dcd 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -52,6 +52,7 @@
 ScreenRecoveryUI::ScreenRecoveryUI() :
     currentIcon(NONE),
     installingFrame(0),
+    rtl_locale(false),
     progressBarType(EMPTY),
     progressScopeStart(0),
     progressScopeSize(0),
@@ -158,18 +159,35 @@
             float p = progressScopeStart + progress * progressScopeSize;
             int pos = (int) (p * width);
 
-            if (pos > 0) {
-                gr_blit(progressBarFill, 0, 0, pos, height, dx, dy);
-            }
-            if (pos < width-1) {
-                gr_blit(progressBarEmpty, pos, 0, width-pos, height, dx+pos, dy);
+            if (rtl_locale) {
+                // Fill the progress bar from right to left.
+                if (pos > 0) {
+                    gr_blit(progressBarFill, width-pos, 0, pos, height, dx+width-pos, dy);
+                }
+                if (pos < width-1) {
+                    gr_blit(progressBarEmpty, 0, 0, width-pos, height, dx, dy);
+                }
+            } else {
+                // Fill the progress bar from left to right.
+                if (pos > 0) {
+                    gr_blit(progressBarFill, 0, 0, pos, height, dx, dy);
+                }
+                if (pos < width-1) {
+                    gr_blit(progressBarEmpty, pos, 0, width-pos, height, dx+pos, dy);
+                }
             }
         }
 
         if (progressBarType == INDETERMINATE) {
             static int frame = 0;
             gr_blit(progressBarIndeterminate[frame], 0, 0, width, height, dx, dy);
-            frame = (frame + 1) % indeterminate_frames;
+            // in RTL locales, we run the animation backwards, which
+            // makes the spinner spin the other way.
+            if (rtl_locale) {
+                frame = (frame + indeterminate_frames - 1) % indeterminate_frames;
+            } else {
+                frame = (frame + 1) % indeterminate_frames;
+            }
         }
     }
 }
@@ -360,6 +378,28 @@
     RecoveryUI::Init();
 }
 
+void ScreenRecoveryUI::SetLocale(const char* locale) {
+    if (locale) {
+        char* lang = strdup(locale);
+        for (char* p = lang; *p; ++p) {
+            if (*p == '_') {
+                *p = '\0';
+                break;
+            }
+        }
+
+        // A bit cheesy: keep an explicit list of supported languages
+        // that are RTL.
+        if (strcmp(lang, "ar") == 0 ||   // Arabic
+            strcmp(lang, "fa") == 0 ||   // Persian (Farsi)
+            strcmp(lang, "he") == 0 ||   // Hebrew (new language code)
+            strcmp(lang, "iw") == 0) {   // Hebrew (old language code)
+            rtl_locale = true;
+        }
+        free(lang);
+    }
+}
+
 void ScreenRecoveryUI::SetBackground(Icon icon)
 {
     pthread_mutex_lock(&updateMutex);
diff --git a/screen_ui.h b/screen_ui.h
index 16ee741..8005172 100644
--- a/screen_ui.h
+++ b/screen_ui.h
@@ -29,6 +29,7 @@
     ScreenRecoveryUI();
 
     void Init();
+    void SetLocale(const char* locale);
 
     // overall recovery state ("background image")
     void SetBackground(Icon icon);
@@ -55,6 +56,7 @@
   private:
     Icon currentIcon;
     int installingFrame;
+    bool rtl_locale;
 
     pthread_mutex_t updateMutex;
     gr_surface backgroundIcon[5];
diff --git a/ui.h b/ui.h
index ccbb466..acb5766 100644
--- a/ui.h
+++ b/ui.h
@@ -30,6 +30,9 @@
     // Initialize the object; called before anything else.
     virtual void Init();
 
+    // After calling Init(), you can tell the UI what locale it is operating in.
+    virtual void SetLocale(const char* locale) { }
+
     // Set the overall recovery state ("background image").
     enum Icon { NONE, INSTALLING_UPDATE, ERASING, NO_COMMAND, ERROR };
     virtual void SetBackground(Icon icon) = 0;