summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Android Build Merger (Role) <android-build-merger@google.com> 2017-04-04 03:41:50 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-04-04 03:41:56 +0000
commitdfc07c00521d51ff01dd3027e7ed5c872c486a65 (patch)
tree2d3361468ec6c985ff0aaaf421cf14bd2f4e37c8
parent5dbb0f00472141da8128edf1a08f473ed7a0cd6e (diff)
parentbcc5b9f569356fa5076ca7348c40f521035a55d6 (diff)
Merge "Merge "Themes: Apply themes to system_server safely" into oc-dev am: a52fc49845 am: b188c93a45"
-rw-r--r--core/java/android/app/ActivityThread.java21
-rw-r--r--core/java/android/app/ApplicationPackageManager.java4
-rw-r--r--core/java/android/app/ContextImpl.java12
-rw-r--r--core/java/android/app/ResourcesManager.java2
-rw-r--r--core/java/android/content/Context.java14
-rw-r--r--services/core/java/com/android/server/SystemService.java11
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java39
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java1
-rw-r--r--services/core/java/com/android/server/am/BaseErrorDialog.java1
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java6
-rw-r--r--services/core/java/com/android/server/power/ShutdownThread.java17
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java8
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java13
-rw-r--r--services/java/com/android/server/SystemServer.java3
14 files changed, 119 insertions, 33 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e49aad2cd607..d1d462c2fbe8 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -221,6 +221,7 @@ public final class ActivityThread {
private long mNetworkBlockSeq = INVALID_PROC_STATE_SEQ;
private ContextImpl mSystemContext;
+ private ContextImpl mSystemUiContext;
static volatile IPackageManager sPackageManager;
@@ -2190,9 +2191,19 @@ public final class ActivityThread {
}
}
+ public ContextImpl getSystemUiContext() {
+ synchronized (this) {
+ if (mSystemUiContext == null) {
+ mSystemUiContext = ContextImpl.createSystemUiContext(this);
+ }
+ return mSystemUiContext;
+ }
+ }
+
public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
synchronized (this) {
getSystemContext().installSystemApplicationInfo(info, classLoader);
+ getSystemUiContext().installSystemApplicationInfo(info, classLoader);
// give ourselves a default profiler
mProfiler = new Profiler();
@@ -5031,6 +5042,11 @@ public final class ActivityThread {
if ((systemTheme.getChangingConfigurations() & configDiff) != 0) {
systemTheme.rebase();
}
+
+ final Theme systemUiTheme = getSystemUiContext().getTheme();
+ if ((systemUiTheme.getChangingConfigurations() & configDiff) != 0) {
+ systemUiTheme.rebase();
+ }
}
ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
@@ -5086,9 +5102,10 @@ public final class ActivityThread {
// Trigger a regular Configuration change event, only with a different assetsSeq number
// so that we actually call through to all components.
+ // TODO(adamlesinski): Change this to make use of ActivityManager's upcoming ability to
+ // store configurations per-process.
Configuration newConfig = new Configuration();
- newConfig.unset();
- newConfig.assetsSeq = mConfiguration.assetsSeq + 1;
+ newConfig.assetsSeq = (mConfiguration != null ? mConfiguration.assetsSeq : 0) + 1;
handleConfigurationChanged(newConfig, null);
// Schedule all activities to reload
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 461f9cc35125..a6838f8bbf0a 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1352,7 +1352,7 @@ public class ApplicationPackageManager extends PackageManager {
public Resources getResourcesForApplication(@NonNull ApplicationInfo app)
throws NameNotFoundException {
if (app.packageName.equals("system")) {
- return mContext.mMainThread.getSystemContext().getResources();
+ return mContext.mMainThread.getSystemUiContext().getResources();
}
final boolean sameUid = (app.uid == Process.myUid());
final Resources r = mContext.mMainThread.getTopLevelResources(
@@ -1383,7 +1383,7 @@ public class ApplicationPackageManager extends PackageManager {
"Call does not support special user #" + userId);
}
if ("system".equals(appPackageName)) {
- return mContext.mMainThread.getSystemContext().getResources();
+ return mContext.mMainThread.getSystemUiContext().getResources();
}
try {
ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, sDefaultFlags, userId);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index f95fa990b79e..c5e970f99c1f 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2217,6 +2217,18 @@ class ContextImpl extends Context {
return context;
}
+ /**
+ * System Context to be used for UI. This Context has resources that can be themed.
+ */
+ static ContextImpl createSystemUiContext(ActivityThread mainThread) {
+ LoadedApk packageInfo = new LoadedApk(mainThread);
+ ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
+ null);
+ context.setResources(createResources(null, packageInfo, null, Display.DEFAULT_DISPLAY, null,
+ packageInfo.getCompatibilityInfo()));
+ return context;
+ }
+
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index b42df5e2e0fb..489a0f0975ae 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -984,7 +984,7 @@ public class ResourcesManager {
final ResourcesKey key = mResourceImpls.keyAt(i);
final WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i);
final ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null;
- if (impl != null && key.mResDir != null && key.mResDir.equals(baseCodePath)) {
+ if (impl != null && (key.mResDir == null || key.mResDir.equals(baseCodePath))) {
updatedResourceKeys.put(impl, new ResourcesKey(
key.mResDir,
key.mSplitResDirs,
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index aa2adc74bc88..a585720ab895 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4642,4 +4642,18 @@ public abstract class Context {
public Handler getMainThreadHandler() {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
+
+ /**
+ * Throws an exception if the Context is using system resources,
+ * which are non-runtime-overlay-themable and may show inconsistent UI.
+ * @hide
+ */
+ public void assertRuntimeOverlayThemable() {
+ // Resources.getSystem() is a singleton and the only Resources not managed by
+ // ResourcesManager; therefore Resources.getSystem() is not themable.
+ if (getResources() == Resources.getSystem()) {
+ throw new IllegalArgumentException("Non-UI context used to display UI; "
+ + "get a UI context from ActivityThread#getSystemUiContext()");
+ }
+ }
}
diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java
index 421d5a6ab964..c105b1244e74 100644
--- a/services/core/java/com/android/server/SystemService.java
+++ b/services/core/java/com/android/server/SystemService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import android.app.ActivityThread;
import android.content.Context;
import android.os.IBinder;
import android.os.ServiceManager;
@@ -104,6 +105,16 @@ public abstract class SystemService {
}
/**
+ * Get the system UI context. This context is to be used for displaying UI. It is themable,
+ * which means resources can be overridden at runtime. Do not use to retrieve properties that
+ * configure the behavior of the device that is not UX related.
+ */
+ public final Context getUiContext() {
+ // This has already been set up by the time any SystemServices are created.
+ return ActivityThread.currentActivityThread().getSystemUiContext();
+ }
+
+ /**
* Returns true if the system is running in safe mode.
* TODO: we should define in which phase this becomes valid
*/
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 81ba7a733225..4c747a1c5433 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1350,7 +1350,13 @@ public class ActivityManagerService extends IActivityManager.Stub
@GuardedBy("this") boolean mLaunchWarningShown = false;
@GuardedBy("this") boolean mCheckedForSetup = false;
- Context mContext;
+ final Context mContext;
+
+ /**
+ * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
+ * change at runtime. Use mContext for non-UI purposes.
+ */
+ final Context mUiContext;
/**
* The time at which we will allow normal application switches again,
@@ -1852,7 +1858,7 @@ public class ActivityManagerService extends IActivityManager.Stub
} break;
case SHOW_FACTORY_ERROR_UI_MSG: {
Dialog d = new FactoryErrorDialog(
- mContext, msg.getData().getCharSequence("msg"));
+ mUiContext, msg.getData().getCharSequence("msg"));
d.show();
ensureBootCompleted();
} break;
@@ -1863,7 +1869,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (!app.waitedForDebugger) {
Dialog d = new AppWaitingForDebuggerDialog(
ActivityManagerService.this,
- mContext, app);
+ mUiContext, app);
app.waitDialog = d;
app.waitedForDebugger = true;
d.show();
@@ -1878,24 +1884,24 @@ public class ActivityManagerService extends IActivityManager.Stub
} break;
case SHOW_UID_ERROR_UI_MSG: {
if (mShowDialogs) {
- AlertDialog d = new BaseErrorDialog(mContext);
+ AlertDialog d = new BaseErrorDialog(mUiContext);
d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
d.setCancelable(false);
- d.setTitle(mContext.getText(R.string.android_system_label));
- d.setMessage(mContext.getText(R.string.system_error_wipe_data));
- d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
+ d.setTitle(mUiContext.getText(R.string.android_system_label));
+ d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
+ d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
obtainMessage(DISMISS_DIALOG_UI_MSG, d));
d.show();
}
} break;
case SHOW_FINGERPRINT_ERROR_UI_MSG: {
if (mShowDialogs) {
- AlertDialog d = new BaseErrorDialog(mContext);
+ AlertDialog d = new BaseErrorDialog(mUiContext);
d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
d.setCancelable(false);
- d.setTitle(mContext.getText(R.string.android_system_label));
- d.setMessage(mContext.getText(R.string.system_error_manufacturer));
- d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
+ d.setTitle(mUiContext.getText(R.string.android_system_label));
+ d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
+ d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
obtainMessage(DISMISS_DIALOG_UI_MSG, d));
d.show();
}
@@ -1919,7 +1925,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (mode == ActivityManager.COMPAT_MODE_DISABLED
|| mode == ActivityManager.COMPAT_MODE_ENABLED) {
mCompatModeDialog = new CompatModeDialog(
- ActivityManagerService.this, mContext,
+ ActivityManagerService.this, mUiContext,
ar.info.applicationInfo);
mCompatModeDialog.show();
}
@@ -1939,7 +1945,7 @@ public class ActivityManagerService extends IActivityManager.Stub
ar.packageName)) {
// TODO(multi-display): Show dialog on appropriate display.
mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
- ActivityManagerService.this, mContext, ar.info.applicationInfo);
+ ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
mUnsupportedDisplaySizeDialog.show();
}
}
@@ -2731,6 +2737,7 @@ public class ActivityManagerService extends IActivityManager.Stub
public ActivityManagerService(Injector injector) {
mInjector = injector;
mContext = mInjector.getContext();
+ mUiContext = null;
GL_ES_VERSION = 0;
mActivityStarter = null;
mAppErrors = null;
@@ -2762,8 +2769,10 @@ public class ActivityManagerService extends IActivityManager.Stub
LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
mInjector = new Injector();
mContext = systemContext;
+
mFactoryTest = FactoryTest.getMode();
mSystemThread = ActivityThread.currentActivityThread();
+ mUiContext = mSystemThread.getSystemUiContext();
Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
@@ -2806,7 +2815,7 @@ public class ActivityManagerService extends IActivityManager.Stub
mServices = new ActiveServices(this);
mProviderMap = new ProviderMap(this);
- mAppErrors = new AppErrors(mContext, this);
+ mAppErrors = new AppErrors(mUiContext, this);
// TODO: Move creation of battery stats service outside of activity manager service.
File dataDir = Environment.getDataDirectory();
@@ -23893,7 +23902,7 @@ public class ActivityManagerService extends IActivityManager.Stub
final boolean updateFrameworkRes = packagesToUpdate.contains("android");
for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
final ProcessRecord app = mLruProcesses.get(i);
- if (app.thread == null || app.pid == Process.myPid()) {
+ if (app.thread == null) {
continue;
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 21c131c3616f..ba72dcf23c98 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -98,6 +98,7 @@ class AppErrors {
AppErrors(Context context, ActivityManagerService service) {
+ context.assertRuntimeOverlayThemable();
mService = service;
mContext = context;
}
diff --git a/services/core/java/com/android/server/am/BaseErrorDialog.java b/services/core/java/com/android/server/am/BaseErrorDialog.java
index 5f7f67a8a5e8..347a357aae04 100644
--- a/services/core/java/com/android/server/am/BaseErrorDialog.java
+++ b/services/core/java/com/android/server/am/BaseErrorDialog.java
@@ -34,6 +34,7 @@ class BaseErrorDialog extends AlertDialog {
public BaseErrorDialog(Context context) {
super(context, com.android.internal.R.style.Theme_Dialog_AppError);
+ context.assertRuntimeOverlayThemable();
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 9c4e700c87d3..a60dae7c7914 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -2671,11 +2671,11 @@ public final class PowerManagerService extends SystemService
public void run() {
synchronized (this) {
if (haltMode == HALT_MODE_REBOOT_SAFE_MODE) {
- ShutdownThread.rebootSafeMode(mContext, confirm);
+ ShutdownThread.rebootSafeMode(getUiContext(), confirm);
} else if (haltMode == HALT_MODE_REBOOT) {
- ShutdownThread.reboot(mContext, reason, confirm);
+ ShutdownThread.reboot(getUiContext(), reason, confirm);
} else {
- ShutdownThread.shutdown(mContext, reason, confirm);
+ ShutdownThread.shutdown(getUiContext(), reason, confirm);
}
}
}
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 841e2a158c4f..864e83ef1f86 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -79,7 +79,7 @@ public final class ShutdownThread extends Thread {
private static final int SHUTDOWN_VIBRATE_MS = 500;
// state tracking
- private static Object sIsStartedGuard = new Object();
+ private static final Object sIsStartedGuard = new Object();
private static boolean sIsStarted = false;
private static boolean mReboot;
@@ -121,7 +121,8 @@ public final class ShutdownThread extends Thread {
* state etc. Must be called from a Looper thread in which its UI
* is shown.
*
- * @param context Context used to display the shutdown progress dialog.
+ * @param context Context used to display the shutdown progress dialog. This must be a context
+ * suitable for displaying UI (aka Themable).
* @param reason code to pass to android_reboot() (e.g. "userrequested"), or null.
* @param confirm true if user confirmation is needed before shutting down.
*/
@@ -132,7 +133,11 @@ public final class ShutdownThread extends Thread {
shutdownInner(context, confirm);
}
- static void shutdownInner(final Context context, boolean confirm) {
+ private static void shutdownInner(final Context context, boolean confirm) {
+ // ShutdownThread is called from many places, so best to verify here that the context passed
+ // in is themed.
+ context.assertRuntimeOverlayThemable();
+
// ensure that only one thread is trying to power down.
// any additional calls are just returned
synchronized (sIsStartedGuard) {
@@ -204,7 +209,8 @@ public final class ShutdownThread extends Thread {
* state etc. Must be called from a Looper thread in which its UI
* is shown.
*
- * @param context Context used to display the shutdown progress dialog.
+ * @param context Context used to display the shutdown progress dialog. This must be a context
+ * suitable for displaying UI (aka Themable).
* @param reason code to pass to the kernel (e.g. "recovery"), or null.
* @param confirm true if user confirmation is needed before shutting down.
*/
@@ -220,7 +226,8 @@ public final class ShutdownThread extends Thread {
* Request a reboot into safe mode. Must be called from a Looper thread in which its UI
* is shown.
*
- * @param context Context used to display the shutdown progress dialog.
+ * @param context Context used to display the shutdown progress dialog. This must be a context
+ * suitable for displaying UI (aka Themable).
* @param confirm true if user confirmation is needed before shutting down.
*/
public static void rebootSafeMode(final Context context, boolean confirm) {
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 212bd61dbc9a..218d21826d93 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.statusbar;
+import android.app.ActivityThread;
import android.app.StatusBarManager;
import android.content.ComponentName;
import android.content.Context;
@@ -61,6 +62,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub {
private static final boolean SPEW = false;
private final Context mContext;
+
private final WindowManagerService mWindowManager;
private Handler mHandler = new Handler();
private NotificationDelegate mNotificationDelegate;
@@ -777,10 +779,12 @@ public class StatusBarManagerService extends IStatusBarService.Stub {
long identity = Binder.clearCallingIdentity();
try {
mHandler.post(() -> {
+ // ShutdownThread displays UI, so give it a UI context.
+ Context uiContext = ActivityThread.currentActivityThread().getSystemUiContext();
if (safeMode) {
- ShutdownThread.rebootSafeMode(mContext, false);
+ ShutdownThread.rebootSafeMode(uiContext, false);
} else {
- ShutdownThread.reboot(mContext, PowerManager.SHUTDOWN_USER_REQUESTED, false);
+ ShutdownThread.reboot(uiContext, PowerManager.SHUTDOWN_USER_REQUESTED, false);
}
});
} finally {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1691d1408356..f1796de2d342 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -102,6 +102,7 @@ import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager.TaskSnapshot;
import android.app.ActivityManagerInternal;
+import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.content.BroadcastReceiver;
@@ -3196,19 +3197,25 @@ public class WindowManagerService extends IWindowManager.Stub
// Called by window manager policy. Not exposed externally.
@Override
public void shutdown(boolean confirm) {
- ShutdownThread.shutdown(mContext, PowerManager.SHUTDOWN_USER_REQUESTED, confirm);
+ // Pass in the UI context, since ShutdownThread requires it (to show UI).
+ ShutdownThread.shutdown(ActivityThread.currentActivityThread().getSystemUiContext(),
+ PowerManager.SHUTDOWN_USER_REQUESTED, confirm);
}
// Called by window manager policy. Not exposed externally.
@Override
public void reboot(boolean confirm) {
- ShutdownThread.reboot(mContext, PowerManager.SHUTDOWN_USER_REQUESTED, confirm);
+ // Pass in the UI context, since ShutdownThread requires it (to show UI).
+ ShutdownThread.reboot(ActivityThread.currentActivityThread().getSystemUiContext(),
+ PowerManager.SHUTDOWN_USER_REQUESTED, confirm);
}
// Called by window manager policy. Not exposed externally.
@Override
public void rebootSafeMode(boolean confirm) {
- ShutdownThread.rebootSafeMode(mContext, confirm);
+ // Pass in the UI context, since ShutdownThread requires it (to show UI).
+ ShutdownThread.rebootSafeMode(ActivityThread.currentActivityThread().getSystemUiContext(),
+ confirm);
}
public void setCurrentProfileIds(final int[] currentProfileIds) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 3f197b7f3927..1312c8f55c48 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -475,6 +475,9 @@ public final class SystemServer {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
+
+ final Context systemUiContext = activityThread.getSystemUiContext();
+ systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
/**