summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java59
-rw-r--r--services/core/java/com/android/server/location/LocationBasedCountryDetector.java40
-rw-r--r--services/core/java/com/android/server/notification/CalendarTracker.java4
-rw-r--r--services/core/java/com/android/server/notification/EventConditionProvider.java2
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java51
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java25
-rw-r--r--services/core/java/com/android/server/pm/Settings.java2
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java2
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java13
-rw-r--r--services/core/java/com/android/server/power/ShutdownThread.java157
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java12
-rw-r--r--services/core/jni/com_android_server_location_GpsLocationProvider.cpp6
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java45
13 files changed, 323 insertions, 95 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6e1b434..706e965 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -39,6 +39,8 @@ import static org.xmlpull.v1.XmlPullParser.START_TAG;
import android.Manifest;
import android.app.AppOpsManager;
import android.app.ApplicationThreadNative;
+import android.app.AssistContent;
+import android.app.AssistStructure;
import android.app.IActivityContainer;
import android.app.IActivityContainerCallback;
import android.app.IAppTask;
@@ -360,6 +362,10 @@ public final class ActivityManagerService extends ActivityManagerNative
// to respond with the result.
static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
+ // How long top wait when going through the modern assist (which doesn't need to block
+ // on getting this result before starting to launch its UI).
+ static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
+
// Maximum number of persisted Uri grants a package is allowed
static final int MAX_PERSISTED_URI_GRANTS = 128;
@@ -477,6 +483,8 @@ public final class ActivityManagerService extends ActivityManagerNative
public final int userHandle;
public boolean haveResult = false;
public Bundle result = null;
+ public AssistStructure structure = null;
+ public AssistContent content = null;
public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
String _hint, IResultReceiver _receiver, int _userHandle) {
activity = _activity;
@@ -8529,13 +8537,16 @@ public final class ActivityManagerService extends ActivityManagerNative
return;
}
+ // Find any running services associated with this app and stop if needed.
+ mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
+
if (!killProcess) {
return;
}
// Determine if the process(es) for this task should be killed.
final String pkg = component.getPackageName();
- ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
+ ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
for (int i = 0; i < pmap.size(); i++) {
@@ -8564,20 +8575,24 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ if (proc.foregroundServices) {
+ // Don't kill process(es) with foreground service.
+ return;
+ }
+
// Add process to kill list.
procsToKill.add(proc);
}
}
- // Find any running services associated with this app and stop if needed.
- mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
-
// Kill the running processes.
for (int i = 0; i < procsToKill.size(); i++) {
ProcessRecord pr = procsToKill.get(i);
- if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
+ if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
+ && pr.curReceiver == null) {
pr.kill("remove task", true);
} else {
+ // We delay killing processes that are not in the background or running a receiver.
pr.waitingToKill = "remove task";
}
}
@@ -10617,7 +10632,7 @@ public final class ActivityManagerService extends ActivityManagerNative
@Override
public Bundle getAssistContextExtras(int requestType) {
PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
- UserHandle.getCallingUserId());
+ UserHandle.getCallingUserId(), PENDING_ASSIST_EXTRAS_TIMEOUT);
if (pae == null) {
return null;
}
@@ -10639,11 +10654,12 @@ public final class ActivityManagerService extends ActivityManagerNative
@Override
public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
- enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId());
+ enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId(),
+ PENDING_ASSIST_EXTRAS_LONG_TIMEOUT);
}
private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
- IResultReceiver receiver, int userHandle) {
+ IResultReceiver receiver, int userHandle, long timeout) {
enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
"enqueueAssistContext()");
synchronized (this) {
@@ -10669,7 +10685,7 @@ public final class ActivityManagerService extends ActivityManagerNative
activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
requestType);
mPendingAssistExtras.add(pae);
- mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
+ mHandler.postDelayed(pae, timeout);
} catch (RemoteException e) {
Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
return null;
@@ -10698,10 +10714,13 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- public void reportAssistContextExtras(IBinder token, Bundle extras) {
+ public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
+ AssistContent content) {
PendingAssistExtras pae = (PendingAssistExtras)token;
synchronized (pae) {
pae.result = extras;
+ pae.structure = structure;
+ pae.content = content;
pae.haveResult = true;
pae.notifyAll();
if (pae.intent == null && pae.receiver == null) {
@@ -10721,8 +10740,12 @@ public final class ActivityManagerService extends ActivityManagerNative
}
if (pae.receiver != null) {
// Caller wants result sent back to them.
+ Bundle topBundle = new Bundle();
+ topBundle.putBundle("data", pae.extras);
+ topBundle.putParcelable("structure", pae.structure);
+ topBundle.putParcelable("content", pae.content);
try {
- pae.receiver.send(0, pae.extras);
+ pae.receiver.send(0, topBundle);
} catch (RemoteException e) {
}
return;
@@ -10741,7 +10764,8 @@ public final class ActivityManagerService extends ActivityManagerNative
}
public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
- return enqueueAssistContext(requestType, intent, hint, null, userHandle) != null;
+ return enqueueAssistContext(requestType, intent, hint, null, userHandle,
+ PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
}
public void registerProcessObserver(IProcessObserver observer) {
@@ -18327,8 +18351,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- private final boolean applyOomAdjLocked(ProcessRecord app,
- ProcessRecord TOP_APP, boolean doingAll, long now) {
+ private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
boolean success = true;
if (app.curRawAdj != app.setRawAdj) {
@@ -18350,8 +18373,8 @@ public final class ActivityManagerService extends ActivityManagerNative
if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
"Setting process group of " + app.processName
+ " to " + app.curSchedGroup);
- if (app.waitingToKill != null &&
- app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
+ if (app.waitingToKill != null && app.curReceiver == null
+ && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
app.kill(app.waitingToKill, true);
success = false;
} else {
@@ -18581,7 +18604,7 @@ public final class ActivityManagerService extends ActivityManagerNative
computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
- return applyOomAdjLocked(app, TOP_APP, doingAll, now);
+ return applyOomAdjLocked(app, doingAll, now);
}
final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
@@ -18799,7 +18822,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- applyOomAdjLocked(app, TOP_APP, true, now);
+ applyOomAdjLocked(app, true, now);
// Count the number of process types.
switch (app.curProcState) {
diff --git a/services/core/java/com/android/server/location/LocationBasedCountryDetector.java b/services/core/java/com/android/server/location/LocationBasedCountryDetector.java
index 03db621..6527899 100644
--- a/services/core/java/com/android/server/location/LocationBasedCountryDetector.java
+++ b/services/core/java/com/android/server/location/LocationBasedCountryDetector.java
@@ -23,6 +23,7 @@ import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
+import android.os.Binder;
import android.os.Bundle;
import android.util.Slog;
@@ -95,33 +96,48 @@ public class LocationBasedCountryDetector extends CountryDetectorBase {
* Register a listener with a provider name
*/
protected void registerListener(String provider, LocationListener listener) {
- mLocationManager.requestLocationUpdates(provider, 0, 0, listener);
+ final long bid = Binder.clearCallingIdentity();
+ try {
+ mLocationManager.requestLocationUpdates(provider, 0, 0, listener);
+ } finally {
+ Binder.restoreCallingIdentity(bid);
+ }
}
/**
* Unregister an already registered listener
*/
protected void unregisterListener(LocationListener listener) {
- mLocationManager.removeUpdates(listener);
+ final long bid = Binder.clearCallingIdentity();
+ try {
+ mLocationManager.removeUpdates(listener);
+ } finally {
+ Binder.restoreCallingIdentity(bid);
+ }
}
/**
* @return the last known location from all providers
*/
protected Location getLastKnownLocation() {
- List<String> providers = mLocationManager.getAllProviders();
- Location bestLocation = null;
- for (String provider : providers) {
- Location lastKnownLocation = mLocationManager.getLastKnownLocation(provider);
- if (lastKnownLocation != null) {
- if (bestLocation == null ||
- bestLocation.getElapsedRealtimeNanos() <
- lastKnownLocation.getElapsedRealtimeNanos()) {
- bestLocation = lastKnownLocation;
+ final long bid = Binder.clearCallingIdentity();
+ try {
+ List<String> providers = mLocationManager.getAllProviders();
+ Location bestLocation = null;
+ for (String provider : providers) {
+ Location lastKnownLocation = mLocationManager.getLastKnownLocation(provider);
+ if (lastKnownLocation != null) {
+ if (bestLocation == null ||
+ bestLocation.getElapsedRealtimeNanos() <
+ lastKnownLocation.getElapsedRealtimeNanos()) {
+ bestLocation = lastKnownLocation;
+ }
}
}
+ return bestLocation;
+ } finally {
+ Binder.restoreCallingIdentity(bid);
}
- return bestLocation;
}
/**
diff --git a/services/core/java/com/android/server/notification/CalendarTracker.java b/services/core/java/com/android/server/notification/CalendarTracker.java
index de321fe..783b16f 100644
--- a/services/core/java/com/android/server/notification/CalendarTracker.java
+++ b/services/core/java/com/android/server/notification/CalendarTracker.java
@@ -16,8 +16,6 @@
package com.android.server.notification;
-import static android.service.notification.ZenModeConfig.EventInfo.ANY_CALENDAR;
-
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
@@ -183,7 +181,7 @@ public class CalendarTracker {
calendarPrimary));
final boolean meetsTime = time >= begin && time < end;
final boolean meetsCalendar = calendarVisible && calendarPrimary
- && (filter.calendar == ANY_CALENDAR || filter.calendar == calendarId);
+ && (filter.calendar == null || Objects.equals(filter.calendar, owner));
final boolean meetsAvailability = availability != Instances.AVAILABILITY_FREE;
if (meetsCalendar && meetsAvailability) {
if (DEBUG) Log.d(TAG, " MEETS CALENDAR & AVAILABILITY");
diff --git a/services/core/java/com/android/server/notification/EventConditionProvider.java b/services/core/java/com/android/server/notification/EventConditionProvider.java
index 46cc47b..88ef366 100644
--- a/services/core/java/com/android/server/notification/EventConditionProvider.java
+++ b/services/core/java/com/android/server/notification/EventConditionProvider.java
@@ -211,7 +211,7 @@ public class EventConditionProvider extends SystemConditionProviderService {
continue;
}
CheckEventResult result = null;
- if (event.calendar == EventInfo.ANY_CALENDAR) {
+ if (event.calendar == null) { // any calendar
// event could exist on any tracker
for (int i = 0; i < mTrackers.size(); i++) {
final CalendarTracker tracker = mTrackers.valueAt(i);
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 755b2ea..eafcae4 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -37,6 +37,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings.Global;
import android.service.notification.IConditionListener;
@@ -48,6 +49,7 @@ import android.util.ArraySet;
import android.util.Log;
import android.util.SparseArray;
+import com.android.internal.logging.MetricsLogger;
import com.android.internal.R;
import com.android.server.LocalServices;
@@ -79,6 +81,7 @@ public class ZenModeHelper {
private final RingerModeDelegate mRingerModeDelegate = new RingerModeDelegate();
private final ZenModeConditions mConditions;
private final SparseArray<ZenModeConfig> mConfigs = new SparseArray<>();
+ private final Metrics mMetrics = new Metrics();
private int mZenMode;
private int mUser = UserHandle.USER_OWNER;
@@ -90,6 +93,7 @@ public class ZenModeHelper {
public ZenModeHelper(Context context, Looper looper, ConditionProviders conditionProviders) {
mContext = context;
mHandler = new H(looper);
+ addCallback(mMetrics);
mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
mDefaultConfig = readDefaultConfig(context.getResources());
appendDefaultScheduleRules(mDefaultConfig);
@@ -144,6 +148,7 @@ public class ZenModeHelper {
if (mAudioManager != null) {
mAudioManager.setRingerModeDelegate(mRingerModeDelegate);
}
+ mHandler.postMetricsTimer();
}
public void onUserSwitched(int user) {
@@ -265,6 +270,13 @@ public class ZenModeHelper {
return;
}
config.manualRule = null; // don't restore the manual rule
+ if (config.automaticRules != null) {
+ for (ZenModeConfig.ZenRule automaticRule : config.automaticRules.values()) {
+ // don't restore transient state from restored automatic rules
+ automaticRule.snoozing = false;
+ automaticRule.condition = null;
+ }
+ }
}
if (DEBUG) Log.d(TAG, "readXml");
setConfig(config, "readXml");
@@ -498,7 +510,7 @@ public class ZenModeHelper {
if (config == null) return;
final EventInfo events = new EventInfo();
- events.calendar = EventInfo.ANY_CALENDAR;
+ events.calendar = null; // any calendar
events.reply = EventInfo.REPLY_YES_OR_MAYBE;
final ZenRule rule = new ZenRule();
rule.enabled = false;
@@ -689,8 +701,37 @@ public class ZenModeHelper {
}
}
+ private final class Metrics extends Callback {
+ private static final String COUNTER_PREFIX = "dnd_mode_";
+ private static final long MINIMUM_LOG_PERIOD_MS = 60 * 1000;
+
+ private int mPreviousZenMode = -1;
+ private long mBeginningMs = 0L;
+
+ @Override
+ void onZenModeChanged() {
+ emit();
+ }
+
+ private void emit() {
+ mHandler.postMetricsTimer();
+ final long now = SystemClock.elapsedRealtime();
+ final long since = (now - mBeginningMs);
+ if (mPreviousZenMode != mZenMode || since > MINIMUM_LOG_PERIOD_MS) {
+ if (mPreviousZenMode != -1) {
+ MetricsLogger.count(mContext, COUNTER_PREFIX + mPreviousZenMode, (int) since);
+ }
+ mPreviousZenMode = mZenMode;
+ mBeginningMs = now;
+ }
+ }
+ }
+
private final class H extends Handler {
private static final int MSG_DISPATCH = 1;
+ private static final int MSG_METRICS = 2;
+
+ private static final long METRICS_PERIOD_MS = 6 * 60 * 60 * 1000;
private H(Looper looper) {
super(looper);
@@ -701,12 +742,20 @@ public class ZenModeHelper {
sendEmptyMessage(MSG_DISPATCH);
}
+ private void postMetricsTimer() {
+ removeMessages(MSG_METRICS);
+ sendEmptyMessageDelayed(MSG_METRICS, METRICS_PERIOD_MS);
+ }
+
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_DISPATCH:
dispatchOnZenModeChanged();
break;
+ case MSG_METRICS:
+ mMetrics.emit();
+ break;
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3531796..f9bfe72 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -303,6 +303,7 @@ public class PackageManagerService extends IPackageManager.Stub {
static final int SCAN_TRUSTED_OVERLAY = 1<<9;
static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
static final int SCAN_REQUIRE_KNOWN = 1<<12;
+ static final int SCAN_MOVE = 1<<13;
static final int REMOVE_CHATTY = 1<<16;
@@ -6347,16 +6348,19 @@ public class PackageManagerService extends IPackageManager.Stub {
if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
deriveNonSystemPackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
} else {
- // TODO: We need this second call to derive in two cases :
- //
- // - To update the native library paths based on the final install location.
- // - We don't call dexopt when moving packages, and so we have to scan again.
- //
- // We can simplify this and avoid having to scan the package again by letting
- // scanPackageLI know if the current install was a move (and deriving things only
- // in that case) and by "reparenting" the native lib directory in the case of
- // a normal (non-move) install.
- deriveNonSystemPackageAbi(pkg, scanFile, cpuAbiOverride, false /* extract libs */);
+ if ((scanFlags & SCAN_MOVE) != 0) {
+ // We haven't run dex-opt for this move (since we've moved the compiled output too)
+ // but we already have this packages package info in the PackageSetting. We just
+ // use that and derive the native library path based on the new codepath.
+ pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
+ pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
+ }
+
+ // Set native library paths again. For moves, the path will be updated based on the
+ // ABIs we've determined above. For non-moves, the path will be updated based on the
+ // ABIs we determined during compilation, but the path will depend on the final
+ // package path (after the rename away from the stage path).
+ setNativeLibraryPaths(pkg);
}
if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
@@ -11645,6 +11649,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (args.move != null) {
// We did an in-place move, so dex is ready to roll
scanFlags |= SCAN_NO_DEX;
+ scanFlags |= SCAN_MOVE;
} else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
// Enable SCAN_NO_DEX flag to skip dexopt at a later stage
scanFlags |= SCAN_NO_DEX;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index d2a135c..8f2db30 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4386,7 +4386,7 @@ final class Settings {
FileInputStream in;
try {
- in = new FileInputStream(permissionsFile);
+ in = new AtomicFile(permissionsFile).openRead();
} catch (FileNotFoundException fnfe) {
Slog.i(PackageManagerService.TAG, "No permissions state");
return;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 671c44e..6a63aab 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -4264,7 +4264,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// that is being hidden in an animation - keep the
// keyguard hidden until the new window shows up and
// we know whether to show the keyguard or not.
- if (win.isAnimatingLw() && appWindow && showWhenLocked) {
+ if (win.isAnimatingLw() && appWindow && showWhenLocked && mKeyguardHidden) {
mHideLockScreen = true;
mWinShowWhenLocked = win;
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 5aea746..1b5391e 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -2518,8 +2518,7 @@ public final class PowerManagerService extends SystemService
/**
* Low-level function to reboot the device. On success, this
* function doesn't return. If more than 20 seconds passes from
- * the time a reboot is requested (120 seconds for reboot to
- * recovery), this method returns.
+ * the time a reboot is requested, this method returns.
*
* @param reason code to pass to the kernel (e.g. "recovery"), or null.
*/
@@ -2527,27 +2526,21 @@ public final class PowerManagerService extends SystemService
if (reason == null) {
reason = "";
}
- long duration;
if (reason.equals(PowerManager.REBOOT_RECOVERY)) {
// If we are rebooting to go into recovery, instead of
// setting sys.powerctl directly we'll start the
// pre-recovery service which will do some preparation for
// recovery and then reboot for us.
- //
- // This preparation can take more than 20 seconds if
- // there's a very large update package, so lengthen the
- // timeout. We have seen 750MB packages take 3-4 minutes
SystemProperties.set("ctl.start", "pre-recovery");
- duration = 300 * 1000L;
} else {
SystemProperties.set("sys.powerctl", "reboot," + reason);
- duration = 20 * 1000L;
}
try {
- Thread.sleep(duration);
+ Thread.sleep(20 * 1000L);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
+ Slog.wtf(TAG, "Unexpected return from lowLevelReboot!");
}
@Override // Watchdog.Monitor implementation
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 84eab42..e5981fb 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-
+
package com.android.server.power;
import android.app.ActivityManagerNative;
@@ -44,6 +44,8 @@ import android.os.Vibrator;
import android.os.SystemVibrator;
import android.os.storage.IMountService;
import android.os.storage.IMountShutdownObserver;
+import android.system.ErrnoException;
+import android.system.Os;
import com.android.internal.telephony.ITelephony;
import com.android.server.pm.PackageManagerService;
@@ -51,6 +53,11 @@ import com.android.server.pm.PackageManagerService;
import android.util.Log;
import android.view.WindowManager;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
public final class ShutdownThread extends Thread {
// constants
private static final String TAG = "ShutdownThread";
@@ -59,14 +66,18 @@ public final class ShutdownThread extends Thread {
private static final int MAX_BROADCAST_TIME = 10*1000;
private static final int MAX_SHUTDOWN_WAIT_TIME = 20*1000;
private static final int MAX_RADIO_WAIT_TIME = 12*1000;
+ private static final int MAX_UNCRYPT_WAIT_TIME = 15*60*1000;
// length of vibration before shutting down
private static final int SHUTDOWN_VIBRATE_MS = 500;
-
+
// state tracking
private static Object sIsStartedGuard = new Object();
private static boolean sIsStarted = false;
-
+
+ // uncrypt status file
+ private static final String UNCRYPT_STATUS_FILE = "/cache/recovery/uncrypt_status";
+
private static boolean mReboot;
private static boolean mRebootSafeMode;
private static String mRebootReason;
@@ -94,10 +105,11 @@ public final class ShutdownThread extends Thread {
private Handler mHandler;
private static AlertDialog sConfirmDialog;
-
+ private ProgressDialog mProgressDialog;
+
private ShutdownThread() {
}
-
+
/**
* Request a clean shutdown, waiting for subsystems to clean up their
* state etc. Must be called from a Looper thread in which its UI
@@ -226,7 +238,11 @@ public final class ShutdownThread extends Thread {
// throw up an indeterminate system dialog to indicate radio is
// shutting down.
ProgressDialog pd = new ProgressDialog(context);
- pd.setTitle(context.getText(com.android.internal.R.string.power_off));
+ if (PowerManager.REBOOT_RECOVERY.equals(mRebootReason)) {
+ pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_recovery_title));
+ } else {
+ pd.setTitle(context.getText(com.android.internal.R.string.power_off));
+ }
pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
pd.setIndeterminate(true);
pd.setCancelable(false);
@@ -234,6 +250,7 @@ public final class ShutdownThread extends Thread {
pd.show();
+ sInstance.mProgressDialog = pd;
sInstance.mContext = context;
sInstance.mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
@@ -307,14 +324,14 @@ public final class ShutdownThread extends Thread {
}
Log.i(TAG, "Sending shutdown broadcast...");
-
+
// First send the high-level shut down broadcast.
mActionDone = false;
Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
mContext.sendOrderedBroadcastAsUser(intent,
UserHandle.ALL, null, br, mHandler, 0, null, null);
-
+
final long endTime = SystemClock.elapsedRealtime() + MAX_BROADCAST_TIME;
synchronized (mActionDoneSync) {
while (!mActionDone) {
@@ -329,9 +346,9 @@ public final class ShutdownThread extends Thread {
}
}
}
-
+
Log.i(TAG, "Shutting down activity manager...");
-
+
final IActivityManager am =
ActivityManagerNative.asInterface(ServiceManager.checkService("activity"));
if (am != null) {
@@ -390,9 +407,55 @@ public final class ShutdownThread extends Thread {
}
}
+ // If it's to reboot into recovery, invoke uncrypt via init service.
+ if (mRebootReason.equals(PowerManager.REBOOT_RECOVERY)) {
+ uncrypt();
+ }
+
rebootOrShutdown(mContext, mReboot, mRebootReason);
}
+ private void prepareUncryptProgress() {
+ // Reset the dialog message to show the decrypt process.
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mProgressDialog != null) {
+ mProgressDialog.dismiss();
+ }
+ // It doesn't work to change the style of the existing
+ // one. Have to create a new one.
+ ProgressDialog pd = new ProgressDialog(mContext);
+
+ pd.setTitle(mContext.getText(
+ com.android.internal.R.string.reboot_to_recovery_title));
+ pd.setMessage(mContext.getText(
+ com.android.internal.R.string.reboot_to_recovery_progress));
+ pd.setIndeterminate(false);
+ pd.setMax(100);
+ pd.setCancelable(false);
+ pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+ pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+ pd.setProgressNumberFormat(null);
+ pd.setProgress(0);
+
+ mProgressDialog = pd;
+ mProgressDialog.show();
+ }
+ });
+ }
+
+ private void setUncryptProgress(final int progress) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mProgressDialog != null) {
+ mProgressDialog.setProgress(progress);
+ }
+ }
+ });
+ }
+
private void shutdownRadios(int timeout) {
// If a radio is wedged, disabling it may hang so we do this work in another thread,
// just in case.
@@ -537,4 +600,78 @@ public final class ShutdownThread extends Thread {
Log.i(TAG, "Performing low-level shutdown...");
PowerManagerService.lowLevelShutdown();
}
+
+ private void uncrypt() {
+ Log.i(TAG, "Calling uncrypt and monitoring the progress...");
+
+ // Update the ProcessDialog message and style.
+ sInstance.prepareUncryptProgress();
+
+ final boolean[] done = new boolean[1];
+ done[0] = false;
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ // Create the status pipe file to communicate with /system/bin/uncrypt.
+ new File(UNCRYPT_STATUS_FILE).delete();
+ try {
+ Os.mkfifo(UNCRYPT_STATUS_FILE, 0600);
+ } catch (ErrnoException e) {
+ Log.w(TAG, "ErrnoException when creating named pipe \"" + UNCRYPT_STATUS_FILE +
+ "\": " + e.getMessage());
+ }
+
+ SystemProperties.set("ctl.start", "uncrypt");
+
+ // Read the status from the pipe.
+ try (BufferedReader reader = new BufferedReader(
+ new FileReader(UNCRYPT_STATUS_FILE))) {
+
+ int last_status = Integer.MIN_VALUE;
+ while (true) {
+ String str = reader.readLine();
+ try {
+ int status = Integer.parseInt(str);
+
+ // Avoid flooding the log with the same message.
+ if (status == last_status && last_status != Integer.MIN_VALUE) {
+ continue;
+ }
+ last_status = status;
+
+ if (status >= 0 && status < 100) {
+ // Update status
+ Log.d(TAG, "uncrypt read status: " + status);
+ sInstance.setUncryptProgress(status);
+ } else if (status == 100) {
+ Log.d(TAG, "uncrypt successfully finished.");
+ sInstance.setUncryptProgress(status);
+ break;
+ } else {
+ // Error in /system/bin/uncrypt. Or it's rebooting to recovery
+ // to perform other operations (e.g. factory reset).
+ Log.d(TAG, "uncrypt failed with status: " + status);
+ break;
+ }
+ } catch (NumberFormatException unused) {
+ Log.d(TAG, "uncrypt invalid status received: " + str);
+ break;
+ }
+ }
+ } catch (IOException unused) {
+ Log.w(TAG, "IOException when reading \"" + UNCRYPT_STATUS_FILE + "\".");
+ }
+ done[0] = true;
+ }
+ };
+ t.start();
+
+ try {
+ t.join(MAX_UNCRYPT_WAIT_TIME);
+ } catch (InterruptedException unused) {
+ }
+ if (!done[0]) {
+ Log.w(TAG, "Timed out waiting for uncrypt.");
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 5d8979f..6042c27 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -466,6 +466,8 @@ public class WindowManagerService extends IWindowManager.Stub
boolean mShowingBootMessages = false;
boolean mBootAnimationStopped = false;
+ /** Dump of the windows and app tokens at the time of the last ANR. Cleared after
+ * LAST_ANR_LIFETIME_DURATION_MSECS */
String mLastANRState;
/** All DisplayContents in the world, kept here */
@@ -1025,7 +1027,7 @@ public class WindowManagerService extends IWindowManager.Stub
private void placeWindowAfter(WindowState pos, WindowState window) {
final WindowList windows = pos.getWindowList();
final int i = windows.indexOf(pos);
- if (true || DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
+ if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
TAG, "Adding window " + window + " at "
+ (i+1) + " of " + windows.size() + " (after " + pos + ")");
windows.add(i+1, window);
@@ -1035,7 +1037,7 @@ public class WindowManagerService extends IWindowManager.Stub
private void placeWindowBefore(WindowState pos, WindowState window) {
final WindowList windows = pos.getWindowList();
int i = windows.indexOf(pos);
- if (true || DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
+ if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
TAG, "Adding window " + window + " at "
+ i + " of " + windows.size() + " (before " + pos + ")");
if (i < 0) {
@@ -1133,7 +1135,7 @@ public class WindowManagerService extends IWindowManager.Stub
//apptoken note that the window could be a floating window
//that was created later or a window at the top of the list of
//windows associated with this token.
- if (true || DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
+ if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
"not Base app: Adding window " + win + " at " + (newIdx + 1) + " of " +
N);
windows.add(newIdx + 1, win);
@@ -1255,7 +1257,7 @@ public class WindowManagerService extends IWindowManager.Stub
break;
}
}
- if (true || DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
+ if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
"Based on layer: Adding window " + win + " at " + (i + 1) + " of " + N);
windows.add(i + 1, win);
mWindowsChanged = true;
@@ -3720,7 +3722,7 @@ public class WindowManagerService extends IWindowManager.Stub
atoken.layoutConfigChanges = (configChanges &
(ActivityInfo.CONFIG_SCREEN_SIZE | ActivityInfo.CONFIG_ORIENTATION)) != 0;
atoken.mLaunchTaskBehind = launchTaskBehind;
- if (true || DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
+ if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
+ " to stack=" + stackId + " task=" + taskId + " at " + addPos);
Task task = mTaskIdToTask.get(taskId);
diff --git a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
index 3804e1d..5c27b1f 100644
--- a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
@@ -220,9 +220,9 @@ static void agps_status_callback(AGpsStatus* agps_status)
case AF_INET:
{
struct sockaddr_in *in = (struct sockaddr_in*)&(agps_status->addr);
- uint32_t *pAddr = (uint32_t*)&(in->sin_addr);
- byteArray = convert_to_ipv4(*pAddr, true /* net_order */);
- if (byteArray != NULL) {
+ uint32_t ipAddr = *(uint32_t*)&(in->sin_addr);
+ byteArray = convert_to_ipv4(ipAddr, true /* net_order */);
+ if (ipAddr == INADDR_NONE || byteArray != NULL) {
isSupported = true;
}
IF_ALOGD() {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 03abfba..1117373 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -20,6 +20,7 @@ import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.AppOpsManager;
import android.app.AssistContent;
+import android.app.AssistStructure;
import android.app.IActivityManager;
import android.content.ClipData;
import android.content.ComponentName;
@@ -291,33 +292,37 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
return;
}
if (mHaveAssistData) {
+ Bundle assistData;
+ AssistStructure structure;
+ AssistContent content;
if (mAssistData != null) {
+ assistData = mAssistData.getBundle("data");
+ structure = mAssistData.getParcelable("structure");
+ content = mAssistData.getParcelable("content");
int uid = mAssistData.getInt(Intent.EXTRA_ASSIST_UID, -1);
- if (uid >= 0) {
- Bundle assistContext = mAssistData.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
- if (assistContext != null) {
- AssistContent content = AssistContent.getAssistContent(assistContext);
- if (content != null) {
- Intent intent = content.getIntent();
- if (intent != null) {
- ClipData data = intent.getClipData();
- if (data != null && Intent.isAccessUriMode(intent.getFlags())) {
- grantClipDataPermissions(data, intent.getFlags(), uid,
- mCallingUid, mSessionComponentName.getPackageName());
- }
- }
- ClipData data = content.getClipData();
- if (data != null) {
- grantClipDataPermissions(data,
- Intent.FLAG_GRANT_READ_URI_PERMISSION,
- uid, mCallingUid, mSessionComponentName.getPackageName());
- }
+ if (uid >= 0 && content != null) {
+ Intent intent = content.getIntent();
+ if (intent != null) {
+ ClipData data = intent.getClipData();
+ if (data != null && Intent.isAccessUriMode(intent.getFlags())) {
+ grantClipDataPermissions(data, intent.getFlags(), uid,
+ mCallingUid, mSessionComponentName.getPackageName());
}
}
+ ClipData data = content.getClipData();
+ if (data != null) {
+ grantClipDataPermissions(data,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION,
+ uid, mCallingUid, mSessionComponentName.getPackageName());
+ }
}
+ } else {
+ assistData = null;
+ structure = null;
+ content = null;
}
try {
- mSession.handleAssist(mAssistData);
+ mSession.handleAssist(assistData, structure, content);
} catch (RemoteException e) {
}
mAssistData = null;