Merge "Move more fields to InstallSource."
diff --git a/Android.bp b/Android.bp
index 0547481..1918ad7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1597,3 +1597,24 @@
"core/java/com/android/internal/util/StateMachine.java",
],
}
+
+filegroup {
+ name: "framework-wifistack-shared-srcs",
+ srcs: [
+ ":framework-annotations",
+ "core/java/android/util/KeyValueListParser.java",
+ "core/java/android/util/LocalLog.java",
+ "core/java/android/util/Rational.java",
+ "core/java/android/util/proto/ProtoStream.java",
+ "core/java/android/util/proto/ProtoOutputStream.java",
+ "core/java/com/android/internal/util/FastXmlSerializer.java",
+ "core/java/com/android/internal/util/HexDump.java",
+ "core/java/com/android/internal/util/IState.java",
+ "core/java/com/android/internal/util/MessageUtils.java",
+ "core/java/com/android/internal/util/Preconditions.java",
+ "core/java/com/android/internal/util/State.java",
+ "core/java/com/android/internal/util/StateMachine.java",
+ "core/java/com/android/internal/util/WakeupMessage.java",
+ "core/java/com/android/internal/util/XmlUtils.java",
+ ],
+}
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 6249de3..8618d4d 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -5760,6 +5760,8 @@
AUTO_DENIED = 8;
// permission request was ignored because permission is restricted
IGNORED_RESTRICTED_PERMISSION = 9;
+ // one time permission was granted by user action
+ USER_GRANTED_ONE_TIME = 10;
}
// The result of the permission grant
optional Result result = 6;
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 8ea1ff5..375a06e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -6633,6 +6633,8 @@
* The calling device admin must be a profile owner or device owner. If it is not, a security
* exception will be thrown.
*
+ * <p>NOTE: Performs disk I/O and shouldn't be called on the main thread.
+ *
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param filter The IntentFilter for which a default handler is added.
* @param activity The Activity that is added as default intent handler.
@@ -7203,7 +7205,8 @@
* used, calling with an empty list only allows the built-in system services. Any non-system
* accessibility service that's currently enabled must be included in the list.
* <p>
- * System accessibility services are always available to the user the list can't modify this.
+ * System accessibility services are always available to the user and this method can't
+ * disable them.
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param packageNames List of accessibility service package names.
* @return {@code true} if the operation succeeded, or {@code false} if the list didn't
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
index f91341f..0679595 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
@@ -16,16 +16,19 @@
package com.android.systemui.statusbar;
+import static com.android.systemui.Dependency.BG_HANDLER_NAME;
+
import android.annotation.NonNull;
import android.os.Handler;
import android.os.HandlerExecutor;
-import android.os.Looper;
import android.provider.DeviceConfig;
import android.util.ArrayMap;
import java.util.Map;
import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
/**
* Class to manage simple DeviceConfig-based feature flags.
@@ -36,16 +39,22 @@
* $ adb shell device_config put systemui <key> <true|false>
* }
*
- * You will probably need to @{$ adb reboot} afterwards in order for the code to pick up the change.
+ * You will probably need to restart systemui for the changes to be picked up:
+ *
+ * {@code
+ * $ adb shell am crash com.android.systemui
+ * }
*/
+@Singleton
public class FeatureFlags {
private final Map<String, Boolean> mCachedDeviceConfigFlags = new ArrayMap<>();
@Inject
- public FeatureFlags() {
+ public FeatureFlags(
+ @Named(BG_HANDLER_NAME) Handler bgHandler) {
DeviceConfig.addOnPropertiesChangedListener(
"systemui",
- new HandlerExecutor(new Handler(Looper.getMainLooper())),
+ new HandlerExecutor(bgHandler),
this::onPropertiesChanged);
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 3262514..b793b39 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1909,14 +1909,17 @@
mAddingToTask = true;
}
} else if (mStartActivity.mActivityComponent.equals(targetTask.realActivity)) {
- // In this case the top activity on the task is the same as the one being launched,
- // so we take that as a request to bring the task to the foreground. If the top
- // activity in the task is the root activity, deliver this new intent to it if it
- // desires.
- if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
- || LAUNCH_SINGLE_TOP == mLaunchMode)
- && targetTaskTop.mActivityComponent.equals(
- mStartActivity.mActivityComponent) && mStartActivity.resultTo == null) {
+ if (targetTask == mInTask) {
+ // In this case we are bringing up an existing activity from a recent task. We
+ // don't need to add a new activity instance on top.
+ } else if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
+ || LAUNCH_SINGLE_TOP == mLaunchMode)
+ && targetTaskTop.mActivityComponent.equals(mStartActivity.mActivityComponent)
+ && mStartActivity.resultTo == null) {
+ // In this case the top activity on the task is the same as the one being launched,
+ // so we take that as a request to bring the task to the foreground. If the top
+ // activity in the task is the root activity, deliver this new intent to it if it
+ // desires.
if (targetTaskTop.isRootOfTask()) {
targetTaskTop.getTaskRecord().setIntent(mStartActivity);
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 150e26e..56bbc05 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2535,7 +2535,6 @@
changes |= FINISH_LAYOUT_REDO_LAYOUT;
}
} else if (topIsFullscreen
- && !mDisplayContent.isStackVisible(WINDOWING_MODE_FREEFORM)
&& !mDisplayContent.isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) {
if (DEBUG_LAYOUT) Slog.v(TAG, "** HIDING status bar");
if (mStatusBarController.setBarShowingLw(false)) {
@@ -2595,7 +2594,7 @@
* window.
*/
private boolean topAppHidesStatusBar() {
- if (mTopFullscreenOpaqueWindowState == null) {
+ if (mTopFullscreenOpaqueWindowState == null || mForceShowSystemBars) {
return false;
}
final int fl = PolicyControl.getWindowFlags(null,
@@ -3258,9 +3257,9 @@
final boolean resizing = mDisplayContent.getDockedDividerController().isResizing();
// We need to force system bars when the docked stack is visible, when the freeform stack
- // is visible but also when we are resizing for the transitions when docked stack
+ // is focused but also when we are resizing for the transitions when docked stack
// visibility changes.
- mForceShowSystemBars = dockedStackVisible || freeformStackVisible || resizing
+ mForceShowSystemBars = dockedStackVisible || win.inFreeformWindowingMode() || resizing
|| mForceShowSystemBarsFromExternal;
final boolean forceOpaqueStatusBar = mForceShowSystemBars && !mForceStatusBarFromKeyguard;
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
index 70ac0be..a8b9839 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
@@ -18,11 +18,14 @@
import com.android.protolog.tool.CommandOptions.Companion.USAGE
import com.github.javaparser.ParseProblemException
+import com.github.javaparser.ParserConfiguration
import com.github.javaparser.StaticJavaParser
import com.github.javaparser.ast.CompilationUnit
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Executors
import java.util.jar.JarOutputStream
import java.util.zip.ZipEntry
import kotlin.system.exitProcess
@@ -45,30 +48,38 @@
val outJar = JarOutputStream(out)
val processor = ProtoLogCallProcessor(command.protoLogClassNameArg,
command.protoLogGroupsClassNameArg, groups)
- val transformer = SourceTransformer(command.protoLogImplClassNameArg, processor)
- command.javaSourceArgs.forEach { path ->
- val file = File(path)
- val text = file.readText()
- val newPath = path
- val outSrc = try {
- val code = tryParse(text, path)
- if (containsProtoLogText(text, command.protoLogClassNameArg)) {
- transformer.processClass(text, newPath, code)
- } else {
+ val executor = newThreadPool()
+
+ command.javaSourceArgs.map { path ->
+ executor.submitCallable {
+ val transformer = SourceTransformer(command.protoLogImplClassNameArg, processor)
+ val file = File(path)
+ val text = file.readText()
+ val outSrc = try {
+ val code = tryParse(text, path)
+ if (containsProtoLogText(text, command.protoLogClassNameArg)) {
+ transformer.processClass(text, path, code)
+ } else {
+ text
+ }
+ } catch (ex: ParsingException) {
+ // If we cannot parse this file, skip it (and log why). Compilation will fail
+ // in a subsequent build step.
+ println("\n${ex.message}\n")
text
}
- } catch (ex: ParsingException) {
- // If we cannot parse this file, skip it (and log why). Compilation will fail
- // in a subsequent build step.
- println("\n${ex.message}\n")
- text
+ path to outSrc
}
- outJar.putNextEntry(ZipEntry(newPath))
+ }.map { future ->
+ val (path, outSrc) = future.get()
+ outJar.putNextEntry(ZipEntry(path))
outJar.write(outSrc.toByteArray())
outJar.closeEntry()
}
+ executor.shutdown()
+
outJar.close()
out.close()
}
@@ -92,23 +103,36 @@
val processor = ProtoLogCallProcessor(command.protoLogClassNameArg,
command.protoLogGroupsClassNameArg, groups)
val builder = ViewerConfigBuilder(processor)
- command.javaSourceArgs.forEach { path ->
- val file = File(path)
- val text = file.readText()
- if (containsProtoLogText(text, command.protoLogClassNameArg)) {
- try {
- val code = tryParse(text, path)
- val pack = if (code.packageDeclaration.isPresent) code.packageDeclaration
- .get().nameAsString else ""
- val newPath = pack.replace('.', '/') + '/' + file.name
- builder.processClass(code, newPath)
- } catch (ex: ParsingException) {
- // If we cannot parse this file, skip it (and log why). Compilation will fail
- // in a subsequent build step.
- println("\n${ex.message}\n")
+
+ val executor = newThreadPool()
+
+ command.javaSourceArgs.map { path ->
+ executor.submitCallable {
+ val file = File(path)
+ val text = file.readText()
+ if (containsProtoLogText(text, command.protoLogClassNameArg)) {
+ try {
+ val code = tryParse(text, path)
+ val pack = if (code.packageDeclaration.isPresent) code.packageDeclaration
+ .get().nameAsString else ""
+ val newPath = pack.replace('.', '/') + '/' + file.name
+ builder.findLogCalls(code, newPath)
+ } catch (ex: ParsingException) {
+ // If we cannot parse this file, skip it (and log why). Compilation will fail
+ // in a subsequent build step.
+ println("\n${ex.message}\n")
+ null
+ }
+ } else {
+ null
}
}
+ }.forEach { future ->
+ builder.addLogCalls(future.get() ?: return@forEach)
}
+
+ executor.shutdown()
+
val out = FileOutputStream(command.viewerConfigJsonArg)
out.write(builder.build().toByteArray())
out.close()
@@ -122,6 +146,11 @@
@JvmStatic
fun main(args: Array<String>) {
+ StaticJavaParser.setConfiguration(ParserConfiguration().apply {
+ setLanguageLevel(ParserConfiguration.LanguageLevel.RAW)
+ setAttributeComments(false)
+ })
+
try {
val command = CommandOptions(args)
when (command.command) {
@@ -138,3 +167,8 @@
}
}
}
+
+private fun <T> ExecutorService.submitCallable(f: () -> T) = submit(f)
+
+private fun newThreadPool() = Executors.newFixedThreadPool(
+ Runtime.getRuntime().availableProcessors())
diff --git a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
index 00fd038..9a38773 100644
--- a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
@@ -42,7 +42,6 @@
import com.github.javaparser.ast.type.Type
import com.github.javaparser.printer.PrettyPrinter
import com.github.javaparser.printer.PrettyPrinterConfiguration
-import com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter
class SourceTransformer(
protoLogImplClassName: String,
@@ -135,7 +134,8 @@
// Inline the new statement.
val printedIfStmt = inlinePrinter.print(ifStmt)
// Append blank lines to preserve line numbering in file (to allow debugging)
- val newLines = LexicalPreservingPrinter.print(parentStmt).count { c -> c == '\n' }
+ val parentRange = parentStmt.range.get()
+ val newLines = parentRange.end.line - parentRange.begin.line
val newStmt = printedIfStmt.substringBeforeLast('}') + ("\n".repeat(newLines)) + '}'
// pre-workaround code, see explanation below
/*
@@ -224,9 +224,7 @@
fileName = path
processedCode = code.split('\n').toMutableList()
offsets = IntArray(processedCode.size)
- LexicalPreservingPrinter.setup(compilationUnit)
protoLogCallProcessor.process(compilationUnit, this, fileName)
- // return LexicalPreservingPrinter.print(compilationUnit)
return processedCode.joinToString("\n")
}
}
diff --git a/tools/protologtool/src/com/android/protolog/tool/ViewerConfigBuilder.kt b/tools/protologtool/src/com/android/protolog/tool/ViewerConfigBuilder.kt
index 941455a..c100826 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ViewerConfigBuilder.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ViewerConfigBuilder.kt
@@ -23,39 +23,52 @@
import java.io.StringWriter
class ViewerConfigBuilder(
- private val protoLogCallVisitor: ProtoLogCallProcessor
-) : ProtoLogCallVisitor {
- override fun processCall(
- call: MethodCallExpr,
- messageString: String,
- level: LogLevel,
- group: LogGroup
- ) {
+ private val processor: ProtoLogCallProcessor
+) {
+ private fun addLogCall(logCall: LogCall, context: ParsingContext) {
+ val group = logCall.logGroup
+ val messageString = logCall.messageString
if (group.enabled) {
- val position = fileName
- val key = CodeUtils.hash(position, messageString, level, group)
+ val key = logCall.key()
if (statements.containsKey(key)) {
- if (statements[key] != LogCall(messageString, level, group, position)) {
+ if (statements[key] != logCall) {
throw HashCollisionException(
"Please modify the log message \"$messageString\" " +
- "or \"${statements[key]}\" - their hashes are equal.",
- ParsingContext(fileName, call))
+ "or \"${statements[key]}\" - their hashes are equal.", context)
}
} else {
groups.add(group)
- statements[key] = LogCall(messageString, level, group, position)
- call.range.isPresent
+ statements[key] = logCall
}
}
}
private val statements: MutableMap<Int, LogCall> = mutableMapOf()
private val groups: MutableSet<LogGroup> = mutableSetOf()
- private var fileName: String = ""
- fun processClass(unit: CompilationUnit, fileName: String) {
- this.fileName = fileName
- protoLogCallVisitor.process(unit, this, fileName)
+ fun findLogCalls(unit: CompilationUnit, fileName: String): List<Pair<LogCall, ParsingContext>> {
+ val calls = mutableListOf<Pair<LogCall, ParsingContext>>()
+ val visitor = object : ProtoLogCallVisitor {
+ override fun processCall(
+ call: MethodCallExpr,
+ messageString: String,
+ level: LogLevel,
+ group: LogGroup
+ ) {
+ val logCall = LogCall(messageString, level, group, fileName)
+ val context = ParsingContext(fileName, call)
+ calls.add(logCall to context)
+ }
+ }
+ processor.process(unit, visitor, fileName)
+
+ return calls
+ }
+
+ fun addLogCalls(calls: List<Pair<LogCall, ParsingContext>>) {
+ calls.forEach { (logCall, context) ->
+ addLogCall(logCall, context)
+ }
}
fun build(): String {
@@ -101,5 +114,7 @@
val logLevel: LogLevel,
val logGroup: LogGroup,
val position: String
- )
+ ) {
+ fun key() = CodeUtils.hash(position, messageString, logLevel, logGroup)
+ }
}
diff --git a/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigBuilderTest.kt b/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigBuilderTest.kt
index 2b6abcd..a24761a 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigBuilderTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigBuilderTest.kt
@@ -17,8 +17,7 @@
package com.android.protolog.tool
import com.android.json.stream.JsonReader
-import com.github.javaparser.ast.CompilationUnit
-import com.github.javaparser.ast.expr.MethodCallExpr
+import com.android.protolog.tool.ViewerConfigBuilder.LogCall
import org.junit.Assert.assertEquals
import org.junit.Test
import org.mockito.Mockito
@@ -34,14 +33,12 @@
private val GROUP1 = LogGroup("TEST_GROUP", true, true, TAG1)
private val GROUP2 = LogGroup("DEBUG_GROUP", true, true, TAG2)
private val GROUP3 = LogGroup("DEBUG_GROUP", true, true, TAG2)
+ private val GROUP_DISABLED = LogGroup("DEBUG_GROUP", false, true, TAG2)
+ private val GROUP_TEXT_DISABLED = LogGroup("DEBUG_GROUP", true, false, TAG2)
private const val PATH = "/tmp/test.java"
}
- private val processor: ProtoLogCallProcessor = Mockito.mock(ProtoLogCallProcessor::class.java)
- private val configBuilder = ViewerConfigBuilder(processor)
- private val dummyCompilationUnit = CompilationUnit()
-
- private fun <T> any(type: Class<T>): T = Mockito.any<T>(type)
+ private val configBuilder = ViewerConfigBuilder(Mockito.mock(ProtoLogCallProcessor::class.java))
private fun parseConfig(json: String): Map<Int, ViewerConfigParser.ConfigEntry> {
return ViewerConfigParser().parseConfig(JsonReader(StringReader(json)))
@@ -49,22 +46,10 @@
@Test
fun processClass() {
- Mockito.`when`(processor.process(any(CompilationUnit::class.java),
- any(ProtoLogCallVisitor::class.java), any(String::class.java)))
- .thenAnswer { invocation ->
- val visitor = invocation.arguments[1] as ProtoLogCallVisitor
-
- visitor.processCall(MethodCallExpr(), TEST1.messageString, LogLevel.INFO,
- GROUP1)
- visitor.processCall(MethodCallExpr(), TEST2.messageString, LogLevel.DEBUG,
- GROUP2)
- visitor.processCall(MethodCallExpr(), TEST3.messageString, LogLevel.ERROR,
- GROUP3)
-
- invocation.arguments[0] as CompilationUnit
- }
-
- configBuilder.processClass(dummyCompilationUnit, PATH)
+ configBuilder.addLogCalls(listOf(
+ LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH),
+ LogCall(TEST2.messageString, LogLevel.DEBUG, GROUP2, PATH),
+ LogCall(TEST3.messageString, LogLevel.ERROR, GROUP3, PATH)).withContext())
val parsedConfig = parseConfig(configBuilder.build())
assertEquals(3, parsedConfig.size)
@@ -78,22 +63,10 @@
@Test
fun processClass_nonUnique() {
- Mockito.`when`(processor.process(any(CompilationUnit::class.java),
- any(ProtoLogCallVisitor::class.java), any(String::class.java)))
- .thenAnswer { invocation ->
- val visitor = invocation.arguments[1] as ProtoLogCallVisitor
-
- visitor.processCall(MethodCallExpr(), TEST1.messageString, LogLevel.INFO,
- GROUP1)
- visitor.processCall(MethodCallExpr(), TEST1.messageString, LogLevel.INFO,
- GROUP1)
- visitor.processCall(MethodCallExpr(), TEST1.messageString, LogLevel.INFO,
- GROUP1)
-
- invocation.arguments[0] as CompilationUnit
- }
-
- configBuilder.processClass(dummyCompilationUnit, PATH)
+ configBuilder.addLogCalls(listOf(
+ LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH),
+ LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH),
+ LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH)).withContext())
val parsedConfig = parseConfig(configBuilder.build())
assertEquals(1, parsedConfig.size)
@@ -103,28 +76,19 @@
@Test
fun processClass_disabled() {
- Mockito.`when`(processor.process(any(CompilationUnit::class.java),
- any(ProtoLogCallVisitor::class.java), any(String::class.java)))
- .thenAnswer { invocation ->
- val visitor = invocation.arguments[1] as ProtoLogCallVisitor
-
- visitor.processCall(MethodCallExpr(), TEST1.messageString, LogLevel.INFO,
- GROUP1)
- visitor.processCall(MethodCallExpr(), TEST2.messageString, LogLevel.DEBUG,
- LogGroup("DEBUG_GROUP", false, true, TAG2))
- visitor.processCall(MethodCallExpr(), TEST3.messageString, LogLevel.ERROR,
- LogGroup("DEBUG_GROUP", true, false, TAG2))
-
- invocation.arguments[0] as CompilationUnit
- }
-
- configBuilder.processClass(dummyCompilationUnit, PATH)
+ configBuilder.addLogCalls(listOf(
+ LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH),
+ LogCall(TEST2.messageString, LogLevel.DEBUG, GROUP_DISABLED, PATH),
+ LogCall(TEST3.messageString, LogLevel.ERROR, GROUP_TEXT_DISABLED, PATH))
+ .withContext())
val parsedConfig = parseConfig(configBuilder.build())
assertEquals(2, parsedConfig.size)
- assertEquals(TEST1, parsedConfig[CodeUtils.hash(PATH, TEST1.messageString,
- LogLevel.INFO, GROUP1)])
- assertEquals(TEST3, parsedConfig[CodeUtils.hash(PATH, TEST3.messageString,
- LogLevel.ERROR, LogGroup("DEBUG_GROUP", true, false, TAG2))])
+ assertEquals(TEST1, parsedConfig[CodeUtils.hash(
+ PATH, TEST1.messageString, LogLevel.INFO, GROUP1)])
+ assertEquals(TEST3, parsedConfig[CodeUtils.hash(
+ PATH, TEST3.messageString, LogLevel.ERROR, GROUP_TEXT_DISABLED)])
}
+
+ private fun List<LogCall>.withContext() = map { it to ParsingContext() }
}