Merge "Write app warning configs on IO thread" into udc-qpr-dev

This commit is contained in:
Riddle Hsu
2023-06-27 07:53:32 +00:00
committed by Android (Google) Code Review

View File

@@ -16,7 +16,9 @@
package com.android.server.wm; package com.android.server.wm;
import android.annotation.NonNull;
import android.annotation.UiThread; import android.annotation.UiThread;
import android.annotation.WorkerThread;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName; import android.content.ComponentName;
@@ -30,14 +32,18 @@ import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Message; import android.os.Message;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile; import android.util.AtomicFile;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Slog; import android.util.Slog;
import android.util.Xml; import android.util.Xml;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils; import com.android.internal.util.ArrayUtils;
import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer; import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.IoThread;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@@ -45,9 +51,7 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.util.HashMap; import java.util.concurrent.atomic.AtomicReference;
import java.util.HashSet;
import java.util.Map;
/** /**
* Manages warning dialogs shown during application lifecycle. * Manages warning dialogs shown during application lifecycle.
@@ -61,11 +65,12 @@ class AppWarnings {
public static final int FLAG_HIDE_DEPRECATED_SDK = 0x04; public static final int FLAG_HIDE_DEPRECATED_SDK = 0x04;
public static final int FLAG_HIDE_DEPRECATED_ABI = 0x08; public static final int FLAG_HIDE_DEPRECATED_ABI = 0x08;
private final HashMap<String, Integer> mPackageFlags = new HashMap<>(); @GuardedBy("mPackageFlags")
private final ArrayMap<String, Integer> mPackageFlags = new ArrayMap<>();
private final ActivityTaskManagerService mAtm; private final ActivityTaskManagerService mAtm;
private final Context mUiContext; private final Context mUiContext;
private final ConfigHandler mHandler; private final WriteConfigTask mWriteConfigTask;
private final UiHandler mUiHandler; private final UiHandler mUiHandler;
private final AtomicFile mConfigFile; private final AtomicFile mConfigFile;
@@ -75,30 +80,20 @@ class AppWarnings {
private DeprecatedAbiDialog mDeprecatedAbiDialog; private DeprecatedAbiDialog mDeprecatedAbiDialog;
/** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */ /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
private HashSet<ComponentName> mAlwaysShowUnsupportedCompileSdkWarningActivities = private final ArraySet<ComponentName> mAlwaysShowUnsupportedCompileSdkWarningActivities =
new HashSet<>(); new ArraySet<>();
/** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */ /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) { void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
mAlwaysShowUnsupportedCompileSdkWarningActivities.add(activity); mAlwaysShowUnsupportedCompileSdkWarningActivities.add(activity);
} }
/** /** Creates a new warning dialog manager. */
* Creates a new warning dialog manager.
* <p>
* <strong>Note:</strong> Must be called from the ActivityManagerService thread.
*
* @param atm
* @param uiContext
* @param handler
* @param uiHandler
* @param systemDir
*/
public AppWarnings(ActivityTaskManagerService atm, Context uiContext, Handler handler, public AppWarnings(ActivityTaskManagerService atm, Context uiContext, Handler handler,
Handler uiHandler, File systemDir) { Handler uiHandler, File systemDir) {
mAtm = atm; mAtm = atm;
mUiContext = uiContext; mUiContext = uiContext;
mHandler = new ConfigHandler(handler.getLooper()); mWriteConfigTask = new WriteConfigTask();
mUiHandler = new UiHandler(uiHandler.getLooper()); mUiHandler = new UiHandler(uiHandler.getLooper());
mConfigFile = new AtomicFile(new File(systemDir, CONFIG_FILE_NAME), "warnings-config"); mConfigFile = new AtomicFile(new File(systemDir, CONFIG_FILE_NAME), "warnings-config");
@@ -256,8 +251,9 @@ class AppWarnings {
mUiHandler.hideDialogsForPackage(name); mUiHandler.hideDialogsForPackage(name);
synchronized (mPackageFlags) { synchronized (mPackageFlags) {
mPackageFlags.remove(name); if (mPackageFlags.remove(name) != null) {
mHandler.scheduleWrite(); mWriteConfigTask.schedule();
}
} }
} }
@@ -425,7 +421,7 @@ class AppWarnings {
} else { } else {
mPackageFlags.remove(name); mPackageFlags.remove(name);
} }
mHandler.scheduleWrite(); mWriteConfigTask.schedule();
} }
} }
} }
@@ -556,46 +552,30 @@ class AppWarnings {
} }
} }
/** private final class WriteConfigTask implements Runnable {
* Handles messages on the ActivityTaskManagerService thread. private static final long WRITE_CONFIG_DELAY_MS = 10000;
*/ final AtomicReference<ArrayMap<String, Integer>> mPendingPackageFlags =
private final class ConfigHandler extends Handler { new AtomicReference<>();
private static final int MSG_WRITE = 1;
private static final int DELAY_MSG_WRITE = 10000;
public ConfigHandler(Looper looper) {
super(looper, null, true);
}
@Override @Override
public void handleMessage(Message msg) { public void run() {
switch (msg.what) { final ArrayMap<String, Integer> packageFlags = mPendingPackageFlags.getAndSet(null);
case MSG_WRITE: if (packageFlags != null) {
writeConfigToFileAmsThread(); writeConfigToFile(packageFlags);
break;
} }
} }
public void scheduleWrite() { @GuardedBy("mPackageFlags")
removeMessages(MSG_WRITE); void schedule() {
sendEmptyMessageDelayed(MSG_WRITE, DELAY_MSG_WRITE); if (mPendingPackageFlags.getAndSet(new ArrayMap<>(mPackageFlags)) == null) {
IoThread.getHandler().postDelayed(this, WRITE_CONFIG_DELAY_MS);
}
} }
} }
/** /** Writes the configuration file. */
* Writes the configuration file. @WorkerThread
* <p> private void writeConfigToFile(@NonNull ArrayMap<String, Integer> packageFlags) {
* <strong>Note:</strong> Should be called from the ActivityManagerService thread unless you
* don't care where you're doing I/O operations. But you <i>do</i> care, don't you?
*/
private void writeConfigToFileAmsThread() {
// Create a shallow copy so that we don't have to synchronize on config.
final HashMap<String, Integer> packageFlags;
synchronized (mPackageFlags) {
packageFlags = new HashMap<>(mPackageFlags);
}
FileOutputStream fos = null; FileOutputStream fos = null;
try { try {
fos = mConfigFile.startWrite(); fos = mConfigFile.startWrite();
@@ -605,9 +585,9 @@ class AppWarnings {
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
out.startTag(null, "packages"); out.startTag(null, "packages");
for (Map.Entry<String, Integer> entry : packageFlags.entrySet()) { for (int i = 0; i < packageFlags.size(); i++) {
String pkg = entry.getKey(); final String pkg = packageFlags.keyAt(i);
int mode = entry.getValue(); final int mode = packageFlags.valueAt(i);
if (mode == 0) { if (mode == 0) {
continue; continue;
} }