summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/PackageParser.java18
-rw-r--r--core/java/android/os/ZygoteProcess.java45
-rw-r--r--core/java/android/provider/Settings.java13
-rw-r--r--core/java/android/view/DisplayCutout.java6
-rw-r--r--core/java/android/view/View.java4
-rw-r--r--core/java/com/android/internal/os/KernelCpuThreadReader.java72
-rw-r--r--core/java/com/android/internal/os/Zygote.java3
-rw-r--r--core/java/com/android/internal/os/ZygoteArguments.java15
-rw-r--r--core/java/com/android/internal/os/ZygoteConnection.java46
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java1
-rw-r--r--core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java46
-rw-r--r--packages/CaptivePortalLogin/AndroidManifest.xml1
-rw-r--r--packages/NetworkStack/AndroidManifest.xml1
-rw-r--r--packages/NetworkStackPermissionStub/AndroidManifest.xml3
-rw-r--r--packages/SystemUI/res/values-sw320dp/dimens.xml5
-rw-r--r--packages/SystemUI/res/values-sw410dp/dimens.xml4
-rw-r--r--packages/SystemUI/res/values/strings.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java38
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java15
-rw-r--r--services/core/java/com/android/server/os/BugreportManagerServiceImpl.java7
20 files changed, 302 insertions, 43 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 99c7f2be4eef..a006f2374393 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -8444,6 +8444,21 @@ public class PackageParser {
public static PackageInfo generatePackageInfoFromApex(File apexFile, boolean collectCerts)
throws PackageParserException {
PackageInfo pi = new PackageInfo();
+ int parseFlags = 0;
+ if (collectCerts) {
+ parseFlags |= PARSE_COLLECT_CERTIFICATES;
+ try {
+ if (apexFile.getCanonicalPath().startsWith("/system")) {
+ // Don't need verify the APK integrity of APEXes on /system, just like
+ // we don't do that for APKs.
+ // TODO(b/126514108): we may be able to do this for APEXes on /data as well.
+ parseFlags |= PARSE_IS_SYSTEM_DIR;
+ }
+ } catch (IOException e) {
+ throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
+ "Failed to get path for " + apexFile.getPath(), e);
+ }
+ }
// TODO(b/123086053) properly fill in the ApplicationInfo with data from AndroidManifest
// Add ApplicationInfo to the PackageInfo.
@@ -8458,8 +8473,7 @@ public class PackageParser {
// TODO(b/123052859): We should avoid these repeated calls to parseApkLite each time
// we want to generate information for APEX modules.
- PackageParser.ApkLite apk = PackageParser.parseApkLite(apexFile,
- collectCerts ? PackageParser.PARSE_COLLECT_CERTIFICATES : 0);
+ PackageParser.ApkLite apk = PackageParser.parseApkLite(apexFile, parseFlags);
pi.packageName = apk.packageName;
ai.packageName = apk.packageName;
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index e49b65e63c77..650232f79738 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -253,6 +253,11 @@ public class ZygoteProcess {
private int mHiddenApiAccessLogSampleRate;
/**
+ * Proportion of hidden API accesses that should be logged to statslog; 0 - 0x10000.
+ */
+ private int mHiddenApiAccessStatslogSampleRate;
+
+ /**
* The state of the connection to the primary zygote.
*/
private ZygoteState primaryZygoteState;
@@ -487,6 +492,7 @@ public class ZygoteProcess {
"--start-child-zygote",
"--set-api-blacklist-exemptions",
"--hidden-api-log-sampling-rate",
+ "--hidden-api-statslog-sampling-rate",
"--invoke-with"
};
@@ -776,6 +782,21 @@ public class ZygoteProcess {
}
}
+ /**
+ * Set the precentage of detected hidden API accesses that are logged to the new event log.
+ *
+ * <p>This rate will take affect for all new processes forked from the zygote after this call.
+ *
+ * @param rate An integer between 0 and 0x10000 inclusive. 0 means no event logging.
+ */
+ public void setHiddenApiAccessStatslogSampleRate(int rate) {
+ synchronized (mLock) {
+ mHiddenApiAccessStatslogSampleRate = rate;
+ maybeSetHiddenApiAccessStatslogSampleRate(primaryZygoteState);
+ maybeSetHiddenApiAccessStatslogSampleRate(secondaryZygoteState);
+ }
+ }
+
@GuardedBy("mLock")
private boolean maybeSetApiBlacklistExemptions(ZygoteState state, boolean sendIfEmpty) {
if (state == null || state.isClosed()) {
@@ -830,6 +851,30 @@ public class ZygoteProcess {
}
}
+ private void maybeSetHiddenApiAccessStatslogSampleRate(ZygoteState state) {
+ if (state == null || state.isClosed()) {
+ return;
+ }
+ if (mHiddenApiAccessStatslogSampleRate == -1) {
+ return;
+ }
+ try {
+ state.mZygoteOutputWriter.write(Integer.toString(1));
+ state.mZygoteOutputWriter.newLine();
+ state.mZygoteOutputWriter.write("--hidden-api-statslog-sampling-rate="
+ + Integer.toString(mHiddenApiAccessStatslogSampleRate));
+ state.mZygoteOutputWriter.newLine();
+ state.mZygoteOutputWriter.flush();
+ int status = state.mZygoteInputStream.readInt();
+ if (status != 0) {
+ Slog.e(LOG_TAG, "Failed to set hidden API statslog sampling rate; status "
+ + status);
+ }
+ } catch (IOException ioe) {
+ Slog.e(LOG_TAG, "Failed to set hidden API statslog sampling rate", ioe);
+ }
+ }
+
/**
* Creates a ZygoteState for the primary zygote if it doesn't exist or has been disconnected.
*/
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 0d7e00f708a3..d395a9f9b61e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -13376,8 +13376,8 @@ public final class Settings {
"hidden_api_blacklist_exemptions";
/**
- * Sampling rate for hidden API access event logs, as an integer in the range 0 to 0x10000
- * inclusive.
+ * Sampling rate for hidden API access event logs with libmetricslogger, as an integer in
+ * the range 0 to 0x10000 inclusive.
*
* @hide
*/
@@ -13385,6 +13385,15 @@ public final class Settings {
"hidden_api_access_log_sampling_rate";
/**
+ * Sampling rate for hidden API access event logging with statslog, as an integer in the
+ * range 0 to 0x10000 inclusive.
+ *
+ * @hide
+ */
+ public static final String HIDDEN_API_ACCESS_STATSLOG_SAMPLING_RATE =
+ "hidden_api_access_statslog_sampling_rate";
+
+ /**
* Hidden API enforcement policy for apps.
*
* Values correspond to @{@link
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index 25526b869302..610f7edef451 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -233,6 +233,9 @@ public final class DisplayCutout {
/**
* Creates a DisplayCutout instance.
*
+ * <p>Note that this is only useful for tests. For production code, developers should always
+ * use a {@link DisplayCutout} obtained from the system.</p>
+ *
* @param safeInsets the insets from each edge which avoid the display cutout as returned by
* {@link #getSafeInsetTop()} etc.
* @param boundLeft the left bounding rect of the display cutout in pixels. If null is passed,
@@ -253,6 +256,9 @@ public final class DisplayCutout {
/**
* Creates a DisplayCutout instance.
*
+ * <p>Note that this is only useful for tests. For production code, developers should always
+ * use a {@link DisplayCutout} obtained from the system.</p>
+ *
* @param safeInsets the insets from each edge which avoid the display cutout as returned by
* {@link #getSafeInsetTop()} etc.
* @param boundingRects the bounding rects of the display cutouts as returned by
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 45e7d2cfff39..877b3044f7c3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5971,7 +5971,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
@NonNull
public List<Integer> getAttributeResolutionStack(@AttrRes int attribute) {
ArrayList<Integer> stack = new ArrayList<>();
- if (!sDebugViewAttributes) {
+ if (!sDebugViewAttributes || mAttributeResolutionStacks == null) {
return stack;
}
if (mSourceLayoutId != ID_NULL) {
@@ -6003,7 +6003,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
@NonNull
public Map<Integer, Integer> getAttributeSourceResourceMap() {
HashMap<Integer, Integer> map = new HashMap<>();
- if (!sDebugViewAttributes) {
+ if (!sDebugViewAttributes || mAttributeSourceResId == null) {
return map;
}
for (int i = 0; i < mAttributeSourceResId.size(); i++) {
diff --git a/core/java/com/android/internal/os/KernelCpuThreadReader.java b/core/java/com/android/internal/os/KernelCpuThreadReader.java
index 6bbfc2b1277a..6a9db1004912 100644
--- a/core/java/com/android/internal/os/KernelCpuThreadReader.java
+++ b/core/java/com/android/internal/os/KernelCpuThreadReader.java
@@ -103,6 +103,16 @@ public class KernelCpuThreadReader {
private static final int ID_ERROR = -1;
/**
+ * Thread ID used when reporting CPU used by other threads
+ */
+ private static final int OTHER_THREADS_ID = -1;
+
+ /**
+ * Thread name used when reporting CPU used by other threads
+ */
+ private static final String OTHER_THREADS_NAME = "__OTHER_THREADS";
+
+ /**
* When checking whether to report data for a thread, we check the UID of the thread's owner
* against this predicate
*/
@@ -140,9 +150,10 @@ public class KernelCpuThreadReader {
/**
* Create with a path where `proc` is mounted. Used primarily for testing
*
- * @param procPath where `proc` is mounted (to find, see {@code mount | grep ^proc})
+ * @param procPath where `proc` is mounted (to find, see {@code mount | grep
+ * ^proc})
* @param initialTimeInStatePath where the initial {@code time_in_state} file exists to define
- * format
+ * format
*/
@VisibleForTesting
public KernelCpuThreadReader(
@@ -250,8 +261,8 @@ public class KernelCpuThreadReader {
* Read all of the CPU usage statistics for each child thread of a process
*
* @param processPath the {@code /proc} path of the thread
- * @param processId the ID of the process
- * @param uid the ID of the user who owns the process
+ * @param processId the ID of the process
+ * @param uid the ID of the user who owns the process
* @return process CPU usage containing usage of all child threads. Null if the process exited
* and its {@code proc} directory was removed while collecting information
*/
@@ -263,14 +274,24 @@ public class KernelCpuThreadReader {
+ " and user ID " + uid);
}
+ int[] filteredThreadsCpuUsage = null;
final Path allThreadsPath = processPath.resolve("task");
final ArrayList<ThreadCpuUsage> threadCpuUsages = new ArrayList<>();
try (DirectoryStream<Path> threadPaths = Files.newDirectoryStream(allThreadsPath)) {
for (Path threadDirectory : threadPaths) {
ThreadCpuUsage threadCpuUsage = getThreadCpuUsage(threadDirectory);
- if (threadCpuUsage != null) {
- threadCpuUsages.add(threadCpuUsage);
+ if (threadCpuUsage == null) {
+ continue;
}
+ if (mMinimumTotalCpuUsageMillis < totalCpuUsage(threadCpuUsage.usageTimesMillis)) {
+ if (filteredThreadsCpuUsage == null) {
+ filteredThreadsCpuUsage = new int[mFrequenciesKhz.length];
+ }
+ filteredThreadsCpuUsage =
+ sumCpuUsage(filteredThreadsCpuUsage, threadCpuUsage.usageTimesMillis);
+ continue;
+ }
+ threadCpuUsages.add(threadCpuUsage);
}
} catch (IOException e) {
// Expected when a process finishes
@@ -282,6 +303,12 @@ public class KernelCpuThreadReader {
return null;
}
+ // Add the filtered out thread CPU usage under an "other threads" ThreadCpuUsage
+ if (filteredThreadsCpuUsage != null) {
+ threadCpuUsages.add(new ThreadCpuUsage(
+ OTHER_THREADS_ID, OTHER_THREADS_NAME, filteredThreadsCpuUsage));
+ }
+
if (DEBUG) {
Slog.d(TAG, "Read CPU usage of " + threadCpuUsages.size() + " threads");
}
@@ -368,15 +395,6 @@ public class KernelCpuThreadReader {
}
int[] cpuUsages = mFrequencyBucketCreator.getBucketedValues(cpuUsagesLong);
- // Check if the total CPU usage below the threshold
- int totalCpuUsage = 0;
- for (int i = 0; i < cpuUsages.length; i++) {
- totalCpuUsage += cpuUsages[i];
- }
- if (totalCpuUsage < mMinimumTotalCpuUsageMillis) {
- return null;
- }
-
return new ThreadCpuUsage(threadId, threadName, cpuUsages);
}
@@ -424,6 +442,28 @@ public class KernelCpuThreadReader {
}
/**
+ * Get the sum of all CPU usage across all frequencies
+ */
+ private static int totalCpuUsage(int[] cpuUsage) {
+ int total = 0;
+ for (int i = 0; i < cpuUsage.length; i++) {
+ total += cpuUsage[i];
+ }
+ return total;
+ }
+
+ /**
+ * Add two CPU frequency usages together
+ */
+ private static int[] sumCpuUsage(int[] a, int[] b) {
+ int[] summed = new int[a.length];
+ for (int i = 0; i < a.length; i++) {
+ summed[i] = a[i] + b[i];
+ }
+ return summed;
+ }
+
+ /**
* Puts frequencies and usage times into buckets
*/
@VisibleForTesting
@@ -440,7 +480,7 @@ public class KernelCpuThreadReader {
* Buckets based of a list of frequencies
*
* @param frequencies the frequencies to base buckets off
- * @param numBuckets how many buckets to create
+ * @param numBuckets how many buckets to create
*/
@VisibleForTesting
public FrequencyBucketCreator(long[] frequencies, int numBuckets) {
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 58b48d88fa38..0ccaec0be20e 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -645,6 +645,9 @@ public final class Zygote {
} else if (args.mHiddenApiAccessLogSampleRate != -1) {
throw new IllegalArgumentException(
BLASTULA_ERROR_PREFIX + "--hidden-api-log-sampling-rate=");
+ } else if (args.mHiddenApiAccessStatslogSampleRate != -1) {
+ throw new IllegalArgumentException(
+ BLASTULA_ERROR_PREFIX + "--hidden-api-statslog-sampling-rate=");
} else if (args.mInvokeWith != null) {
throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--invoke-with");
} else if (args.mPermittedCapabilities != 0 || args.mEffectiveCapabilities != 0) {
diff --git a/core/java/com/android/internal/os/ZygoteArguments.java b/core/java/com/android/internal/os/ZygoteArguments.java
index 9cb5820a32ce..3beee788a582 100644
--- a/core/java/com/android/internal/os/ZygoteArguments.java
+++ b/core/java/com/android/internal/os/ZygoteArguments.java
@@ -205,6 +205,12 @@ class ZygoteArguments {
int mHiddenApiAccessLogSampleRate = -1;
/**
+ * Sampling rate for logging hidden API accesses to statslog. This is sent to the
+ * pre-forked zygote at boot time, or when it changes, via --hidden-api-statslog-sampling-rate.
+ */
+ int mHiddenApiAccessStatslogSampleRate = -1;
+
+ /**
* Constructs instance and parses args
*
* @param args zygote command-line args
@@ -391,6 +397,15 @@ class ZygoteArguments {
"Invalid log sampling rate: " + rateStr, nfe);
}
expectRuntimeArgs = false;
+ } else if (arg.startsWith("--hidden-api-statslog-sampling-rate=")) {
+ String rateStr = arg.substring(arg.indexOf('=') + 1);
+ try {
+ mHiddenApiAccessStatslogSampleRate = Integer.parseInt(rateStr);
+ } catch (NumberFormatException nfe) {
+ throw new IllegalArgumentException(
+ "Invalid statslog sampling rate: " + rateStr, nfe);
+ }
+ expectRuntimeArgs = false;
} else if (arg.startsWith("--package-name=")) {
if (mPackageName != null) {
throw new IllegalArgumentException("Duplicate arg specified");
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index c7ba22df5700..bcdce311d940 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -37,6 +37,7 @@ import android.system.ErrnoException;
import android.system.Os;
import android.system.StructPollfd;
import android.util.Log;
+import android.util.StatsLog;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -192,9 +193,11 @@ class ZygoteConnection {
return handleApiBlacklistExemptions(zygoteServer, parsedArgs.mApiBlacklistExemptions);
}
- if (parsedArgs.mHiddenApiAccessLogSampleRate != -1) {
+ if (parsedArgs.mHiddenApiAccessLogSampleRate != -1
+ || parsedArgs.mHiddenApiAccessStatslogSampleRate != -1) {
return handleHiddenApiAccessLogSampleRate(zygoteServer,
- parsedArgs.mHiddenApiAccessLogSampleRate);
+ parsedArgs.mHiddenApiAccessLogSampleRate,
+ parsedArgs.mHiddenApiAccessStatslogSampleRate);
}
if (parsedArgs.mPermittedCapabilities != 0 || parsedArgs.mEffectiveCapabilities != 0) {
@@ -396,9 +399,11 @@ class ZygoteConnection {
private final MetricsLogger mMetricsLogger = new MetricsLogger();
private static HiddenApiUsageLogger sInstance = new HiddenApiUsageLogger();
private int mHiddenApiAccessLogSampleRate = 0;
+ private int mHiddenApiAccessStatslogSampleRate = 0;
- public static void setHiddenApiAccessLogSampleRate(int sampleRate) {
+ public static void setHiddenApiAccessLogSampleRates(int sampleRate, int newSampleRate) {
sInstance.mHiddenApiAccessLogSampleRate = sampleRate;
+ sInstance.mHiddenApiAccessStatslogSampleRate = newSampleRate;
}
public static HiddenApiUsageLogger getInstance() {
@@ -410,6 +415,9 @@ class ZygoteConnection {
if (sampledValue < mHiddenApiAccessLogSampleRate) {
logUsage(packageName, signature, accessMethod, accessDenied);
}
+ if (sampledValue < mHiddenApiAccessStatslogSampleRate) {
+ newLogUsage(signature, accessMethod, accessDenied);
+ }
}
private void logUsage(String packageName, String signature, int accessMethod,
@@ -439,6 +447,27 @@ class ZygoteConnection {
}
mMetricsLogger.write(logMaker);
}
+
+ private void newLogUsage(String signature, int accessMethod, boolean accessDenied) {
+ int accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__NONE;
+ switch(accessMethod) {
+ case HiddenApiUsageLogger.ACCESS_METHOD_NONE:
+ accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__NONE;
+ break;
+ case HiddenApiUsageLogger.ACCESS_METHOD_REFLECTION:
+ accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__REFLECTION;
+ break;
+ case HiddenApiUsageLogger.ACCESS_METHOD_JNI:
+ accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__JNI;
+ break;
+ case HiddenApiUsageLogger.ACCESS_METHOD_LINKING:
+ accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__LINKING;
+ break;
+ }
+ int uid = Process.myUid();
+ StatsLog.write(StatsLog.HIDDEN_API_USED, uid, signature,
+ accessMethodProto, accessDenied);
+ }
}
/**
@@ -450,15 +479,18 @@ class ZygoteConnection {
* a Runnable object that must be returned to ZygoteServer.runSelectLoop to be invoked.
*
* @param zygoteServer The server object that received the request
- * @param samplingRate The new sample rate
+ * @param samplingRate The new sample rate for regular logging
+ * @param statsdSamplingRate The new sample rate for statslog logging
* @return A Runnable object representing a new app in any blastulas spawned from here; the
* zygote process will always receive a null value from this function.
*/
private Runnable handleHiddenApiAccessLogSampleRate(ZygoteServer zygoteServer,
- int samplingRate) {
+ int samplingRate, int statsdSamplingRate) {
return stateChangeWithBlastulaPoolReset(zygoteServer, () -> {
- ZygoteInit.setHiddenApiAccessLogSampleRate(samplingRate);
- HiddenApiUsageLogger.setHiddenApiAccessLogSampleRate(samplingRate);
+ int maxSamplingRate = Math.max(samplingRate, statsdSamplingRate);
+ ZygoteInit.setHiddenApiAccessLogSampleRate(maxSamplingRate);
+ HiddenApiUsageLogger.setHiddenApiAccessLogSampleRates(samplingRate,
+ statsdSamplingRate);
ZygoteInit.setHiddenApiUsageLogger(HiddenApiUsageLogger.getInstance());
});
}
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 23cd96382d1a..69632c1d4167 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -287,6 +287,7 @@ public class SettingsBackupTest {
Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE,
+ Settings.Global.HIDDEN_API_ACCESS_STATSLOG_SAMPLING_RATE,
Settings.Global.HIDDEN_API_POLICY,
Settings.Global.HIDE_ERROR_DIALOGS,
Settings.Global.HTTP_PROXY,
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java
index 442ece5a884d..5dddd1afbb60 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java
@@ -218,6 +218,51 @@ public class KernelCpuThreadReaderTest {
}
+ @Test
+ public void testReader_otherThreads() throws IOException {
+ final Path processPath = mProcDirectory.toPath().resolve("self");
+ setupDirectory(
+ processPath,
+ new int[]{1, 2, 3},
+ "process",
+ new String[]{"thread1", "thread2", "thread3"},
+ new int[]{1000, 2000},
+ new int[][]{{0, 100}, {10, 0}, {0, 300}});
+ final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
+ 8,
+ i -> true,
+ 2000,
+ mProcDirectory.toPath(),
+ processPath.resolve("task/1/time_in_state"),
+ new KernelCpuThreadReader.Injector() {
+ @Override
+ public int myPid() {
+ return 1000;
+ }
+
+ @Override
+ public int myUid() {
+ return 0;
+ }
+
+ @Override
+ public int getUidForPid(int pid) {
+ return 0;
+ }
+ });
+ checkResults(
+ kernelCpuThreadReader.getCurrentProcessCpuUsage(),
+ kernelCpuThreadReader.getCpuFrequenciesKhz(),
+ 0,
+ 1000,
+ new int[]{-1, 3},
+ "process",
+ new String[]{"__OTHER_THREADS", "thread3"},
+ new int[]{1000, 2000},
+ new int[][]{{100, 1000}, {0, 3000}}
+ );
+ }
+
private void setupDirectory(Path processPath, int[] threadIds, String processName,
String[] threadNames, int[] cpuFrequencies, int[][] cpuTimes) throws IOException {
// Make /proc/$PID
@@ -259,6 +304,7 @@ public class KernelCpuThreadReaderTest {
assertEquals(processId, processCpuUsage.processId);
assertEquals(uid, processCpuUsage.uid);
assertEquals(processName, processCpuUsage.processName);
+ assertEquals(threadIds.length, processCpuUsage.threadCpuUsages.size());
// Sort the thread CPU usages to compare with test case
final ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages =
diff --git a/packages/CaptivePortalLogin/AndroidManifest.xml b/packages/CaptivePortalLogin/AndroidManifest.xml
index 2a4323851068..a5f3b88fef0a 100644
--- a/packages/CaptivePortalLogin/AndroidManifest.xml
+++ b/packages/CaptivePortalLogin/AndroidManifest.xml
@@ -21,6 +21,7 @@
android:versionCode="10"
android:versionName="Q-initial">
+ <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml
index 90521de6a453..740c573eb914 100644
--- a/packages/NetworkStack/AndroidManifest.xml
+++ b/packages/NetworkStack/AndroidManifest.xml
@@ -21,6 +21,7 @@
android:sharedUserId="android.uid.networkstack"
android:versionCode="10"
android:versionName="Q-initial">
+ <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
diff --git a/packages/NetworkStackPermissionStub/AndroidManifest.xml b/packages/NetworkStackPermissionStub/AndroidManifest.xml
index ba8a178eaea4..62bf3de3fb95 100644
--- a/packages/NetworkStackPermissionStub/AndroidManifest.xml
+++ b/packages/NetworkStackPermissionStub/AndroidManifest.xml
@@ -21,6 +21,7 @@
android:sharedUserId="android.uid.networkstack"
android:versionCode="10"
android:versionName="Q-initial">
+ <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
<!--
This package only exists to define the below permissions, and enforce that they are only
granted to apps sharing the same signature.
@@ -36,4 +37,4 @@
android:protectionLevel="signature"/>
<application android:name="com.android.server.NetworkStackPermissionStub"/>
-</manifest> \ No newline at end of file
+</manifest>
diff --git a/packages/SystemUI/res/values-sw320dp/dimens.xml b/packages/SystemUI/res/values-sw320dp/dimens.xml
index 0c2b1cc5e679..8f27f45c5396 100644
--- a/packages/SystemUI/res/values-sw320dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw320dp/dimens.xml
@@ -15,9 +15,8 @@
~ limitations under the License
-->
<resources>
-
<!-- Global actions grid -->
- <dimen name="global_actions_grid_container_bottom_margin">16dp</dimen>
+ <dimen name="global_actions_grid_container_bottom_margin">4dp</dimen>
<dimen name="global_actions_grid_vertical_padding">0dp</dimen>
<dimen name="global_actions_grid_horizontal_padding">3dp</dimen>
@@ -29,7 +28,7 @@
<dimen name="global_actions_grid_item_icon_width">18dp</dimen>
<dimen name="global_actions_grid_item_icon_height">18dp</dimen>
- <dimen name="global_actions_grid_item_icon_top_margin">12dp</dimen>
+ <dimen name="global_actions_grid_item_icon_top_margin">10dp</dimen>
<dimen name="global_actions_grid_item_icon_side_margin">22dp</dimen>
<dimen name="global_actions_grid_item_icon_bottom_margin">4dp</dimen>
diff --git a/packages/SystemUI/res/values-sw410dp/dimens.xml b/packages/SystemUI/res/values-sw410dp/dimens.xml
index 4197eb2519fa..73d1857c0063 100644
--- a/packages/SystemUI/res/values-sw410dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw410dp/dimens.xml
@@ -23,7 +23,7 @@
<dimen name="qs_detail_items_padding_top">16dp</dimen>
<!-- Global actions grid -->
- <dimen name="global_actions_grid_container_bottom_margin">16dp</dimen>
+ <dimen name="global_actions_grid_container_bottom_margin">4dp</dimen>
<dimen name="global_actions_grid_vertical_padding">8dp</dimen>
<dimen name="global_actions_grid_horizontal_padding">4dp</dimen>
@@ -35,7 +35,7 @@
<dimen name="global_actions_grid_item_icon_width">24dp</dimen>
<dimen name="global_actions_grid_item_icon_height">24dp</dimen>
- <dimen name="global_actions_grid_item_icon_top_margin">16dp</dimen>
+ <dimen name="global_actions_grid_item_icon_top_margin">14dp</dimen>
<dimen name="global_actions_grid_item_icon_side_margin">24dp</dimen>
<dimen name="global_actions_grid_item_icon_bottom_margin">4dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d53c78543b65..5338bb4792d9 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -776,7 +776,7 @@
<!-- QuickSettings: Wifi secondary label shown when the wifi is being enabled [CHAR LIMIT=NONE] -->
<string name="quick_settings_wifi_secondary_label_transient">Turning on&#8230;</string>
<!-- QuickSettings: Cast title [CHAR LIMIT=NONE] -->
- <string name="quick_settings_cast_title">Cast</string>
+ <string name="quick_settings_cast_title">Screen Cast</string>
<!-- QuickSettings: Cast detail panel, status text when casting [CHAR LIMIT=NONE] -->
<string name="quick_settings_casting">Casting</string>
<!-- QuickSettings: Cast detail panel, default device name [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index f05ac4c107eb..0b1e9c399410 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -21,6 +21,7 @@ import static android.media.MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
+import android.media.projection.MediaProjectionInfo;
import android.provider.Settings;
import android.service.quicksettings.Tile;
import android.util.Log;
@@ -125,7 +126,30 @@ public class CastTile extends QSTileImpl<BooleanState> {
});
return;
}
- showDetail(true);
+
+ CastDevice activeProjection = getActiveDeviceMediaProjection();
+ if (activeProjection == null) {
+ showDetail(true);
+ } else {
+ mController.stopCasting(activeProjection);
+ }
+ }
+
+ private CastDevice getActiveDeviceMediaProjection() {
+ CastDevice activeDevice = null;
+ for (CastDevice device : mController.getCastDevices()) {
+ if (device.state == CastDevice.STATE_CONNECTED
+ || device.state == CastDevice.STATE_CONNECTING) {
+ activeDevice = device;
+ break;
+ }
+ }
+
+ if (activeDevice != null && activeDevice.tag instanceof MediaProjectionInfo) {
+ return activeDevice;
+ }
+
+ return null;
}
@Override
@@ -161,21 +185,23 @@ public class CastTile extends QSTileImpl<BooleanState> {
for (CastDevice device : devices) {
if (device.state == CastDevice.STATE_CONNECTED) {
state.value = true;
- state.label = getDeviceName(device);
+ state.secondaryLabel = getDeviceName(device);
state.contentDescription = state.contentDescription + "," +
mContext.getString(R.string.accessibility_cast_name, state.label);
} else if (device.state == CastDevice.STATE_CONNECTING) {
connecting = true;
}
}
- if (!state.value && connecting) {
- state.label = mContext.getString(R.string.quick_settings_connecting);
+ if (connecting && !state.value) {
+ state.secondaryLabel = mContext.getString(R.string.quick_settings_connecting);
}
state.icon = ResourceIcon.get(state.value ? R.drawable.ic_qs_cast_on
: R.drawable.ic_qs_cast_off);
- if (mWifiConnected) {
+ if (mWifiConnected || state.value) {
state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
- state.secondaryLabel = "";
+ if (!state.value) {
+ state.secondaryLabel = "";
+ }
state.contentDescription = state.contentDescription + ","
+ mContext.getString(R.string.accessibility_quick_settings_open_details);
state.expandedAccessibilityClassName = Button.class.getName();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index fe85d231b903..ccb9d82571f7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2129,6 +2129,7 @@ public class ActivityManagerService extends IActivityManager.Stub
private String mExemptionsStr;
private List<String> mExemptions = Collections.emptyList();
private int mLogSampleRate = -1;
+ private int mStatslogSampleRate = -1;
@HiddenApiEnforcementPolicy private int mPolicy = HIDDEN_API_ENFORCEMENT_DEFAULT;
public HiddenApiSettings(Handler handler, Context context) {
@@ -2146,6 +2147,11 @@ public class ActivityManagerService extends IActivityManager.Stub
false,
this);
mContext.getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(
+ Settings.Global.HIDDEN_API_ACCESS_STATSLOG_SAMPLING_RATE),
+ false,
+ this);
+ mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY),
false,
this);
@@ -2181,6 +2187,15 @@ public class ActivityManagerService extends IActivityManager.Stub
mLogSampleRate = logSampleRate;
ZYGOTE_PROCESS.setHiddenApiAccessLogSampleRate(mLogSampleRate);
}
+ int statslogSampleRate = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.HIDDEN_API_ACCESS_STATSLOG_SAMPLING_RATE, 0);
+ if (statslogSampleRate < 0 || statslogSampleRate > 0x10000) {
+ statslogSampleRate = -1;
+ }
+ if (statslogSampleRate != -1 && statslogSampleRate != mStatslogSampleRate) {
+ mStatslogSampleRate = statslogSampleRate;
+ ZYGOTE_PROCESS.setHiddenApiAccessStatslogSampleRate(mStatslogSampleRate);
+ }
mPolicy = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY);
}
diff --git a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
index f4454ae2a180..85a3ba1a8559 100644
--- a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
+++ b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
@@ -78,7 +78,12 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub {
Preconditions.checkNotNull(bugreportFd);
Preconditions.checkNotNull(listener);
validateBugreportMode(bugreportMode);
- ensureIsPrimaryUser();
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ ensureIsPrimaryUser();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
int callingUid = Binder.getCallingUid();
mAppOps.checkPackage(callingUid, callingPackage);