diff options
Diffstat (limited to 'services')
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; |