MountService: Add an ACTION_SHUTDOWN handler and export a method for external shutdown

Signed-off-by: San Mehat <san@google.com>
This commit is contained in:
San Mehat
2010-01-07 10:39:41 -08:00
parent 1a8eec69e1
commit 91c7761139
2 changed files with 70 additions and 1 deletions

View File

@@ -115,4 +115,10 @@ interface IMountService
*/
String[] getSecureCacheList();
/**
* Shuts down the MountService and gracefully unmounts
* all external media.
*/
void shutdown();
}

View File

@@ -115,6 +115,8 @@ class MountService extends IMountService.Stub {
// start processing events before we ought-to
mContext.registerReceiver(mBroadcastReceiver,
new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
mContext.registerReceiver(mBroadcastReceiver,
new IntentFilter(Intent.ACTION_SHUTDOWN), null, null);
mListener = new MountListener(this);
mShowSafeUnmountNotificationWhenUnmounted = false;
@@ -126,13 +128,74 @@ class MountService extends IMountService.Stub {
BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
Thread thread = new Thread(mListener, MountListener.class.getName());
thread.start();
} else if (action.equals(Intent.ACTION_SHUTDOWN)) {
shutdown();
}
}
};
public void shutdown() {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.SHUTDOWN)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires SHUTDOWN permission");
}
Log.d(TAG, "Shutting down");
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_SHARED)) {
/*
* If the media is currently shared, unshare it.
* XXX: This is still dangerous!. We should not
* be rebooting at *all* if UMS is enabled, since
* the UMS host could have dirty FAT cache entries
* yet to flush.
*/
try {
setMassStorageEnabled(false);
} catch (Exception e) {
Log.e(TAG, "ums disable failed", e);
}
} else if (state.equals(Environment.MEDIA_CHECKING)) {
/*
* If the media is being checked, then we need to wait for
* it to complete before being able to proceed.
*/
// XXX: @hackbod - Should we disable the ANR timer here?
int retries = 30;
while (state.equals(Environment.MEDIA_CHECKING) && (retries-- >=0)) {
try {
Thread.sleep(1000);
} catch (InterruptedException iex) {
Log.e(TAG, "Interrupted while waiting for media", iex);
break;
}
state = Environment.getExternalStorageState();
}
if (retries == 0) {
Log.e(TAG, "Timed out waiting for media to check");
}
}
if (state.equals(Environment.MEDIA_MOUNTED)) {
/*
* If the media is mounted, then gracefully unmount it.
*/
try {
String m = Environment.getExternalStorageDirectory().toString();
unmountMedia(m);
} catch (Exception e) {
Log.e(TAG, "external storage unmount failed", e);
}
}
}
/**
* @return true if USB mass storage support is enabled.
*/