summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/ActivityManagerNative.java22
-rw-r--r--core/java/android/app/IActivityManager.java5
-rw-r--r--core/java/android/content/Intent.java10
-rw-r--r--core/java/android/content/SyncManager.java12
-rw-r--r--core/java/android/content/SyncStorageEngine.java19
-rw-r--r--core/java/android/os/Power.java7
6 files changed, 67 insertions, 8 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 53e6f34..541f413 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -990,6 +990,14 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
+ case SHUTDOWN_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ boolean res = shutdown(data.readInt());
+ reply.writeNoException();
+ reply.writeInt(res ? 1 : 0);
+ return true;
+ }
+
case PEEK_SERVICE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
Intent service = Intent.CREATOR.createFromParcel(data);
@@ -2160,5 +2168,19 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
+ public boolean shutdown(int timeout) throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(timeout);
+ mRemote.transact(SHUTDOWN_TRANSACTION, data, reply, 0);
+ reply.readException();
+ boolean res = reply.readInt() != 0;
+ reply.recycle();
+ data.recycle();
+ return res;
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 2ac6160..56b29c1 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -16,7 +16,6 @@
package android.app;
-import android.app.ActivityManager.MemoryInfo;
import android.content.ComponentName;
import android.content.ContentProviderNative;
import android.content.IContentProvider;
@@ -34,7 +33,6 @@ import android.os.IInterface;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.ParcelFileDescriptor;
-import android.text.TextUtils;
import android.os.Bundle;
import java.util.List;
@@ -225,6 +223,8 @@ public interface IActivityManager extends IInterface {
public boolean profileControl(String process, boolean start,
String path) throws RemoteException;
+ public boolean shutdown(int timeout) throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -370,4 +370,5 @@ public interface IActivityManager extends IInterface {
int GET_DEVICE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+83;
int PEEK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+84;
int PROFILE_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+85;
+ int SHUTDOWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+86;
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index ebdd588..e8ca27b 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -510,6 +510,7 @@ import java.util.Set;
* <li> {@link #ACTION_BATTERY_CHANGED}
* <li> {@link #ACTION_POWER_CONNECTED}
* <li> {@link #ACTION_POWER_DISCONNECTED}
+ * <li> {@link #ACTION_SHUTDOWN}
* </ul>
*
* <h3>Standard Categories</h3>
@@ -1271,6 +1272,15 @@ public class Intent implements Parcelable {
public static final String ACTION_POWER_DISCONNECTED =
"android.intent.action.POWER_DISCONNECTED";
/**
+ * Broadcast Action: Device is shutting down.
+ * This is broadcast when the device is being shut down (completely turned
+ * off, not sleeping). Once the broadcast is complete, the final shutdown
+ * will proceed and all unsaved data lost. Apps will not normally need
+ * to handle this, since the forground activity will be paused as well.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN";
+ /**
* Broadcast Action: Indicates low memory condition on the device
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 019abb8..03cfbea 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -255,6 +255,14 @@ class SyncManager implements OnAccountsUpdatedListener {
}
};
+ private BroadcastReceiver mShutdownIntentReceiver =
+ new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ Log.w(TAG, "Writing sync state before shutdown...");
+ getSyncStorageEngine().writeAllState();
+ }
+ };
+
private static final String ACTION_SYNC_ALARM = "android.content.syncmanager.SYNC_ALARM";
private static final String SYNC_POLL_ALARM = "android.content.syncmanager.SYNC_POLL_ALARM";
private final SyncHandler mSyncHandler;
@@ -301,6 +309,10 @@ class SyncManager implements OnAccountsUpdatedListener {
intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
context.registerReceiver(mStorageIntentReceiver, intentFilter);
+ intentFilter = new IntentFilter(Intent.ACTION_SHUTDOWN);
+ intentFilter.setPriority(100);
+ context.registerReceiver(mShutdownIntentReceiver, intentFilter);
+
if (!factoryTest) {
mNotificationMgr = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index e20e70f..8379795 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -740,7 +740,7 @@ public class SyncStorageEngine extends Handler {
}
boolean writeStatisticsNow = false;
- int day = getCurrentDay();
+ int day = getCurrentDayLocked();
if (mDayStats[0] == null) {
mDayStats[0] = new DayStats(day);
} else if (day != mDayStats[0].day) {
@@ -929,7 +929,7 @@ public class SyncStorageEngine extends Handler {
}
}
- private int getCurrentDay() {
+ private int getCurrentDayLocked() {
mCal.setTimeInMillis(System.currentTimeMillis());
final int dayOfYear = mCal.get(Calendar.DAY_OF_YEAR);
if (mYear != mCal.get(Calendar.YEAR)) {
@@ -1009,6 +1009,21 @@ public class SyncStorageEngine extends Handler {
return status;
}
+ public void writeAllState() {
+ synchronized (mAuthorities) {
+ // Account info is always written so no need to do it here.
+
+ if (mNumPendingFinished > 0) {
+ // Only write these if they are out of date.
+ writePendingOperationsLocked();
+ }
+
+ // Just always write these... they are likely out of date.
+ writeStatusLocked();
+ writeStatisticsLocked();
+ }
+ }
+
/**
* Read all account information back in to the initial engine state.
*/
diff --git a/core/java/android/os/Power.java b/core/java/android/os/Power.java
index 47497e5..3679e47 100644
--- a/core/java/android/os/Power.java
+++ b/core/java/android/os/Power.java
@@ -80,10 +80,9 @@ public class Power
public static native int setLastUserActivityTimeout(long ms);
/**
- * Turn the device off.
- *
- * This method is considered deprecated in favor of
- * {@link android.policy.ShutdownThread.shutdownAfterDisablingRadio()}.
+ * Low-level function turn the device off immediately, without trying
+ * to be clean. Most people should use
+ * {@link android.internal.app.ShutdownThread} for a clean shutdown.
*
* @deprecated
* @hide