* commit '6fb7fd3a0939413d8968fc0d404ed499d7f7dc52': Fix issue #7267494, issue #7212347
This commit is contained in:
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user