Allow IO During boot process, BootActions.

NOTE: this is only compiled into products with PRODUCT_IOT=true.

Introduce BootActions that a developer can provide to manipulate IO
before the android framework comes up on boot.

We will look for a configuration file at /oem/app/etc/boot_action.conf and
expect it to tell us the name of a shared library. We will then fetch
this library from /oem/app/lib/${arch}/ and load it. We expect it to export
boot_action_init(), boot_action_shutdown(), and optionally
boot_action_start_part(int partNumber, int playNumber).

We will then call boot_action_init() during boot after PeripheralManager
is up and call boot_action_shutdown() when the android framework is up
and we are going to start loading APKs.

We will also call boot_action_start_part(*) when each part of the boot
animation is started, use this if you want to synchronize the boot
action and the boot animation.

Boot actions run in a restricted environment and in general can only
make calls to PeripheralManager.

Bug: 37992717
Test: Pushed to local imx7d to test boot actions, pushed to bullhead test that animation+sound still works.
Change-Id: I9e53a17567f8028ea84486d637e1d231ee1125e1
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 6b2de4b..6526123 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -96,11 +96,9 @@
 
 // ---------------------------------------------------------------------------
 
-BootAnimation::BootAnimation(InitCallback initCallback,
-                             PlayPartCallback partCallback)
+BootAnimation::BootAnimation(sp<Callbacks> callbacks)
         : Thread(false), mClockEnabled(true), mTimeIsAccurate(false),
-        mTimeFormat12Hour(false), mTimeCheckThread(NULL),
-        mInitCallback(initCallback), mPlayPartCallback(partCallback) {
+        mTimeFormat12Hour(false), mTimeCheckThread(NULL), mCallbacks(callbacks) {
     mSession = new SurfaceComposerClient();
 
     std::string powerCtl = android::base::GetProperty("sys.powerctl", "");
@@ -357,6 +355,8 @@
     initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png");
     initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");
 
+    mCallbacks->init({});
+
     // clear screen
     glShadeModel(GL_FLAT);
     glDisable(GL_DITHER);
@@ -424,6 +424,7 @@
     int exitnow = atoi(value);
     if (exitnow) {
         requestExit();
+        mCallbacks->shutdown();
     }
 }
 
@@ -777,9 +778,7 @@
         }
     }
 
-    if (mInitCallback != nullptr) {
-        mInitCallback(animation.parts);
-    }
+    mCallbacks->init(animation.parts);
 
     zip->endIteration(cookie);
 
@@ -887,9 +886,7 @@
             if(exitPending() && !part.playUntilComplete)
                 break;
 
-            if (mPlayPartCallback != nullptr) {
-                mPlayPartCallback(i, part, r);
-            }
+            mCallbacks->playPart(i, part, r);
 
             glClearColor(
                     part.backgroundColor[0],