Clean up Gps/Flp Hardware on shut-down.

Ensures that the GPS and FLP HAL interfaces are deinitialized upon
system shut-down. This gives a chance for the underlying HAL to
close cleanly any resources it could be holding.
Note this approach only works for a device's power-off, scenarios
such as adb shell stop / start cannot  be handled, because in such
cases the process is terminated sending SIGKILL to it.

Bug: 23279835
Bug: 23279593
Change-Id: I29b3306c0ae2b384d0542031080a15fdbe49dd71
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 468ead0..885c765 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -307,6 +307,7 @@
         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
         intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
         intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
+        intentFilter.addAction(Intent.ACTION_SHUTDOWN);
 
         mContext.registerReceiverAsUser(new BroadcastReceiver() {
             @Override
@@ -317,12 +318,36 @@
                 } else if (Intent.ACTION_MANAGED_PROFILE_ADDED.equals(action)
                         || Intent.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {
                     updateUserProfiles(mCurrentUserId);
+                } else if (Intent.ACTION_SHUTDOWN.equals(action)) {
+                    shutdownComponents();
                 }
             }
         }, UserHandle.ALL, intentFilter, null, mLocationHandler);
     }
 
     /**
+     * Provides a way for components held by the {@link LocationManagerService} to clean-up
+     * gracefully on system's shutdown.
+     *
+     * NOTES:
+     * 1) Only provides a chance to clean-up on an opt-in basis. This guarantees back-compat
+     * support for components that do not wish to handle such event.
+     */
+    private void shutdownComponents() {
+        if(D) Log.d(TAG, "Shutting down components...");
+
+        LocationProviderInterface gpsProvider = mProvidersByName.get(LocationManager.GPS_PROVIDER);
+        if (gpsProvider != null && gpsProvider.isEnabled()) {
+            gpsProvider.disable();
+        }
+
+        FlpHardwareProvider flpHardwareProvider = FlpHardwareProvider.getInstance(mContext);
+        if (FlpHardwareProvider.isSupported() && flpHardwareProvider != null) {
+            flpHardwareProvider.cleanup();
+        }
+    }
+
+    /**
      * Makes a list of userids that are related to the current user. This is
      * relevant when using managed profiles. Otherwise the list only contains
      * the current user.