summaryrefslogtreecommitdiffstats
path: root/services/core/java/com/android/server/am/ActivityManagerService.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/core/java/com/android/server/am/ActivityManagerService.java')
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java201
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);
}
}