diff options
Diffstat (limited to 'services/core/java/com/android/server/am/ActivityManagerService.java')
-rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 201 |
1 files changed, 175 insertions, 26 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 2f3cdf7..fb65a15 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1,6 +1,8 @@ /* * Copyright (C) 2006-2008 The Android Open Source Project - * + * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc. + * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. + * Not a Contribution. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,6 +54,7 @@ import android.app.usage.UsageStatsManagerInternal; import android.appwidget.AppWidgetManager; import android.content.pm.PermissionInfo; import android.content.res.Resources; +import android.content.res.ThemeConfig; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; @@ -71,8 +74,8 @@ import android.util.ArraySet; import android.util.DebugUtils; import android.util.SparseIntArray; import android.view.Display; -import android.util.BoostFramework; +import android.view.InflateException; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.AssistUtils; @@ -171,6 +174,7 @@ import android.content.pm.InstrumentationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; +import android.content.pm.ThemeUtils; import android.content.pm.UserInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PathPermission; @@ -179,6 +183,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; +import android.content.res.ThemeConfig; import android.net.Proxy; import android.net.ProxyInfo; import android.net.Uri; @@ -389,6 +394,8 @@ public final class ActivityManagerService extends ActivityManagerNative // How many bytes to write into the dropbox log before truncating static final int DROPBOX_MAX_SIZE = 256 * 1024; + static final String PROP_REFRESH_THEME = "sys.refresh_theme"; + // Access modes for handleIncomingUser. static final int ALLOW_NON_FULL = 0; static final int ALLOW_NON_FULL_IN_PROFILE = 1; @@ -1012,6 +1019,7 @@ public final class ActivityManagerService extends ActivityManagerNative boolean mLaunchWarningShown = false; Context mContext; + Context mUiContext; int mFactoryTest; @@ -1363,6 +1371,8 @@ public final class ActivityManagerService extends ActivityManagerNative static final int REPORT_TIME_TRACKER_MSG = 55; static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56; static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57; + static final int POST_PRIVACY_NOTIFICATION_MSG = 58; + static final int CANCEL_PRIVACY_NOTIFICATION_MSG = 59; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; @@ -1435,7 +1445,7 @@ public final class ActivityManagerService extends ActivityManagerNative return; } if (mShowDialogs && !mSleeping && !mShuttingDown) { - Dialog d = new AppErrorDialog(mContext, + Dialog d = new AppErrorDialog(getUiContext(), ActivityManagerService.this, res, proc); d.show(); proc.crashDialog = d; @@ -1470,7 +1480,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (mShowDialogs) { Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, - mContext, proc, (ActivityRecord)data.get("activity"), + getUiContext(), proc, (ActivityRecord)data.get("activity"), msg.arg1 != 0); d.show(); proc.anrDialog = d; @@ -1496,7 +1506,7 @@ public final class ActivityManagerService extends ActivityManagerNative } AppErrorResult res = (AppErrorResult) data.get("result"); if (mShowDialogs && !mSleeping && !mShuttingDown) { - Dialog d = new StrictModeViolationDialog(mContext, + Dialog d = new StrictModeViolationDialog(getUiContext(), ActivityManagerService.this, res, proc); d.show(); proc.crashDialog = d; @@ -1510,7 +1520,7 @@ public final class ActivityManagerService extends ActivityManagerNative } break; case SHOW_FACTORY_ERROR_MSG: { Dialog d = new FactoryErrorDialog( - mContext, msg.getData().getCharSequence("msg")); + getUiContext(), msg.getData().getCharSequence("msg")); d.show(); ensureBootCompleted(); } break; @@ -1521,7 +1531,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (!app.waitedForDebugger) { Dialog d = new AppWaitingForDebuggerDialog( ActivityManagerService.this, - mContext, app); + getUiContext(), app); app.waitDialog = d; app.waitedForDebugger = true; d.show(); @@ -2048,6 +2058,69 @@ public final class ActivityManagerService extends ActivityManagerNative // it is finished we make sure it is reset to its default. mUserIsMonkey = false; } break; + case POST_PRIVACY_NOTIFICATION_MSG: { + INotificationManager inm = NotificationManager.getService(); + if (inm == null) { + return; + } + + ActivityRecord root = (ActivityRecord)msg.obj; + ProcessRecord process = root.app; + if (process == null) { + return; + } + + try { + Context context = mContext.createPackageContext(process.info.packageName, 0); + String text = mContext.getString(R.string.privacy_guard_notification_detail, + context.getApplicationInfo().loadLabel(context.getPackageManager())); + String title = mContext.getString(R.string.privacy_guard_notification); + + Intent infoIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, + Uri.fromParts("package", root.packageName, null)); + + Notification notification = new Notification(); + notification.icon = com.android.internal.R.drawable.stat_notify_privacy_guard; + notification.when = 0; + notification.flags = Notification.FLAG_ONGOING_EVENT; + notification.priority = Notification.PRIORITY_LOW; + notification.defaults = 0; + notification.sound = null; + notification.vibrate = null; + notification.setLatestEventInfo(mContext, + title, text, + PendingIntent.getActivityAsUser(mContext, 0, infoIntent, + PendingIntent.FLAG_CANCEL_CURRENT, null, + new UserHandle(root.userId))); + + try { + int[] outId = new int[1]; + inm.enqueueNotificationWithTag("android", "android", null, + R.string.privacy_guard_notification, + notification, outId, root.userId); + } catch (RuntimeException e) { + Slog.w(ActivityManagerService.TAG, + "Error showing notification for privacy guard", e); + } catch (RemoteException e) { + } + } catch (NameNotFoundException e) { + Slog.w(TAG, "Unable to create context for privacy guard notification", e); + } + } break; + case CANCEL_PRIVACY_NOTIFICATION_MSG: { + INotificationManager inm = NotificationManager.getService(); + if (inm == null) { + return; + } + try { + inm.cancelNotificationWithTag("android", null, + R.string.privacy_guard_notification, msg.arg1); + } catch (RuntimeException e) { + Slog.w(ActivityManagerService.TAG, + "Error canceling notification for service", e); + } catch (RemoteException e) { + } + } break; } } }; @@ -2596,6 +2669,15 @@ public final class ActivityManagerService extends ActivityManagerNative -1, Process.SYSTEM_UID, UserHandle.USER_ALL); } + private Context getUiContext() { + synchronized (this) { + if (mUiContext == null && mBooted) { + mUiContext = ThemeUtils.createUiContext(mContext); + } + return mUiContext != null ? mUiContext : mContext; + } + } + /** * Initialize the application bind args. These are passed to each * process when the bindApplication() IPC is sent to the process. They're @@ -3320,6 +3402,13 @@ public final class ActivityManagerService extends ActivityManagerNative debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; } + //Check if zygote should refresh its fonts + boolean refreshTheme = false; + if (SystemProperties.getBoolean(PROP_REFRESH_THEME, false)) { + SystemProperties.set(PROP_REFRESH_THEME, "false"); + refreshTheme = true; + } + String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; if (requiredAbi == null) { requiredAbi = Build.SUPPORTED_ABIS[0]; @@ -3344,7 +3433,7 @@ public final class ActivityManagerService extends ActivityManagerNative Process.ProcessStartResult startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, - app.info.dataDir, entryPointArgs); + app.info.dataDir, refreshTheme, entryPointArgs); checkTime(startTime, "startProcess: returned from zygote!"); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); @@ -3366,17 +3455,6 @@ public final class ActivityManagerService extends ActivityManagerNative checkTime(startTime, "startProcess: building log message"); StringBuilder buf = mStringBuilder; buf.setLength(0); - if(hostingType.equals("activity")) - { - BoostFramework mPerf = null; - if (null == mPerf) { - mPerf = new BoostFramework(); - } - if (mPerf != null) { - mPerf.perfIOPrefetchStart(startResult.pid,app.processName); - } - } - buf.append("Start proc "); buf.append(startResult.pid); buf.append(':'); @@ -3866,7 +3944,8 @@ public final class ActivityManagerService extends ActivityManagerNative if (sourceRecord == null) { throw new SecurityException("Called with bad activity token: " + resultTo); } - if (!sourceRecord.info.packageName.equals("android")) { + if (!sourceRecord.info.packageName.equals("android") && + !sourceRecord.info.packageName.equals("org.cyanogenmod.resolver")) { throw new SecurityException( "Must be called from an activity that is declared in the android package"); } @@ -5115,7 +5194,7 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public void run() { synchronized (ActivityManagerService.this) { - final Dialog d = new LaunchWarningWindow(mContext, cur, next); + final Dialog d = new LaunchWarningWindow(getUiContext(), cur, next); d.show(); mUiHandler.postDelayed(new Runnable() { @Override @@ -6315,14 +6394,16 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public void keyguardGoingAway(boolean disableWindowAnimations, - boolean keyguardGoingToNotificationShade) { + boolean keyguardGoingToNotificationShade, + boolean keyguardShowingMedia) { enforceNotIsolatedCaller("keyguardGoingAway"); final long token = Binder.clearCallingIdentity(); try { synchronized (this) { if (DEBUG_LOCKSCREEN) logLockScreen(""); mWindowManager.keyguardGoingAway(disableWindowAnimations, - keyguardGoingToNotificationShade); + keyguardGoingToNotificationShade, + keyguardShowingMedia); if (mLockScreenShown == LOCK_SCREEN_SHOWN) { mLockScreenShown = LOCK_SCREEN_HIDDEN; updateSleepIfNeededLocked(); @@ -6388,6 +6469,13 @@ public final class ActivityManagerService extends ActivityManagerNative } }, dumpheapFilter); + ThemeUtils.registerThemeChangeReceiver(mContext, new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + mUiContext = null; + } + }); + // Let system services know. mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); @@ -6439,7 +6527,7 @@ public final class ActivityManagerService extends ActivityManagerNative }, 0, null, null, new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED}, - AppOpsManager.OP_NONE, null, true, false, + AppOpsManager.OP_BOOT_COMPLETED, null, true, false, MY_PID, Process.SYSTEM_UID, userId); } } @@ -10244,7 +10332,13 @@ public final class ActivityManagerService extends ActivityManagerNative if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { app.persistent = true; - app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; + + // The Adj score defines an order of processes to be killed. + // If a process is shared by multiple apps, maxAdj must be set by the highest + // prioritized app to avoid being killed. + if (app.maxAdj >= ProcessList.PERSISTENT_PROC_ADJ) { + app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; + } } if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { mPersistentStartingProcesses.add(app); @@ -10682,6 +10776,7 @@ public final class ActivityManagerService extends ActivityManagerNative public void requestBugReport() { enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); + mContext.sendBroadcast(new Intent("android.intent.action.BUGREPORT_STARTED")); SystemProperties.set("ctl.start", "bugreport"); } @@ -10759,9 +10854,15 @@ public final class ActivityManagerService extends ActivityManagerNative return true; } } + final int anrPid = proc.pid; mHandler.post(new Runnable() { @Override public void run() { + if (anrPid != proc.pid) { + Slog.i(TAG, "Ignoring stale ANR (occurred in " + anrPid + + ", but current pid is " + proc.pid + ")"); + return; + } appNotResponding(proc, activity, parent, aboveSystem, annotation); } }); @@ -11984,6 +12085,28 @@ public final class ActivityManagerService extends ActivityManagerNative } } + private void sendAppFailureBroadcast(String pkgName) { + Intent intent = new Intent(Intent.ACTION_APP_FAILURE, + (pkgName != null)? Uri.fromParts("package", pkgName, null) : null); + mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT_OR_SELF); + } + + /** + * A possible theme crash is one that throws one of the following exceptions + * {@link android.content.res.Resources.NotFoundException} + * {@link android.view.InflateException} + * + * @param exceptionClassName + * @return True if exceptionClassName is one of the above exceptions + */ + private boolean isPossibleThemeCrash(String exceptionClassName) { + if (Resources.NotFoundException.class.getName().equals(exceptionClassName) || + InflateException.class.getName().equals(exceptionClassName)) { + return true; + } + return false; + } + private boolean handleAppCrashLocked(ProcessRecord app, String reason, String shortMsg, String longMsg, String stackTrace) { long now = SystemClock.uptimeMillis(); @@ -11994,6 +12117,9 @@ public final class ActivityManagerService extends ActivityManagerNative } else { crashTime = null; } + + if (isPossibleThemeCrash(shortMsg)) sendAppFailureBroadcast(app.info.packageName); + if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { // This process loses! Slog.w(TAG, "Process " + app.info.processName @@ -12793,6 +12919,9 @@ public final class ActivityManagerService extends ActivityManagerNative || (!allUids && app.uid != callingUid)) { continue; } + if (app.processName.equals("system")) { + continue; + } if ((app.thread != null) && (!app.crashing && !app.notResponding)) { // Generate process state info for running application ActivityManager.RunningAppProcessInfo currApp = @@ -17290,6 +17419,9 @@ public final class ActivityManagerService extends ActivityManagerNative synchronized(this) { ci = new Configuration(mConfiguration); ci.userSetLocale = false; + if (ci.themeConfig == null) { + ci.themeConfig = ThemeConfig.getBootTheme(mContext.getContentResolver()); + } } return ci; } @@ -17379,6 +17511,11 @@ public final class ActivityManagerService extends ActivityManagerNative values.locale)); } + if (values.themeConfig != null) { + saveThemeResourceLocked(values.themeConfig, + !values.themeConfig.equals(mConfiguration.themeConfig)); + } + mConfigurationSeq++; if (mConfigurationSeq <= 0) { mConfigurationSeq = 1; @@ -17434,6 +17571,10 @@ public final class ActivityManagerService extends ActivityManagerNative null, AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { + // if locale changed, time format may have changed + final int is24Hour = android.text.format.DateFormat.is24HourFormat(mContext) ? 1 : 0; + mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); + // now send general broadcast intent = new Intent(Intent.ACTION_LOCALE_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); if (!mProcessesReady) { @@ -17531,6 +17672,14 @@ public final class ActivityManagerService extends ActivityManagerNative return srec.launchedFromPackage; } + private void saveThemeResourceLocked(ThemeConfig t, boolean isDiff){ + if(isDiff) { + Settings.Secure.putStringForUser(mContext.getContentResolver(), + Configuration.THEME_PKG_CONFIGURATION_PERSISTENCE_PROPERTY, t.toJson(), + UserHandle.USER_CURRENT); + } + } + // ========================================================= // LIFETIME MANAGEMENT // ========================================================= @@ -20268,7 +20417,7 @@ public final class ActivityManagerService extends ActivityManagerNative broadcastIntentLocked(null, null, intent, null, null, 0, null, null, new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED}, - AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID, + AppOpsManager.OP_BOOT_COMPLETED, null, true, false, MY_PID, Process.SYSTEM_UID, userId); } } |