summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp64
-rw-r--r--apex/media/framework/java/android/media/MediaParser.java6
-rw-r--r--api/current.txt2
-rwxr-xr-xapi/system-current.txt4
-rw-r--r--cmds/incident_helper/Android.bp2
-rw-r--r--cmds/incidentd/Android.bp4
-rw-r--r--cmds/statsd/Android.bp13
-rw-r--r--cmds/statsd/src/external/GpuStatsPuller.cpp163
-rw-r--r--cmds/statsd/src/external/GpuStatsPuller.h42
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.cpp10
-rw-r--r--cmds/statsd/tests/external/GpuStatsPuller_test.cpp185
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java20
-rwxr-xr-xcore/java/android/os/Build.java7
-rw-r--r--core/java/android/os/Environment.java17
-rw-r--r--core/java/android/provider/Telephony.java1
-rw-r--r--core/java/android/service/textclassifier/TextClassifierService.java30
-rw-r--r--core/java/android/timezone/CountryTimeZones.java49
-rw-r--r--core/java/android/util/TimeUtils.java2
-rw-r--r--core/java/android/view/textclassifier/TextClassificationConstants.java23
-rw-r--r--core/java/android/widget/Editor.java10
-rw-r--r--core/java/android/widget/Toast.java1
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java4
-rw-r--r--core/java/com/android/internal/os/RuntimeInit.java2
-rw-r--r--core/proto/android/app/settings_enums.proto7
-rw-r--r--core/proto/android/os/incident.proto6
-rw-r--r--core/proto/android/server/activitymanagerservice.proto1
-rw-r--r--core/proto/android/server/notificationhistory.proto2
-rw-r--r--core/proto/android/service/sensor_service.proto246
-rw-r--r--core/res/AndroidManifest.xml13
-rw-r--r--core/res/res/values/config.xml3
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--core/tests/coretests/AndroidManifest.xml4
-rw-r--r--core/tests/coretests/src/android/content/integrity/AtomicFormulaTest.java12
-rw-r--r--core/tests/coretests/src/android/content/integrity/IntegrityFormulaTest.java12
-rw-r--r--core/tests/coretests/src/android/os/BuildTest.java2
-rw-r--r--core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java42
-rw-r--r--core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java13
-rw-r--r--core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java63
-rw-r--r--data/etc/com.android.settings.xml3
-rw-r--r--data/etc/platform.xml5
-rw-r--r--data/etc/privapp-permissions-platform.xml4
-rw-r--r--libs/hwui/HardwareBitmapUploader.cpp21
-rw-r--r--media/java/android/media/IMediaRoute2Provider.aidl1
-rw-r--r--media/java/android/media/IMediaRouterService.aidl3
-rw-r--r--media/java/android/media/MediaRoute2ProviderService.java37
-rw-r--r--media/java/android/media/MediaRouter2.java25
-rw-r--r--media/java/android/media/MediaRouter2Manager.java24
-rw-r--r--media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java7
-rw-r--r--media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java14
-rw-r--r--packages/SettingsLib/Android.bp1
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/Utils.java18
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java11
-rw-r--r--packages/Shell/AndroidManifest.xml5
-rw-r--r--packages/SystemUI/AndroidManifest.xml1
-rw-r--r--packages/SystemUI/res/layout/auth_credential_password_view.xml1
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt43
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt72
-rw-r--r--packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java15
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java8
-rw-r--r--services/core/java/com/android/server/compat/PlatformCompat.java45
-rw-r--r--services/core/java/com/android/server/media/MediaRoute2Provider.java1
-rw-r--r--services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java16
-rw-r--r--services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java60
-rw-r--r--services/core/java/com/android/server/media/MediaRouterService.java13
-rw-r--r--services/core/java/com/android/server/media/SystemMediaRoute2Provider.java5
-rw-r--r--services/core/java/com/android/server/pm/Installer.java6
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java12
-rw-r--r--services/core/java/com/android/server/policy/LegacyGlobalActions.java2
-rw-r--r--services/core/java/com/android/server/stats/pull/StatsPullAtomService.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityStartController.java20
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java1
-rw-r--r--services/tests/mockingservicestests/AndroidManifest.xml2
-rw-r--r--services/tests/servicestests/AndroidManifest.xml2
-rw-r--r--services/tests/uiservicestests/AndroidManifest.xml2
-rw-r--r--tests/PlatformCompatGating/Android.bp9
-rw-r--r--tests/PlatformCompatGating/AndroidManifest.xml2
-rw-r--r--tests/PlatformCompatGating/AndroidTest.xml1
-rw-r--r--tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java13
-rw-r--r--tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatPermissionsTest.java319
-rw-r--r--tests/PlatformCompatGating/test-rules/Android.bp2
-rw-r--r--tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java12
-rw-r--r--tools/stats_log_api_gen/Android.bp2
-rw-r--r--tools/stats_log_api_gen/java_writer_q.cpp26
-rw-r--r--tools/streaming_proto/cpp/main.cpp14
94 files changed, 1291 insertions, 845 deletions
diff --git a/Android.bp b/Android.bp
index 5796fb17046c..12bc90680dd5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -653,6 +653,33 @@ gensrcs {
output_extension: "srcjar",
}
+gensrcs {
+ name: "framework-cppstream-protos",
+ depfile: true,
+
+ tools: [
+ "aprotoc",
+ "protoc-gen-cppstream",
+ ],
+
+ cmd: "mkdir -p $(genDir) " +
+ "&& $(location aprotoc) " +
+ " --plugin=$(location protoc-gen-cppstream) " +
+ " --dependency_out=$(depfile) " +
+ " --cppstream_out=$(genDir) " +
+ " -Iexternal/protobuf/src " +
+ " -I . " +
+ " $(in)",
+
+ srcs: [
+ ":ipconnectivity-proto-src",
+ "core/proto/**/*.proto",
+ "libs/incident/**/*.proto",
+ ],
+
+ output_extension: "proto.h",
+}
+
filegroup {
name: "framework-annotations",
srcs: [
@@ -1010,43 +1037,6 @@ aidl_interface {
},
}
-gensrcs {
- name: "gen-platform-proto-constants",
- depfile: true,
-
- tools: [
- "aprotoc",
- "protoc-gen-cppstream",
- ],
-
- srcs: [
- "core/proto/android/os/backtrace.proto",
- "core/proto/android/os/batterytype.proto",
- "core/proto/android/os/cpufreq.proto",
- "core/proto/android/os/cpuinfo.proto",
- "core/proto/android/os/data.proto",
- "core/proto/android/os/kernelwake.proto",
- "core/proto/android/os/pagetypeinfo.proto",
- "core/proto/android/os/procrank.proto",
- "core/proto/android/os/ps.proto",
- "core/proto/android/os/system_properties.proto",
- "core/proto/android/util/event_log_tags.proto",
- "core/proto/android/util/log.proto",
- ],
-
- // Append protoc-gen-cppstream tool's PATH otherwise aprotoc can't find the plugin tool
- cmd: "mkdir -p $(genDir) " +
- "&& $(location aprotoc) " +
- " --plugin=$(location protoc-gen-cppstream) " +
- " --dependency_out=$(depfile) " +
- " --cppstream_out=$(genDir) " +
- " -Iexternal/protobuf/src " +
- " -I . " +
- " $(in)",
-
- output_extension: "proto.h",
-}
-
subdirs = [
"cmds/*",
diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java
index d59270c6a51b..96110e1541f8 100644
--- a/apex/media/framework/java/android/media/MediaParser.java
+++ b/apex/media/framework/java/android/media/MediaParser.java
@@ -15,6 +15,7 @@
*/
package android.media;
+import android.annotation.CheckResult;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.Uri;
@@ -32,6 +33,7 @@ import com.google.android.exoplayer2.extractor.PositionHolder;
import com.google.android.exoplayer2.extractor.SeekMap.SeekPoints;
import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.extractor.amr.AmrExtractor;
+import com.google.android.exoplayer2.extractor.flac.FlacExtractor;
import com.google.android.exoplayer2.extractor.flv.FlvExtractor;
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
import com.google.android.exoplayer2.extractor.mp3.Mp3Extractor;
@@ -382,6 +384,7 @@ public final class MediaParser {
* parse the input.
*/
@NonNull
+ @CheckResult
private static UnrecognizedInputFormatException createForExtractors(
@NonNull String... extractorNames) {
StringBuilder builder = new StringBuilder();
@@ -536,7 +539,7 @@ public final class MediaParser {
}
}
if (mExtractor == null) {
- UnrecognizedInputFormatException.createForExtractors(mExtractorNamesPool);
+ throw UnrecognizedInputFormatException.createForExtractors(mExtractorNamesPool);
}
return true;
}
@@ -912,6 +915,7 @@ public final class MediaParser {
extractorFactoriesByName.put("exo.Ac4Extractor", Ac4Extractor::new);
extractorFactoriesByName.put("exo.AdtsExtractor", AdtsExtractor::new);
extractorFactoriesByName.put("exo.AmrExtractor", AmrExtractor::new);
+ extractorFactoriesByName.put("exo.FlacExtractor", FlacExtractor::new);
extractorFactoriesByName.put("exo.FlvExtractor", FlvExtractor::new);
extractorFactoriesByName.put("exo.FragmentedMp4Extractor", FragmentedMp4Extractor::new);
extractorFactoriesByName.put("exo.MatroskaExtractor", MatroskaExtractor::new);
diff --git a/api/current.txt b/api/current.txt
index 6e3a6562b146..81c4c922b730 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -26799,7 +26799,6 @@ package android.media {
method public abstract void onSelectRoute(@NonNull String, @NonNull String);
method public abstract void onSetVolume(@NonNull String, int);
method public abstract void onTransferToRoute(@NonNull String, @NonNull String);
- method public abstract void onUpdateVolume(@NonNull String, int);
field public static final long REQUEST_ID_UNKNOWN = 0L; // 0x0L
field public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService";
}
@@ -35688,6 +35687,7 @@ package android.os {
field public static final String INCREMENTAL;
field public static final int PREVIEW_SDK_INT;
field public static final String RELEASE;
+ field @NonNull public static final String RELEASE_OR_CODENAME;
field @Deprecated public static final String SDK;
field public static final int SDK_INT;
field public static final String SECURITY_PATCH;
diff --git a/api/system-current.txt b/api/system-current.txt
index 97914ddf7064..7903fbab696a 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1473,9 +1473,9 @@ package android.bluetooth {
public final class BluetoothAdapter {
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean addOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean connectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean connectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice);
method public boolean disableBLE();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean disconnectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean disconnectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice);
method public boolean enableBLE();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean enableNoAutoConnect();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean factoryReset();
diff --git a/cmds/incident_helper/Android.bp b/cmds/incident_helper/Android.bp
index 64f4c667820d..f07743ec2ee6 100644
--- a/cmds/incident_helper/Android.bp
+++ b/cmds/incident_helper/Android.bp
@@ -44,7 +44,7 @@ cc_defaults {
"src/ih_util.cpp",
],
- generated_headers: ["gen-platform-proto-constants"],
+ generated_headers: ["framework-cppstream-protos"],
shared_libs: [
"libbase",
diff --git a/cmds/incidentd/Android.bp b/cmds/incidentd/Android.bp
index cc724a626baf..c47526abad53 100644
--- a/cmds/incidentd/Android.bp
+++ b/cmds/incidentd/Android.bp
@@ -43,7 +43,7 @@ cc_binary {
],
local_include_dirs: ["src"],
- generated_headers: ["gen-platform-proto-constants"],
+ generated_headers: ["framework-cppstream-protos"],
proto: {
type: "lite",
@@ -98,7 +98,7 @@ cc_test {
],
local_include_dirs: ["src"],
- generated_headers: ["gen-platform-proto-constants"],
+ generated_headers: ["framework-cppstream-protos"],
srcs: [
"tests/**/*.cpp",
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 8e5309fcbb7d..3a2472efb601 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -65,7 +65,6 @@ cc_defaults {
"src/config/ConfigListener.cpp",
"src/config/ConfigManager.cpp",
"src/experiment_ids.proto",
- "src/external/GpuStatsPuller.cpp",
"src/external/Perfetto.cpp",
"src/external/PullResultReceiver.cpp",
"src/external/puller_util.cpp",
@@ -111,7 +110,7 @@ cc_defaults {
],
cflags: [
- // "-DNEW_ENCODING_SCHEME",
+ "-DNEW_ENCODING_SCHEME",
],
local_include_dirs: [
@@ -122,19 +121,18 @@ cc_defaults {
"android.frameworks.stats@1.0",
"libbase",
"libcutils",
- "liblog",
"libprotoutil",
"libstatslog",
- "libstatssocket",
+ "libstatsmetadata",
"libsysutils",
],
shared_libs: [
"libbinder",
- "libgraphicsenv",
"libhidlbase",
"libincident",
+ "liblog",
"libservices",
- "libstatsmetadata",
+ "libstatssocket",
"libutils",
],
}
@@ -161,7 +159,7 @@ genrule {
],
}
-cc_library_shared {
+cc_library_static {
name: "libstatsmetadata",
host_supported: true,
generated_sources: [
@@ -278,7 +276,6 @@ cc_test {
"tests/e2e/PartialBucket_e2e_test.cpp",
"tests/e2e/ValueMetric_pull_e2e_test.cpp",
"tests/e2e/WakelockDuration_e2e_test.cpp",
- "tests/external/GpuStatsPuller_test.cpp",
"tests/external/puller_util_test.cpp",
"tests/external/StatsCallbackPuller_test.cpp",
"tests/external/StatsPuller_test.cpp",
diff --git a/cmds/statsd/src/external/GpuStatsPuller.cpp b/cmds/statsd/src/external/GpuStatsPuller.cpp
deleted file mode 100644
index 3229ba82fe3c..000000000000
--- a/cmds/statsd/src/external/GpuStatsPuller.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * 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
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "GpuStatsPuller.h"
-
-#include <binder/IServiceManager.h>
-#include <graphicsenv/GpuStatsInfo.h>
-#include <graphicsenv/IGpuService.h>
-
-#include "logd/LogEvent.h"
-
-#include "stats_log_util.h"
-#include "statslog.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoReader;
-
-GpuStatsPuller::GpuStatsPuller(const int tagId) : StatsPuller(tagId) {
-}
-
-static sp<IGpuService> getGpuService() {
- const sp<IBinder> binder = defaultServiceManager()->checkService(String16("gpu"));
- if (!binder) {
- ALOGE("Failed to get gpu service");
- return nullptr;
- }
-
- return interface_cast<IGpuService>(binder);
-}
-
-static bool pullGpuStatsGlobalInfo(const sp<IGpuService>& gpuService,
- std::vector<std::shared_ptr<LogEvent>>* data) {
- std::vector<GpuStatsGlobalInfo> stats;
- status_t status = gpuService->getGpuStatsGlobalInfo(&stats);
- if (status != OK) {
- return false;
- }
-
- data->clear();
- data->reserve(stats.size());
- for (const auto& info : stats) {
- std::shared_ptr<LogEvent> event = make_shared<LogEvent>(
- android::util::GPU_STATS_GLOBAL_INFO, getWallClockNs(), getElapsedRealtimeNs());
- if (!event->write(info.driverPackageName)) return false;
- if (!event->write(info.driverVersionName)) return false;
- if (!event->write((int64_t)info.driverVersionCode)) return false;
- if (!event->write(info.driverBuildTime)) return false;
- if (!event->write((int64_t)info.glLoadingCount)) return false;
- if (!event->write((int64_t)info.glLoadingFailureCount)) return false;
- if (!event->write((int64_t)info.vkLoadingCount)) return false;
- if (!event->write((int64_t)info.vkLoadingFailureCount)) return false;
- if (!event->write(info.vulkanVersion)) return false;
- if (!event->write(info.cpuVulkanVersion)) return false;
- if (!event->write(info.glesVersion)) return false;
- if (!event->write((int64_t)info.angleLoadingCount)) return false;
- if (!event->write((int64_t)info.angleLoadingFailureCount)) return false;
- event->init();
- data->emplace_back(event);
- }
-
- return true;
-}
-
-static bool pullGpuStatsAppInfo(const sp<IGpuService>& gpuService,
- std::vector<std::shared_ptr<LogEvent>>* data) {
- std::vector<GpuStatsAppInfo> stats;
- status_t status = gpuService->getGpuStatsAppInfo(&stats);
- if (status != OK) {
- return false;
- }
-
- data->clear();
- data->reserve(stats.size());
- for (const auto& info : stats) {
- std::shared_ptr<LogEvent> event = make_shared<LogEvent>(
- android::util::GPU_STATS_APP_INFO, getWallClockNs(), getElapsedRealtimeNs());
- if (!event->write(info.appPackageName)) return false;
- if (!event->write((int64_t)info.driverVersionCode)) return false;
- if (!event->writeBytes(int64VectorToProtoByteString(info.glDriverLoadingTime))) {
- return false;
- }
- if (!event->writeBytes(int64VectorToProtoByteString(info.vkDriverLoadingTime))) {
- return false;
- }
- if (!event->writeBytes(int64VectorToProtoByteString(info.angleDriverLoadingTime))) {
- return false;
- }
- if (!event->write(info.cpuVulkanInUse)) return false;
- if (!event->write(info.falsePrerotation)) return false;
- if (!event->write(info.gles1InUse)) return false;
- event->init();
- data->emplace_back(event);
- }
-
- return true;
-}
-
-bool GpuStatsPuller::PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) {
- const sp<IGpuService> gpuService = getGpuService();
- if (!gpuService) {
- return false;
- }
-
- switch (mTagId) {
- case android::util::GPU_STATS_GLOBAL_INFO:
- return pullGpuStatsGlobalInfo(gpuService, data);
- case android::util::GPU_STATS_APP_INFO:
- return pullGpuStatsAppInfo(gpuService, data);
- default:
- break;
- }
-
- return false;
-}
-
-static std::string protoOutputStreamToByteString(ProtoOutputStream& proto) {
- if (!proto.size()) return "";
-
- std::string byteString;
- sp<ProtoReader> reader = proto.data();
- while (reader->readBuffer() != nullptr) {
- const size_t toRead = reader->currentToRead();
- byteString.append((char*)reader->readBuffer(), toRead);
- reader->move(toRead);
- }
-
- if (byteString.size() != proto.size()) return "";
-
- return byteString;
-}
-
-std::string int64VectorToProtoByteString(const std::vector<int64_t>& value) {
- if (value.empty()) return "";
-
- ProtoOutputStream proto;
- for (const auto& ele : value) {
- proto.write(android::util::FIELD_TYPE_INT64 | android::util::FIELD_COUNT_REPEATED |
- 1 /* field id */,
- (long long)ele);
- }
-
- return protoOutputStreamToByteString(proto);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/GpuStatsPuller.h b/cmds/statsd/src/external/GpuStatsPuller.h
deleted file mode 100644
index 2da199c51e0f..000000000000
--- a/cmds/statsd/src/external/GpuStatsPuller.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * 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
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "StatsPuller.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Pull GpuStats from GpuService.
- */
-class GpuStatsPuller : public StatsPuller {
-public:
- explicit GpuStatsPuller(const int tagId);
- bool PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) override;
-};
-
-// convert a int64_t vector into a byte string for proto message like:
-// message RepeatedInt64Wrapper {
-// repeated int64 value = 1;
-// }
-std::string int64VectorToProtoByteString(const std::vector<int64_t>& value);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 15d7e33d63fd..3ceff7529440 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -32,7 +32,6 @@
#include "../logd/LogEvent.h"
#include "../stats_log_util.h"
#include "../statscompanion_util.h"
-#include "GpuStatsPuller.h"
#include "StatsCallbackPuller.h"
#include "TrainInfoPuller.h"
#include "statslog.h"
@@ -51,15 +50,6 @@ StatsPullerManager::StatsPullerManager()
: kAllPullAtomInfo({
// TrainInfo.
{{.atomTag = android::util::TRAIN_INFO}, new TrainInfoPuller()},
-
- // GpuStatsGlobalInfo
- {{.atomTag = android::util::GPU_STATS_GLOBAL_INFO},
- new GpuStatsPuller(android::util::GPU_STATS_GLOBAL_INFO)},
-
- // GpuStatsAppInfo
- {{.atomTag = android::util::GPU_STATS_APP_INFO},
- new GpuStatsPuller(android::util::GPU_STATS_APP_INFO)},
-
}),
mNextPullTimeNs(NO_ALARM_UPDATE) {
}
diff --git a/cmds/statsd/tests/external/GpuStatsPuller_test.cpp b/cmds/statsd/tests/external/GpuStatsPuller_test.cpp
deleted file mode 100644
index ae92705aff4c..000000000000
--- a/cmds/statsd/tests/external/GpuStatsPuller_test.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * 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
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#undef LOG_TAG
-#define LOG_TAG "GpuStatsPuller_test"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <graphicsenv/GpuStatsInfo.h>
-#include <log/log.h>
-
-#include "src/external/GpuStatsPuller.h"
-#include "statslog.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// clang-format off
-static const std::string DRIVER_PACKAGE_NAME = "TEST_DRIVER";
-static const std::string DRIVER_VERSION_NAME = "TEST_DRIVER_VERSION";
-static const std::string APP_PACKAGE_NAME = "TEST_APP";
-static const int64_t TIMESTAMP_WALLCLOCK = 111;
-static const int64_t TIMESTAMP_ELAPSED = 222;
-static const int64_t DRIVER_VERSION_CODE = 333;
-static const int64_t DRIVER_BUILD_TIME = 444;
-static const int64_t GL_LOADING_COUNT = 3;
-static const int64_t GL_LOADING_FAILURE_COUNT = 1;
-static const int64_t VK_LOADING_COUNT = 4;
-static const int64_t VK_LOADING_FAILURE_COUNT = 0;
-static const int64_t ANGLE_LOADING_COUNT = 2;
-static const int64_t ANGLE_LOADING_FAILURE_COUNT = 1;
-static const int64_t GL_DRIVER_LOADING_TIME_0 = 555;
-static const int64_t GL_DRIVER_LOADING_TIME_1 = 666;
-static const int64_t VK_DRIVER_LOADING_TIME_0 = 777;
-static const int64_t VK_DRIVER_LOADING_TIME_1 = 888;
-static const int64_t VK_DRIVER_LOADING_TIME_2 = 999;
-static const int64_t ANGLE_DRIVER_LOADING_TIME_0 = 1010;
-static const int64_t ANGLE_DRIVER_LOADING_TIME_1 = 1111;
-static const int32_t VULKAN_VERSION = 1;
-static const int32_t CPU_VULKAN_VERSION = 2;
-static const int32_t GLES_VERSION = 3;
-static const bool CPU_VULKAN_IN_USE = true;
-static const bool FALSE_PREROTATION = true;
-static const bool GLES_1_IN_USE = true;
-static const size_t NUMBER_OF_VALUES_GLOBAL = 13;
-static const size_t NUMBER_OF_VALUES_APP = 8;
-// clang-format on
-
-class MockGpuStatsPuller : public GpuStatsPuller {
-public:
- MockGpuStatsPuller(const int tagId, vector<std::shared_ptr<LogEvent>>* data)
- : GpuStatsPuller(tagId), mData(data){};
-
-private:
- bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override {
- *data = *mData;
- return true;
- }
-
- vector<std::shared_ptr<LogEvent>>* mData;
-};
-
-class GpuStatsPuller_test : public ::testing::Test {
-public:
- GpuStatsPuller_test() {
- const ::testing::TestInfo* const test_info =
- ::testing::UnitTest::GetInstance()->current_test_info();
- ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
- }
-
- ~GpuStatsPuller_test() {
- const ::testing::TestInfo* const test_info =
- ::testing::UnitTest::GetInstance()->current_test_info();
- ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
- }
-};
-
-TEST_F(GpuStatsPuller_test, PullGpuStatsGlobalInfo) {
- vector<std::shared_ptr<LogEvent>> inData, outData;
- std::shared_ptr<LogEvent> event = make_shared<LogEvent>(android::util::GPU_STATS_GLOBAL_INFO,
- TIMESTAMP_WALLCLOCK, TIMESTAMP_ELAPSED);
- EXPECT_TRUE(event->write(DRIVER_PACKAGE_NAME));
- EXPECT_TRUE(event->write(DRIVER_VERSION_NAME));
- EXPECT_TRUE(event->write(DRIVER_VERSION_CODE));
- EXPECT_TRUE(event->write(DRIVER_BUILD_TIME));
- EXPECT_TRUE(event->write(GL_LOADING_COUNT));
- EXPECT_TRUE(event->write(GL_LOADING_FAILURE_COUNT));
- EXPECT_TRUE(event->write(VK_LOADING_COUNT));
- EXPECT_TRUE(event->write(VK_LOADING_FAILURE_COUNT));
- EXPECT_TRUE(event->write(VULKAN_VERSION));
- EXPECT_TRUE(event->write(CPU_VULKAN_VERSION));
- EXPECT_TRUE(event->write(GLES_VERSION));
- EXPECT_TRUE(event->write(ANGLE_LOADING_COUNT));
- EXPECT_TRUE(event->write(ANGLE_LOADING_FAILURE_COUNT));
- event->init();
- inData.emplace_back(event);
- MockGpuStatsPuller mockPuller(android::util::GPU_STATS_GLOBAL_INFO, &inData);
- mockPuller.ForceClearCache();
- mockPuller.Pull(&outData);
-
- ASSERT_EQ(1, outData.size());
- EXPECT_EQ(android::util::GPU_STATS_GLOBAL_INFO, outData[0]->GetTagId());
- ASSERT_EQ(NUMBER_OF_VALUES_GLOBAL, outData[0]->size());
- EXPECT_EQ(DRIVER_PACKAGE_NAME, outData[0]->getValues()[0].mValue.str_value);
- EXPECT_EQ(DRIVER_VERSION_NAME, outData[0]->getValues()[1].mValue.str_value);
- EXPECT_EQ(DRIVER_VERSION_CODE, outData[0]->getValues()[2].mValue.long_value);
- EXPECT_EQ(DRIVER_BUILD_TIME, outData[0]->getValues()[3].mValue.long_value);
- EXPECT_EQ(GL_LOADING_COUNT, outData[0]->getValues()[4].mValue.long_value);
- EXPECT_EQ(GL_LOADING_FAILURE_COUNT, outData[0]->getValues()[5].mValue.long_value);
- EXPECT_EQ(VK_LOADING_COUNT, outData[0]->getValues()[6].mValue.long_value);
- EXPECT_EQ(VK_LOADING_FAILURE_COUNT, outData[0]->getValues()[7].mValue.long_value);
- EXPECT_EQ(VULKAN_VERSION, outData[0]->getValues()[8].mValue.int_value);
- EXPECT_EQ(CPU_VULKAN_VERSION, outData[0]->getValues()[9].mValue.int_value);
- EXPECT_EQ(GLES_VERSION, outData[0]->getValues()[10].mValue.int_value);
- EXPECT_EQ(ANGLE_LOADING_COUNT, outData[0]->getValues()[11].mValue.long_value);
- EXPECT_EQ(ANGLE_LOADING_FAILURE_COUNT, outData[0]->getValues()[12].mValue.long_value);
-}
-
-TEST_F(GpuStatsPuller_test, PullGpuStatsAppInfo) {
- vector<std::shared_ptr<LogEvent>> inData, outData;
- std::shared_ptr<LogEvent> event = make_shared<LogEvent>(android::util::GPU_STATS_APP_INFO,
- TIMESTAMP_WALLCLOCK, TIMESTAMP_ELAPSED);
- EXPECT_TRUE(event->write(APP_PACKAGE_NAME));
- EXPECT_TRUE(event->write(DRIVER_VERSION_CODE));
- std::vector<int64_t> glDriverLoadingTime;
- glDriverLoadingTime.emplace_back(GL_DRIVER_LOADING_TIME_0);
- glDriverLoadingTime.emplace_back(GL_DRIVER_LOADING_TIME_1);
- std::vector<int64_t> vkDriverLoadingTime;
- vkDriverLoadingTime.emplace_back(VK_DRIVER_LOADING_TIME_0);
- vkDriverLoadingTime.emplace_back(VK_DRIVER_LOADING_TIME_1);
- vkDriverLoadingTime.emplace_back(VK_DRIVER_LOADING_TIME_2);
- std::vector<int64_t> angleDriverLoadingTime;
- angleDriverLoadingTime.emplace_back(ANGLE_DRIVER_LOADING_TIME_0);
- angleDriverLoadingTime.emplace_back(ANGLE_DRIVER_LOADING_TIME_1);
- EXPECT_TRUE(event->write(int64VectorToProtoByteString(glDriverLoadingTime)));
- EXPECT_TRUE(event->write(int64VectorToProtoByteString(vkDriverLoadingTime)));
- EXPECT_TRUE(event->write(int64VectorToProtoByteString(angleDriverLoadingTime)));
- EXPECT_TRUE(event->write(CPU_VULKAN_IN_USE));
- EXPECT_TRUE(event->write(FALSE_PREROTATION));
- EXPECT_TRUE(event->write(GLES_1_IN_USE));
- event->init();
- inData.emplace_back(event);
- MockGpuStatsPuller mockPuller(android::util::GPU_STATS_APP_INFO, &inData);
- mockPuller.ForceClearCache();
- mockPuller.Pull(&outData);
-
- ASSERT_EQ(1, outData.size());
- EXPECT_EQ(android::util::GPU_STATS_APP_INFO, outData[0]->GetTagId());
- ASSERT_EQ(NUMBER_OF_VALUES_APP, outData[0]->size());
- EXPECT_EQ(APP_PACKAGE_NAME, outData[0]->getValues()[0].mValue.str_value);
- EXPECT_EQ(DRIVER_VERSION_CODE, outData[0]->getValues()[1].mValue.long_value);
- EXPECT_EQ(int64VectorToProtoByteString(glDriverLoadingTime),
- outData[0]->getValues()[2].mValue.str_value);
- EXPECT_EQ(int64VectorToProtoByteString(vkDriverLoadingTime),
- outData[0]->getValues()[3].mValue.str_value);
- EXPECT_EQ(int64VectorToProtoByteString(angleDriverLoadingTime),
- outData[0]->getValues()[4].mValue.str_value);
- EXPECT_EQ(CPU_VULKAN_IN_USE, outData[0]->getValues()[5].mValue.int_value);
- EXPECT_EQ(FALSE_PREROTATION, outData[0]->getValues()[6].mValue.int_value);
- EXPECT_EQ(GLES_1_IN_USE, outData[0]->getValues()[7].mValue.int_value);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 2e93d43f7c15..01ccb86fb129 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1861,15 +1861,19 @@ public final class BluetoothAdapter {
}
/**
- * Connects all enabled and supported bluetooth profiles between the local and remote device
+ * Connects all enabled and supported bluetooth profiles between the local and remote device.
+ * Connection is asynchronous and you should listen to each profile's broadcast intent
+ * ACTION_CONNECTION_STATE_CHANGED to verify whether connection was successful. For example,
+ * to verify a2dp is connected, you would listen for
+ * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}
*
* @param device is the remote device with which to connect these profiles
- * @return true if all profiles successfully connected, false if an error occurred
+ * @return true if message sent to try to connect all profiles, false if an error occurred
*
* @hide
*/
@SystemApi
- @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean connectAllEnabledProfiles(@NonNull BluetoothDevice device) {
try {
mServiceLock.readLock().lock();
@@ -1886,15 +1890,19 @@ public final class BluetoothAdapter {
}
/**
- * Disconnects all enabled and supported bluetooth profiles between the local and remote device
+ * Disconnects all enabled and supported bluetooth profiles between the local and remote device.
+ * Disconnection is asynchronous and you should listen to each profile's broadcast intent
+ * ACTION_CONNECTION_STATE_CHANGED to verify whether disconnection was successful. For example,
+ * to verify a2dp is disconnected, you would listen for
+ * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}
*
* @param device is the remote device with which to disconnect these profiles
- * @return true if all profiles successfully disconnected, false if an error occurred
+ * @return true if message sent to try to disconnect all profiles, false if an error occurred
*
* @hide
*/
@SystemApi
- @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean disconnectAllEnabledProfiles(@NonNull BluetoothDevice device) {
try {
mServiceLock.readLock().lock();
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index a29173469ffb..70b2db70a9e8 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -240,6 +240,13 @@ public class Build {
public static final String RELEASE = getString("ro.build.version.release");
/**
+ * The version string we show to the user; may be {@link #RELEASE} or
+ * {@link #CODENAME} if not a final release build.
+ */
+ @NonNull public static final String RELEASE_OR_CODENAME = getString(
+ "ro.build.version.release_or_codename");
+
+ /**
* The base OS build the product is based on.
*/
public static final String BASE_OS = SystemProperties.get("ro.build.version.base_os", "");
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 44f12a6adf60..21a1e0f0a108 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -34,9 +34,11 @@ import android.text.TextUtils;
import android.util.Log;
import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
+import java.util.List;
/**
* Provides access to environment variables.
@@ -539,12 +541,21 @@ public class Environment {
@SystemApi
public static @NonNull Collection<File> getInternalMediaDirectories() {
final ArrayList<File> res = new ArrayList<>();
- res.add(new File(Environment.getRootDirectory(), "media"));
- res.add(new File(Environment.getOemDirectory(), "media"));
- res.add(new File(Environment.getProductDirectory(), "media"));
+ addCanonicalFile(res, new File(Environment.getRootDirectory(), "media"));
+ addCanonicalFile(res, new File(Environment.getOemDirectory(), "media"));
+ addCanonicalFile(res, new File(Environment.getProductDirectory(), "media"));
return res;
}
+ private static void addCanonicalFile(List<File> list, File file) {
+ try {
+ list.add(file.getCanonicalFile());
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to resolve " + file + ": " + e);
+ list.add(file);
+ }
+ }
+
/**
* Return the primary shared/external storage directory. This directory may
* not currently be accessible if it has been mounted by the user on their
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index b6f5138a6582..adfa885f121e 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -5205,6 +5205,7 @@ public final class Telephony {
/**
* TelephonyProvider column name for allowed network types. Indicate which network types
* are allowed. Default is -1.
+ * <P>Type: BIGINT (long) </P>
*/
public static final String ALLOWED_NETWORK_TYPES = "allowed_network_types";
}
diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java
index 848868a5532f..3ff6f549e337 100644
--- a/core/java/android/service/textclassifier/TextClassifierService.java
+++ b/core/java/android/service/textclassifier/TextClassifierService.java
@@ -41,6 +41,7 @@ import android.util.Slog;
import android.view.textclassifier.ConversationActions;
import android.view.textclassifier.SelectionEvent;
import android.view.textclassifier.TextClassification;
+import android.view.textclassifier.TextClassificationConstants;
import android.view.textclassifier.TextClassificationContext;
import android.view.textclassifier.TextClassificationManager;
import android.view.textclassifier.TextClassificationSessionId;
@@ -404,22 +405,27 @@ public abstract class TextClassifierService extends Service {
*/
@NonNull
public static TextClassifier getDefaultTextClassifierImplementation(@NonNull Context context) {
- final String defaultTextClassifierPackageName =
- context.getPackageManager().getDefaultTextClassifierPackageName();
- if (TextUtils.isEmpty(defaultTextClassifierPackageName)) {
- return TextClassifier.NO_OP;
- }
- if (defaultTextClassifierPackageName.equals(context.getPackageName())) {
- throw new RuntimeException(
- "The default text classifier itself should not call the"
- + "getDefaultTextClassifierImplementation() method.");
- }
final TextClassificationManager tcm =
context.getSystemService(TextClassificationManager.class);
- if (tcm != null) {
+ if (tcm == null) {
+ return TextClassifier.NO_OP;
+ }
+ TextClassificationConstants settings = new TextClassificationConstants();
+ if (settings.getUseDefaultTextClassifierAsDefaultImplementation()) {
+ final String defaultTextClassifierPackageName =
+ context.getPackageManager().getDefaultTextClassifierPackageName();
+ if (TextUtils.isEmpty(defaultTextClassifierPackageName)) {
+ return TextClassifier.NO_OP;
+ }
+ if (defaultTextClassifierPackageName.equals(context.getPackageName())) {
+ throw new RuntimeException(
+ "The default text classifier itself should not call the"
+ + "getDefaultTextClassifierImplementation() method.");
+ }
return tcm.getTextClassifier(TextClassifier.DEFAULT_SERVICE);
+ } else {
+ return tcm.getTextClassifier(TextClassifier.LOCAL);
}
- return TextClassifier.NO_OP;
}
/** @hide **/
diff --git a/core/java/android/timezone/CountryTimeZones.java b/core/java/android/timezone/CountryTimeZones.java
index ab2c4fc1bf23..ee3a8a79d5d7 100644
--- a/core/java/android/timezone/CountryTimeZones.java
+++ b/core/java/android/timezone/CountryTimeZones.java
@@ -18,7 +18,6 @@ package android.timezone;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SuppressLint;
import android.icu.util.TimeZone;
import java.util.ArrayList;
@@ -206,27 +205,47 @@ public final class CountryTimeZones {
}
/**
- * Returns a time zone for the country, if there is one, that matches the desired properties. If
- * there are multiple matches and the {@code bias} is one of them then it is returned, otherwise
- * an arbitrary match is returned based on the {@link #getEffectiveTimeZoneMappingsAt(long)}
- * ordering.
+ * Returns a time zone for the country, if there is one, that matches the supplied properties.
+ * If there are multiple matches and the {@code bias} is one of them then it is returned,
+ * otherwise an arbitrary match is returned based on the {@link
+ * #getEffectiveTimeZoneMappingsAt(long)} ordering.
*
+ * @param whenMillis the UTC time to match against
+ * @param bias the time zone to prefer, can be {@code null} to indicate there is no preference
* @param totalOffsetMillis the offset from UTC at {@code whenMillis}
* @param isDst the Daylight Savings Time state at {@code whenMillis}. {@code true} means DST,
- * {@code false} means not DST, {@code null} means unknown
- * @param dstOffsetMillis the part of {@code totalOffsetMillis} contributed by DST, only used if
- * {@code isDst} is {@code true}. The value can be {@code null} if the DST offset is
- * unknown
- * @param whenMillis the UTC time to match against
- * @param bias the time zone to prefer, can be {@code null}
+ * {@code false} means not DST
+ * @return an {@link OffsetResult} with information about a matching zone, or {@code null} if
+ * there is no match
*/
@Nullable
- public OffsetResult lookupByOffsetWithBias(int totalOffsetMillis, @Nullable Boolean isDst,
- @SuppressLint("AutoBoxing") @Nullable Integer dstOffsetMillis, long whenMillis,
- @Nullable TimeZone bias) {
+ public OffsetResult lookupByOffsetWithBias(long whenMillis, @Nullable TimeZone bias,
+ int totalOffsetMillis, boolean isDst) {
libcore.timezone.CountryTimeZones.OffsetResult delegateOffsetResult =
mDelegate.lookupByOffsetWithBias(
- totalOffsetMillis, isDst, dstOffsetMillis, whenMillis, bias);
+ whenMillis, bias, totalOffsetMillis, isDst);
+ return delegateOffsetResult == null ? null :
+ new OffsetResult(
+ delegateOffsetResult.getTimeZone(), delegateOffsetResult.isOnlyMatch());
+ }
+
+ /**
+ * Returns a time zone for the country, if there is one, that matches the supplied properties.
+ * If there are multiple matches and the {@code bias} is one of them then it is returned,
+ * otherwise an arbitrary match is returned based on the {@link
+ * #getEffectiveTimeZoneMappingsAt(long)} ordering.
+ *
+ * @param whenMillis the UTC time to match against
+ * @param bias the time zone to prefer, can be {@code null} to indicate there is no preference
+ * @param totalOffsetMillis the offset from UTC at {@code whenMillis}
+ * @return an {@link OffsetResult} with information about a matching zone, or {@code null} if
+ * there is no match
+ */
+ @Nullable
+ public OffsetResult lookupByOffsetWithBias(long whenMillis, @Nullable TimeZone bias,
+ int totalOffsetMillis) {
+ libcore.timezone.CountryTimeZones.OffsetResult delegateOffsetResult =
+ mDelegate.lookupByOffsetWithBias(whenMillis, bias, totalOffsetMillis);
return delegateOffsetResult == null ? null :
new OffsetResult(
delegateOffsetResult.getTimeZone(), delegateOffsetResult.isOnlyMatch());
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index 36f4e5361ea6..4b3afbaada64 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -80,7 +80,7 @@ public class TimeUtils {
return null;
}
CountryTimeZones.OffsetResult offsetResult = countryTimeZones.lookupByOffsetWithBias(
- offsetMillis, isDst, null /* dstOffsetMillis */, whenMillis, bias);
+ whenMillis, bias, offsetMillis, isDst);
return offsetResult != null ? offsetResult.getTimeZone() : null;
}
diff --git a/core/java/android/view/textclassifier/TextClassificationConstants.java b/core/java/android/view/textclassifier/TextClassificationConstants.java
index ed69513b7f69..3d5ac58e7704 100644
--- a/core/java/android/view/textclassifier/TextClassificationConstants.java
+++ b/core/java/android/view/textclassifier/TextClassificationConstants.java
@@ -17,6 +17,7 @@
package android.view.textclassifier;
import android.annotation.Nullable;
+import android.content.Context;
import android.provider.DeviceConfig;
import com.android.internal.annotations.VisibleForTesting;
@@ -167,6 +168,16 @@ public final class TextClassificationConstants {
static final String TEXT_CLASSIFIER_SERVICE_PACKAGE_OVERRIDE =
"textclassifier_service_package_override";
+ /**
+ * Whether to use the default system text classifier as the default text classifier
+ * implementation. The local text classifier is used if it is {@code false}.
+ *
+ * @see android.service.textclassifier.TextClassifierService#getDefaultTextClassifierImplementation(Context)
+ */
+ // TODO: Once the system health experiment is done, remove this together with local TC.
+ private static final String USE_DEFAULT_SYSTEM_TEXT_CLASSIFIER_AS_DEFAULT_IMPL =
+ "use_default_system_text_classifier_as_default_impl";
+
private static final String DEFAULT_TEXT_CLASSIFIER_SERVICE_PACKAGE_OVERRIDE = null;
private static final boolean LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
private static final boolean SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
@@ -209,7 +220,8 @@ public final class TextClassificationConstants {
private static final boolean TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT = true;
private static final boolean TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT = true;
private static final boolean DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT = true;
- private static final float[] LANG_ID_CONTEXT_SETTINGS_DEFAULT = new float[] {20f, 1.0f, 0.4f};
+ private static final float[] LANG_ID_CONTEXT_SETTINGS_DEFAULT = new float[]{20f, 1.0f, 0.4f};
+ private static final boolean USE_DEFAULT_SYSTEM_TEXT_CLASSIFIER_AS_DEFAULT_IMPL_DEFAULT = true;
@Nullable
public String getTextClassifierServicePackageOverride() {
@@ -331,6 +343,13 @@ public final class TextClassificationConstants {
LANG_ID_CONTEXT_SETTINGS, LANG_ID_CONTEXT_SETTINGS_DEFAULT);
}
+ public boolean getUseDefaultTextClassifierAsDefaultImplementation() {
+ return DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ USE_DEFAULT_SYSTEM_TEXT_CLASSIFIER_AS_DEFAULT_IMPL,
+ USE_DEFAULT_SYSTEM_TEXT_CLASSIFIER_AS_DEFAULT_IMPL_DEFAULT);
+ }
+
void dump(IndentingPrintWriter pw) {
pw.println("TextClassificationConstants:");
pw.increaseIndent();
@@ -378,6 +397,8 @@ public final class TextClassificationConstants {
.println();
pw.printPair("textclassifier_service_package_override",
getTextClassifierServicePackageOverride()).println();
+ pw.printPair("use_default_system_text_classifier_as_default_impl",
+ getUseDefaultTextClassifierAsDefaultImplementation()).println();
pw.decreaseIndent();
}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 7fd41508dfc3..4e4a9837b32c 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -454,15 +454,17 @@ public class Editor {
aspectRatio = 5.5f;
}
- final Paint.FontMetrics fontMetrics = mTextView.getPaint().getFontMetrics();
- final float sourceHeight = fontMetrics.descent - fontMetrics.ascent;
+ final Layout layout = mTextView.getLayout();
+ final int line = layout.getLineForOffset(mTextView.getSelectionStart());
+ final int sourceHeight =
+ layout.getLineBottomWithoutSpacing(line) - layout.getLineTop(line);
// Slightly increase the height to avoid tooLargeTextForMagnifier() returns true.
int height = (int)(sourceHeight * zoom) + 2;
int width = (int)(aspectRatio * height);
params.setFishEyeStyle()
.setSize(width, height)
- .setSourceSize(width, Math.round(sourceHeight))
+ .setSourceSize(width, sourceHeight)
.setElevation(0)
.setInitialZoom(zoom)
.setClippingEnabled(false);
@@ -5041,7 +5043,7 @@ public class Editor {
// Vertically snap to middle of current line.
showPosInView.y = ((mTextView.getLayout().getLineTop(lineNumber)
- + mTextView.getLayout().getLineBottom(lineNumber)) / 2.0f
+ + mTextView.getLayout().getLineBottomWithoutSpacing(lineNumber)) / 2.0f
+ mTextView.getTotalPaddingTop() - mTextView.getScrollY()) * mTextViewScaleY;
return true;
}
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 78d4e61ea953..db714c2439bd 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -266,6 +266,7 @@ public class Toast {
* targeting API level {@link Build.VERSION_CODES#R} or higher that are in the background
* will not have custom toast views displayed.
*/
+ @Deprecated
public View getView() {
return mNextView;
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index a43e4fe118a9..65cad834d5be 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -2424,6 +2424,10 @@ public class ChooserActivity extends ResolverActivity implements
offset += findViewById(R.id.content_preview_container).getHeight();
}
+ if (hasWorkProfile() && ENABLE_TABBED_VIEW) {
+ offset += findViewById(R.id.tabs).getHeight();
+ }
+
int directShareHeight = 0;
rowsToShow = Math.min(4, rowsToShow);
for (int i = 0, childCount = recyclerView.getChildCount();
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index c6ed624d73ac..518911e652f6 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -323,7 +323,7 @@ public class RuntimeInit {
result.append(System.getProperty("java.vm.version")); // such as 1.1.0
result.append(" (Linux; U; Android ");
- String version = Build.VERSION.RELEASE; // "1.0" or "3.4b5"
+ String version = Build.VERSION.RELEASE_OR_CODENAME; // "1.0" or "3.4b5"
result.append(version.length() > 0 ? version : "1.0");
// add the model for the release build
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index a6e08d2cecc1..fc0a2ef6041a 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2562,7 +2562,7 @@ enum PageId {
// CATEGORY: SETTINGS
// OS: R
OPEN_SUPPORTED_LINKS = 1824;
-
+
// OPEN: Settings > Display > Dark theme > Set start time dialog
DIALOG_DARK_THEME_SET_START_TIME = 1825;
@@ -2573,4 +2573,9 @@ enum PageId {
// CATEGORY: SETTINGS
// OS: R
VIBRATE_FOR_CALLS = 1827;
+
+ // OPEN: Settings > Connected devices > Connection preferences > NFC
+ // CATEGORY: SETTINGS
+ // OS: R
+ CONNECTION_DEVICE_ADVANCED_NFC = 1828;
}
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 8adcc9ed905d..bf4cdee72b2d 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -52,6 +52,7 @@ import "frameworks/base/core/proto/android/service/package.proto";
import "frameworks/base/core/proto/android/service/print.proto";
import "frameworks/base/core/proto/android/service/procstats.proto";
import "frameworks/base/core/proto/android/service/restricted_image.proto";
+import "frameworks/base/core/proto/android/service/sensor_service.proto";
import "frameworks/base/core/proto/android/service/usb.proto";
import "frameworks/base/core/proto/android/util/event_log_tags.proto";
import "frameworks/base/core/proto/android/util/log.proto";
@@ -492,6 +493,11 @@ message IncidentProto {
(section).args = "contexthub --proto"
];
+ optional android.service.SensorServiceProto sensor_service = 3053 [
+ (section).type = SECTION_DUMPSYS,
+ (section).args = "sensorservice --proto"
+ ];
+
// Reserved for OEMs.
extensions 50000 to 100000;
}
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index 0a2fd7093a49..2d2ead455a4d 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -27,7 +27,6 @@ import "frameworks/base/core/proto/android/content/component_name.proto";
import "frameworks/base/core/proto/android/content/configuration.proto";
import "frameworks/base/core/proto/android/content/intent.proto";
import "frameworks/base/core/proto/android/content/package_item_info.proto";
-import "frameworks/base/core/proto/android/graphics/rect.proto";
import "frameworks/base/core/proto/android/internal/processstats.proto";
import "frameworks/base/core/proto/android/os/bundle.proto";
import "frameworks/base/core/proto/android/os/looper.proto";
diff --git a/core/proto/android/server/notificationhistory.proto b/core/proto/android/server/notificationhistory.proto
index 1e6ee3f1a3a8..6749719be124 100644
--- a/core/proto/android/server/notificationhistory.proto
+++ b/core/proto/android/server/notificationhistory.proto
@@ -17,8 +17,6 @@
syntax = "proto2";
package com.android.server.notification;
-import "frameworks/base/core/proto/android/server/enums.proto";
-
option java_multiple_files = true;
// On disk data store for historical notifications
diff --git a/core/proto/android/service/sensor_service.proto b/core/proto/android/service/sensor_service.proto
new file mode 100644
index 000000000000..8598f86a7f28
--- /dev/null
+++ b/core/proto/android/service/sensor_service.proto
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package android.service;
+
+import "frameworks/base/core/proto/android/privacy.proto";
+
+option java_multiple_files = true;
+
+/*
+ * Notes:
+ * 1. When using ProtoOutputStream to write this proto message, must call
+ * token = ProtoOutputStream#start(fieldId) before and ProtoOutputStream#end(token) after
+ * writing a nested message.
+ * 2. Never reuse a proto field number. When removing a field, mark it as reserved.
+ */
+
+// Proto dump of android::SensorService. dumpsys sensorservice --proto
+message SensorServiceProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ enum OperatingModeEnum {
+ OP_MODE_UNKNOWN = 0;
+ OP_MODE_NORMAL = 1;
+ OP_MODE_RESTRICTED = 2;
+ OP_MODE_DATA_INJECTION = 3;
+ }
+
+ optional int64 current_time_ms = 1;
+ optional SensorDeviceProto sensor_device = 2;
+ optional SensorListProto sensors = 3;
+ optional SensorFusionProto fusion_state = 4;
+ optional SensorEventsProto sensor_events = 5;
+ repeated ActiveSensorProto active_sensors = 6;
+ optional int32 socket_buffer_size = 7;
+ optional int32 socket_buffer_size_in_events = 8;
+ optional bool wake_lock_acquired = 9;
+ optional OperatingModeEnum operating_mode = 10;
+ // Non-empty only if operating_mode is RESTRICTED or DATA_INJECTION.
+ optional string whitelisted_package = 11;
+ optional bool sensor_privacy = 12;
+ repeated SensorEventConnectionProto active_connections = 13;
+ repeated SensorDirectConnectionProto direct_connections = 14;
+ repeated SensorRegistrationInfoProto previous_registrations = 15;
+}
+
+// Proto dump of android::SensorDevice
+message SensorDeviceProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional bool initialized = 1;
+ optional int32 total_sensors = 2;
+ optional int32 active_sensors = 3;
+
+ message SensorProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional int32 handle = 1;
+ optional int32 active_count = 2;
+ repeated float sampling_period_ms = 3;
+ optional float sampling_period_selected = 4;
+ repeated float batching_period_ms = 5;
+ optional float batching_period_selected = 6;
+ }
+ repeated SensorProto sensors = 4;
+}
+
+// Proto dump of android::SensorServiceUtil::SensorList
+message SensorListProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ enum ReportingModeEnum {
+ RM_UNKNOWN = 0;
+ RM_CONTINUOUS = 1;
+ RM_ON_CHANGE = 2;
+ RM_ONE_SHOT = 3;
+ RM_SPECIAL_TRIGGER = 4;
+ }
+
+ message SensorProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional int32 handle = 1;
+ optional string name = 2;
+ optional string vendor = 3;
+ optional int32 version = 4;
+ optional string string_type = 5;
+ optional int32 type = 6;
+ optional string required_permission = 7;
+ optional int32 flags = 8;
+ optional ReportingModeEnum reporting_mode = 9;
+ optional int32 max_delay_us = 10;
+ optional int32 min_delay_us = 11;
+ optional int32 fifo_max_event_count = 12;
+ optional int32 fifo_reserved_event_count = 13;
+ optional bool is_wakeup = 14;
+ optional bool data_injection_supported = 15;
+ optional bool is_dynamic = 16;
+ optional bool has_additional_info = 17;
+ optional int32 highest_rate_level = 18;
+ optional bool ashmem = 19;
+ optional bool gralloc = 20;
+ optional float min_value = 21;
+ optional float max_value = 22;
+ optional float resolution = 23;
+ optional float power_usage = 24;
+ }
+ repeated SensorProto sensors = 1;
+}
+
+
+// Proto dump of android::SensorFusion
+message SensorFusionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ message FusionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional bool enabled = 1;
+ optional int32 num_clients = 2;
+ optional float estimated_gyro_rate = 3;
+ optional float attitude_x = 4;
+ optional float attitude_y = 5;
+ optional float attitude_z = 6;
+ optional float attitude_w = 7;
+ optional float attitude_length = 8;
+ optional float bias_x = 9;
+ optional float bias_y = 10;
+ optional float bias_z = 11;
+ }
+ optional FusionProto fusion_9axis = 1;
+ optional FusionProto fusion_nomag = 2;
+ optional FusionProto fusion_nogyro = 3;
+}
+
+// Proto dump of android::SensorServiceUtil::RecentEventLogger
+message SensorEventsProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ message Event {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional float timestamp_sec = 1;
+ optional int64 wall_timestamp_ms = 2;
+ optional bool masked = 3;
+ optional int64 int64_data = 4;
+ repeated float float_array = 5;
+ }
+
+ message RecentEventsLog {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional string name = 1;
+ optional int32 recent_events_count = 2;
+ repeated Event events = 3;
+ }
+ repeated RecentEventsLog recent_events_logs = 1;
+}
+
+message ActiveSensorProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional string name = 1;
+ optional int32 handle = 2;
+ optional int32 num_connections = 3;
+}
+
+// Proto dump of android::SensorService::SensorDirectConnection
+message SensorDirectConnectionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ message SensorProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional int32 sensor = 1;
+ optional int32 rate = 2;
+ }
+
+ optional string package_name = 1;
+ optional int32 hal_channel_handle = 2;
+ optional int32 num_sensor_activated = 3;
+ repeated SensorProto sensors = 4;
+}
+
+// Proto dump of android::SensorService::SensorEventConnection
+message SensorEventConnectionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ message FlushInfoProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional string sensor_name = 1;
+ optional int32 sensor_handle = 2;
+ optional bool first_flush_pending = 3;
+ optional int32 pending_flush_events_to_send = 4;
+ }
+
+ enum OperatingModeEnum {
+ OP_MODE_UNKNOWN = 0;
+ OP_MODE_NORMAL = 1;
+ OP_MODE_RESTRICTED = 2;
+ OP_MODE_DATA_INJECTION = 3;
+ }
+
+ optional OperatingModeEnum operating_mode = 1;
+ optional string package_name = 2;
+ optional int32 wake_lock_ref_count = 3;
+ optional int32 uid = 4;
+ optional int32 cache_size = 5;
+ optional int32 max_cache_size = 6;
+ repeated FlushInfoProto flush_infos = 7;
+ optional int32 events_received = 8;
+ optional int32 events_sent = 9;
+ optional int32 events_cache = 10;
+ optional int32 events_dropped = 11;
+ optional int32 total_acks_needed = 12;
+ optional int32 total_acks_received = 13;
+}
+
+// Proto dump of android::SensorService::SensorRegistrationInfo
+message SensorRegistrationInfoProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional int64 timestamp_sec = 1;
+ optional int32 sensor_handle = 2;
+ optional string package_name = 3;
+ optional int32 pid = 4;
+ optional int32 uid = 5;
+ optional int64 sampling_rate_us = 6;
+ optional int64 max_report_latency_us = 7;
+ optional bool activated = 8;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index efa7d591fa38..27d41d4d5ca4 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4878,6 +4878,19 @@
<permission android:name="android.permission.ACCESS_SHARED_LIBRARIES"
android:protectionLevel="signature|installer" />
+ <!-- Allows an app to log compat change usage.
+ @hide <p>Not for use by third-party applications.</p> -->
+ <permission android:name="android.permission.LOG_COMPAT_CHANGE"
+ android:protectionLevel="signature|privileged" />
+ <!-- Allows an app to read compat change config.
+ @hide <p>Not for use by third-party applications.</p> -->
+ <permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"
+ android:protectionLevel="signature|privileged" />
+ <!-- Allows an app to override compat change config.
+ @hide <p>Not for use by third-party applications.</p> -->
+ <permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"
+ android:protectionLevel="signature|privileged" />
+
<!-- Allows input events to be monitored. Very dangerous! @hide -->
<permission android:name="android.permission.MONITOR_INPUT"
android:protectionLevel="signature" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b2d08a9730fc..31e68e88c0a8 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4343,4 +4343,7 @@
Determines whether the specified key groups can be used to wake up the device. -->
<bool name="config_wakeOnDpadKeyPress">true</bool>
<bool name="config_wakeOnAssistKeyPress">true</bool>
+
+ <!-- Whether to default to an expanded list of users on the lock screen user switcher. -->
+ <bool name="config_expandLockScreenUserSwitcher">false</bool>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c59d25f10b0b..2453bb18577f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3863,4 +3863,7 @@
<!-- Toast message for background started foreground service while-in-use permission restriction feature -->
<java-symbol type="string" name="allow_while_in_use_permission_in_fgs" />
+
+ <!-- Whether to expand the lock screen user switcher by default -->
+ <java-symbol type="bool" name="config_expandLockScreenUserSwitcher" />
</resources>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index ee93b397bedf..59335a595334 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -111,6 +111,10 @@
<uses-permission android:name="android.permission.MOVE_PACKAGE" />
<uses-permission android:name="android.permission.PACKAGE_VERIFICATION_AGENT" />
+ <!-- gating and logging permissions -->
+ <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE" />
+ <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
+
<!-- os storage test permissions -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.ASEC_ACCESS" />
diff --git a/core/tests/coretests/src/android/content/integrity/AtomicFormulaTest.java b/core/tests/coretests/src/android/content/integrity/AtomicFormulaTest.java
index bf782034c8f1..7733559c156a 100644
--- a/core/tests/coretests/src/android/content/integrity/AtomicFormulaTest.java
+++ b/core/tests/coretests/src/android/content/integrity/AtomicFormulaTest.java
@@ -90,18 +90,18 @@ public class AtomicFormulaTest {
}
@Test
- public void testValidAtomicFormula_stringValue_appCertificateAutoHashed() {
+ public void testValidAtomicFormula_stringValue_appCertificateIsNotAutoHashed() {
String appCert = "cert";
StringAtomicFormula stringAtomicFormula =
new StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, appCert);
assertThat(stringAtomicFormula.getKey()).isEqualTo(AtomicFormula.APP_CERTIFICATE);
- assertThat(stringAtomicFormula.getValue()).doesNotMatch(appCert);
- assertThat(stringAtomicFormula.getIsHashedValue()).isTrue();
+ assertThat(stringAtomicFormula.getValue()).matches(appCert);
+ assertThat(stringAtomicFormula.getIsHashedValue()).isFalse();
}
@Test
- public void testValidAtomicFormula_stringValue_installerCertificateAutoHashed() {
+ public void testValidAtomicFormula_stringValue_installerCertificateIsNotAutoHashed() {
String installerCert = "cert";
StringAtomicFormula stringAtomicFormula =
new StringAtomicFormula(AtomicFormula.INSTALLER_CERTIFICATE,
@@ -109,8 +109,8 @@ public class AtomicFormulaTest {
assertThat(stringAtomicFormula.getKey()).isEqualTo(
AtomicFormula.INSTALLER_CERTIFICATE);
- assertThat(stringAtomicFormula.getValue()).doesNotMatch(installerCert);
- assertThat(stringAtomicFormula.getIsHashedValue()).isTrue();
+ assertThat(stringAtomicFormula.getValue()).matches(installerCert);
+ assertThat(stringAtomicFormula.getIsHashedValue()).isFalse();
}
@Test
diff --git a/core/tests/coretests/src/android/content/integrity/IntegrityFormulaTest.java b/core/tests/coretests/src/android/content/integrity/IntegrityFormulaTest.java
index c1806028f75b..dc03167f51a9 100644
--- a/core/tests/coretests/src/android/content/integrity/IntegrityFormulaTest.java
+++ b/core/tests/coretests/src/android/content/integrity/IntegrityFormulaTest.java
@@ -40,7 +40,7 @@ public class IntegrityFormulaTest {
assertThat(stringAtomicFormula.getKey()).isEqualTo(AtomicFormula.PACKAGE_NAME);
assertThat(stringAtomicFormula.getValue()).isEqualTo(packageName);
- assertThat(stringAtomicFormula.getIsHashedValue()).isEqualTo(false);
+ assertThat(stringAtomicFormula.getIsHashedValue()).isFalse();
}
@Test
@@ -53,8 +53,8 @@ public class IntegrityFormulaTest {
(AtomicFormula.StringAtomicFormula) formula;
assertThat(stringAtomicFormula.getKey()).isEqualTo(AtomicFormula.APP_CERTIFICATE);
- assertThat(stringAtomicFormula.getValue()).doesNotMatch(appCertificate);
- assertThat(stringAtomicFormula.getIsHashedValue()).isEqualTo(true);
+ assertThat(stringAtomicFormula.getValue()).matches(appCertificate);
+ assertThat(stringAtomicFormula.getIsHashedValue()).isFalse();
}
@Test
@@ -68,7 +68,7 @@ public class IntegrityFormulaTest {
assertThat(stringAtomicFormula.getKey()).isEqualTo(AtomicFormula.INSTALLER_NAME);
assertThat(stringAtomicFormula.getValue()).isEqualTo(installerName);
- assertThat(stringAtomicFormula.getIsHashedValue()).isEqualTo(false);
+ assertThat(stringAtomicFormula.getIsHashedValue()).isFalse();
}
@Test
@@ -81,8 +81,8 @@ public class IntegrityFormulaTest {
(AtomicFormula.StringAtomicFormula) formula;
assertThat(stringAtomicFormula.getKey()).isEqualTo(AtomicFormula.INSTALLER_CERTIFICATE);
- assertThat(stringAtomicFormula.getValue()).doesNotMatch(installerCertificate);
- assertThat(stringAtomicFormula.getIsHashedValue()).isEqualTo(true);
+ assertThat(stringAtomicFormula.getValue()).matches(installerCertificate);
+ assertThat(stringAtomicFormula.getIsHashedValue()).isFalse();
}
@Test
diff --git a/core/tests/coretests/src/android/os/BuildTest.java b/core/tests/coretests/src/android/os/BuildTest.java
index decc76869a53..2295eb989108 100644
--- a/core/tests/coretests/src/android/os/BuildTest.java
+++ b/core/tests/coretests/src/android/os/BuildTest.java
@@ -60,7 +60,7 @@ public class BuildTest extends TestCase {
assertNotEmpty("BRAND", Build.BRAND);
assertNotEmpty("MODEL", Build.MODEL);
assertNotEmpty("VERSION.INCREMENTAL", Build.VERSION.INCREMENTAL);
- assertNotEmpty("VERSION.RELEASE", Build.VERSION.RELEASE);
+ assertNotEmpty("VERSION.RELEASE", Build.VERSION.RELEASE_OR_CODENAME);
assertNotEmpty("TYPE", Build.TYPE);
Assert.assertNotNull("TAGS", Build.TAGS); // TAGS is allowed to be empty.
assertNotEmpty("FINGERPRINT", Build.FINGERPRINT);
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index df6b9066ea5c..ce71bebfc455 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -38,6 +38,7 @@ import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -355,6 +356,7 @@ public class ChooserActivityTest {
// enable the work tab feature flag
ResolverActivity.ENABLE_TABBED_VIEW = true;
+ markWorkProfileUserAvailable();
Intent sendIntent = createSendTextIntent();
List<ResolvedComponentInfo> resolvedComponentInfos =
createResolvedComponentsForTestWithOtherProfile(2);
@@ -1209,17 +1211,24 @@ public class ChooserActivityTest {
// enable the work tab feature flag
ResolverActivity.ENABLE_TABBED_VIEW = true;
int personalProfileTargets = 3;
+ int otherProfileTargets = 1;
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTest(personalProfileTargets);
+ createResolvedComponentsForTestWithOtherProfile(
+ personalProfileTargets + otherProfileTargets, /* userID */ 10);
int workProfileTargets = 4;
List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(
workProfileTargets);
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
- Mockito.isA(List.class))).thenReturn(personalResolvedComponentInfos);
+ Mockito.isA(List.class)))
+ .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
- Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
+ Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
+ when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class),
+ eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos));
Intent sendIntent = createSendTextIntent();
sendIntent.setType("TestType");
markWorkProfileUserAvailable();
@@ -1229,8 +1238,6 @@ public class ChooserActivityTest {
waitForIdle();
assertThat(activity.getCurrentUserHandle().getIdentifier(), is(0));
- // The work list adapter must only be filled when we open the work tab
- assertThat(activity.getWorkListAdapter().getCount(), is(0));
onView(withText(R.string.resolver_work_tab)).perform(click());
assertThat(activity.getCurrentUserHandle().getIdentifier(), is(10));
assertThat(activity.getPersonalListAdapter().getCount(), is(personalProfileTargets));
@@ -1243,11 +1250,22 @@ public class ChooserActivityTest {
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
int workProfileTargets = 4;
+ List<ResolvedComponentInfo> personalResolvedComponentInfos =
+ createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
List<ResolvedComponentInfo> workResolvedComponentInfos =
createResolvedComponentsForTest(workProfileTargets);
+ when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class)))
+ .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
+ when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class),
+ eq(UserHandle.SYSTEM)))
+ .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
Intent sendIntent = createSendTextIntent();
sendIntent.setType("TestType");
@@ -1357,6 +1375,20 @@ public class ChooserActivityTest {
return infoList;
}
+ private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile(
+ int numberOfResults, int userId) {
+ List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
+ for (int i = 0; i < numberOfResults; i++) {
+ if (i == 0) {
+ infoList.add(
+ ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId));
+ } else {
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
+ }
+ }
+ return infoList;
+ }
+
private List<ResolvedComponentInfo> createResolvedComponentsForTestWithUserId(
int numberOfResults, int userId) {
List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
index eee62bb791bf..a68b59086d42 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
@@ -16,10 +16,15 @@
package com.android.internal.app;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.annotation.Nullable;
+import android.app.prediction.AppPredictionContext;
+import android.app.prediction.AppPredictionManager;
+import android.app.prediction.AppPredictor;
import android.app.usage.UsageStatsManager;
import android.content.ContentResolver;
import android.content.Context;
@@ -40,6 +45,8 @@ import com.android.internal.app.chooser.TargetInfo;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import org.mockito.Mockito;
+
import java.util.function.Function;
public class ChooserWrapperActivity extends ChooserActivity {
@@ -173,6 +180,12 @@ public class ChooserWrapperActivity extends ChooserActivity {
return mMultiProfilePagerAdapter.getCurrentUserHandle();
}
+ @Override
+ public Context createContextAsUser(UserHandle user, int flags) {
+ // return the current context as a work profile doesn't really exist in these tests
+ return getApplicationContext();
+ }
+
/**
* We cannot directly mock the activity created since instrumentation creates it.
* <p>
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
index 911490f30799..5f4194aa51e3 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
@@ -225,6 +225,7 @@ public class ResolverActivityTest {
// enable the work tab feature flag
ResolverActivity.ENABLE_TABBED_VIEW = true;
+ markWorkProfileUserAvailable();
Intent sendIntent = createSendImageIntent();
List<ResolvedComponentInfo> resolvedComponentInfos =
createResolvedComponentsForTestWithOtherProfile(2);
@@ -246,7 +247,6 @@ public class ResolverActivityTest {
chosen[0] = targetInfo.getResolveInfo();
return true;
};
-
// Make a stable copy of the components as the original list may be modified
List<ResolvedComponentInfo> stableCopy =
createResolvedComponentsForTestWithOtherProfile(2);
@@ -443,7 +443,7 @@ public class ResolverActivityTest {
// enable the work tab feature flag
ResolverActivity.ENABLE_TABBED_VIEW = true;
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTest(3);
+ createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
@@ -451,6 +451,11 @@ public class ResolverActivityTest {
when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
+ when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class),
+ eq(UserHandle.SYSTEM)))
+ .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
Intent sendIntent = createSendImageIntent();
markWorkProfileUserAvailable();
@@ -478,17 +483,20 @@ public class ResolverActivityTest {
Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.isA(List.class),
- eq(sOverrides.workProfileUserHandle))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
+ eq(sOverrides.workProfileUserHandle)))
+ .thenReturn(new ArrayList<>(workResolvedComponentInfos));
when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.isA(List.class),
- eq(sOverrides.workProfileUserHandle))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
+ eq(sOverrides.workProfileUserHandle)))
+ .thenReturn(new ArrayList<>(workResolvedComponentInfos));
when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
- Mockito.isA(List.class))).thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+ Mockito.isA(List.class)))
+ .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.isA(List.class),
@@ -502,7 +510,7 @@ public class ResolverActivityTest {
onView(withText(R.string.resolver_work_tab)).perform(click());
assertThat(activity.getCurrentUserHandle().getIdentifier(), is(10));
- assertThat(activity.getPersonalListAdapter().getCount(), is(3));
+ assertThat(activity.getPersonalListAdapter().getCount(), is(2));
}
@Test
@@ -511,14 +519,20 @@ public class ResolverActivityTest {
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTest(3);
+ createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
- Mockito.isA(List.class))).thenReturn(personalResolvedComponentInfos);
+ Mockito.isA(List.class)))
+ .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
+ when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class),
+ eq(UserHandle.SYSTEM)))
+ .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
Intent sendIntent = createSendImageIntent();
final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
@@ -536,14 +550,20 @@ public class ResolverActivityTest {
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTest(3);
+ createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
- Mockito.isA(List.class))).thenReturn(personalResolvedComponentInfos);
+ Mockito.isA(List.class)))
+ .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
+ when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class),
+ eq(UserHandle.SYSTEM)))
+ .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
Intent sendIntent = createSendImageIntent();
ResolveInfo[] chosen = new ResolveInfo[1];
sOverrides.onSafelyStartCallback = targetInfo -> {
@@ -587,17 +607,20 @@ public class ResolverActivityTest {
Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.isA(List.class),
- eq(sOverrides.workProfileUserHandle))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
+ eq(sOverrides.workProfileUserHandle)))
+ .thenReturn(new ArrayList<>(workResolvedComponentInfos));
when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.isA(List.class),
- eq(sOverrides.workProfileUserHandle))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
+ eq(sOverrides.workProfileUserHandle)))
+ .thenReturn(new ArrayList<>(workResolvedComponentInfos));
when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
- Mockito.isA(List.class))).thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+ Mockito.isA(List.class)))
+ .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.isA(List.class),
@@ -678,6 +701,20 @@ public class ResolverActivityTest {
return infoList;
}
+ private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile(
+ int numberOfResults, int userId) {
+ List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
+ for (int i = 0; i < numberOfResults; i++) {
+ if (i == 0) {
+ infoList.add(
+ ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId));
+ } else {
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
+ }
+ }
+ return infoList;
+ }
+
private void waitForIdle() {
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}
diff --git a/data/etc/com.android.settings.xml b/data/etc/com.android.settings.xml
index a200a510cf12..fe1182ecad4f 100644
--- a/data/etc/com.android.settings.xml
+++ b/data/etc/com.android.settings.xml
@@ -26,6 +26,7 @@
<permission name="android.permission.DELETE_PACKAGES"/>
<permission name="android.permission.FORCE_STOP_PACKAGES"/>
<permission name="android.permission.LOCAL_MAC_ADDRESS"/>
+ <permission name="android.permission.LOG_COMPAT_CHANGE" />
<permission name="android.permission.MANAGE_DEBUGGING"/>
<permission name="android.permission.MANAGE_DEVICE_ADMINS"/>
<permission name="android.permission.MANAGE_FINGERPRINT"/>
@@ -37,8 +38,10 @@
<permission name="android.permission.MODIFY_PHONE_STATE"/>
<permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<permission name="android.permission.MOVE_PACKAGE"/>
+ <permission name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG" />
<permission name="android.permission.OVERRIDE_WIFI_CONFIG"/>
<permission name="android.permission.PACKAGE_USAGE_STATS"/>
+ <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
<permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
<permission name="android.permission.READ_SEARCH_INDEXABLES"/>
<permission name="android.permission.REBOOT"/>
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index da505505628e..6929d0d1879d 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -72,6 +72,11 @@
<group gid="net_admin" />
</permission>
+ <permission name="android.permission.MAINLINE_NETWORK_STACK" >
+ <group gid="net_admin" />
+ <group gid="net_raw" />
+ </permission>
+
<!-- The group that /cache belongs to, linked to the permission
set on the applications that can access /cache -->
<permission name="android.permission.ACCESS_CACHE_FILESYSTEM" >
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index b5eba090691f..b9a7e225bdb9 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -366,6 +366,10 @@ applications that come with the platform
<permission name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
<!-- Permission required for Tethering CTS tests. -->
<permission name="android.permission.TETHER_PRIVILEGED"/>
+ <!-- Permissions required for ganting and logging -->
+ <permission name="android.permission.LOG_COMPAT_CHANGE" />
+ <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
+ <permission name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG" />
<!-- Permissions required to test ambient display. -->
<permission name="android.permission.READ_DREAM_STATE" />
<permission name="android.permission.WRITE_DREAM_STATE" />
diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp
index 3681c69e912b..a3d552faeb0a 100644
--- a/libs/hwui/HardwareBitmapUploader.cpp
+++ b/libs/hwui/HardwareBitmapUploader.cpp
@@ -187,7 +187,9 @@ private:
EGLSyncKHR fence = mUploadThread->queue().runSync([&]() -> EGLSyncKHR {
AutoSkiaGlTexture glTexture;
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
- GL_CHECKPOINT(MODERATE);
+ if (GLUtils::dumpGLErrors()) {
+ return EGL_NO_SYNC_KHR;
+ }
// glTexSubImage2D is synchronous in sense that it memcpy() from pointer that we
// provide.
@@ -195,19 +197,26 @@ private:
// when we first use it in drawing
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
format.format, format.type, bitmap.getPixels());
- GL_CHECKPOINT(MODERATE);
+ if (GLUtils::dumpGLErrors()) {
+ return EGL_NO_SYNC_KHR;
+ }
EGLSyncKHR uploadFence =
eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_FENCE_KHR, NULL);
- LOG_ALWAYS_FATAL_IF(uploadFence == EGL_NO_SYNC_KHR,
- "Could not create sync fence %#x", eglGetError());
+ if (uploadFence == EGL_NO_SYNC_KHR) {
+ ALOGW("Could not create sync fence %#x", eglGetError());
+ };
glFlush();
+ GLUtils::dumpGLErrors();
return uploadFence;
});
+ if (fence == EGL_NO_SYNC_KHR) {
+ return false;
+ }
EGLint waitStatus = eglClientWaitSyncKHR(display, fence, 0, FENCE_TIMEOUT);
- LOG_ALWAYS_FATAL_IF(waitStatus != EGL_CONDITION_SATISFIED_KHR,
- "Failed to wait for the fence %#x", eglGetError());
+ ALOGE_IF(waitStatus != EGL_CONDITION_SATISFIED_KHR,
+ "Failed to wait for the fence %#x", eglGetError());
eglDestroySyncKHR(display, fence);
}
diff --git a/media/java/android/media/IMediaRoute2Provider.aidl b/media/java/android/media/IMediaRoute2Provider.aidl
index 194669c19018..9131f3bc960d 100644
--- a/media/java/android/media/IMediaRoute2Provider.aidl
+++ b/media/java/android/media/IMediaRoute2Provider.aidl
@@ -37,5 +37,4 @@ oneway interface IMediaRoute2Provider {
void notifyControlRequestSent(String id, in Intent request);
void requestSetVolume(String id, int volume);
- void requestUpdateVolume(String id, int delta);
}
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index dac0fba876be..6fef46889742 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -52,7 +52,6 @@ interface IMediaRouterService {
void sendControlRequest(IMediaRouter2Client client, in MediaRoute2Info route,
in Intent request);
void requestSetVolume2(IMediaRouter2Client client, in MediaRoute2Info route, int volume);
- void requestUpdateVolume2(IMediaRouter2Client client, in MediaRoute2Info route, int direction);
void requestCreateSession(IMediaRouter2Client client, in MediaRoute2Info route, int requestId,
in @nullable Bundle sessionHints);
@@ -70,8 +69,6 @@ interface IMediaRouterService {
void requestSetVolume2Manager(IMediaRouter2Manager manager,
in MediaRoute2Info route, int volume);
- void requestUpdateVolume2Manager(IMediaRouter2Manager manager,
- in MediaRoute2Info route, int direction);
List<RoutingSessionInfo> getActiveSessions(IMediaRouter2Manager manager);
void selectClientRoute(IMediaRouter2Manager manager,
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
index d0b5d486d19c..20a59bba54c6 100644
--- a/media/java/android/media/MediaRoute2ProviderService.java
+++ b/media/java/android/media/MediaRoute2ProviderService.java
@@ -46,13 +46,20 @@ import java.util.concurrent.atomic.AtomicBoolean;
/**
* Base class for media route provider services.
* <p>
+ * Media route provider services are used to publish {@link MediaRoute2Info media routes} such as
+ * speakers, TVs, etc. The routes are published by calling {@link #notifyRoutes(Collection)}.
+ * Media apps which use {@link MediaRouter2} can request to play their media on the routes.
+ * </p><p>
+ * When {@link MediaRouter2 media router} wants to play media on a route,
+ * {@link #onCreateSession(String, String, long, Bundle)} will be called to handle the request.
+ * A session can be considered as a group of currently selected routes for each connection.
+ * Create and manage the sessions by yourself, and notify the {@link RoutingSessionInfo
+ * session infos} when there are any changes.
+ * </p><p>
* The system media router service will bind to media route provider services when a
* {@link RouteDiscoveryPreference discovery preference} is registered via
- * a {@link MediaRouter2 media router} by an application.
- * </p><p>
- * To implement your own media route provider service, extend this class and
- * override {@link #onDiscoveryPreferenceChanged(RouteDiscoveryPreference)} to publish
- * {@link MediaRoute2Info routes}.
+ * a {@link MediaRouter2 media router} by an application. See
+ * {@link #onDiscoveryPreferenceChanged(RouteDiscoveryPreference)} for the details.
* </p>
*/
public abstract class MediaRoute2ProviderService extends Service {
@@ -118,22 +125,15 @@ public abstract class MediaRoute2ProviderService extends Service {
public abstract void onControlRequest(@NonNull String routeId, @NonNull Intent request);
/**
- * Called when requestSetVolume is called on a route of the provider
+ * Called when requestSetVolume is called on a route of the provider.
*
* @param routeId the id of the route
* @param volume the target volume
+ * @see MediaRoute2Info#getVolumeMax()
*/
public abstract void onSetVolume(@NonNull String routeId, int volume);
/**
- * Called when requestUpdateVolume is called on a route of the provider
- *
- * @param routeId id of the route
- * @param delta the delta to add to the current volume
- */
- public abstract void onUpdateVolume(@NonNull String routeId, int delta);
-
- /**
* Gets information of the session with the given id.
*
* @param sessionId id of the session
@@ -520,14 +520,5 @@ public abstract class MediaRoute2ProviderService extends Service {
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetVolume,
MediaRoute2ProviderService.this, routeId, volume));
}
-
- @Override
- public void requestUpdateVolume(String routeId, int delta) {
- if (!checkCallerisSystem()) {
- return;
- }
- mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onUpdateVolume,
- MediaRoute2ProviderService.this, routeId, delta));
- }
}
}
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 515cabe5a5c9..d7b74df0a5e6 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -462,31 +462,6 @@ public class MediaRouter2 {
}
}
- /**
- * Requests an incremental volume update for the route asynchronously.
- * <p>
- * It may have no effect if the route is currently not selected.
- * </p>
- *
- * @param delta The delta to add to the current volume.
- * @hide
- */
- public void requestUpdateVolume(@NonNull MediaRoute2Info route, int delta) {
- Objects.requireNonNull(route, "route must not be null");
-
- Client2 client;
- synchronized (sRouterLock) {
- client = mClient;
- }
- if (client != null) {
- try {
- mMediaRouterService.requestUpdateVolume2(client, route, delta);
- } catch (RemoteException ex) {
- Log.e(TAG, "Unable to send control request.", ex);
- }
- }
- }
-
void addRoutesOnHandler(List<MediaRoute2Info> routes) {
// TODO: When onRoutesAdded is first called,
// 1) clear mRoutes before adding the routes
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 662eeb1418f1..b1f930d0f2cc 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -294,30 +294,6 @@ public class MediaRouter2Manager {
}
}
- /**
- * Requests an incremental volume update for the route asynchronously.
- * <p>
- * It may have no effect if the route is currently not selected.
- * </p>
- *
- * @param delta The delta to add to the current volume.
- */
- public void requestUpdateVolume(@NonNull MediaRoute2Info route, int delta) {
- Objects.requireNonNull(route, "route must not be null");
-
- Client client;
- synchronized (sLock) {
- client = mClient;
- }
- if (client != null) {
- try {
- mMediaRouterService.requestUpdateVolume2Manager(client, route, delta);
- } catch (RemoteException ex) {
- Log.e(TAG, "Unable to send control request.", ex);
- }
- }
- }
-
void addRoutesOnHandler(List<MediaRoute2Info> routes) {
synchronized (mRoutesLock) {
for (MediaRoute2Info route : routes) {
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
index 4316e42bb0e1..f10e5ebb5d3e 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
@@ -289,12 +289,13 @@ public class MediaRouterManagerTest {
MediaRoute2Info volRoute = routes.get(ROUTE_ID_VARIABLE_VOLUME);
int originalVolume = volRoute.getVolume();
- int deltaVolume = (originalVolume == volRoute.getVolumeMax() ? -1 : 1);
+ int targetVolume = originalVolume == volRoute.getVolumeMax()
+ ? originalVolume - 1 : originalVolume + 1;
awaitOnRouteChangedManager(
- () -> mManager.requestUpdateVolume(volRoute, deltaVolume),
+ () -> mManager.requestSetVolume(volRoute, targetVolume),
ROUTE_ID_VARIABLE_VOLUME,
- (route -> route.getVolume() == originalVolume + deltaVolume));
+ (route -> route.getVolume() == targetVolume));
awaitOnRouteChangedManager(
() -> mManager.requestSetVolume(volRoute, originalVolume),
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java
index f1a08f29e0cc..1a866cafff90 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java
@@ -154,20 +154,6 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
}
@Override
- public void onUpdateVolume(String routeId, int delta) {
- MediaRoute2Info route = mRoutes.get(routeId);
- if (route == null) {
- return;
- }
- int volume = route.getVolume() + delta;
- volume = Math.min(volume, Math.max(0, route.getVolumeMax()));
- mRoutes.put(routeId, new MediaRoute2Info.Builder(route)
- .setVolume(volume)
- .build());
- publishRoutes();
- }
-
- @Override
public void onCreateSession(String packageName, String routeId, long requestId,
@Nullable Bundle sessionHints) {
MediaRoute2Info route = mRoutes.get(routeId);
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 9c8345dafbc8..62124934f416 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -10,6 +10,7 @@ android_library {
"androidx.appcompat_appcompat",
"androidx.lifecycle_lifecycle-runtime",
"androidx.mediarouter_mediarouter-nodeps",
+ "iconloader",
"SettingsLibHelpUtils",
"SettingsLibRestrictedLockUtils",
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index de523d9f9bc8..213e3657254d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -3,6 +3,7 @@ package com.android.settingslib;
import android.annotation.ColorInt;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -13,6 +14,7 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.location.LocationManager;
import android.media.AudioManager;
@@ -27,8 +29,11 @@ import android.telephony.AccessNetworkConstants;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
+import androidx.annotation.NonNull;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.UserIcons;
+import com.android.launcher3.icons.IconFactory;
import com.android.settingslib.drawable.UserIconDrawable;
import java.text.NumberFormat;
@@ -424,6 +429,19 @@ public class Utils {
return state;
}
+ /**
+ * Get the {@link Drawable} that represents the app icon
+ */
+ public static @NonNull Drawable getBadgedIcon(
+ @NonNull Context context, @NonNull ApplicationInfo appInfo) {
+ final UserHandle user = UserHandle.getUserHandleForUid(appInfo.uid);
+ try (IconFactory iconFactory = IconFactory.obtain(context)) {
+ final Bitmap iconBmp = iconFactory.createBadgedIconBitmap(
+ appInfo.loadUnbadgedIcon(context.getPackageManager()), user, false).icon;
+ return new BitmapDrawable(context.getResources(), iconBmp);
+ }
+ }
+
private static boolean isNotInIwlan(ServiceState serviceState) {
final NetworkRegistrationInfo networkRegWlan = serviceState.getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS,
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index 19c666459723..af728887c917 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -59,6 +59,7 @@ import androidx.lifecycle.OnLifecycleEvent;
import com.android.internal.R;
import com.android.internal.util.ArrayUtils;
+import com.android.settingslib.Utils;
import java.io.File;
import java.io.IOException;
@@ -495,7 +496,7 @@ public class ApplicationsState {
return;
}
synchronized (entry) {
- entry.ensureIconLocked(mContext, mDrawableFactory);
+ entry.ensureIconLocked(mContext);
}
}
@@ -1216,7 +1217,7 @@ public class ApplicationsState {
AppEntry entry = mAppEntries.get(i);
if (entry.icon == null || !entry.mounted) {
synchronized (entry) {
- if (entry.ensureIconLocked(mContext, mDrawableFactory)) {
+ if (entry.ensureIconLocked(mContext)) {
if (!mRunning) {
mRunning = true;
Message m = mMainHandler.obtainMessage(
@@ -1587,10 +1588,10 @@ public class ApplicationsState {
}
}
- boolean ensureIconLocked(Context context, IconDrawableFactory drawableFactory) {
+ boolean ensureIconLocked(Context context) {
if (this.icon == null) {
if (this.apkFile.exists()) {
- this.icon = drawableFactory.getBadgedIcon(info);
+ this.icon = Utils.getBadgedIcon(context, info);
return true;
} else {
this.mounted = false;
@@ -1601,7 +1602,7 @@ public class ApplicationsState {
// its icon.
if (this.apkFile.exists()) {
this.mounted = true;
- this.icon = drawableFactory.getBadgedIcon(info);
+ this.icon = Utils.getBadgedIcon(context, info);
return true;
}
}
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 6a89b71be897..1d679c7bcbdd 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -223,6 +223,11 @@
<!-- permissions required for CTS test - PhoneStateListenerTest -->
<uses-permission android:name="android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH" />
+ <!-- Permissions required for ganting and logging -->
+ <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE"/>
+ <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
+ <uses-permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"/>
+
<!-- Permission required for CTS test - UiModeManagerTest -->
<uses-permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED"/>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 139a8c3f7411..1fe967b4750d 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -645,7 +645,6 @@
<activity android:name=".controls.management.ControlsProviderSelectorActivity"
android:label="Controls Providers"
android:theme="@style/Theme.ControlsManagement"
- android:exported="true"
android:showForAllUsers="true"
android:excludeFromRecents="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
diff --git a/packages/SystemUI/res/layout/auth_credential_password_view.xml b/packages/SystemUI/res/layout/auth_credential_password_view.xml
index a1c593fa455c..b14bc7de06c4 100644
--- a/packages/SystemUI/res/layout/auth_credential_password_view.xml
+++ b/packages/SystemUI/res/layout/auth_credential_password_view.xml
@@ -73,6 +73,7 @@
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
+ android:minHeight="48dp"
android:gravity="center"
android:inputType="textPassword"
android:maxLength="500"
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 6062a3d45be0..20d19ece575c 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -533,10 +533,6 @@ public class BubbleStackView extends FrameLayout {
mBubbleContainer.addView(mOverflowBtn, 0,
new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
- mOverflowBtn.setOnClickListener(v -> {
- setSelectedBubble(null);
- });
-
TypedArray ta = mContext.obtainStyledAttributes(
new int[]{android.R.attr.colorBackgroundFloating});
int bgColor = ta.getColor(0, Color.WHITE /* default */);
@@ -856,6 +852,10 @@ public class BubbleStackView extends FrameLayout {
updateBubbleZOrdersAndDotPosition(false /* animate */);
}
+ void showOverflow() {
+ setSelectedBubble(null);
+ }
+
/**
* Changes the currently selected bubble. If the stack is already expanded, the newly selected
* bubble will be shown immediately. This does not change the expanded state or change the
@@ -950,6 +950,10 @@ public class BubbleStackView extends FrameLayout {
}
if (mIsExpanded) {
if (isIntersecting(mBubbleContainer, x, y)) {
+ if (BubbleExperimentConfig.allowBubbleOverflow(mContext)
+ && isIntersecting(mOverflowBtn, x, y)) {
+ return mOverflowBtn;
+ }
// Could be tapping or dragging a bubble while expanded
for (int i = 0; i < getBubbleCount(); i++) {
BadgedImageView view = (BadgedImageView) mBubbleContainer.getChildAt(i);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java
index fdeaf1f016c3..5a9d44b6da2c 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java
@@ -24,6 +24,7 @@ import android.view.View;
import android.view.ViewConfiguration;
import com.android.systemui.Dependency;
+import com.android.systemui.R;
/**
* Handles interpreting touches on a {@link BubbleStackView}. This includes expanding, collapsing,
@@ -109,6 +110,10 @@ class BubbleTouchHandler implements View.OnTouchListener {
if (!(mTouchedView instanceof BadgedImageView)
&& !(mTouchedView instanceof BubbleStackView)
&& !(mTouchedView instanceof BubbleFlyoutView)) {
+
+ if (mTouchedView.getId() == R.id.bubble_overflow_button) {
+ mStack.showOverflow();
+ }
// Not touching anything touchable, but we shouldn't collapse (e.g. touching edge
// of expanded view).
mStack.hideBubbleMenu();
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
index a6f1d84877c5..7de1557ebc65 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
@@ -19,9 +19,12 @@ package com.android.systemui.controls.controller
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.ComponentName
+import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
+import android.database.ContentObserver
+import android.net.Uri
import android.os.Environment
import android.os.UserHandle
import android.provider.Settings
@@ -30,6 +33,7 @@ import android.service.controls.actions.ControlAction
import android.util.ArrayMap
import android.util.Log
import com.android.internal.annotations.GuardedBy
+import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.DumpController
import com.android.systemui.Dumpable
import com.android.systemui.broadcast.BroadcastDispatcher
@@ -53,15 +57,16 @@ class ControlsControllerImpl @Inject constructor (
private val uiController: ControlsUiController,
private val bindingController: ControlsBindingController,
private val listingController: ControlsListingController,
- broadcastDispatcher: BroadcastDispatcher,
+ private val broadcastDispatcher: BroadcastDispatcher,
optionalWrapper: Optional<ControlsFavoritePersistenceWrapper>,
dumpController: DumpController
) : Dumpable, ControlsController {
companion object {
private const val TAG = "ControlsControllerImpl"
- const val CONTROLS_AVAILABLE = "systemui.controls_available"
- const val USER_CHANGE_RETRY_DELAY = 500L // ms
+ internal const val CONTROLS_AVAILABLE = "systemui.controls_available"
+ internal val URI = Settings.Secure.getUriFor(CONTROLS_AVAILABLE)
+ private const val USER_CHANGE_RETRY_DELAY = 500L // ms
}
// Map of map: ComponentName -> (String -> ControlInfo).
@@ -69,9 +74,11 @@ class ControlsControllerImpl @Inject constructor (
@GuardedBy("currentFavorites")
private val currentFavorites = ArrayMap<ComponentName, MutableMap<String, ControlInfo>>()
- private var userChanging = true
- override var available = Settings.Secure.getInt(
- context.contentResolver, CONTROLS_AVAILABLE, 0) != 0
+ private var userChanging: Boolean = true
+
+ private val contentResolver: ContentResolver
+ get() = context.contentResolver
+ override var available = Settings.Secure.getInt(contentResolver, CONTROLS_AVAILABLE, 0) != 0
private set
private var currentUser = context.user
@@ -95,8 +102,8 @@ class ControlsControllerImpl @Inject constructor (
val fileName = Environment.buildPath(
userContext.filesDir, ControlsFavoritePersistenceWrapper.FILE_NAME)
persistenceWrapper.changeFile(fileName)
- available = Settings.Secure.getIntForUser(
- context.contentResolver, CONTROLS_AVAILABLE, 0) != 0
+ available = Settings.Secure.getIntForUser(contentResolver, CONTROLS_AVAILABLE,
+ /* default */ 0, newUser.identifier) != 0
synchronized(currentFavorites) {
currentFavorites.clear()
}
@@ -123,6 +130,25 @@ class ControlsControllerImpl @Inject constructor (
}
}
+ @VisibleForTesting
+ internal val settingObserver = object : ContentObserver(null) {
+ override fun onChange(selfChange: Boolean, uri: Uri, userId: Int) {
+ // Do not listen to changes in the middle of user change, those will be read by the
+ // user-switch receiver.
+ if (userChanging || userId != currentUserId) {
+ return
+ }
+ available = Settings.Secure.getIntForUser(contentResolver, CONTROLS_AVAILABLE,
+ /* default */ 0, currentUserId) != 0
+ synchronized(currentFavorites) {
+ currentFavorites.clear()
+ }
+ if (available) {
+ loadFavorites()
+ }
+ }
+ }
+
init {
dumpController.registerDumpable(this)
if (available) {
@@ -135,6 +161,7 @@ class ControlsControllerImpl @Inject constructor (
executor,
UserHandle.ALL
)
+ contentResolver.registerContentObserver(URI, false, settingObserver, UserHandle.USER_ALL)
}
private fun confirmAvailability(): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
index fad2d94d6cf3..88b19b58a453 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
@@ -34,14 +34,17 @@ import android.widget.ImageView
import android.widget.TextView
import com.android.systemui.controls.controller.ControlsController
+import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.R
const val MIN_LEVEL = 0
const val MAX_LEVEL = 10000
+private const val UPDATE_DELAY_IN_MILLIS = 2000L
class ControlViewHolder(
val layout: ViewGroup,
- val controlsController: ControlsController
+ val controlsController: ControlsController,
+ val uiExecutor: DelayableExecutor
) {
val icon: ImageView = layout.requireViewById(R.id.icon)
val status: TextView = layout.requireViewById(R.id.status)
@@ -52,6 +55,7 @@ class ControlViewHolder(
val clipLayer: ClipDrawable
val gd: GradientDrawable
lateinit var cws: ControlWithState
+ var cancelUpdate: Runnable? = null
init {
val ld = layout.getBackground() as LayerDrawable
@@ -63,6 +67,8 @@ class ControlViewHolder(
fun bindData(cws: ControlWithState) {
this.cws = cws
+ cancelUpdate?.run()
+
val (status, template) = cws.control?.let {
title.setText(it.getTitle())
subtitle.setText(it.getSubtitle())
@@ -86,6 +92,27 @@ class ControlViewHolder(
findBehavior(status, template).apply(this, cws)
}
+ fun actionResponse(@ControlAction.ResponseResult response: Int) {
+ val text = when (response) {
+ ControlAction.RESPONSE_OK -> "Success"
+ ControlAction.RESPONSE_FAIL -> "Error"
+ else -> ""
+ }
+
+ if (!text.isEmpty()) {
+ val previousText = status.getText()
+ val previousTextExtra = statusExtra.getText()
+
+ cancelUpdate = uiExecutor.executeDelayed({
+ status.setText(previousText)
+ statusExtra.setText(previousTextExtra)
+ }, UPDATE_DELAY_IN_MILLIS)
+
+ status.setText(text)
+ statusExtra.setText("")
+ }
+ }
+
fun action(action: ControlAction) {
controlsController.action(cws.ci, action)
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
index b07a75d5e757..d70c86fc3266 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
@@ -22,6 +22,8 @@ import android.service.controls.actions.ControlAction
import android.view.ViewGroup
interface ControlsUiController {
+ val available: Boolean
+
fun show(parent: ViewGroup)
fun hide()
fun onRefreshState(componentName: ComponentName, controls: List<Control>)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index a777faf57fce..ed521e3be535 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -38,10 +38,10 @@ import com.android.systemui.controls.controller.ControlInfo
import com.android.systemui.controls.management.ControlsProviderSelectorActivity
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.R
+import com.android.systemui.util.concurrency.DelayableExecutor
import dagger.Lazy
-import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Singleton
@@ -104,18 +104,23 @@ class TokenProviderConnection(val cc: ControlsController, val context: Context)
}
}
+private data class ControlKey(val componentName: ComponentName, val controlId: String)
+
@Singleton
class ControlsUiControllerImpl @Inject constructor (
val controlsController: Lazy<ControlsController>,
val context: Context,
- @Main val uiExecutor: Executor
+ @Main val uiExecutor: DelayableExecutor
) : ControlsUiController {
private lateinit var controlInfos: List<ControlInfo>
- private val controlsById = mutableMapOf<Pair<ComponentName, String>, ControlWithState>()
- private val controlViewsById = mutableMapOf<String, ControlViewHolder>()
+ private val controlsById = mutableMapOf<ControlKey, ControlWithState>()
+ private val controlViewsById = mutableMapOf<ControlKey, ControlViewHolder>()
private lateinit var parent: ViewGroup
+ override val available: Boolean
+ get() = controlsController.get().available
+
override fun show(parent: ViewGroup) {
Log.d(TAG, "show()")
@@ -125,7 +130,7 @@ class ControlsUiControllerImpl @Inject constructor (
controlInfos.map {
ControlWithState(it, null)
- }.associateByTo(controlsById) { Pair(it.ci.component, it.ci.controlId) }
+ }.associateByTo(controlsById) { ControlKey(it.ci.component, it.ci.controlId) }
if (controlInfos.isEmpty()) {
showInitialSetupView()
@@ -178,9 +183,10 @@ class ControlsUiControllerImpl @Inject constructor (
val item = inflater.inflate(
R.layout.controls_base_item, lastRow, false) as ViewGroup
lastRow.addView(item)
- val cvh = ControlViewHolder(item, controlsController.get())
- cvh.bindData(controlsById.get(Pair(it.component, it.controlId))!!)
- controlViewsById.put(it.controlId, cvh)
+ val cvh = ControlViewHolder(item, controlsController.get(), uiExecutor)
+ val key = ControlKey(it.component, it.controlId)
+ cvh.bindData(controlsById.getValue(key))
+ controlViewsById.put(key, cvh)
}
if ((controlInfos.size % 2) == 1) {
@@ -205,21 +211,24 @@ class ControlsUiControllerImpl @Inject constructor (
override fun onRefreshState(componentName: ComponentName, controls: List<Control>) {
Log.d(TAG, "onRefreshState()")
controls.forEach { c ->
- controlsById.get(Pair(componentName, c.getControlId()))?.let {
+ controlsById.get(ControlKey(componentName, c.getControlId()))?.let {
Log.d(TAG, "onRefreshState() for id: " + c.getControlId())
val cws = ControlWithState(it.ci, c)
- controlsById.put(Pair(componentName, c.getControlId()), cws)
+ val key = ControlKey(componentName, c.getControlId())
+ controlsById.put(key, cws)
uiExecutor.execute {
- controlViewsById.get(c.getControlId())?.bindData(cws)
+ controlViewsById.get(key)?.bindData(cws)
}
}
}
}
override fun onActionResponse(componentName: ComponentName, controlId: String, response: Int) {
- Log.d(TAG, "onActionResponse()")
- TODO("not implemented")
+ val key = ControlKey(componentName, controlId)
+ uiExecutor.execute {
+ controlViewsById.get(key)?.actionResponse(response)
+ }
}
private fun createRow(inflater: LayoutInflater, parent: ViewGroup): ViewGroup {
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 45c07a3e4693..082b0656b32e 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -1899,9 +1899,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
private boolean shouldShowControls() {
- return isCurrentUserOwner()
- && !mKeyguardManager.isDeviceLocked()
- && Settings.Secure.getInt(mContext.getContentResolver(),
- "systemui.controls_available", 0) == 1;
+ return !mKeyguardManager.isDeviceLocked()
+ && mControlsUiController.getAvailable();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
index 0134aa3a15df..5de6d1c42b4f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
@@ -169,7 +169,7 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) {
v.setText(mContext.getString(
com.android.internal.R.string.bugreport_status,
- Build.VERSION.RELEASE,
+ Build.VERSION.RELEASE_OR_CODENAME,
Build.ID));
v.setVisibility(View.VISIBLE);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java b/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
index 9e3e94ce4186..6c697184f082 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
@@ -36,6 +36,7 @@ import android.media.MediaMetadata;
import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
+import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -370,6 +371,13 @@ public class QSMediaPlayer {
if (mSeamless == null) {
return;
}
+ Handler handler = mSeamless.getHandler();
+ handler.post(() -> {
+ updateChipInternal(device);
+ });
+ }
+
+ private void updateChipInternal(MediaDevice device) {
ColorStateList fgTintList = ColorStateList.valueOf(mForegroundColor);
// Update the outline color
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 2907cd41a0db..8dfcb0ac215d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -134,6 +134,8 @@ public class UserSwitcherController implements Dumpable {
mBroadcastDispatcher.registerReceiver(
mReceiver, filter, null /* handler */, UserHandle.SYSTEM);
+ mSimpleUserSwitcher = shouldUseSimpleUserSwitcher();
+
mSecondaryUserServiceIntent = new Intent(context, SystemUISecondaryUserService.class);
filter = new IntentFilter();
@@ -258,22 +260,20 @@ public class UserSwitcherController implements Dumpable {
&& mUserManager.canAddMoreUsers();
boolean createIsRestricted = !addUsersWhenLocked;
- if (!mSimpleUserSwitcher) {
- if (guestRecord == null) {
- if (canCreateGuest) {
- guestRecord = new UserRecord(null /* info */, null /* picture */,
- true /* isGuest */, false /* isCurrent */,
- false /* isAddUser */, createIsRestricted, canSwitchUsers);
- checkIfAddUserDisallowedByAdminOnly(guestRecord);
- records.add(guestRecord);
- }
- } else {
- int index = guestRecord.isCurrent ? 0 : records.size();
- records.add(index, guestRecord);
+ if (guestRecord == null) {
+ if (canCreateGuest) {
+ guestRecord = new UserRecord(null /* info */, null /* picture */,
+ true /* isGuest */, false /* isCurrent */,
+ false /* isAddUser */, createIsRestricted, canSwitchUsers);
+ checkIfAddUserDisallowedByAdminOnly(guestRecord);
+ records.add(guestRecord);
}
+ } else {
+ int index = guestRecord.isCurrent ? 0 : records.size();
+ records.add(index, guestRecord);
}
- if (!mSimpleUserSwitcher && canCreateUser) {
+ if (canCreateUser) {
UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */,
false /* isGuest */, false /* isCurrent */, true /* isAddUser */,
createIsRestricted, canSwitchUsers);
@@ -562,8 +562,7 @@ public class UserSwitcherController implements Dumpable {
private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) {
public void onChange(boolean selfChange) {
- mSimpleUserSwitcher = Settings.Global.getInt(mContext.getContentResolver(),
- SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0;
+ mSimpleUserSwitcher = shouldUseSimpleUserSwitcher();
mAddUsersWhenLocked = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0;
refreshUsers(UserHandle.USER_NULL);
@@ -579,6 +578,7 @@ public class UserSwitcherController implements Dumpable {
final UserRecord u = mUsers.get(i);
pw.print(" "); pw.println(u.toString());
}
+ pw.println("mSimpleUserSwitcher=" + mSimpleUserSwitcher);
}
public String getCurrentUserName(Context context) {
@@ -717,6 +717,13 @@ public class UserSwitcherController implements Dumpable {
}
}
+ private boolean shouldUseSimpleUserSwitcher() {
+ int defaultSimpleUserSwitcher = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_expandLockScreenUserSwitcher) ? 1 : 0;
+ return Settings.Global.getInt(mContext.getContentResolver(),
+ SIMPLE_USER_SWITCHER_GLOBAL_SETTING, defaultSimpleUserSwitcher) != 0;
+ }
+
public void startActivity(Intent intent) {
mActivityStarter.startActivity(intent, true);
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
index a60ca6201419..49ada1a5e41e 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
@@ -158,7 +158,7 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference
String demoTime = "1010"; // 10:10, a classic choice of horologists
try {
- String[] versionParts = android.os.Build.VERSION.RELEASE.split("\\.");
+ String[] versionParts = android.os.Build.VERSION.RELEASE_OR_CODENAME.split("\\.");
int majorVersion = Integer.valueOf(versionParts[0]);
demoTime = String.format("%02d00", majorVersion % 24);
} catch (IllegalArgumentException ex) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
index 897091f69f36..e3bcdc8b0b60 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
@@ -32,12 +32,13 @@ import androidx.test.filters.SmallTest
import com.android.systemui.DumpController
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastDispatcher
-import com.android.systemui.controls.management.ControlsListingController
import com.android.systemui.controls.ControlStatus
+import com.android.systemui.controls.management.ControlsListingController
import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.time.FakeSystemClock
import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
@@ -82,7 +83,7 @@ class ControlsControllerImplTest : SysuiTestCase() {
private lateinit var broadcastReceiverCaptor: ArgumentCaptor<BroadcastReceiver>
private lateinit var delayableExecutor: FakeExecutor
- private lateinit var controller: ControlsController
+ private lateinit var controller: ControlsControllerImpl
companion object {
fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
@@ -416,5 +417,70 @@ class ControlsControllerImplTest : SysuiTestCase() {
verify(listingController).changeUser(UserHandle.of(otherUser))
assertTrue(controller.getFavoriteControls().isEmpty())
assertEquals(otherUser, controller.currentUserId)
+ assertTrue(controller.available)
+ }
+
+ @Test
+ fun testDisableFeature_notAvailable() {
+ Settings.Secure.putIntForUser(mContext.contentResolver,
+ ControlsControllerImpl.CONTROLS_AVAILABLE, 0, user)
+ controller.settingObserver.onChange(false, ControlsControllerImpl.URI, 0)
+ assertFalse(controller.available)
+ }
+
+ @Test
+ fun testDisableFeature_clearFavorites() {
+ controller.changeFavoriteStatus(TEST_CONTROL_INFO, true)
+ assertFalse(controller.getFavoriteControls().isEmpty())
+
+ Settings.Secure.putIntForUser(mContext.contentResolver,
+ ControlsControllerImpl.CONTROLS_AVAILABLE, 0, user)
+ controller.settingObserver.onChange(false, ControlsControllerImpl.URI, user)
+ assertTrue(controller.getFavoriteControls().isEmpty())
+ }
+
+ @Test
+ fun testDisableFeature_noChangeForNotCurrentUser() {
+ controller.changeFavoriteStatus(TEST_CONTROL_INFO, true)
+ Settings.Secure.putIntForUser(mContext.contentResolver,
+ ControlsControllerImpl.CONTROLS_AVAILABLE, 0, otherUser)
+ controller.settingObserver.onChange(false, ControlsControllerImpl.URI, otherUser)
+
+ assertTrue(controller.available)
+ assertFalse(controller.getFavoriteControls().isEmpty())
+ }
+
+ @Test
+ fun testCorrectUserSettingOnUserChange() {
+ Settings.Secure.putIntForUser(mContext.contentResolver,
+ ControlsControllerImpl.CONTROLS_AVAILABLE, 0, otherUser)
+
+ val intent = Intent(Intent.ACTION_USER_SWITCHED).apply {
+ putExtra(Intent.EXTRA_USER_HANDLE, otherUser)
+ }
+ val pendingResult = mock(BroadcastReceiver.PendingResult::class.java)
+ `when`(pendingResult.sendingUserId).thenReturn(otherUser)
+ broadcastReceiverCaptor.value.pendingResult = pendingResult
+
+ broadcastReceiverCaptor.value.onReceive(mContext, intent)
+
+ assertFalse(controller.available)
+ }
+
+ @Test
+ fun testCountFavoritesForComponent_singleComponent() {
+ controller.changeFavoriteStatus(TEST_CONTROL_INFO, true)
+
+ assertEquals(1, controller.countFavoritesForComponent(TEST_COMPONENT))
+ assertEquals(0, controller.countFavoritesForComponent(TEST_COMPONENT_2))
+ }
+
+ @Test
+ fun testCountFavoritesForComponent_multipleComponents() {
+ controller.changeFavoriteStatus(TEST_CONTROL_INFO, true)
+ controller.changeFavoriteStatus(TEST_CONTROL_INFO_2, true)
+
+ assertEquals(1, controller.countFavoritesForComponent(TEST_COMPONENT))
+ assertEquals(1, controller.countFavoritesForComponent(TEST_COMPONENT_2))
}
-} \ No newline at end of file
+}
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
index 07abe1adeb52..39c402be84a3 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
@@ -272,13 +272,6 @@ public class Tethering {
mStateReceiver = new StateReceiver();
- mNetdCallback = new NetdCallback();
- try {
- mNetd.registerUnsolicitedEventListener(mNetdCallback);
- } catch (RemoteException e) {
- mLog.e("Unable to register netd UnsolicitedEventListener");
- }
-
final UserManager userManager = (UserManager) mContext.getSystemService(
Context.USER_SERVICE);
mTetheringRestriction = new UserRestrictionActionListener(userManager, this);
@@ -287,6 +280,14 @@ public class Tethering {
// Load tethering configuration.
updateConfiguration();
+ // NetdCallback should be registered after updateConfiguration() to ensure
+ // TetheringConfiguration is created.
+ mNetdCallback = new NetdCallback();
+ try {
+ mNetd.registerUnsolicitedEventListener(mNetdCallback);
+ } catch (RemoteException e) {
+ mLog.e("Unable to register netd UnsolicitedEventListener");
+ }
startStateMachineUpdaters(mHandler);
startTrackDefaultNetwork();
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index ec3dbe9f850e..672617090a71 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -6581,6 +6581,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
private ArrayMap<NetworkRequestInfo, NetworkAgentInfo> computeRequestReassignmentForNetwork(
+ @NonNull final NetworkReassignment changes,
@NonNull final NetworkAgentInfo newNetwork) {
final int score = newNetwork.getCurrentScore();
final ArrayMap<NetworkRequestInfo, NetworkAgentInfo> reassignedRequests = new ArrayMap<>();
@@ -6591,7 +6592,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
// requests or not, and doesn't affect the network's score.
if (nri.request.isListen()) continue;
- final NetworkAgentInfo currentNetwork = nri.mSatisfier;
+ // The reassignment has been seeded with the initial assignment, therefore
+ // getReassignment can't be null and mNewNetwork is only null if there was no
+ // satisfier in the first place or there was an explicit reassignment to null.
+ final NetworkAgentInfo currentNetwork = changes.getReassignment(nri).mNewNetwork;
final boolean satisfies = newNetwork.satisfies(nri.request);
if (newNetwork == currentNetwork && satisfies) continue;
@@ -6641,7 +6645,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (VDBG || DDBG) log("rematching " + newNetwork.name());
final ArrayMap<NetworkRequestInfo, NetworkAgentInfo> reassignedRequests =
- computeRequestReassignmentForNetwork(newNetwork);
+ computeRequestReassignmentForNetwork(changes, newNetwork);
// Find and migrate to this Network any NetworkRequests for
// which this network is now the best.
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 2fc9d04623f8..c4e6427a0dfb 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -16,6 +16,11 @@
package com.android.server.compat;
+import static android.Manifest.permission.LOG_COMPAT_CHANGE;
+import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG;
+import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
import android.app.ActivityManager;
import android.app.IActivityManager;
import android.content.Context;
@@ -67,12 +72,14 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@Override
public void reportChange(long changeId, ApplicationInfo appInfo) {
+ checkCompatChangeLogPermission();
reportChange(changeId, appInfo.uid,
ChangeReporter.STATE_LOGGED);
}
@Override
public void reportChangeByPackageName(long changeId, String packageName, int userId) {
+ checkCompatChangeLogPermission();
ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
if (appInfo == null) {
return;
@@ -82,11 +89,13 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@Override
public void reportChangeByUid(long changeId, int uid) {
+ checkCompatChangeLogPermission();
reportChange(changeId, uid, ChangeReporter.STATE_LOGGED);
}
@Override
public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
+ checkCompatChangeReadAndLogPermission();
if (mCompatConfig.isChangeEnabled(changeId, appInfo)) {
reportChange(changeId, appInfo.uid,
ChangeReporter.STATE_ENABLED);
@@ -99,6 +108,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@Override
public boolean isChangeEnabledByPackageName(long changeId, String packageName, int userId) {
+ checkCompatChangeReadAndLogPermission();
ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
if (appInfo == null) {
return true;
@@ -108,6 +118,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@Override
public boolean isChangeEnabledByUid(long changeId, int uid) {
+ checkCompatChangeReadAndLogPermission();
String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
if (packages == null || packages.length == 0) {
return true;
@@ -140,6 +151,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@Override
public void setOverrides(CompatibilityChangeConfig overrides, String packageName)
throws RemoteException, SecurityException {
+ checkCompatChangeOverridePermission();
mCompatConfig.addOverrides(overrides, packageName);
killPackage(packageName);
}
@@ -147,11 +159,13 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@Override
public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName)
throws RemoteException, SecurityException {
+ checkCompatChangeOverridePermission();
mCompatConfig.addOverrides(overrides, packageName);
}
@Override
public void clearOverrides(String packageName) throws RemoteException, SecurityException {
+ checkCompatChangeOverridePermission();
mCompatConfig.removePackageOverrides(packageName);
killPackage(packageName);
}
@@ -159,12 +173,14 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@Override
public void clearOverridesForTest(String packageName)
throws RemoteException, SecurityException {
+ checkCompatChangeOverridePermission();
mCompatConfig.removePackageOverrides(packageName);
}
@Override
public boolean clearOverride(long changeId, String packageName)
throws RemoteException, SecurityException {
+ checkCompatChangeOverridePermission();
boolean existed = mCompatConfig.removeOverride(changeId, packageName);
killPackage(packageName);
return existed;
@@ -172,11 +188,13 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@Override
public CompatibilityChangeConfig getAppConfig(ApplicationInfo appInfo) {
+ checkCompatChangeReadAndLogPermission();
return mCompatConfig.getAppConfig(appInfo);
}
@Override
public CompatibilityChangeInfo[] listAllChanges() {
+ checkCompatChangeReadPermission();
return mCompatConfig.dumpChanges();
}
@@ -215,6 +233,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ checkCompatChangeReadAndLogPermission();
if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
mCompatConfig.dumpConfig(pw);
}
@@ -272,4 +291,30 @@ public class PlatformCompat extends IPlatformCompat.Stub {
Binder.restoreCallingIdentity(identity);
}
}
+
+ private void checkCompatChangeLogPermission() throws SecurityException {
+ if (mContext.checkCallingOrSelfPermission(LOG_COMPAT_CHANGE)
+ != PERMISSION_GRANTED) {
+ throw new SecurityException("Cannot log compat change usage");
+ }
+ }
+
+ private void checkCompatChangeReadPermission() throws SecurityException {
+ if (mContext.checkCallingOrSelfPermission(READ_COMPAT_CHANGE_CONFIG)
+ != PERMISSION_GRANTED) {
+ throw new SecurityException("Cannot read compat change");
+ }
+ }
+
+ private void checkCompatChangeOverridePermission() throws SecurityException {
+ if (mContext.checkCallingOrSelfPermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
+ != PERMISSION_GRANTED) {
+ throw new SecurityException("Cannot override compat change");
+ }
+ }
+
+ private void checkCompatChangeReadAndLogPermission() throws SecurityException {
+ checkCompatChangeReadPermission();
+ checkCompatChangeLogPermission();
+ }
}
diff --git a/services/core/java/com/android/server/media/MediaRoute2Provider.java b/services/core/java/com/android/server/media/MediaRoute2Provider.java
index 7b17b4ed6219..83588846ade8 100644
--- a/services/core/java/com/android/server/media/MediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/MediaRoute2Provider.java
@@ -63,7 +63,6 @@ abstract class MediaRoute2Provider {
public abstract void sendControlRequest(String routeId, Intent request);
public abstract void requestSetVolume(String routeId, int volume);
- public abstract void requestUpdateVolume(String routeId, int delta);
@NonNull
public String getUniqueId() {
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
index e22ea4681428..d08fb71d3dee 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
@@ -138,14 +138,6 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
}
}
- @Override
- public void requestUpdateVolume(String routeId, int delta) {
- if (mConnectionReady) {
- mActiveConnection.requestUpdateVolume(routeId, delta);
- updateBinding();
- }
- }
-
public boolean hasComponentName(String packageName, String className) {
return mComponentName.getPackageName().equals(packageName)
&& mComponentName.getClassName().equals(className);
@@ -518,14 +510,6 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
}
}
- public void requestUpdateVolume(String routeId, int delta) {
- try {
- mProvider.requestUpdateVolume(routeId, delta);
- } catch (RemoteException ex) {
- Slog.e(TAG, "Failed to deliver request to request update volume.", ex);
- }
- }
-
@Override
public void binderDied() {
mHandler.post(() -> onConnectionDied(Connection.this));
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 358cc29e3d64..b1133223e59a 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -334,20 +334,6 @@ class MediaRouter2ServiceImpl {
}
}
- public void requestUpdateVolume2(IMediaRouter2Client client, MediaRoute2Info route, int delta) {
- Objects.requireNonNull(client, "client must not be null");
- Objects.requireNonNull(route, "route must not be null");
-
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mLock) {
- requestUpdateVolumeLocked(client, route, delta);
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
public void requestCreateClientSession(IMediaRouter2Manager manager, String packageName,
MediaRoute2Info route, int requestId) {
final long token = Binder.clearCallingIdentity();
@@ -375,21 +361,6 @@ class MediaRouter2ServiceImpl {
}
}
- public void requestUpdateVolume2Manager(IMediaRouter2Manager manager,
- MediaRoute2Info route, int delta) {
- Objects.requireNonNull(manager, "manager must not be null");
- Objects.requireNonNull(route, "route must not be null");
-
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mLock) {
- requestUpdateVolumeLocked(manager, route, delta);
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
@NonNull
public List<RoutingSessionInfo> getActiveSessions(IMediaRouter2Manager manager) {
final long token = Binder.clearCallingIdentity();
@@ -628,18 +599,6 @@ class MediaRouter2ServiceImpl {
}
}
- private void requestUpdateVolumeLocked(IMediaRouter2Client client, MediaRoute2Info route,
- int delta) {
- final IBinder binder = client.asBinder();
- Client2Record clientRecord = mAllClientRecords.get(binder);
-
- if (clientRecord != null) {
- clientRecord.mUserRecord.mHandler.sendMessage(
- obtainMessage(UserHandler::requestUpdateVolume,
- clientRecord.mUserRecord.mHandler, route, delta));
- }
- }
-
private void registerManagerLocked(IMediaRouter2Manager manager,
int uid, int pid, String packageName, int userId, boolean trusted) {
final IBinder binder = manager.asBinder();
@@ -713,18 +672,6 @@ class MediaRouter2ServiceImpl {
}
}
- private void requestUpdateVolumeLocked(IMediaRouter2Manager manager, MediaRoute2Info route,
- int delta) {
- final IBinder binder = manager.asBinder();
- ManagerRecord managerRecord = mAllManagerRecords.get(binder);
-
- if (managerRecord != null) {
- managerRecord.mUserRecord.mHandler.sendMessage(
- obtainMessage(UserHandler::requestUpdateVolume,
- managerRecord.mUserRecord.mHandler, route, delta));
- }
- }
-
private List<RoutingSessionInfo> getActiveSessionsLocked(IMediaRouter2Manager manager) {
final IBinder binder = manager.asBinder();
ManagerRecord managerRecord = mAllManagerRecords.get(binder);
@@ -1459,13 +1406,6 @@ class MediaRouter2ServiceImpl {
}
}
- private void requestUpdateVolume(MediaRoute2Info route, int delta) {
- final MediaRoute2Provider provider = findProvider(route.getProviderId());
- if (provider != null) {
- provider.requestUpdateVolume(route.getOriginalId(), delta);
- }
- }
-
private List<IMediaRouter2Client> getClients() {
final List<IMediaRouter2Client> clients = new ArrayList<>();
MediaRouter2ServiceImpl service = mServiceRef.get();
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index e1d38039b955..57f0328f1c00 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -539,12 +539,6 @@ public final class MediaRouterService extends IMediaRouterService.Stub
// Binder call
@Override
- public void requestUpdateVolume2(IMediaRouter2Client client, MediaRoute2Info route, int delta) {
- mService2.requestUpdateVolume2(client, route, delta);
- }
-
- // Binder call
- @Override
public void requestSetVolume2Manager(IMediaRouter2Manager manager,
MediaRoute2Info route, int volume) {
mService2.requestSetVolume2Manager(manager, route, volume);
@@ -552,13 +546,6 @@ public final class MediaRouterService extends IMediaRouterService.Stub
// Binder call
@Override
- public void requestUpdateVolume2Manager(IMediaRouter2Manager manager,
- MediaRoute2Info route, int delta) {
- mService2.requestUpdateVolume2Manager(manager, route, delta);
- }
-
- // Binder call
- @Override
public List<RoutingSessionInfo> getActiveSessions(IMediaRouter2Manager manager) {
return mService2.getActiveSessions(manager);
}
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index 798a781a9d6c..888f7ce74ba4 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -153,11 +153,6 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
public void requestSetVolume(String routeId, int volume) {
}
- //TODO: implement method
- @Override
- public void requestUpdateVolume(String routeId, int delta) {
- }
-
private void initializeDefaultRoute() {
mDefaultRoute = new MediaRoute2Info.Builder(
DEFAULT_ROUTE_ID,
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 40ea6cfb6d4a..b98bb0831b0e 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -234,12 +234,12 @@ public class Installer extends SystemService {
}
public void moveCompleteApp(String fromUuid, String toUuid, String packageName,
- String dataAppName, int appId, String seInfo, int targetSdkVersion)
- throws InstallerException {
+ String dataAppName, int appId, String seInfo, int targetSdkVersion,
+ String fromCodePath) throws InstallerException {
if (!checkBeforeRemote()) return;
try {
mInstalld.moveCompleteApp(fromUuid, toUuid, packageName, dataAppName, appId, seInfo,
- targetSdkVersion);
+ targetSdkVersion, fromCodePath);
} catch (Exception e) {
throw InstallerException.from(e);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c14b42dd69c8..e4ec3745e01d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -13978,9 +13978,11 @@ public class PackageManagerService extends IPackageManager.Stub
final int appId;
final String seinfo;
final int targetSdkVersion;
+ final String fromCodePath;
public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
- String dataAppName, int appId, String seinfo, int targetSdkVersion) {
+ String dataAppName, int appId, String seinfo, int targetSdkVersion,
+ String fromCodePath) {
this.moveId = moveId;
this.fromUuid = fromUuid;
this.toUuid = toUuid;
@@ -13989,6 +13991,7 @@ public class PackageManagerService extends IPackageManager.Stub
this.appId = appId;
this.seinfo = seinfo;
this.targetSdkVersion = targetSdkVersion;
+ this.fromCodePath = fromCodePath;
}
}
@@ -15104,7 +15107,8 @@ public class PackageManagerService extends IPackageManager.Stub
synchronized (mInstaller) {
try {
mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
- move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
+ move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion,
+ move.fromCodePath);
} catch (InstallerException e) {
Slog.w(TAG, "Failed to move app", e);
return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
@@ -22054,6 +22058,7 @@ public class PackageManagerService extends IPackageManager.Stub
final PackageFreezer freezer;
final int[] installedUserIds;
final boolean isCurrentLocationExternal;
+ final String fromCodePath;
// reader
synchronized (mLock) {
@@ -22110,6 +22115,7 @@ public class PackageManagerService extends IPackageManager.Stub
targetSdkVersion = pkg.getTargetSdkVersion();
freezer = freezePackage(packageName, "movePackageInternal");
installedUserIds = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
+ fromCodePath = pkg.getCodePath();
}
final Bundle extras = new Bundle();
@@ -22238,7 +22244,7 @@ public class PackageManagerService extends IPackageManager.Stub
final String dataAppName = codeFile.getName();
move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
- dataAppName, appId, seinfo, targetSdkVersion);
+ dataAppName, appId, seinfo, targetSdkVersion, fromCodePath);
} else {
move = null;
}
diff --git a/services/core/java/com/android/server/policy/LegacyGlobalActions.java b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
index 6daf5162ebad..6eba59acbc94 100644
--- a/services/core/java/com/android/server/policy/LegacyGlobalActions.java
+++ b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
@@ -402,7 +402,7 @@ class LegacyGlobalActions implements DialogInterface.OnDismissListener, DialogIn
public String getStatus() {
return mContext.getString(
com.android.internal.R.string.bugreport_status,
- Build.VERSION.RELEASE,
+ Build.VERSION.RELEASE_OR_CODENAME,
Build.ID);
}
}
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 96f1219861ec..5c79f6e6391d 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -2480,7 +2480,7 @@ public class StatsPullAtomService extends SystemService {
.writeString(Build.BRAND)
.writeString(Build.PRODUCT)
.writeString(Build.DEVICE)
- .writeString(Build.VERSION.RELEASE)
+ .writeString(Build.VERSION.RELEASE_OR_CODENAME)
.writeString(Build.ID)
.writeString(Build.VERSION.INCREMENTAL)
.writeString(Build.TYPE)
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 75d87edbc437..f35ba9e69ed7 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -386,6 +386,8 @@ public class ActivityStartController {
} else {
callingPid = callingUid = -1;
}
+ final int filterCallingUid = ActivityStarter.computeResolveFilterUid(
+ callingUid, realCallingUid, UserHandle.USER_NULL);
final SparseArray<String> startingUidPkgs = new SparseArray<>();
final long origId = Binder.clearCallingIdentity();
try {
@@ -408,9 +410,7 @@ public class ActivityStartController {
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i],
- 0 /* startFlags */, null /* profilerInfo */, userId,
- ActivityStarter.computeResolveFilterUid(
- callingUid, realCallingUid, UserHandle.USER_NULL));
+ 0 /* startFlags */, null /* profilerInfo */, userId, filterCallingUid);
aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);
if (aInfo != null) {
@@ -457,6 +457,7 @@ public class ActivityStartController {
Slog.wtf(TAG, sb.toString());
}
+ final IBinder sourceResultTo = resultTo;
final ActivityRecord[] outActivity = new ActivityRecord[1];
// Lock the loop to ensure the activities launched in a sequence.
synchronized (mService.mGlobalLock) {
@@ -470,7 +471,18 @@ public class ActivityStartController {
}
return startResult;
}
- resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
+ final ActivityRecord started = outActivity[0];
+ if (started != null && started.getUid() == filterCallingUid) {
+ // Only the started activity which has the same uid as the source caller can
+ // be the caller of next activity.
+ resultTo = started.appToken;
+ } else {
+ resultTo = sourceResultTo;
+ // Different apps not adjacent to the caller are forced to be new task.
+ if (i < starters.length - 1) {
+ starters[i + 1].getIntent().addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ }
+ }
}
}
} finally {
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 9e3292b59402..c7270f257923 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2493,7 +2493,6 @@ class ActivityStarter {
return this;
}
- @VisibleForTesting
Intent getIntent() {
return mRequest.intent;
}
diff --git a/services/tests/mockingservicestests/AndroidManifest.xml b/services/tests/mockingservicestests/AndroidManifest.xml
index 0e24b0314b2d..44eb8285c7db 100644
--- a/services/tests/mockingservicestests/AndroidManifest.xml
+++ b/services/tests/mockingservicestests/AndroidManifest.xml
@@ -17,6 +17,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.frameworks.mockingservicestests">
+ <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE"/>
+ <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
<uses-permission android:name="android.permission.HARDWARE_TEST"/>
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index d2ddff3627b9..1212f2082404 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -65,6 +65,8 @@
<uses-permission android:name="android.permission.WATCH_APPOPS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.SUSPEND_APPS"/>
+ <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE" />
+ <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
<uses-permission android:name="android.permission.CONTROL_KEYGUARD"/>
<uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE"/>
<uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
diff --git a/services/tests/uiservicestests/AndroidManifest.xml b/services/tests/uiservicestests/AndroidManifest.xml
index 180deb5c4dcc..dab0a5f0e279 100644
--- a/services/tests/uiservicestests/AndroidManifest.xml
+++ b/services/tests/uiservicestests/AndroidManifest.xml
@@ -28,6 +28,8 @@
<uses-permission android:name="android.permission.ACCESS_VOICE_INTERACTION_SERVICE" />
<uses-permission android:name="android.permission.DEVICE_POWER" />
<uses-permission android:name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY" />
+ <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE"/>
+ <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS" />
<uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT"/>
diff --git a/tests/PlatformCompatGating/Android.bp b/tests/PlatformCompatGating/Android.bp
index 5e9ef8efc402..74dfde848191 100644
--- a/tests/PlatformCompatGating/Android.bp
+++ b/tests/PlatformCompatGating/Android.bp
@@ -18,14 +18,11 @@ android_test {
name: "PlatformCompatGating",
// Only compile source java files in this apk.
srcs: ["src/**/*.java"],
- certificate: "platform",
- libs: [
- "android.test.runner",
- "android.test.base",
- ],
static_libs: [
"junit",
- "android-support-test",
+ "androidx.test.runner",
+ "androidx.test.core",
+ "androidx.test.ext.junit",
"mockito-target-minus-junit4",
"truth-prebuilt",
"platform-compat-test-rules"
diff --git a/tests/PlatformCompatGating/AndroidManifest.xml b/tests/PlatformCompatGating/AndroidManifest.xml
index 7f14b83fbc75..c24dc31b7bf3 100644
--- a/tests/PlatformCompatGating/AndroidManifest.xml
+++ b/tests/PlatformCompatGating/AndroidManifest.xml
@@ -6,6 +6,6 @@
<uses-library android:name="android.test.runner" />
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.tests.gating"/>
</manifest>
diff --git a/tests/PlatformCompatGating/AndroidTest.xml b/tests/PlatformCompatGating/AndroidTest.xml
index c62684837332..0c7485b27fb8 100644
--- a/tests/PlatformCompatGating/AndroidTest.xml
+++ b/tests/PlatformCompatGating/AndroidTest.xml
@@ -24,7 +24,6 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="com.android.tests.gating"/>
- <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
<option name="hidden-api-checks" value="false"/>
</test>
</configuration>
diff --git a/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java
index dc317f1941c7..c1ce0e99640c 100644
--- a/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java
+++ b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java
@@ -18,8 +18,9 @@ package com.android.tests.gating;
import static com.google.common.truth.Truth.assertThat;
import android.compat.testing.PlatformCompatChangeRule;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
import com.android.compat.testing.DummyApi;
@@ -81,14 +82,14 @@ public class PlatformCompatGatingTest {
@Test
@EnableCompatChanges({DummyApi.CHANGE_SYSTEM_SERVER})
public void testDummyGatingPositiveSystemServer() {
- assertThat(
- DummyApi.dummySystemServer(InstrumentationRegistry.getTargetContext())).isTrue();
+ assertThat(DummyApi.dummySystemServer(
+ InstrumentationRegistry.getInstrumentation().getTargetContext())).isTrue();
}
@Test
@DisableCompatChanges({DummyApi.CHANGE_SYSTEM_SERVER})
public void testDummyGatingNegativeSystemServer() {
- assertThat(
- DummyApi.dummySystemServer(InstrumentationRegistry.getTargetContext())).isFalse();
+ assertThat(DummyApi.dummySystemServer(
+ InstrumentationRegistry.getInstrumentation().getTargetContext())).isFalse();
}
}
diff --git a/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatPermissionsTest.java b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatPermissionsTest.java
new file mode 100644
index 000000000000..9b9e5815a588
--- /dev/null
+++ b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatPermissionsTest.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tests.gating;
+
+import static android.Manifest.permission.LOG_COMPAT_CHANGE;
+import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG;
+import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG;
+
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.compat.Compatibility.ChangeConfig;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Process;
+import android.os.ServiceManager;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.internal.compat.CompatibilityChangeConfig;
+import com.android.internal.compat.IPlatformCompat;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@RunWith(JUnit4.class)
+public final class PlatformCompatPermissionsTest {
+
+ // private Context mContext;
+ private IPlatformCompat mPlatformCompat;
+
+ @Rule
+ public final ExpectedException thrown = ExpectedException.none();
+ private Context mContext;
+ private UiAutomation mUiAutomation;
+ private PackageManager mPackageManager;
+
+ @Before
+ public void setUp() {
+ // mContext;
+ mPlatformCompat = IPlatformCompat.Stub
+ .asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ mUiAutomation = instrumentation.getUiAutomation();
+ mContext = instrumentation.getTargetContext();
+
+ mPackageManager = mContext.getPackageManager();
+ }
+
+ @After
+ public void tearDown() {
+
+ mUiAutomation.dropShellPermissionIdentity();
+ }
+
+ @Test
+ public void reportChange_noLogCompatChangePermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+ final String packageName = mContext.getPackageName();
+
+ mPlatformCompat.reportChange(1, mPackageManager.getApplicationInfo(packageName, 0));
+ }
+
+ @Test
+ public void reportChange_logCompatChangePermission_noThrow()
+ throws Throwable {
+ mUiAutomation.adoptShellPermissionIdentity(LOG_COMPAT_CHANGE);
+ final String packageName = mContext.getPackageName();
+
+ mPlatformCompat.reportChange(1, mPackageManager.getApplicationInfo(packageName, 0));
+ }
+
+ @Test
+ public void reportChangeByPackageName_noLogCompatChangePermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+ final String packageName = mContext.getPackageName();
+
+ mPlatformCompat.reportChangeByPackageName(1, packageName, 0);
+ }
+
+ @Test
+ public void reportChangeByPackageName_logCompatChangePermission_noThrow()
+ throws Throwable {
+ mUiAutomation.adoptShellPermissionIdentity(LOG_COMPAT_CHANGE);
+ final String packageName = mContext.getPackageName();
+
+ mPlatformCompat.reportChangeByPackageName(1, packageName, 0);
+ }
+
+ @Test
+ public void reportChangeByUid_noLogCompatChangePermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+
+ mPlatformCompat.reportChangeByUid(1, Process.myUid());
+ }
+
+ @Test
+ public void reportChangeByUid_logCompatChangePermission_noThrow()
+ throws Throwable {
+ mUiAutomation.adoptShellPermissionIdentity(LOG_COMPAT_CHANGE);
+
+ mPlatformCompat.reportChangeByUid(1, Process.myUid());
+ }
+
+ @Test
+ public void isChangeEnabled_noReadCompatConfigPermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+ final String packageName = mContext.getPackageName();
+
+ mPlatformCompat.isChangeEnabled(1, mPackageManager.getApplicationInfo(packageName, 0));
+ }
+
+ @Test
+ public void isChangeEnabled_noLogCompatChangeConfigPermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+ mUiAutomation.adoptShellPermissionIdentity(READ_COMPAT_CHANGE_CONFIG);
+ final String packageName = mContext.getPackageName();
+
+ mPlatformCompat.isChangeEnabled(1, mPackageManager.getApplicationInfo(packageName, 0));
+ }
+
+ @Test
+ public void isChangeEnabled_readAndLogCompatChangeConfigPermission_noThrow()
+ throws Throwable {
+ mUiAutomation.adoptShellPermissionIdentity(READ_COMPAT_CHANGE_CONFIG, LOG_COMPAT_CHANGE);
+ final String packageName = mContext.getPackageName();
+
+ mPlatformCompat.isChangeEnabled(1, mPackageManager.getApplicationInfo(packageName, 0));
+ }
+
+ @Test
+ public void isChangeEnabledByPackageName_noReadCompatConfigPermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+ final String packageName = mContext.getPackageName();
+
+ mPlatformCompat.isChangeEnabledByPackageName(1, packageName, 0);
+ }
+
+ @Test
+ public void isChangeEnabledByPackageName_noLogompatConfigPermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+ mUiAutomation.adoptShellPermissionIdentity(READ_COMPAT_CHANGE_CONFIG);
+ final String packageName = mContext.getPackageName();
+
+ mPlatformCompat.isChangeEnabledByPackageName(1, packageName, 0);
+ }
+
+ @Test
+ public void isChangeEnabledByPackageName_readAndLogCompatChangeConfigPermission_noThrow()
+ throws Throwable {
+ mUiAutomation.adoptShellPermissionIdentity(READ_COMPAT_CHANGE_CONFIG, LOG_COMPAT_CHANGE);
+ final String packageName = mContext.getPackageName();
+
+ mPlatformCompat.isChangeEnabledByPackageName(1, packageName, 0);
+ }
+
+ @Test
+ public void isChangeEnabledByUid_noReadCompatConfigPermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+
+ mPlatformCompat.isChangeEnabledByUid(1, Process.myUid());
+ }
+
+ @Test
+ public void isChangeEnabledByUid_noLogCompatChangePermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+ mUiAutomation.adoptShellPermissionIdentity(READ_COMPAT_CHANGE_CONFIG);
+
+ mPlatformCompat.isChangeEnabledByUid(1, Process.myUid());
+ }
+
+ @Test
+ public void isChangeEnabledByUid_readAndLogCompatChangeConfigPermission_noThrow()
+ throws Throwable {
+ mUiAutomation.adoptShellPermissionIdentity(READ_COMPAT_CHANGE_CONFIG, LOG_COMPAT_CHANGE);
+
+ mPlatformCompat.isChangeEnabledByUid(1, Process.myUid());
+ }
+
+ @Test
+ public void setOverrides_noOverridesPermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+ Set<Long> enabled = new HashSet<>();
+ Set<Long> disabled = new HashSet<>();
+ ChangeConfig changeConfig = new ChangeConfig(enabled, disabled);
+ CompatibilityChangeConfig compatibilityChangeConfig =
+ new CompatibilityChangeConfig(changeConfig);
+
+ mPlatformCompat.setOverrides(compatibilityChangeConfig, "foo.bar");
+ }
+ @Test
+ public void setOverrides_overridesPermission_noThrow()
+ throws Throwable {
+ mUiAutomation.adoptShellPermissionIdentity(OVERRIDE_COMPAT_CHANGE_CONFIG);
+ Set<Long> enabled = new HashSet<>();
+ Set<Long> disabled = new HashSet<>();
+ ChangeConfig changeConfig = new ChangeConfig(enabled, disabled);
+ CompatibilityChangeConfig compatibilityChangeConfig =
+ new CompatibilityChangeConfig(changeConfig);
+
+ mPlatformCompat.setOverrides(compatibilityChangeConfig, "foo.bar");
+ }
+
+ @Test
+ public void setOverridesForTest_noOverridesPermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+ Set<Long> enabled = new HashSet<>();
+ Set<Long> disabled = new HashSet<>();
+ ChangeConfig changeConfig = new ChangeConfig(enabled, disabled);
+ CompatibilityChangeConfig compatibilityChangeConfig =
+ new CompatibilityChangeConfig(changeConfig);
+
+ mPlatformCompat.setOverridesForTest(compatibilityChangeConfig, "foo.bar");
+ }
+ @Test
+ public void setOverridesForTest_overridesPermission_noThrow()
+ throws Throwable {
+ mUiAutomation.adoptShellPermissionIdentity(OVERRIDE_COMPAT_CHANGE_CONFIG);
+ Set<Long> enabled = new HashSet<>();
+ Set<Long> disabled = new HashSet<>();
+ ChangeConfig changeConfig = new ChangeConfig(enabled, disabled);
+ CompatibilityChangeConfig compatibilityChangeConfig =
+ new CompatibilityChangeConfig(changeConfig);
+
+ mPlatformCompat.setOverridesForTest(compatibilityChangeConfig, "foo.bar");
+ }
+
+ @Test
+ public void clearOverrides_noOverridesPermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+
+ mPlatformCompat.clearOverrides("foo.bar");
+ }
+ @Test
+ public void clearOverrides_overridesPermission_noThrow()
+ throws Throwable {
+ mUiAutomation.adoptShellPermissionIdentity(OVERRIDE_COMPAT_CHANGE_CONFIG);
+
+ mPlatformCompat.clearOverrides("foo.bar");
+ }
+
+ @Test
+ public void clearOverridesForTest_noOverridesPermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+
+ mPlatformCompat.clearOverridesForTest("foo.bar");
+ }
+ @Test
+ public void clearOverridesForTest_overridesPermission_noThrow()
+ throws Throwable {
+ mUiAutomation.adoptShellPermissionIdentity(OVERRIDE_COMPAT_CHANGE_CONFIG);
+
+ mPlatformCompat.clearOverridesForTest("foo.bar");
+ }
+
+ @Test
+ public void clearOverride_noOverridesPermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+
+ mPlatformCompat.clearOverride(1, "foo.bar");
+ }
+ @Test
+ public void clearOverride_overridesPermission_noThrow()
+ throws Throwable {
+ mUiAutomation.adoptShellPermissionIdentity(OVERRIDE_COMPAT_CHANGE_CONFIG);
+
+ mPlatformCompat.clearOverride(1, "foo.bar");
+ }
+
+ @Test
+ public void listAllChanges_noReadCompatConfigPermission_throwsSecurityException()
+ throws Throwable {
+ thrown.expect(SecurityException.class);
+
+ mPlatformCompat.listAllChanges();
+ }
+ @Test
+ public void listAllChanges_readCompatConfigPermission_noThrow()
+ throws Throwable {
+ mUiAutomation.adoptShellPermissionIdentity(READ_COMPAT_CHANGE_CONFIG);
+
+ mPlatformCompat.listAllChanges();
+ }
+}
diff --git a/tests/PlatformCompatGating/test-rules/Android.bp b/tests/PlatformCompatGating/test-rules/Android.bp
index 8211ef523ee7..10fa2dc0d7c6 100644
--- a/tests/PlatformCompatGating/test-rules/Android.bp
+++ b/tests/PlatformCompatGating/test-rules/Android.bp
@@ -19,7 +19,7 @@ java_library {
srcs: ["src/**/*.java"],
static_libs: [
"junit",
- "android-support-test",
+ "androidx.test.core",
"truth-prebuilt",
"core-compat-test-rules"
],
diff --git a/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
index 932ec643d478..d6846faa5c00 100644
--- a/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
+++ b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
@@ -16,13 +16,17 @@
package android.compat.testing;
+import android.Manifest;
import android.app.Instrumentation;
+import android.app.UiAutomation;
import android.compat.Compatibility;
import android.compat.Compatibility.ChangeConfig;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.support.test.InstrumentationRegistry;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
import com.android.internal.compat.CompatibilityChangeConfig;
import com.android.internal.compat.IPlatformCompat;
@@ -83,12 +87,17 @@ public class PlatformCompatChangeRule extends CoreCompatChangeRule {
@Override
public void evaluate() throws Throwable {
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ UiAutomation uiAutomation = instrumentation.getUiAutomation();
String packageName = instrumentation.getTargetContext().getPackageName();
IPlatformCompat platformCompat = IPlatformCompat.Stub
.asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
if (platformCompat == null) {
throw new IllegalStateException("Could not get IPlatformCompat service!");
}
+ uiAutomation.adoptShellPermissionIdentity(
+ Manifest.permission.LOG_COMPAT_CHANGE,
+ Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG,
+ Manifest.permission.READ_COMPAT_CHANGE_CONFIG);
Compatibility.setOverrides(mConfig);
try {
platformCompat.setOverridesForTest(new CompatibilityChangeConfig(mConfig),
@@ -101,6 +110,7 @@ public class PlatformCompatChangeRule extends CoreCompatChangeRule {
} catch (RemoteException e) {
throw new RuntimeException("Could not call IPlatformCompat binder method!", e);
} finally {
+ uiAutomation.dropShellPermissionIdentity();
Compatibility.clearOverrides();
}
}
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
index d3958a65c704..a251c053e004 100644
--- a/tools/stats_log_api_gen/Android.bp
+++ b/tools/stats_log_api_gen/Android.bp
@@ -30,7 +30,7 @@ cc_binary_host {
"utils.cpp",
],
cflags: [
- "-DSTATS_SCHEMA_LEGACY",
+ //"-DSTATS_SCHEMA_LEGACY",
"-Wall",
"-Werror",
],
diff --git a/tools/stats_log_api_gen/java_writer_q.cpp b/tools/stats_log_api_gen/java_writer_q.cpp
index a68c3a208869..12c050d8ef8d 100644
--- a/tools/stats_log_api_gen/java_writer_q.cpp
+++ b/tools/stats_log_api_gen/java_writer_q.cpp
@@ -175,9 +175,7 @@ int write_java_methods_q_schema(
indent.c_str());
fprintf(out,
"%s android.util.SparseArray<Float> floatMap = null;\n", indent.c_str());
- fprintf(out,
- "%s int keyValuePairSize = LIST_TYPE_OVERHEAD * 5;\n",
- indent.c_str());
+ fprintf(out, "%s int keyValuePairSize = LIST_TYPE_OVERHEAD;\n", indent.c_str());
fprintf(out,
"%s for (int i = 0; i < count; i++) {\n", indent.c_str());
fprintf(out,
@@ -360,8 +358,9 @@ int write_java_methods_q_schema(
requiredHelpers |= JAVA_MODULE_REQUIRES_FLOAT;
requiredHelpers |= JAVA_MODULE_REQUIRES_KEY_VALUE_PAIRS;
fprintf(out,
- "%s writeKeyValuePairs(buff, pos, intMap, longMap, stringMap, "
- "floatMap);\n", indent.c_str());
+ "%s writeKeyValuePairs(buff, pos, (byte) count, intMap, longMap, "
+ "stringMap, floatMap);\n",
+ indent.c_str());
fprintf(out, "%s pos += keyValuePairSize;\n", indent.c_str());
break;
default:
@@ -472,7 +471,8 @@ void write_java_helpers_for_q_schema_methods(
}
if (requiredHelpers & JAVA_MODULE_REQUIRES_KEY_VALUE_PAIRS) {
- fprintf(out, "%sprivate static void writeKeyValuePairs(byte[] buff, int pos,\n",
+ fprintf(out,
+ "%sprivate static void writeKeyValuePairs(byte[] buff, int pos, byte numPairs,\n",
indent.c_str());
fprintf(out, "%s final android.util.SparseIntArray intMap,\n", indent.c_str());
fprintf(out, "%s final android.util.SparseLongArray longMap,\n", indent.c_str());
@@ -483,15 +483,12 @@ void write_java_helpers_for_q_schema_methods(
// Start list of lists.
fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) 4;\n", indent.c_str());
+ fprintf(out, "%s buff[pos + 1] = (byte) numPairs;\n", indent.c_str());
fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
// Write integers.
fprintf(out, "%s final int intMapSize = null == intMap ? 0 : intMap.size();\n",
indent.c_str());
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) intMapSize;\n", indent.c_str());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
fprintf(out, "%s for (int i = 0; i < intMapSize; i++) {\n", indent.c_str());
fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str());
@@ -509,9 +506,6 @@ void write_java_helpers_for_q_schema_methods(
// Write longs.
fprintf(out, "%s final int longMapSize = null == longMap ? 0 : longMap.size();\n",
indent.c_str());
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) longMapSize;\n", indent.c_str());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
fprintf(out, "%s for (int i = 0; i < longMapSize; i++) {\n", indent.c_str());
fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str());
@@ -529,9 +523,6 @@ void write_java_helpers_for_q_schema_methods(
// Write Strings.
fprintf(out, "%s final int stringMapSize = null == stringMap ? 0 : stringMap.size();\n",
indent.c_str());
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) stringMapSize;\n", indent.c_str());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
fprintf(out, "%s for (int i = 0; i < stringMapSize; i++) {\n", indent.c_str());
fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str());
@@ -556,9 +547,6 @@ void write_java_helpers_for_q_schema_methods(
// Write floats.
fprintf(out, "%s final int floatMapSize = null == floatMap ? 0 : floatMap.size();\n",
indent.c_str());
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) floatMapSize;\n", indent.c_str());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
fprintf(out, "%s for (int i = 0; i < floatMapSize; i++) {\n", indent.c_str());
fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str());
diff --git a/tools/streaming_proto/cpp/main.cpp b/tools/streaming_proto/cpp/main.cpp
index d6b9d81137ac..fe9a438d81d7 100644
--- a/tools/streaming_proto/cpp/main.cpp
+++ b/tools/streaming_proto/cpp/main.cpp
@@ -33,13 +33,13 @@ write_enum(stringstream& text, const EnumDescriptorProto& enu, const string& ind
if (GENERATE_MAPPING) {
string name = make_constant_name(enu.name());
string prefix = name + "_";
- text << indent << "const int _ENUM_" << name << "_COUNT = " << N << ";" << endl;
- text << indent << "const char* _ENUM_" << name << "_NAMES[" << N << "] = {" << endl;
+ text << indent << "static const int _ENUM_" << name << "_COUNT = " << N << ";" << endl;
+ text << indent << "static const char* _ENUM_" << name << "_NAMES[" << N << "] = {" << endl;
for (int i=0; i<N; i++) {
text << indent << INDENT << "\"" << stripPrefix(enu.value(i).name(), prefix) << "\"," << endl;
}
text << indent << "};" << endl;
- text << indent << "const int _ENUM_" << name << "_VALUES[" << N << "] = {" << endl;
+ text << indent << "static const int _ENUM_" << name << "_VALUES[" << N << "] = {" << endl;
for (int i=0; i<N; i++) {
text << indent << INDENT << make_constant_name(enu.value(i).name()) << "," << endl;
}
@@ -102,13 +102,13 @@ write_message(stringstream& text, const DescriptorProto& message, const string&
if (GENERATE_MAPPING) {
N = message.field_size();
- text << indented << "const int _FIELD_COUNT = " << N << ";" << endl;
- text << indented << "const char* _FIELD_NAMES[" << N << "] = {" << endl;
+ text << indented << "static const int _FIELD_COUNT = " << N << ";" << endl;
+ text << indented << "static const char* _FIELD_NAMES[" << N << "] = {" << endl;
for (int i=0; i<N; i++) {
text << indented << INDENT << "\"" << message.field(i).name() << "\"," << endl;
}
text << indented << "};" << endl;
- text << indented << "const uint64_t _FIELD_IDS[" << N << "] = {" << endl;
+ text << indented << "static const uint64_t _FIELD_IDS[" << N << "] = {" << endl;
for (int i=0; i<N; i++) {
text << indented << INDENT << make_constant_name(message.field(i).name()) << "," << endl;
}
@@ -152,7 +152,7 @@ write_header_file(CodeGeneratorResponse* response, const FileDescriptorProto& fi
write_message(text, file_descriptor.message_type(i), "");
}
- for (vector<string>::iterator it = namespaces.begin(); it != namespaces.end(); it++) {
+ for (vector<string>::reverse_iterator it = namespaces.rbegin(); it != namespaces.rend(); it++) {
text << "} // " << *it << endl;
}