am 6fb7fd3a: Merge "Fix issue #7267494, issue #7212347" into jb-mr1-dev

* commit '6fb7fd3a0939413d8968fc0d404ed499d7f7dc52':
  Fix issue #7267494, issue #7212347
This commit is contained in:
Dianne Hackborn
2012-10-03 18:47:51 -07:00
committed by Android Git Automerger
8 changed files with 149 additions and 79 deletions

View File

@ -4529,6 +4529,14 @@ public final class ActivityThread {
IContentProvider provider = pr.mProvider; IContentProvider provider = pr.mProvider;
IBinder jBinder = provider.asBinder(); IBinder jBinder = provider.asBinder();
if (!jBinder.isBinderAlive()) {
// The hosting process of the provider has died; we can't
// use this one.
Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
+ ": existing object's process dead");
handleUnstableProviderDiedLocked(jBinder, true);
return null;
}
// Only increment the ref count if we have one. If we don't then the // Only increment the ref count if we have one. If we don't then the
// provider is not reference counted and never needs to be released. // provider is not reference counted and never needs to be released.
@ -4669,33 +4677,37 @@ public final class ActivityThread {
} }
final void handleUnstableProviderDied(IBinder provider, boolean fromClient) { final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
synchronized(mProviderMap) { synchronized (mProviderMap) {
ProviderRefCount prc = mProviderRefCountMap.get(provider); handleUnstableProviderDiedLocked(provider, fromClient);
if (prc != null) { }
if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider " }
+ provider + " " + prc.holder.info.name);
mProviderRefCountMap.remove(provider); final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
if (prc.client != null && prc.client.mNames != null) { ProviderRefCount prc = mProviderRefCountMap.get(provider);
for (String name : prc.client.mNames) { if (prc != null) {
ProviderClientRecord pr = mProviderMap.get(name); if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
if (pr != null && pr.mProvider.asBinder() == provider) { + provider + " " + prc.holder.info.name);
Slog.i(TAG, "Removing dead content provider: " + name); mProviderRefCountMap.remove(provider);
mProviderMap.remove(name); if (prc.client != null && prc.client.mNames != null) {
} for (String name : prc.client.mNames) {
ProviderClientRecord pr = mProviderMap.get(name);
if (pr != null && pr.mProvider.asBinder() == provider) {
Slog.i(TAG, "Removing dead content provider: " + name);
mProviderMap.remove(name);
} }
} }
if (fromClient) { }
// We found out about this due to execution in our client if (fromClient) {
// code. Tell the activity manager about it now, to ensure // We found out about this due to execution in our client
// that the next time we go to do anything with the provider // code. Tell the activity manager about it now, to ensure
// it knows it is dead (so we don't race with its death // that the next time we go to do anything with the provider
// notification). // it knows it is dead (so we don't race with its death
try { // notification).
ActivityManagerNative.getDefault().unstableProviderDied( try {
prc.holder.connection); ActivityManagerNative.getDefault().unstableProviderDied(
} catch (RemoteException e) { prc.holder.connection);
//do nothing content provider object is dead any way } catch (RemoteException e) {
} //do nothing content provider object is dead any way
} }
} }
} }

View File

@ -37,7 +37,8 @@ interface IPowerManager
void nap(long time); void nap(long time);
boolean isScreenOn(); boolean isScreenOn();
void reboot(String reason); void reboot(boolean confirm, String reason, boolean wait);
void shutdown(boolean confirm, boolean wait);
void crash(String message); void crash(String message);
void setStayOnSetting(int val); void setStayOnSetting(int val);

View File

@ -596,7 +596,7 @@ public final class PowerManager {
*/ */
public void reboot(String reason) { public void reboot(String reason) {
try { try {
mService.reboot(reason); mService.reboot(false, reason, true);
} catch (RemoteException e) { } catch (RemoteException e) {
} }
} }

View File

@ -127,6 +127,8 @@ public final class BatteryService extends Binder {
private long mDischargeStartTime; private long mDischargeStartTime;
private int mDischargeStartLevel; private int mDischargeStartLevel;
private boolean mUpdatesStopped;
private Led mLed; private Led mLed;
private boolean mSentLowBatteryBroadcast = false; private boolean mSentLowBatteryBroadcast = false;
@ -231,7 +233,7 @@ public final class BatteryService extends Binder {
Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN); Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false); intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent); mContext.startActivityAsUser(intent, UserHandle.CURRENT);
} }
} }
@ -244,16 +246,18 @@ public final class BatteryService extends Binder {
Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN); Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false); intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent); mContext.startActivityAsUser(intent, UserHandle.CURRENT);
} }
} }
private void updateLocked() { private void updateLocked() {
// Update the values of mAcOnline, et. all. if (!mUpdatesStopped) {
native_update(); // Update the values of mAcOnline, et. all.
native_update();
// Process the new values. // Process the new values.
processValuesLocked(); processValuesLocked();
}
} }
private void processValuesLocked() { private void processValuesLocked() {
@ -543,6 +547,9 @@ public final class BatteryService extends Binder {
synchronized (mLock) { synchronized (mLock) {
if (args == null || args.length == 0 || "-a".equals(args[0])) { if (args == null || args.length == 0 || "-a".equals(args[0])) {
pw.println("Current Battery Service state:"); pw.println("Current Battery Service state:");
if (mUpdatesStopped) {
pw.println(" (UPDATES STOPPED -- use 'reset' to restart)");
}
pw.println(" AC powered: " + mAcOnline); pw.println(" AC powered: " + mAcOnline);
pw.println(" USB powered: " + mUsbOnline); pw.println(" USB powered: " + mUsbOnline);
pw.println(" Wireless powered: " + mWirelessOnline); pw.println(" Wireless powered: " + mWirelessOnline);
@ -554,35 +561,41 @@ public final class BatteryService extends Binder {
pw.println(" voltage:" + mBatteryVoltage); pw.println(" voltage:" + mBatteryVoltage);
pw.println(" temperature: " + mBatteryTemperature); pw.println(" temperature: " + mBatteryTemperature);
pw.println(" technology: " + mBatteryTechnology); pw.println(" technology: " + mBatteryTechnology);
} else if (false) { } else if (args.length == 3 && "set".equals(args[0])) {
// DO NOT SUBMIT WITH THIS TURNED ON String key = args[1];
if (args.length == 3 && "set".equals(args[0])) { String value = args[2];
String key = args[1]; try {
String value = args[2]; boolean update = true;
try { if ("ac".equals(key)) {
boolean update = true; mAcOnline = Integer.parseInt(value) != 0;
if ("ac".equals(key)) { } else if ("usb".equals(key)) {
mAcOnline = Integer.parseInt(value) != 0; mUsbOnline = Integer.parseInt(value) != 0;
} else if ("usb".equals(key)) { } else if ("wireless".equals(key)) {
mUsbOnline = Integer.parseInt(value) != 0; mWirelessOnline = Integer.parseInt(value) != 0;
} else if ("wireless".equals(key)) { } else if ("status".equals(key)) {
mWirelessOnline = Integer.parseInt(value) != 0; mBatteryStatus = Integer.parseInt(value);
} else if ("status".equals(key)) { } else if ("level".equals(key)) {
mBatteryStatus = Integer.parseInt(value); mBatteryLevel = Integer.parseInt(value);
} else if ("level".equals(key)) { } else if ("invalid".equals(key)) {
mBatteryLevel = Integer.parseInt(value); mInvalidCharger = Integer.parseInt(value);
} else if ("invalid".equals(key)) { } else {
mInvalidCharger = Integer.parseInt(value); pw.println("Unknown set option: " + key);
} else { update = false;
update = false;
}
if (update) {
processValuesLocked();
}
} catch (NumberFormatException ex) {
pw.println("Bad value: " + value);
} }
if (update) {
mUpdatesStopped = true;
processValuesLocked();
}
} catch (NumberFormatException ex) {
pw.println("Bad value: " + value);
} }
} else if (args.length == 1 && "reset".equals(args[0])) {
mUpdatesStopped = false;
updateLocked();
} else {
pw.println("Dump current battery state, or:");
pw.println(" set ac|usb|wireless|status|level|invalid <value>");
pw.println(" reset");
} }
} }
} }

View File

@ -17,9 +17,13 @@
package com.android.server; package com.android.server;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IPowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Slog; import android.util.Slog;
import com.android.server.power.ShutdownThread; import com.android.server.power.ShutdownThread;
@ -39,15 +43,27 @@ public class ShutdownActivity extends Activity {
mConfirm = intent.getBooleanExtra(Intent.EXTRA_KEY_CONFIRM, false); mConfirm = intent.getBooleanExtra(Intent.EXTRA_KEY_CONFIRM, false);
Slog.i(TAG, "onCreate(): confirm=" + mConfirm); Slog.i(TAG, "onCreate(): confirm=" + mConfirm);
Handler h = new Handler(); Thread thr = new Thread("ShutdownActivity") {
h.post(new Runnable() { @Override
public void run() { public void run() {
if (mReboot) { IPowerManager pm = IPowerManager.Stub.asInterface(
ShutdownThread.reboot(ShutdownActivity.this, null, mConfirm); ServiceManager.getService(Context.POWER_SERVICE));
} else { try {
ShutdownThread.shutdown(ShutdownActivity.this, mConfirm); if (mReboot) {
pm.reboot(mConfirm, null, false);
} else {
pm.shutdown(mConfirm, false);
}
} catch (RemoteException e) {
} }
} }
}); };
thr.start();
finish();
// Wait for us to tell the power manager to shutdown.
try {
thr.join();
} catch (InterruptedException e) {
}
} }
} }

View File

@ -305,7 +305,7 @@ public class Watchdog extends Thread {
void rebootSystem(String reason) { void rebootSystem(String reason) {
Slog.i(TAG, "Rebooting system because: " + reason); Slog.i(TAG, "Rebooting system because: " + reason);
PowerManagerService pms = (PowerManagerService) ServiceManager.getService("power"); PowerManagerService pms = (PowerManagerService) ServiceManager.getService("power");
pms.reboot(reason); pms.reboot(false, reason, false);
} }
/** /**

View File

@ -1602,22 +1602,39 @@ public final class PowerManagerService extends IPowerManager.Stub
} }
/** /**
* Reboot the device immediately, passing 'reason' (may be null) * Reboot the device, passing 'reason' (may be null)
* to the underlying __reboot system call. Should not return. * to the underlying __reboot system call. Should not return.
*/ */
@Override // Binder call @Override // Binder call
public void reboot(String reason) { public void reboot(boolean confirm, String reason, boolean wait) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
final long ident = Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity();
try { try {
rebootInternal(reason); rebootInternal(false, confirm, reason, wait);
} finally { } finally {
Binder.restoreCallingIdentity(ident); Binder.restoreCallingIdentity(ident);
} }
} }
private void rebootInternal(final String reason) { /**
* Shutdown the devic, passing 'reason' (may be null)
* to the underlying __reboot system call. Should not return.
*/
@Override // Binder call
public void shutdown(boolean confirm, boolean wait) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
final long ident = Binder.clearCallingIdentity();
try {
rebootInternal(true, confirm, null, wait);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
private void rebootInternal(final boolean shutdown, final boolean confirm,
final String reason, boolean wait) {
if (mHandler == null || !mSystemReady) { if (mHandler == null || !mSystemReady) {
throw new IllegalStateException("Too early to call reboot()"); throw new IllegalStateException("Too early to call reboot()");
} }
@ -1625,7 +1642,11 @@ public final class PowerManagerService extends IPowerManager.Stub
Runnable runnable = new Runnable() { Runnable runnable = new Runnable() {
public void run() { public void run() {
synchronized (this) { synchronized (this) {
ShutdownThread.reboot(mContext, reason, false); if (shutdown) {
ShutdownThread.shutdown(mContext, confirm);
} else {
ShutdownThread.reboot(mContext, reason, confirm);
}
} }
} }
}; };
@ -1636,11 +1657,13 @@ public final class PowerManagerService extends IPowerManager.Stub
mHandler.sendMessage(msg); mHandler.sendMessage(msg);
// PowerManager.reboot() is documented not to return so just wait for the inevitable. // PowerManager.reboot() is documented not to return so just wait for the inevitable.
synchronized (runnable) { if (wait) {
while (true) { synchronized (runnable) {
try { while (true) {
runnable.wait(); try {
} catch (InterruptedException e) { runnable.wait();
} catch (InterruptedException e) {
}
} }
} }
} }

View File

@ -60,7 +60,12 @@ public class BridgePowerManager implements IPowerManager {
} }
@Override @Override
public void reboot(String arg0) throws RemoteException { public void reboot(boolean confirm, String reason, boolean wait) {
// pass for now.
}
@Override
public void shutdown(boolean confirm, boolean wait) {
// pass for now. // pass for now.
} }