diff options
515 files changed, 18601 insertions, 24709 deletions
diff --git a/Android.bp b/Android.bp index 632ef1c60613..594126fcc157 100644 --- a/Android.bp +++ b/Android.bp @@ -162,6 +162,14 @@ filegroup { } filegroup { + name: "framework-telephony-common-sources", + srcs: [ + "telephony/common/**/*.java", + ], + path: "telephony/common", +} + +filegroup { name: "framework-wifi-sources", srcs: [ "wifi/java/**/*.java", @@ -189,6 +197,7 @@ filegroup { ":framework-rs-sources", ":framework-sax-sources", ":framework-telecomm-sources", + ":framework-telephony-common-sources", ":framework-telephony-sources", ":framework-wifi-sources", ":PacProcessor-aidl-sources", @@ -314,7 +323,7 @@ java_defaults { exclude_srcs: [ // See comment on framework-atb-backward-compatibility module below - "core/java/android/content/pm/parsing/library/AndroidTestBaseUpdater.java", + "core/java/android/content/pm/AndroidTestBaseUpdater.java", ], sdk_version: "core_platform", @@ -447,7 +456,7 @@ java_library { name: "framework-atb-backward-compatibility", installable: true, srcs: [ - "core/java/android/content/pm/parsing/library/AndroidTestBaseUpdater.java", + "core/java/android/content/pm/AndroidTestBaseUpdater.java", ], } @@ -814,6 +823,7 @@ frameworks_base_subdirs = [ "opengl/java", "sax/java", "telecomm/java", + "telephony/common", "telephony/java", "wifi/java", "lowpan/java", diff --git a/CleanSpec.mk b/CleanSpec.mk index 6a909c0364e9..f7a285835126 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -254,6 +254,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/DynamicAndroidInsta $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/DefaultContainerService) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/CaptivePortalLogin) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/ext.jar) +$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/telephony/java/com/google/android/mms) # ****************************************************************** # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER # ****************************************************************** diff --git a/apex/statsd/OWNERS b/apex/statsd/OWNERS new file mode 100644 index 000000000000..bed9600bc955 --- /dev/null +++ b/apex/statsd/OWNERS @@ -0,0 +1,9 @@ +jeffreyhuang@google.com +joeo@google.com +jtnguyen@google.com +muhammadq@google.com +ruchirr@google.com +singhtejinder@google.com +tsaichristine@google.com +yaochen@google.com +yro@google.com
\ No newline at end of file diff --git a/api/current.txt b/api/current.txt index 44cb997a250d..3ce043c89b65 100644 --- a/api/current.txt +++ b/api/current.txt @@ -11395,7 +11395,7 @@ package android.content.pm { method public abstract void onPackageRemoved(String, android.os.UserHandle); method public abstract void onPackagesAvailable(String[], android.os.UserHandle, boolean); method public void onPackagesSuspended(String[], android.os.UserHandle); - method public void onPackagesSuspended(String[], android.os.UserHandle, @Nullable android.os.Bundle); + method @Deprecated public void onPackagesSuspended(String[], android.os.UserHandle, @Nullable android.os.Bundle); method public abstract void onPackagesUnavailable(String[], android.os.UserHandle, boolean); method public void onPackagesUnsuspended(String[], android.os.UserHandle); method public void onShortcutsChanged(@NonNull String, @NonNull java.util.List<android.content.pm.ShortcutInfo>, @NonNull android.os.UserHandle); @@ -11908,6 +11908,7 @@ package android.content.pm { field public static final int SIGNATURE_NO_MATCH = -3; // 0xfffffffd field public static final int SIGNATURE_SECOND_NOT_SIGNED = -2; // 0xfffffffe field public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; // 0xfffffffc + field public static final int SYNCHRONOUS = 2; // 0x2 field public static final int VERIFICATION_ALLOW = 1; // 0x1 field public static final int VERIFICATION_REJECT = -1; // 0xffffffff field public static final int VERSION_CODE_HIGHEST = -1; // 0xffffffff @@ -23133,10 +23134,10 @@ package android.location { method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(long, float, @NonNull android.location.Criteria, @NonNull java.util.concurrent.Executor, @NonNull android.location.LocationListener); method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull String, long, float, @NonNull android.app.PendingIntent); method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(long, float, @NonNull android.location.Criteria, @NonNull android.app.PendingIntent); - method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull String, @NonNull android.location.LocationListener, @Nullable android.os.Looper); - method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull android.location.Criteria, @NonNull android.location.LocationListener, @Nullable android.os.Looper); - method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull String, @NonNull android.app.PendingIntent); - method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull android.location.Criteria, @NonNull android.app.PendingIntent); + method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull String, @NonNull android.location.LocationListener, @Nullable android.os.Looper); + method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull android.location.Criteria, @NonNull android.location.LocationListener, @Nullable android.os.Looper); + method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull String, @NonNull android.app.PendingIntent); + method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull android.location.Criteria, @NonNull android.app.PendingIntent); method public boolean sendExtraCommand(@NonNull String, @NonNull String, @Nullable android.os.Bundle); method public void setTestProviderEnabled(@NonNull String, boolean); method public void setTestProviderLocation(@NonNull String, @NonNull android.location.Location); @@ -43171,6 +43172,7 @@ package android.telecom { field public static final String EXTRA_SILENT_RINGING_REQUESTED = "android.telecom.extra.SILENT_RINGING_REQUESTED"; field public static final String EXTRA_SUGGESTED_PHONE_ACCOUNTS = "android.telecom.extra.SUGGESTED_PHONE_ACCOUNTS"; field public static final int STATE_ACTIVE = 4; // 0x4 + field public static final int STATE_AUDIO_PROCESSING = 12; // 0xc field public static final int STATE_CONNECTING = 9; // 0x9 field public static final int STATE_DIALING = 1; // 0x1 field public static final int STATE_DISCONNECTED = 7; // 0x7 @@ -43180,6 +43182,7 @@ package android.telecom { field public static final int STATE_PULLING_CALL = 11; // 0xb field public static final int STATE_RINGING = 2; // 0x2 field public static final int STATE_SELECT_PHONE_ACCOUNT = 8; // 0x8 + field public static final int STATE_SIMULATED_RINGING = 13; // 0xd } public abstract static class Call.Callback { @@ -53053,7 +53056,8 @@ package android.view.contentcapture { method @NonNull public android.view.autofill.AutofillId newAutofillId(@NonNull android.view.autofill.AutofillId, long); method @NonNull public final android.view.ViewStructure newViewStructure(@NonNull android.view.View); method @NonNull public final android.view.ViewStructure newVirtualViewStructure(@NonNull android.view.autofill.AutofillId, long); - method public final void notifySessionLifecycle(boolean); + method public final void notifySessionPaused(); + method public final void notifySessionResumed(); method public final void notifyViewAppeared(@NonNull android.view.ViewStructure); method public final void notifyViewDisappeared(@NonNull android.view.autofill.AutofillId); method public final void notifyViewTextChanged(@NonNull android.view.autofill.AutofillId, @Nullable CharSequence); diff --git a/api/system-current.txt b/api/system-current.txt index e92dc89245ba..c9f96e079f33 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -3431,9 +3431,9 @@ package android.location { method public boolean isProviderEnabledForUser(@NonNull String, @NonNull android.os.UserHandle); method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public boolean isProviderPackage(@NonNull String); method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean registerGnssBatchedLocationCallback(long, boolean, @NonNull android.location.BatchedLocationCallback, @Nullable android.os.Handler); - method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper); - method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.location.LocationListener); - method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.app.PendingIntent); + method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper); + method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.location.LocationListener); + method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull android.app.PendingIntent); method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setExtraLocationControllerPackage(@Nullable String); method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setExtraLocationControllerPackageEnabled(boolean); method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle); @@ -6967,6 +6967,8 @@ package android.telecom { public final class Call { method @Deprecated public void addListener(android.telecom.Call.Listener); + method public void enterBackgroundAudioProcessing(); + method public void exitBackgroundAudioProcessing(boolean); method @Deprecated public void removeListener(android.telecom.Call.Listener); field @Deprecated public static final int STATE_PRE_DIAL_WAIT = 8; // 0x8 } @@ -6975,6 +6977,10 @@ package android.telecom { ctor @Deprecated public Call.Listener(); } + public static class CallScreeningService.CallResponse.Builder { + method public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallFurther(boolean); + } + public abstract class Conference extends android.telecom.Conferenceable { method @Deprecated public final android.telecom.AudioState getAudioState(); method @Deprecated public final long getConnectTimeMillis(); @@ -8383,6 +8389,27 @@ package android.telephony { } +package android.telephony.cdma { + + public final class CdmaSmsCbProgramData implements android.os.Parcelable { + method public int describeContents(); + method public int getCategory(); + method public int getOperation(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 4099; // 0x1003 + field public static final int CATEGORY_CMAS_EXTREME_THREAT = 4097; // 0x1001 + field public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 4351; // 0x10ff + field public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 4096; // 0x1000 + field public static final int CATEGORY_CMAS_SEVERE_THREAT = 4098; // 0x1002 + field public static final int CATEGORY_CMAS_TEST_MESSAGE = 4100; // 0x1004 + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.cdma.CdmaSmsCbProgramData> CREATOR; + field public static final int OPERATION_ADD_CATEGORY = 1; // 0x1 + field public static final int OPERATION_CLEAR_CATEGORIES = 2; // 0x2 + field public static final int OPERATION_DELETE_CATEGORY = 0; // 0x0 + } + +} + package android.telephony.data { public final class DataCallResponse implements android.os.Parcelable { diff --git a/api/test-current.txt b/api/test-current.txt index ee631bee5750..0cf2f1bb33ae 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1093,9 +1093,9 @@ package android.location { method @NonNull public String[] getBackgroundThrottlingWhitelist(); method @NonNull public String[] getIgnoreSettingsWhitelist(); method @NonNull public java.util.List<android.location.LocationRequest> getTestProviderCurrentRequests(String); - method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper); - method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.location.LocationListener); - method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.app.PendingIntent); + method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper); + method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.location.LocationListener); + method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull android.app.PendingIntent); method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle); } @@ -2771,10 +2771,19 @@ package android.service.quicksettings { package android.telecom { + public final class Call { + method public void enterBackgroundAudioProcessing(); + method public void exitBackgroundAudioProcessing(boolean); + } + public final class CallAudioState implements android.os.Parcelable { ctor public CallAudioState(boolean, int, int, @Nullable android.bluetooth.BluetoothDevice, @NonNull java.util.Collection<android.bluetooth.BluetoothDevice>); } + public static class CallScreeningService.CallResponse.Builder { + method public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallFurther(boolean); + } + public abstract class Conference extends android.telecom.Conferenceable { method public android.telecom.Connection getPrimaryConnection(); } @@ -2933,6 +2942,14 @@ package android.telephony { } +package android.telephony.emergency { + + public final class EmergencyNumber implements java.lang.Comparable<android.telephony.emergency.EmergencyNumber> android.os.Parcelable { + field public static final int EMERGENCY_NUMBER_SOURCE_TEST = 32; // 0x20 + } + +} + package android.telephony.mbms { public static class DownloadRequest.Builder { @@ -3355,6 +3372,7 @@ package android.view { public class WindowlessViewRoot { ctor public WindowlessViewRoot(android.content.Context, android.view.Display, android.view.SurfaceControl); method public void addView(android.view.View, android.view.WindowManager.LayoutParams); + method public void relayout(android.view.WindowManager.LayoutParams); } } diff --git a/cmds/idmap2/idmap2/Create.cpp b/cmds/idmap2/idmap2/Create.cpp index bb8d92737563..f482191b09a8 100644 --- a/cmds/idmap2/idmap2/Create.cpp +++ b/cmds/idmap2/idmap2/Create.cpp @@ -50,7 +50,7 @@ Result<Unit> Create(const std::vector<std::string>& args) { std::string overlay_apk_path; std::string idmap_path; std::vector<std::string> policies; - bool ignore_overlayable; + bool ignore_overlayable = false; const CommandLineOptions opts = CommandLineOptions("idmap2 create") diff --git a/cmds/idmap2/idmap2/Dump.cpp b/cmds/idmap2/idmap2/Dump.cpp index 8716bf313ed0..47f442aab235 100644 --- a/cmds/idmap2/idmap2/Dump.cpp +++ b/cmds/idmap2/idmap2/Dump.cpp @@ -39,7 +39,7 @@ using android::idmap2::Unit; Result<Unit> Dump(const std::vector<std::string>& args) { SYSTRACE << "Dump " << args; std::string idmap_path; - bool verbose; + bool verbose = false; const CommandLineOptions opts = CommandLineOptions("idmap2 dump") diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp index 053b7bc9afa3..d0530f2d344e 100644 --- a/cmds/idmap2/idmap2/Scan.cpp +++ b/cmds/idmap2/idmap2/Scan.cpp @@ -178,6 +178,17 @@ Result<Unit> Scan(const std::vector<std::string>& args) { continue; } + // Note that conditional property enablement/exclusion only applies if + // the attribute is present. In its absence, all overlays are presumed enabled. + if (!overlay_info->requiredSystemPropertyName.empty() + && !overlay_info->requiredSystemPropertyValue.empty()) { + // if property set & equal to value, then include overlay - otherwise skip + if (android::base::GetProperty(overlay_info->requiredSystemPropertyName, "") + != overlay_info->requiredSystemPropertyValue) { + continue; + } + } + std::vector<std::string> fulfilled_policies; if (!override_policies.empty()) { fulfilled_policies = override_policies; diff --git a/cmds/idmap2/include/idmap2/ResourceUtils.h b/cmds/idmap2/include/idmap2/ResourceUtils.h index 8797a788dd1d..9a0c2abced5a 100644 --- a/cmds/idmap2/include/idmap2/ResourceUtils.h +++ b/cmds/idmap2/include/idmap2/ResourceUtils.h @@ -30,6 +30,8 @@ namespace android::idmap2::utils { struct OverlayManifestInfo { std::string target_package; // NOLINT(misc-non-private-member-variables-in-classes) std::string target_name; // NOLINT(misc-non-private-member-variables-in-classes) + std::string requiredSystemPropertyName; // NOLINT(misc-non-private-member-variables-in-classes) + std::string requiredSystemPropertyValue; // NOLINT(misc-non-private-member-variables-in-classes) bool is_static; // NOLINT(misc-non-private-member-variables-in-classes) int priority = -1; // NOLINT(misc-non-private-member-variables-in-classes) }; diff --git a/cmds/idmap2/libidmap2/ResourceUtils.cpp b/cmds/idmap2/libidmap2/ResourceUtils.cpp index 71ba3f0f1ac2..dce83e35978d 100644 --- a/cmds/idmap2/libidmap2/ResourceUtils.cpp +++ b/cmds/idmap2/libidmap2/ResourceUtils.cpp @@ -103,6 +103,16 @@ Result<OverlayManifestInfo> ExtractOverlayManifestInfo(const std::string& path, info.priority = std::stoi(iter->second); } + iter = tag->find("requiredSystemPropertyName"); + if (iter != tag->end()) { + info.requiredSystemPropertyName = iter->second; + } + + iter = tag->find("requiredSystemPropertyValue"); + if (iter != tag->end()) { + info.requiredSystemPropertyValue = iter->second; + } + return info; } diff --git a/cmds/idmap2/libidmap2/ZipFile.cpp b/cmds/idmap2/libidmap2/ZipFile.cpp index 4f5e3a45f183..1e1a218163f0 100644 --- a/cmds/idmap2/libidmap2/ZipFile.cpp +++ b/cmds/idmap2/libidmap2/ZipFile.cpp @@ -34,6 +34,7 @@ std::unique_ptr<const ZipFile> ZipFile::Open(const std::string& path) { ::ZipArchiveHandle handle; int32_t status = ::OpenArchive(path.c_str(), &handle); if (status != 0) { + ::CloseArchive(handle); return nullptr; } return std::unique_ptr<ZipFile>(new ZipFile(handle)); diff --git a/cmds/idmap2/static-checks.sh b/cmds/idmap2/static-checks.sh index 41d3c69540b2..a372abdaa146 100755 --- a/cmds/idmap2/static-checks.sh +++ b/cmds/idmap2/static-checks.sh @@ -27,10 +27,11 @@ function _eval() local red="\e[31m" local green="\e[32m" local reset="\e[0m" + local output _log "${green}[ RUN ]${reset} ${label}" - local output="$(eval "$cmd")" - if [[ -z "${output}" ]]; then + output="$(eval "$cmd" 2>&1)" + if [[ $? -eq 0 ]]; then _log "${green}[ OK ]${reset} ${label}" return 0 else diff --git a/cmds/idmap2/valgrind.sh b/cmds/idmap2/valgrind.sh new file mode 100755 index 000000000000..b4ebab0c7ffe --- /dev/null +++ b/cmds/idmap2/valgrind.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# +# Copyright (C) 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. +# + +function _log() +{ + echo -e "$*" >&2 +} + +function _eval() +{ + local label="$1" + local cmd="$2" + local red="\e[31m" + local green="\e[32m" + local reset="\e[0m" + local output + + _log "${green}[ RUN ]${reset} ${label}" + output="$(eval "$cmd" 2>&1)" + if [[ $? -eq 0 ]]; then + _log "${green}[ OK ]${reset} ${label}" + return 0 + else + echo "${output}" + _log "${red}[ FAILED ]${reset} ${label}" + errors=$((errors + 1)) + return 1 + fi +} + +errors=0 +script="$(readlink -f "$BASH_SOURCE")" +prefix="$(dirname "$script")" +target_path="${prefix}/tests/data/target/target.apk" +overlay_path="${prefix}/tests/data/overlay/overlay.apk" +idmap_path="/tmp/a.idmap" +valgrind="valgrind --error-exitcode=1 -q --track-origins=yes --leak-check=full" + +_eval "idmap2 create" "$valgrind idmap2 create --policy public --target-apk-path $target_path --overlay-apk-path $overlay_path --idmap-path $idmap_path" +_eval "idmap2 dump" "$valgrind idmap2 dump --idmap-path $idmap_path" +_eval "idmap2 lookup" "$valgrind idmap2 lookup --idmap-path $idmap_path --config '' --resid test.target:string/str1" +_eval "idmap2 scan" "$valgrind idmap2 scan --input-directory ${prefix}/tests/data/overlay --recursive --target-package-name test.target --target-apk-path $target_path --output-directory /tmp --override-policy public" +_eval "idmap2 verify" "$valgrind idmap2 verify --idmap-path $idmap_path" +_eval "idmap2_tests" "$valgrind $ANDROID_HOST_OUT/nativetest64/idmap2_tests/idmap2_tests" +exit $errors diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index c79b0cab35c6..cb2732561b56 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -138,6 +138,7 @@ cc_defaults { "libprotoutil", "libservices", "libstatslog", + "libstatssocket", "libsysutils", "libtimestats_proto", "libutils", diff --git a/cmds/statsd/src/external/GpuStatsPuller.cpp b/cmds/statsd/src/external/GpuStatsPuller.cpp index bbdb5405ca05..d38b87f046e0 100644 --- a/cmds/statsd/src/external/GpuStatsPuller.cpp +++ b/cmds/statsd/src/external/GpuStatsPuller.cpp @@ -92,9 +92,15 @@ static bool pullGpuStatsAppInfo(const sp<IGpuService>& gpuService, 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->write(int64VectorToProtoByteString(info.glDriverLoadingTime))) return false; - if (!event->write(int64VectorToProtoByteString(info.vkDriverLoadingTime))) return false; - if (!event->write(int64VectorToProtoByteString(info.angleDriverLoadingTime))) 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; event->init(); diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp index 0ade53118d77..fd19c9d61f87 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -332,6 +332,13 @@ bool LogEvent::write(float value) { return false; } +bool LogEvent::writeBytes(const string& value) { + if (mContext) { + return android_log_write_char_array(mContext, value.c_str(), value.length()) >= 0; + } + return false; +} + bool LogEvent::writeKeyValuePairs(int32_t uid, const std::map<int32_t, int32_t>& int_map, const std::map<int32_t, int64_t>& long_map, diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h index 531ce299beef..f1f45a2d3bc7 100644 --- a/cmds/statsd/src/logd/LogEvent.h +++ b/cmds/statsd/src/logd/LogEvent.h @@ -21,9 +21,9 @@ #include <android/frameworks/stats/1.0/types.h> #include <android/os/StatsLogEventWrapper.h> #include <android/util/ProtoOutputStream.h> -#include <log/log_event_list.h> #include <log/log_read.h> #include <private/android_logger.h> +#include <stats_event_list.h> #include <utils/Errors.h> #include <string> @@ -157,6 +157,7 @@ public: bool write(float value); bool write(const std::vector<AttributionNodeInternal>& nodes); bool write(const AttributionNodeInternal& node); + bool writeBytes(const std::string& value); bool writeKeyValuePairs(int32_t uid, const std::map<int32_t, int32_t>& int_map, const std::map<int32_t, int64_t>& long_map, diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp index 504ee22f72e4..0743480bf4ee 100644 --- a/cmds/statsd/tests/LogEvent_test.cpp +++ b/cmds/statsd/tests/LogEvent_test.cpp @@ -582,7 +582,7 @@ TEST(LogEventTest, TestBinaryFieldAtom) { event1.write((int32_t)stats::launcher::LauncherAction::LONGPRESS); event1.write((int32_t)stats::launcher::LauncherState::OVERVIEW); event1.write((int64_t)stats::launcher::LauncherState::ALLAPPS); - event1.write(extension_str); + event1.writeBytes(extension_str); event1.init(); ProtoOutputStream proto; @@ -621,7 +621,7 @@ TEST(LogEventTest, TestBinaryFieldAtom_empty) { event1.write((int32_t)stats::launcher::LauncherAction::LONGPRESS); event1.write((int32_t)stats::launcher::LauncherState::OVERVIEW); event1.write((int64_t)stats::launcher::LauncherState::ALLAPPS); - event1.write(extension_str); + event1.writeBytes(extension_str); event1.init(); ProtoOutputStream proto; diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java index b37ee74b100c..c9f069d62003 100644 --- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java +++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java @@ -78,6 +78,8 @@ public final class Telecom extends BaseCommand { private static final String COMMAND_SET_SIM_COUNT = "set-sim-count"; private static final String COMMAND_GET_SIM_CONFIG = "get-sim-config"; private static final String COMMAND_GET_MAX_PHONES = "get-max-phones"; + private static final String COMMAND_SET_TEST_EMERGENCY_PHONE_ACCOUNT_PACKAGE_FILTER = + "set-test-emergency-phone-account-package-filter"; private ComponentName mComponent; private String mAccountId; @@ -91,7 +93,10 @@ public final class Telecom extends BaseCommand { + "usage: telecom set-phone-account-enabled <COMPONENT> <ID> <USER_SN>\n" + "usage: telecom set-phone-account-disabled <COMPONENT> <ID> <USER_SN>\n" + "usage: telecom register-phone-account <COMPONENT> <ID> <USER_SN> <LABEL>\n" - + "usage: telecom set-user-selected-outgoing-phone-account <COMPONENT> <ID> " + + "usage: telecom register-sim-phone-account [-e] <COMPONENT> <ID> <USER_SN>" + + " <LABEL>: registers a PhoneAccount with CAPABILITY_SIM_SUBSCRIPTION" + + " and optionally CAPABILITY_PLACE_EMERGENCY_CALLS if \"-e\" is provided\n" + + "usage: telecom set-user-selected-outgoing-phone-account [-e] <COMPONENT> <ID> " + "<USER_SN>\n" + "usage: telecom set-test-call-redirection-app <PACKAGE>\n" + "usage: telecom set-test-call-screening-app <PACKAGE>\n" @@ -108,6 +113,7 @@ public final class Telecom extends BaseCommand { + "usage: telecom set-sim-count <COUNT>\n" + "usage: telecom get-sim-config\n" + "usage: telecom get-max-phones\n" + + "usage: telecom set-emer-phone-account-filter <PACKAGE>\n" + "\n" + "telecom set-phone-account-enabled: Enables the given phone account, if it has" + " already been registered with Telecom.\n" @@ -121,6 +127,8 @@ public final class Telecom extends BaseCommand { + "telecom get-default-dialer: Displays the current default dialer.\n" + "\n" + "telecom get-system-dialer: Displays the current system dialer.\n" + + "telecom set-system-dialer: Set the override system dialer to the given" + + " component. To remove the override, send \"default\"\n" + "\n" + "telecom wait-on-handlers: Wait until all handlers finish their work.\n" + "\n" @@ -131,6 +139,10 @@ public final class Telecom extends BaseCommand { + " or \"\" for single SIM\n" + "\n" + "telecom get-max-phones: Get the max supported phones from the modem.\n" + + "telecom set-test-emergency-phone-account-package-filter <PACKAGE>: sets a" + + " package name that will be used for test emergency calls. To clear," + + " send an empty package name. Real emergency calls will still be placed" + + " over Telephony.\n" ); } @@ -219,6 +231,9 @@ public final class Telecom extends BaseCommand { case COMMAND_GET_MAX_PHONES: runGetMaxPhones(); break; + case COMMAND_SET_TEST_EMERGENCY_PHONE_ACCOUNT_PACKAGE_FILTER: + runSetEmergencyPhoneAccountPackageFilter(); + break; default: Log.w(this, "onRun: unknown command: %s", command); throw new IllegalArgumentException ("unknown command '" + command + "'"); @@ -245,19 +260,31 @@ public final class Telecom extends BaseCommand { } private void runRegisterSimPhoneAccount() throws RemoteException { + boolean isEmergencyAccount = false; + String opt; + while ((opt = nextOption()) != null) { + switch (opt) { + case "-e": { + isEmergencyAccount = true; + break; + } + } + } final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs(); final String label = nextArgRequired(); final String address = nextArgRequired(); + int capabilities = PhoneAccount.CAPABILITY_CALL_PROVIDER + | PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION + | (isEmergencyAccount ? PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS : 0); PhoneAccount account = PhoneAccount.builder( handle, label) - .setAddress(Uri.parse(address)) - .setSubscriptionAddress(Uri.parse(address)) - .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | - PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) - .setShortDescription(label) - .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) - .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL) - .build(); + .setAddress(Uri.parse(address)) + .setSubscriptionAddress(Uri.parse(address)) + .setCapabilities(capabilities) + .setShortDescription(label) + .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) + .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL) + .build(); mTelecomService.registerPhoneAccount(account); System.out.println("Success - " + handle + " registered."); } @@ -309,9 +336,11 @@ public final class Telecom extends BaseCommand { } private void runSetSystemDialer() throws RemoteException { - final String packageName = nextArg(); - mTelecomService.setSystemDialerPackage(packageName.equals("default") ? null : packageName); - System.out.println("Success - " + packageName + " set as override system dialer."); + final String flatComponentName = nextArg(); + final ComponentName componentName = (flatComponentName.equals("default") + ? null : parseComponentName(flatComponentName)); + mTelecomService.setSystemDialer(componentName); + System.out.println("Success - " + componentName + " set as override system dialer."); } private void runGetDefaultDialer() throws RemoteException { @@ -355,6 +384,18 @@ public final class Telecom extends BaseCommand { } } + private void runSetEmergencyPhoneAccountPackageFilter() throws RemoteException { + String packageName = mArgs.getNextArg(); + if (TextUtils.isEmpty(packageName)) { + mTelecomService.setTestEmergencyPhoneAccountPackageNameFilter(null); + System.out.println("Success - filter cleared"); + } else { + mTelecomService.setTestEmergencyPhoneAccountPackageNameFilter(packageName); + System.out.println("Success = filter set to " + packageName); + } + + } + private PhoneAccountHandle getPhoneAccountHandleFromArgs() throws RemoteException { if (TextUtils.isEmpty(mArgs.peekNextArg())) { return null; diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt index e1cf7c1a583b..3cb2273776f2 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -1182,284 +1182,4 @@ Lcom/android/server/net/BaseNetworkObserver;-><init>()V Lcom/android/server/ResettableTimeout$T;-><init>(Lcom/android/server/ResettableTimeout;)V Lcom/google/android/gles_jni/EGLImpl;-><init>()V Lcom/google/android/gles_jni/GLImpl;-><init>()V -Lcom/google/android/mms/ContentType;->getAudioTypes()Ljava/util/ArrayList; -Lcom/google/android/mms/ContentType;->getImageTypes()Ljava/util/ArrayList; -Lcom/google/android/mms/ContentType;->getVideoTypes()Ljava/util/ArrayList; -Lcom/google/android/mms/ContentType;->isAudioType(Ljava/lang/String;)Z -Lcom/google/android/mms/ContentType;->isDrmType(Ljava/lang/String;)Z -Lcom/google/android/mms/ContentType;->isImageType(Ljava/lang/String;)Z -Lcom/google/android/mms/ContentType;->isSupportedAudioType(Ljava/lang/String;)Z -Lcom/google/android/mms/ContentType;->isSupportedImageType(Ljava/lang/String;)Z -Lcom/google/android/mms/ContentType;->isSupportedType(Ljava/lang/String;)Z -Lcom/google/android/mms/ContentType;->isSupportedVideoType(Ljava/lang/String;)Z -Lcom/google/android/mms/ContentType;->isTextType(Ljava/lang/String;)Z -Lcom/google/android/mms/ContentType;->isVideoType(Ljava/lang/String;)Z -Lcom/google/android/mms/InvalidHeaderValueException;-><init>(Ljava/lang/String;)V -Lcom/google/android/mms/MmsException;-><init>()V -Lcom/google/android/mms/MmsException;-><init>(Ljava/lang/String;)V -Lcom/google/android/mms/MmsException;-><init>(Ljava/lang/String;Ljava/lang/Throwable;)V -Lcom/google/android/mms/MmsException;-><init>(Ljava/lang/Throwable;)V -Lcom/google/android/mms/pdu/AcknowledgeInd;-><init>(I[B)V -Lcom/google/android/mms/pdu/AcknowledgeInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V -Lcom/google/android/mms/pdu/AcknowledgeInd;->setReportAllowed(I)V -Lcom/google/android/mms/pdu/AcknowledgeInd;->setTransactionId([B)V -Lcom/google/android/mms/pdu/Base64;->decodeBase64([B)[B -Lcom/google/android/mms/pdu/CharacterSets;->getMibEnumValue(Ljava/lang/String;)I -Lcom/google/android/mms/pdu/CharacterSets;->getMimeName(I)Ljava/lang/String; -Lcom/google/android/mms/pdu/DeliveryInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V -Lcom/google/android/mms/pdu/DeliveryInd;->getDate()J -Lcom/google/android/mms/pdu/DeliveryInd;->getMessageId()[B -Lcom/google/android/mms/pdu/DeliveryInd;->getStatus()I -Lcom/google/android/mms/pdu/DeliveryInd;->getTo()[Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/EncodedStringValue;-><init>(I[B)V -Lcom/google/android/mms/pdu/EncodedStringValue;-><init>(Ljava/lang/String;)V -Lcom/google/android/mms/pdu/EncodedStringValue;-><init>([B)V -Lcom/google/android/mms/pdu/EncodedStringValue;->appendTextString([B)V -Lcom/google/android/mms/pdu/EncodedStringValue;->concat([Lcom/google/android/mms/pdu/EncodedStringValue;)Ljava/lang/String; -Lcom/google/android/mms/pdu/EncodedStringValue;->copy(Lcom/google/android/mms/pdu/EncodedStringValue;)Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/EncodedStringValue;->encodeStrings([Ljava/lang/String;)[Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/EncodedStringValue;->extract(Ljava/lang/String;)[Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/EncodedStringValue;->getCharacterSet()I -Lcom/google/android/mms/pdu/EncodedStringValue;->getString()Ljava/lang/String; -Lcom/google/android/mms/pdu/EncodedStringValue;->getTextString()[B -Lcom/google/android/mms/pdu/EncodedStringValue;->setCharacterSet(I)V -Lcom/google/android/mms/pdu/EncodedStringValue;->setTextString([B)V -Lcom/google/android/mms/pdu/GenericPdu;-><init>()V -Lcom/google/android/mms/pdu/GenericPdu;->getFrom()Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/GenericPdu;->getMessageType()I -Lcom/google/android/mms/pdu/GenericPdu;->getPduHeaders()Lcom/google/android/mms/pdu/PduHeaders; -Lcom/google/android/mms/pdu/GenericPdu;->mPduHeaders:Lcom/google/android/mms/pdu/PduHeaders; -Lcom/google/android/mms/pdu/GenericPdu;->setFrom(Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/GenericPdu;->setMessageType(I)V -Lcom/google/android/mms/pdu/MultimediaMessagePdu;-><init>()V -Lcom/google/android/mms/pdu/MultimediaMessagePdu;-><init>(Lcom/google/android/mms/pdu/PduHeaders;Lcom/google/android/mms/pdu/PduBody;)V -Lcom/google/android/mms/pdu/MultimediaMessagePdu;->addTo(Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getBody()Lcom/google/android/mms/pdu/PduBody; -Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getDate()J -Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getPriority()I -Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getSubject()Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getTo()[Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setBody(Lcom/google/android/mms/pdu/PduBody;)V -Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setDate(J)V -Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setPriority(I)V -Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setSubject(Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/NotificationInd;-><init>()V -Lcom/google/android/mms/pdu/NotificationInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V -Lcom/google/android/mms/pdu/NotificationInd;->getContentClass()I -Lcom/google/android/mms/pdu/NotificationInd;->getContentLocation()[B -Lcom/google/android/mms/pdu/NotificationInd;->getDeliveryReport()I -Lcom/google/android/mms/pdu/NotificationInd;->getExpiry()J -Lcom/google/android/mms/pdu/NotificationInd;->getFrom()Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/NotificationInd;->getMessageClass()[B -Lcom/google/android/mms/pdu/NotificationInd;->getMessageSize()J -Lcom/google/android/mms/pdu/NotificationInd;->getSubject()Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/NotificationInd;->getTransactionId()[B -Lcom/google/android/mms/pdu/NotificationInd;->setContentClass(I)V -Lcom/google/android/mms/pdu/NotificationInd;->setContentLocation([B)V -Lcom/google/android/mms/pdu/NotificationInd;->setDeliveryReport(I)V -Lcom/google/android/mms/pdu/NotificationInd;->setExpiry(J)V -Lcom/google/android/mms/pdu/NotificationInd;->setFrom(Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/NotificationInd;->setMessageClass([B)V -Lcom/google/android/mms/pdu/NotificationInd;->setMessageSize(J)V -Lcom/google/android/mms/pdu/NotificationInd;->setSubject(Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/NotificationInd;->setTransactionId([B)V -Lcom/google/android/mms/pdu/NotifyRespInd;-><init>(I[BI)V -Lcom/google/android/mms/pdu/NotifyRespInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V -Lcom/google/android/mms/pdu/NotifyRespInd;->setReportAllowed(I)V -Lcom/google/android/mms/pdu/NotifyRespInd;->setStatus(I)V -Lcom/google/android/mms/pdu/NotifyRespInd;->setTransactionId([B)V -Lcom/google/android/mms/pdu/PduBody;-><init>()V -Lcom/google/android/mms/pdu/PduBody;->addPart(ILcom/google/android/mms/pdu/PduPart;)V -Lcom/google/android/mms/pdu/PduBody;->addPart(Lcom/google/android/mms/pdu/PduPart;)Z -Lcom/google/android/mms/pdu/PduBody;->getPart(I)Lcom/google/android/mms/pdu/PduPart; -Lcom/google/android/mms/pdu/PduBody;->getPartByContentId(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart; -Lcom/google/android/mms/pdu/PduBody;->getPartByContentLocation(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart; -Lcom/google/android/mms/pdu/PduBody;->getPartByFileName(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart; -Lcom/google/android/mms/pdu/PduBody;->getPartByName(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart; -Lcom/google/android/mms/pdu/PduBody;->getPartIndex(Lcom/google/android/mms/pdu/PduPart;)I -Lcom/google/android/mms/pdu/PduBody;->getPartsNum()I -Lcom/google/android/mms/pdu/PduBody;->removePart(I)Lcom/google/android/mms/pdu/PduPart; -Lcom/google/android/mms/pdu/PduComposer$BufferStack;->copy()V -Lcom/google/android/mms/pdu/PduComposer$BufferStack;->mark()Lcom/google/android/mms/pdu/PduComposer$PositionMarker; -Lcom/google/android/mms/pdu/PduComposer$BufferStack;->newbuf()V -Lcom/google/android/mms/pdu/PduComposer$BufferStack;->pop()V -Lcom/google/android/mms/pdu/PduComposer$PositionMarker;->getLength()I -Lcom/google/android/mms/pdu/PduComposer;-><init>(Landroid/content/Context;Lcom/google/android/mms/pdu/GenericPdu;)V -Lcom/google/android/mms/pdu/PduComposer;->appendEncodedString(Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/PduComposer;->appendHeader(I)I -Lcom/google/android/mms/pdu/PduComposer;->appendLongInteger(J)V -Lcom/google/android/mms/pdu/PduComposer;->appendOctet(I)V -Lcom/google/android/mms/pdu/PduComposer;->appendQuotedString(Ljava/lang/String;)V -Lcom/google/android/mms/pdu/PduComposer;->appendQuotedString([B)V -Lcom/google/android/mms/pdu/PduComposer;->appendShortInteger(I)V -Lcom/google/android/mms/pdu/PduComposer;->appendTextString(Ljava/lang/String;)V -Lcom/google/android/mms/pdu/PduComposer;->appendTextString([B)V -Lcom/google/android/mms/pdu/PduComposer;->appendUintvarInteger(J)V -Lcom/google/android/mms/pdu/PduComposer;->appendValueLength(J)V -Lcom/google/android/mms/pdu/PduComposer;->arraycopy([BII)V -Lcom/google/android/mms/pdu/PduComposer;->make()[B -Lcom/google/android/mms/pdu/PduComposer;->mContentTypeMap:Ljava/util/HashMap; -Lcom/google/android/mms/pdu/PduComposer;->mMessage:Ljava/io/ByteArrayOutputStream; -Lcom/google/android/mms/pdu/PduComposer;->mPdu:Lcom/google/android/mms/pdu/GenericPdu; -Lcom/google/android/mms/pdu/PduComposer;->mPduHeader:Lcom/google/android/mms/pdu/PduHeaders; -Lcom/google/android/mms/pdu/PduComposer;->mPosition:I -Lcom/google/android/mms/pdu/PduComposer;->mResolver:Landroid/content/ContentResolver; -Lcom/google/android/mms/pdu/PduComposer;->mStack:Lcom/google/android/mms/pdu/PduComposer$BufferStack; -Lcom/google/android/mms/pdu/PduContentTypes;->contentTypes:[Ljava/lang/String; -Lcom/google/android/mms/pdu/PduHeaders;-><init>()V -Lcom/google/android/mms/pdu/PduHeaders;->appendEncodedStringValue(Lcom/google/android/mms/pdu/EncodedStringValue;I)V -Lcom/google/android/mms/pdu/PduHeaders;->getEncodedStringValue(I)Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/PduHeaders;->getEncodedStringValues(I)[Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/PduHeaders;->getLongInteger(I)J -Lcom/google/android/mms/pdu/PduHeaders;->getOctet(I)I -Lcom/google/android/mms/pdu/PduHeaders;->getTextString(I)[B -Lcom/google/android/mms/pdu/PduHeaders;->setEncodedStringValue(Lcom/google/android/mms/pdu/EncodedStringValue;I)V -Lcom/google/android/mms/pdu/PduHeaders;->setLongInteger(JI)V -Lcom/google/android/mms/pdu/PduHeaders;->setOctet(II)V -Lcom/google/android/mms/pdu/PduParser;-><init>([BZ)V -Lcom/google/android/mms/pdu/PduParser;->checkPartPosition(Lcom/google/android/mms/pdu/PduPart;)I -Lcom/google/android/mms/pdu/PduParser;->log(Ljava/lang/String;)V -Lcom/google/android/mms/pdu/PduParser;->parse()Lcom/google/android/mms/pdu/GenericPdu; -Lcom/google/android/mms/pdu/PduParser;->parseContentType(Ljava/io/ByteArrayInputStream;Ljava/util/HashMap;)[B -Lcom/google/android/mms/pdu/PduParser;->parsePartHeaders(Ljava/io/ByteArrayInputStream;Lcom/google/android/mms/pdu/PduPart;I)Z -Lcom/google/android/mms/pdu/PduParser;->parseShortInteger(Ljava/io/ByteArrayInputStream;)I -Lcom/google/android/mms/pdu/PduParser;->parseUnsignedInt(Ljava/io/ByteArrayInputStream;)I -Lcom/google/android/mms/pdu/PduParser;->parseValueLength(Ljava/io/ByteArrayInputStream;)I -Lcom/google/android/mms/pdu/PduParser;->parseWapString(Ljava/io/ByteArrayInputStream;I)[B -Lcom/google/android/mms/pdu/PduPart;-><init>()V -Lcom/google/android/mms/pdu/PduPart;->generateLocation()Ljava/lang/String; -Lcom/google/android/mms/pdu/PduPart;->getCharset()I -Lcom/google/android/mms/pdu/PduPart;->getContentDisposition()[B -Lcom/google/android/mms/pdu/PduPart;->getContentId()[B -Lcom/google/android/mms/pdu/PduPart;->getContentLocation()[B -Lcom/google/android/mms/pdu/PduPart;->getContentTransferEncoding()[B -Lcom/google/android/mms/pdu/PduPart;->getContentType()[B -Lcom/google/android/mms/pdu/PduPart;->getData()[B -Lcom/google/android/mms/pdu/PduPart;->getDataLength()I -Lcom/google/android/mms/pdu/PduPart;->getDataUri()Landroid/net/Uri; -Lcom/google/android/mms/pdu/PduPart;->getFilename()[B -Lcom/google/android/mms/pdu/PduPart;->getName()[B -Lcom/google/android/mms/pdu/PduPart;->setCharset(I)V -Lcom/google/android/mms/pdu/PduPart;->setContentDisposition([B)V -Lcom/google/android/mms/pdu/PduPart;->setContentId([B)V -Lcom/google/android/mms/pdu/PduPart;->setContentLocation([B)V -Lcom/google/android/mms/pdu/PduPart;->setContentTransferEncoding([B)V -Lcom/google/android/mms/pdu/PduPart;->setContentType([B)V -Lcom/google/android/mms/pdu/PduPart;->setData([B)V -Lcom/google/android/mms/pdu/PduPart;->setDataUri(Landroid/net/Uri;)V -Lcom/google/android/mms/pdu/PduPart;->setFilename([B)V -Lcom/google/android/mms/pdu/PduPart;->setName([B)V -Lcom/google/android/mms/pdu/PduPersister;->ADDRESS_FIELDS:[I -Lcom/google/android/mms/pdu/PduPersister;->CHARSET_COLUMN_NAME_MAP:Ljava/util/HashMap; -Lcom/google/android/mms/pdu/PduPersister;->ENCODED_STRING_COLUMN_NAME_MAP:Ljava/util/HashMap; -Lcom/google/android/mms/pdu/PduPersister;->getByteArrayFromPartColumn(Landroid/database/Cursor;I)[B -Lcom/google/android/mms/pdu/PduPersister;->getBytes(Ljava/lang/String;)[B -Lcom/google/android/mms/pdu/PduPersister;->getIntegerFromPartColumn(Landroid/database/Cursor;I)Ljava/lang/Integer; -Lcom/google/android/mms/pdu/PduPersister;->getPartContentType(Lcom/google/android/mms/pdu/PduPart;)Ljava/lang/String; -Lcom/google/android/mms/pdu/PduPersister;->getPduPersister(Landroid/content/Context;)Lcom/google/android/mms/pdu/PduPersister; -Lcom/google/android/mms/pdu/PduPersister;->getPendingMessages(J)Landroid/database/Cursor; -Lcom/google/android/mms/pdu/PduPersister;->load(Landroid/net/Uri;)Lcom/google/android/mms/pdu/GenericPdu; -Lcom/google/android/mms/pdu/PduPersister;->loadRecipients(ILjava/util/HashSet;Ljava/util/HashMap;Z)V -Lcom/google/android/mms/pdu/PduPersister;->LONG_COLUMN_NAME_MAP:Ljava/util/HashMap; -Lcom/google/android/mms/pdu/PduPersister;->mContentResolver:Landroid/content/ContentResolver; -Lcom/google/android/mms/pdu/PduPersister;->mContext:Landroid/content/Context; -Lcom/google/android/mms/pdu/PduPersister;->MESSAGE_BOX_MAP:Ljava/util/HashMap; -Lcom/google/android/mms/pdu/PduPersister;->move(Landroid/net/Uri;Landroid/net/Uri;)Landroid/net/Uri; -Lcom/google/android/mms/pdu/PduPersister;->mTelephonyManager:Landroid/telephony/TelephonyManager; -Lcom/google/android/mms/pdu/PduPersister;->OCTET_COLUMN_NAME_MAP:Ljava/util/HashMap; -Lcom/google/android/mms/pdu/PduPersister;->PART_PROJECTION:[Ljava/lang/String; -Lcom/google/android/mms/pdu/PduPersister;->PDU_CACHE_INSTANCE:Lcom/google/android/mms/util/PduCache; -Lcom/google/android/mms/pdu/PduPersister;->persist(Lcom/google/android/mms/pdu/GenericPdu;Landroid/net/Uri;ZZLjava/util/HashMap;)Landroid/net/Uri; -Lcom/google/android/mms/pdu/PduPersister;->persistAddress(JI[Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/PduPersister;->persistPart(Lcom/google/android/mms/pdu/PduPart;JLjava/util/HashMap;)Landroid/net/Uri; -Lcom/google/android/mms/pdu/PduPersister;->TEXT_STRING_COLUMN_NAME_MAP:Ljava/util/HashMap; -Lcom/google/android/mms/pdu/PduPersister;->toIsoString([B)Ljava/lang/String; -Lcom/google/android/mms/pdu/PduPersister;->updateAddress(JI[Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/PduPersister;->updateHeaders(Landroid/net/Uri;Lcom/google/android/mms/pdu/SendReq;)V -Lcom/google/android/mms/pdu/PduPersister;->updateParts(Landroid/net/Uri;Lcom/google/android/mms/pdu/PduBody;Ljava/util/HashMap;)V -Lcom/google/android/mms/pdu/QuotedPrintable;->decodeQuotedPrintable([B)[B -Lcom/google/android/mms/pdu/ReadOrigInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V -Lcom/google/android/mms/pdu/ReadOrigInd;->getMessageId()[B -Lcom/google/android/mms/pdu/ReadOrigInd;->getReadStatus()I -Lcom/google/android/mms/pdu/ReadRecInd;-><init>(Lcom/google/android/mms/pdu/EncodedStringValue;[BII[Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/ReadRecInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V -Lcom/google/android/mms/pdu/ReadRecInd;->getMessageId()[B -Lcom/google/android/mms/pdu/ReadRecInd;->setDate(J)V -Lcom/google/android/mms/pdu/RetrieveConf;-><init>()V -Lcom/google/android/mms/pdu/RetrieveConf;-><init>(Lcom/google/android/mms/pdu/PduHeaders;Lcom/google/android/mms/pdu/PduBody;)V -Lcom/google/android/mms/pdu/RetrieveConf;->addCc(Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/RetrieveConf;->getCc()[Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/RetrieveConf;->getContentType()[B -Lcom/google/android/mms/pdu/RetrieveConf;->getDeliveryReport()I -Lcom/google/android/mms/pdu/RetrieveConf;->getFrom()Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/RetrieveConf;->getMessageClass()[B -Lcom/google/android/mms/pdu/RetrieveConf;->getMessageId()[B -Lcom/google/android/mms/pdu/RetrieveConf;->getReadReport()I -Lcom/google/android/mms/pdu/RetrieveConf;->getRetrieveStatus()I -Lcom/google/android/mms/pdu/RetrieveConf;->getRetrieveText()Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/RetrieveConf;->getTransactionId()[B -Lcom/google/android/mms/pdu/RetrieveConf;->setContentType([B)V -Lcom/google/android/mms/pdu/RetrieveConf;->setDeliveryReport(I)V -Lcom/google/android/mms/pdu/RetrieveConf;->setFrom(Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/RetrieveConf;->setMessageClass([B)V -Lcom/google/android/mms/pdu/RetrieveConf;->setMessageId([B)V -Lcom/google/android/mms/pdu/RetrieveConf;->setReadReport(I)V -Lcom/google/android/mms/pdu/RetrieveConf;->setRetrieveStatus(I)V -Lcom/google/android/mms/pdu/RetrieveConf;->setRetrieveText(Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/RetrieveConf;->setTransactionId([B)V -Lcom/google/android/mms/pdu/SendConf;-><init>()V -Lcom/google/android/mms/pdu/SendConf;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V -Lcom/google/android/mms/pdu/SendConf;->getMessageId()[B -Lcom/google/android/mms/pdu/SendConf;->getResponseStatus()I -Lcom/google/android/mms/pdu/SendConf;->getTransactionId()[B -Lcom/google/android/mms/pdu/SendReq;-><init>()V -Lcom/google/android/mms/pdu/SendReq;-><init>(Lcom/google/android/mms/pdu/PduHeaders;Lcom/google/android/mms/pdu/PduBody;)V -Lcom/google/android/mms/pdu/SendReq;->addBcc(Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/SendReq;->addCc(Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/SendReq;->getBcc()[Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/SendReq;->getCc()[Lcom/google/android/mms/pdu/EncodedStringValue; -Lcom/google/android/mms/pdu/SendReq;->getContentType()[B -Lcom/google/android/mms/pdu/SendReq;->getDeliveryReport()I -Lcom/google/android/mms/pdu/SendReq;->getExpiry()J -Lcom/google/android/mms/pdu/SendReq;->getMessageClass()[B -Lcom/google/android/mms/pdu/SendReq;->getMessageSize()J -Lcom/google/android/mms/pdu/SendReq;->getReadReport()I -Lcom/google/android/mms/pdu/SendReq;->getTransactionId()[B -Lcom/google/android/mms/pdu/SendReq;->setBcc([Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/SendReq;->setCc([Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/SendReq;->setContentType([B)V -Lcom/google/android/mms/pdu/SendReq;->setDeliveryReport(I)V -Lcom/google/android/mms/pdu/SendReq;->setExpiry(J)V -Lcom/google/android/mms/pdu/SendReq;->setMessageClass([B)V -Lcom/google/android/mms/pdu/SendReq;->setMessageSize(J)V -Lcom/google/android/mms/pdu/SendReq;->setReadReport(I)V -Lcom/google/android/mms/pdu/SendReq;->setTo([Lcom/google/android/mms/pdu/EncodedStringValue;)V -Lcom/google/android/mms/pdu/SendReq;->setTransactionId([B)V -Lcom/google/android/mms/util/AbstractCache;-><init>()V -Lcom/google/android/mms/util/AbstractCache;->get(Ljava/lang/Object;)Ljava/lang/Object; -Lcom/google/android/mms/util/AbstractCache;->purge(Ljava/lang/Object;)Ljava/lang/Object; -Lcom/google/android/mms/util/AbstractCache;->purgeAll()V -Lcom/google/android/mms/util/AbstractCache;->put(Ljava/lang/Object;Ljava/lang/Object;)Z -Lcom/google/android/mms/util/DownloadDrmHelper;->isDrmConvertNeeded(Ljava/lang/String;)Z -Lcom/google/android/mms/util/DownloadDrmHelper;->modifyDrmFwLockFileExtension(Ljava/lang/String;)Ljava/lang/String; -Lcom/google/android/mms/util/DrmConvertSession;->close(Ljava/lang/String;)I -Lcom/google/android/mms/util/DrmConvertSession;->convert([BI)[B -Lcom/google/android/mms/util/DrmConvertSession;->open(Landroid/content/Context;Ljava/lang/String;)Lcom/google/android/mms/util/DrmConvertSession; -Lcom/google/android/mms/util/PduCache;-><init>()V -Lcom/google/android/mms/util/PduCache;->getInstance()Lcom/google/android/mms/util/PduCache; -Lcom/google/android/mms/util/PduCache;->isUpdating(Landroid/net/Uri;)Z -Lcom/google/android/mms/util/PduCache;->purge(Landroid/net/Uri;)Lcom/google/android/mms/util/PduCacheEntry; -Lcom/google/android/mms/util/PduCache;->purge(Ljava/lang/Object;)Ljava/lang/Object; -Lcom/google/android/mms/util/PduCache;->purgeAll()V -Lcom/google/android/mms/util/PduCacheEntry;-><init>(Lcom/google/android/mms/pdu/GenericPdu;IJ)V -Lcom/google/android/mms/util/PduCacheEntry;->getMessageBox()I -Lcom/google/android/mms/util/PduCacheEntry;->getPdu()Lcom/google/android/mms/pdu/GenericPdu; -Lcom/google/android/mms/util/PduCacheEntry;->getThreadId()J -Lcom/google/android/mms/util/SqliteWrapper;->checkSQLiteException(Landroid/content/Context;Landroid/database/sqlite/SQLiteException;)V -Lcom/google/android/mms/util/SqliteWrapper;->delete(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;[Ljava/lang/String;)I -Lcom/google/android/mms/util/SqliteWrapper;->insert(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;)Landroid/net/Uri; -Lcom/google/android/mms/util/SqliteWrapper;->query(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor; -Lcom/google/android/mms/util/SqliteWrapper;->requery(Landroid/content/Context;Landroid/database/Cursor;)Z -Lcom/google/android/mms/util/SqliteWrapper;->update(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I -Lcom/google/android/mms/pdu/PduParser;->$assertionsDisabled:Z Lcom/google/android/util/AbstractMessageParser$Token$Type;->values()[Lcom/google/android/util/AbstractMessageParser$Token$Type; diff --git a/config/preloaded-classes b/config/preloaded-classes index 5698dfe8a586..8d911443ce06 100644 --- a/config/preloaded-classes +++ b/config/preloaded-classes @@ -877,7 +877,7 @@ android.content.pm.-$$Lambda$jpya2qgMDDEok2GAoKRDqPM5lIE android.content.pm.ActivityInfo$1 android.content.pm.ActivityInfo$WindowLayout android.content.pm.ActivityInfo -android.content.pm.parsing.library.AndroidHidlUpdater +android.content.pm.AndroidHidlUpdater android.content.pm.ApplicationInfo$1 android.content.pm.ApplicationInfo android.content.pm.BaseParceledListSlice @@ -921,10 +921,10 @@ android.content.pm.LauncherApps$1 android.content.pm.LauncherApps android.content.pm.ModuleInfo$1 android.content.pm.ModuleInfo -android.content.pm.parsing.library.OrgApacheHttpLegacyUpdater -android.content.pm.parsing.library.PackageBackwardCompatibility$AndroidTestRunnerSplitUpdater -android.content.pm.parsing.library.PackageBackwardCompatibility$RemoveUnnecessaryAndroidTestBaseLibrary -android.content.pm.parsing.library.PackageBackwardCompatibility +android.content.pm.OrgApacheHttpLegacyUpdater +android.content.pm.PackageBackwardCompatibility$AndroidTestRunnerSplitUpdater +android.content.pm.PackageBackwardCompatibility$RemoveUnnecessaryAndroidTestBaseLibrary +android.content.pm.PackageBackwardCompatibility android.content.pm.PackageInfo$1 android.content.pm.PackageInfo android.content.pm.PackageInstaller$Session @@ -959,7 +959,7 @@ android.content.pm.PackageParser$SigningDetails$1 android.content.pm.PackageParser$SigningDetails android.content.pm.PackageParser$SplitNameComparator android.content.pm.PackageParser -android.content.pm.parsing.library.PackageSharedLibraryUpdater +android.content.pm.PackageSharedLibraryUpdater android.content.pm.PackageStats$1 android.content.pm.PackageStats android.content.pm.PackageUserState diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index cb99a3aa11c6..7f597fef807a 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -188,57 +188,6 @@ public class ActivityManager { final ArrayMap<OnUidImportanceListener, UidObserver> mImportanceListeners = new ArrayMap<>(); /** - * Defines acceptable types of bugreports. - * @hide - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "BUGREPORT_OPTION_" }, value = { - BUGREPORT_OPTION_FULL, - BUGREPORT_OPTION_INTERACTIVE, - BUGREPORT_OPTION_REMOTE, - BUGREPORT_OPTION_WEAR, - BUGREPORT_OPTION_TELEPHONY, - BUGREPORT_OPTION_WIFI - }) - public @interface BugreportMode {} - /** - * Takes a bugreport without user interference (and hence causing less - * interference to the system), but includes all sections. - * @hide - */ - public static final int BUGREPORT_OPTION_FULL = 0; - /** - * Allows user to monitor progress and enter additional data; might not include all - * sections. - * @hide - */ - public static final int BUGREPORT_OPTION_INTERACTIVE = 1; - /** - * Takes a bugreport requested remotely by administrator of the Device Owner app, - * not the device's user. - * @hide - */ - public static final int BUGREPORT_OPTION_REMOTE = 2; - /** - * Takes a bugreport on a wearable device. - * @hide - */ - public static final int BUGREPORT_OPTION_WEAR = 3; - - /** - * Takes a lightweight version of bugreport that only includes a few, urgent sections - * used to report telephony bugs. - * @hide - */ - public static final int BUGREPORT_OPTION_TELEPHONY = 4; - - /** - * Takes a lightweight bugreport that only includes a few sections related to Wifi. - * @hide - */ - public static final int BUGREPORT_OPTION_WIFI = 5; - - /** * <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code * <meta-data>}</a> name for a 'home' Activity that declares a package that is to be * uninstalled in lieu of the declaring one. The package named here must be diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 1cc849936fde..38aac1b47f65 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -4835,7 +4835,7 @@ public final class ActivityThread extends ClientTransactionHandler { View.sDebugViewAttributesApplicationPackage = mCoreSettings.getString( Settings.Global.DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE, ""); String currentPackage = (mBoundApplication != null && mBoundApplication.appInfo != null) - ? mBoundApplication.appInfo.packageName : ""; + ? mBoundApplication.appInfo.packageName : "<unknown-app>"; View.sDebugViewAttributes = mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0 || View.sDebugViewAttributesApplicationPackage.equals(currentPackage); diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index e8918285777b..b56c00e44d3f 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -29,6 +29,7 @@ import android.content.Context; import android.content.Intent; import android.graphics.Insets; import android.graphics.Matrix; +import android.graphics.Rect; import android.graphics.Region; import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; @@ -101,6 +102,8 @@ public class ActivityView extends ViewGroup { private Insets mForwardedInsets; + private float mCornerRadius; + public ActivityView(Context context) { this(context, null /* attrs */); } @@ -204,6 +207,45 @@ public class ActivityView extends ViewGroup { } /** + * @hide + */ + public float getCornerRadius() { + return mSurfaceView.getCornerRadius(); + } + + /** + * Control whether the surface is clipped to the same bounds as the View. If true, then + * the bounds set by {@link #setSurfaceClipBounds(Rect)} are applied to the surface as + * window-crop. + * + * @param clippingEnabled whether to enable surface clipping + * @hide + */ + public void setSurfaceClippingEnabled(boolean clippingEnabled) { + mSurfaceView.setEnableSurfaceClipping(clippingEnabled); + } + + /** + * Sets an area on the contained surface to which it will be clipped + * when it is drawn. Setting the value to null will remove the clip bounds + * and the surface will draw normally, using its full bounds. + * + * @param clipBounds The rectangular area, in the local coordinates of + * this view, to which future drawing operations will be clipped. + * @hide + */ + public void setSurfaceClipBounds(Rect clipBounds) { + mSurfaceView.setClipBounds(clipBounds); + } + + /** + * @hide + */ + public boolean getSurfaceClipBounds(Rect outRect) { + return mSurfaceView.getClipBounds(outRect); + } + + /** * Launch a new activity into this container. * <p>Activity resolved by the provided {@link Intent} must have * {@link android.R.attr#resizeableActivity} attribute set to {@code true} in order to be diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index d74399c54bda..a2013075b379 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -2414,14 +2414,11 @@ public class ApplicationPackageManager extends PackageManager { @Override public Bundle getSuspendedPackageAppExtras() { - final PersistableBundle extras; try { - extras = mPM.getSuspendedPackageAppExtras(mContext.getOpPackageName(), - getUserId()); + return mPM.getSuspendedPackageAppExtras(mContext.getOpPackageName(), getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } - return extras != null ? new Bundle(extras.deepCopy()) : null; } @Override diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java index f9e710e118ea..80c5b17cad23 100644 --- a/core/java/android/app/assist/AssistStructure.java +++ b/core/java/android/app/assist/AssistStructure.java @@ -684,8 +684,9 @@ public class AssistStructure implements Parcelable { static final int FLAGS_HAS_EXTRAS = 0x00400000; static final int FLAGS_HAS_ID = 0x00200000; static final int FLAGS_HAS_CHILDREN = 0x00100000; - static final int FLAGS_HAS_URL = 0x00080000; + static final int FLAGS_HAS_URL_DOMAIN = 0x00080000; static final int FLAGS_HAS_INPUT_TYPE = 0x00040000; + static final int FLAGS_HAS_URL_SCHEME = 0x00020000; static final int FLAGS_HAS_LOCALE_LIST = 0x00010000; static final int FLAGS_ALL_CONTROL = 0xfff00000; @@ -829,8 +830,10 @@ public class AssistStructure implements Parcelable { if ((flags&FLAGS_HAS_INPUT_TYPE) != 0) { mInputType = in.readInt(); } - if ((flags&FLAGS_HAS_URL) != 0) { + if ((flags&FLAGS_HAS_URL_SCHEME) != 0) { mWebScheme = in.readString(); + } + if ((flags&FLAGS_HAS_URL_DOMAIN) != 0) { mWebDomain = in.readString(); } if ((flags&FLAGS_HAS_LOCALE_LIST) != 0) { @@ -891,8 +894,11 @@ public class AssistStructure implements Parcelable { if (mInputType != 0) { flags |= FLAGS_HAS_INPUT_TYPE; } - if (mWebScheme != null || mWebDomain != null) { - flags |= FLAGS_HAS_URL; + if (mWebScheme != null) { + flags |= FLAGS_HAS_URL_SCHEME; + } + if (mWebDomain != null) { + flags |= FLAGS_HAS_URL_DOMAIN; } if (mLocaleList != null) { flags |= FLAGS_HAS_LOCALE_LIST; @@ -1055,8 +1061,10 @@ public class AssistStructure implements Parcelable { if ((flags&FLAGS_HAS_INPUT_TYPE) != 0) { out.writeInt(mInputType); } - if ((flags&FLAGS_HAS_URL) != 0) { + if ((flags & FLAGS_HAS_URL_SCHEME) != 0) { out.writeString(mWebScheme); + } + if ((flags&FLAGS_HAS_URL_DOMAIN) != 0) { out.writeString(mWebDomain); } if ((flags&FLAGS_HAS_LOCALE_LIST) != 0) { @@ -1431,13 +1439,18 @@ public class AssistStructure implements Parcelable { public void setWebDomain(@Nullable String domain) { if (domain == null) return; - final Uri uri = Uri.parse(domain); + Uri uri = Uri.parse(domain); if (uri == null) { // Cannot log domain because it could contain PII; Log.w(TAG, "Failed to parse web domain"); return; } + mWebScheme = uri.getScheme(); + if (mWebScheme == null) { + uri = Uri.parse("http://" + domain); + } + mWebDomain = uri.getHost(); } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 72204daf01ef..39ddc82e9269 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2025,17 +2025,6 @@ public class Intent implements Parcelable, Cloneable { public static final String EXTRA_RESULT_NEEDED = "android.intent.extra.RESULT_NEEDED"; /** - * Intent extra: A {@link Bundle} of extras supplied for the launcher when any packages on - * device are suspended. Will be sent with {@link #ACTION_PACKAGES_SUSPENDED}. - * - * @see PackageManager#isPackageSuspended() - * @see #ACTION_PACKAGES_SUSPENDED - * - * @hide - */ - public static final String EXTRA_LAUNCHER_EXTRAS = "android.intent.extra.LAUNCHER_EXTRAS"; - - /** * Intent extra: ID of the shortcut used to send the share intent. Will be sent with * {@link #ACTION_SEND}. * diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 29f243f76905..415c2428405f 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -1379,8 +1379,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { this.minHeight = minHeight; } - /** @hide */ - public WindowLayout(Parcel source) { + WindowLayout(Parcel source) { width = source.readInt(); widthFraction = source.readFloat(); height = source.readInt(); diff --git a/core/java/android/content/pm/parsing/library/AndroidHidlUpdater.java b/core/java/android/content/pm/AndroidHidlUpdater.java index 81b4bc574197..d0657e5eb8ec 100644 --- a/core/java/android/content/pm/parsing/library/AndroidHidlUpdater.java +++ b/core/java/android/content/pm/AndroidHidlUpdater.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2018 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. @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.content.pm.parsing.library; +package android.content.pm; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_HIDL_BASE; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_HIDL_MANAGER; +import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_BASE; +import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_MANAGER; -import android.content.pm.parsing.ParsedPackage; +import android.content.pm.PackageParser.Package; import android.os.Build; import com.android.internal.annotations.VisibleForTesting; @@ -33,18 +33,20 @@ import com.android.internal.annotations.VisibleForTesting; public class AndroidHidlUpdater extends PackageSharedLibraryUpdater { @Override - public void updatePackage(ParsedPackage parsedPackage) { + public void updatePackage(Package pkg) { + ApplicationInfo info = pkg.applicationInfo; + // This was the default <= P and is maintained for backwards compatibility. - boolean isLegacy = parsedPackage.getTargetSdkVersion() <= Build.VERSION_CODES.P; + boolean isLegacy = info.targetSdkVersion <= Build.VERSION_CODES.P; // Only system apps use these libraries - boolean isSystem = parsedPackage.isSystemApp() || parsedPackage.isUpdatedSystemApp(); + boolean isSystem = info.isSystemApp() || info.isUpdatedSystemApp(); if (isLegacy && isSystem) { - prefixRequiredLibrary(parsedPackage, ANDROID_HIDL_BASE); - prefixRequiredLibrary(parsedPackage, ANDROID_HIDL_MANAGER); + prefixRequiredLibrary(pkg, ANDROID_HIDL_BASE); + prefixRequiredLibrary(pkg, ANDROID_HIDL_MANAGER); } else { - removeLibrary(parsedPackage, ANDROID_HIDL_BASE); - removeLibrary(parsedPackage, ANDROID_HIDL_MANAGER); + removeLibrary(pkg, ANDROID_HIDL_BASE); + removeLibrary(pkg, ANDROID_HIDL_MANAGER); } } } diff --git a/core/java/android/content/pm/parsing/library/AndroidTestBaseUpdater.java b/core/java/android/content/pm/AndroidTestBaseUpdater.java index 25c309931554..da1a693b13c3 100644 --- a/core/java/android/content/pm/parsing/library/AndroidTestBaseUpdater.java +++ b/core/java/android/content/pm/AndroidTestBaseUpdater.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2018 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. @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.content.pm.parsing.library; +package android.content.pm; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_BASE; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_RUNNER; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ParsedPackage; +import android.content.pm.PackageParser.Package; import android.os.Build; import com.android.internal.annotations.VisibleForTesting; @@ -39,22 +38,23 @@ import com.android.internal.annotations.VisibleForTesting; @VisibleForTesting public class AndroidTestBaseUpdater extends PackageSharedLibraryUpdater { - private static boolean apkTargetsApiLevelLessThanOrEqualToQ(AndroidPackage pkg) { - return pkg.getTargetSdkVersion() <= Build.VERSION_CODES.Q; + private static boolean apkTargetsApiLevelLessThanOrEqualToQ(Package pkg) { + int targetSdkVersion = pkg.applicationInfo.targetSdkVersion; + return targetSdkVersion <= Build.VERSION_CODES.Q; } @Override - public void updatePackage(ParsedPackage parsedPackage) { + public void updatePackage(Package pkg) { // Packages targeted at <= Q expect the classes in the android.test.base library // to be accessible so this maintains backward compatibility by adding the // android.test.base library to those packages. - if (apkTargetsApiLevelLessThanOrEqualToQ(parsedPackage)) { - prefixRequiredLibrary(parsedPackage, ANDROID_TEST_BASE); + if (apkTargetsApiLevelLessThanOrEqualToQ(pkg)) { + prefixRequiredLibrary(pkg, ANDROID_TEST_BASE); } else { // If a package already depends on android.test.runner then add a dependency on // android.test.base because android.test.runner depends on classes from the // android.test.base library. - prefixImplicitDependency(parsedPackage, ANDROID_TEST_RUNNER, ANDROID_TEST_BASE); + prefixImplicitDependency(pkg, ANDROID_TEST_RUNNER, ANDROID_TEST_BASE); } } } diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index c6beee2f898a..4d7c43ace923 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -50,6 +50,7 @@ import android.content.pm.VersionedPackage; import android.content.pm.dex.IArtManager; import android.graphics.Bitmap; import android.net.Uri; +import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.content.IntentSender; @@ -280,7 +281,7 @@ interface IPackageManager { boolean isPackageSuspendedForUser(String packageName, int userId); - PersistableBundle getSuspendedPackageAppExtras(String packageName, int userId); + Bundle getSuspendedPackageAppExtras(String packageName, int userId); /** * Backup/restore support - only the system uid may use these. diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index 3933e81c732a..d2a40304e078 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -248,7 +248,11 @@ public class LauncherApps { * system, {@code null} otherwise. * @see PackageManager#isPackageSuspended() * @see #getSuspendedPackageLauncherExtras(String, UserHandle) + * @deprecated {@code launcherExtras} should be obtained by using + * {@link #getSuspendedPackageLauncherExtras(String, UserHandle)}. For all other cases, + * {@link #onPackagesSuspended(String[], UserHandle)} should be used. */ + @Deprecated public void onPackagesSuspended(String[] packageNames, UserHandle user, @Nullable Bundle launcherExtras) { onPackagesSuspended(packageNames, user); diff --git a/core/java/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdater.java b/core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java index 613a06b636e9..707443b19679 100644 --- a/core/java/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdater.java +++ b/core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2018 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. @@ -13,12 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.content.pm.parsing.library; +package android.content.pm; -import static android.content.pm.parsing.library.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; +import static android.content.pm.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ParsedPackage; +import android.content.pm.PackageParser.Package; import android.os.Build; import com.android.internal.annotations.VisibleForTesting; @@ -32,17 +31,18 @@ import com.android.internal.annotations.VisibleForTesting; @VisibleForTesting public class OrgApacheHttpLegacyUpdater extends PackageSharedLibraryUpdater { - private static boolean apkTargetsApiLevelLessThanOrEqualToOMR1(AndroidPackage pkg) { - return pkg.getTargetSdkVersion() < Build.VERSION_CODES.P; + private static boolean apkTargetsApiLevelLessThanOrEqualToOMR1(Package pkg) { + int targetSdkVersion = pkg.applicationInfo.targetSdkVersion; + return targetSdkVersion < Build.VERSION_CODES.P; } @Override - public void updatePackage(ParsedPackage parsedPackage) { + public void updatePackage(Package pkg) { // Packages targeted at <= O_MR1 expect the classes in the org.apache.http.legacy library // to be accessible so this maintains backward compatibility by adding the // org.apache.http.legacy library to those packages. - if (apkTargetsApiLevelLessThanOrEqualToOMR1(parsedPackage)) { - prefixRequiredLibrary(parsedPackage, ORG_APACHE_HTTP_LEGACY); + if (apkTargetsApiLevelLessThanOrEqualToOMR1(pkg)) { + prefixRequiredLibrary(pkg, ORG_APACHE_HTTP_LEGACY); } } } diff --git a/core/java/android/content/pm/parsing/library/PackageBackwardCompatibility.java b/core/java/android/content/pm/PackageBackwardCompatibility.java index 1220fc497b04..4331bd4ac4d4 100644 --- a/core/java/android/content/pm/parsing/library/PackageBackwardCompatibility.java +++ b/core/java/android/content/pm/PackageBackwardCompatibility.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2017 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. @@ -14,14 +14,14 @@ * limitations under the License. */ -package android.content.pm.parsing.library; +package android.content.pm; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_BASE; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_MOCK; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_RUNNER; -import static android.content.pm.parsing.library.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_MOCK; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER; +import static android.content.pm.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; -import android.content.pm.parsing.ParsedPackage; +import android.content.pm.PackageParser.Package; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; @@ -31,7 +31,7 @@ import java.util.List; import java.util.function.Supplier; /** - * Modifies {@link ParsedPackage} in order to maintain backwards compatibility. + * Modifies {@link Package} in order to maintain backwards compatibility. * * @hide */ @@ -60,7 +60,7 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { // will remove any references to org.apache.http.library from the package so that it does // not try and load the library when it is on the bootclasspath. boolean bootClassPathContainsATB = !addOptionalUpdater(packageUpdaters, - "android.content.pm.parsing.library.AndroidTestBaseUpdater", + "android.content.pm.AndroidTestBaseUpdater", RemoveUnnecessaryAndroidTestBaseLibrary::new); PackageSharedLibraryUpdater[] updaterArray = packageUpdaters @@ -123,20 +123,20 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { } /** - * Modify the shared libraries in the supplied {@link ParsedPackage} to maintain backwards + * Modify the shared libraries in the supplied {@link Package} to maintain backwards * compatibility. * - * @param parsedPackage the {@link ParsedPackage} to modify. + * @param pkg the {@link Package} to modify. */ @VisibleForTesting - public static void modifySharedLibraries(ParsedPackage parsedPackage) { - INSTANCE.updatePackage(parsedPackage); + public static void modifySharedLibraries(Package pkg) { + INSTANCE.updatePackage(pkg); } @Override - public void updatePackage(ParsedPackage parsedPackage) { + public void updatePackage(Package pkg) { for (PackageSharedLibraryUpdater packageUpdater : mPackageUpdaters) { - packageUpdater.updatePackage(parsedPackage); + packageUpdater.updatePackage(pkg); } } @@ -161,10 +161,10 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { public static class AndroidTestRunnerSplitUpdater extends PackageSharedLibraryUpdater { @Override - public void updatePackage(ParsedPackage parsedPackage) { + public void updatePackage(Package pkg) { // android.test.runner has a dependency on android.test.mock so if android.test.runner // is present but android.test.mock is not then add android.test.mock. - prefixImplicitDependency(parsedPackage, ANDROID_TEST_RUNNER, ANDROID_TEST_MOCK); + prefixImplicitDependency(pkg, ANDROID_TEST_RUNNER, ANDROID_TEST_MOCK); } } @@ -177,8 +177,8 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { extends PackageSharedLibraryUpdater { @Override - public void updatePackage(ParsedPackage parsedPackage) { - removeLibrary(parsedPackage, ORG_APACHE_HTTP_LEGACY); + public void updatePackage(Package pkg) { + removeLibrary(pkg, ORG_APACHE_HTTP_LEGACY); } } @@ -192,8 +192,8 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { extends PackageSharedLibraryUpdater { @Override - public void updatePackage(ParsedPackage parsedPackage) { - removeLibrary(parsedPackage, ANDROID_TEST_BASE); + public void updatePackage(Package pkg) { + removeLibrary(pkg, ANDROID_TEST_BASE); } } } diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java index aa0002df2c3a..d6fb28f694fd 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -373,9 +373,8 @@ public class PackageInfo implements Parcelable { /** * Whether the overlay is static, meaning it cannot be enabled/disabled at runtime. - * @hide */ - public boolean mOverlayIsStatic; + boolean mOverlayIsStatic; /** * The user-visible SDK version (ex. 26) of the framework against which the application claims diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index fafb56d20ba0..fd14d235a044 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -917,8 +917,9 @@ public abstract class PackageManager { public static final int INSTALL_DRY_RUN = 0x00800000; /** @hide */ - @IntDef(flag = true, prefix = { "DONT_KILL_APP" }, value = { - DONT_KILL_APP + @IntDef(flag = true, value = { + DONT_KILL_APP, + SYNCHRONOUS }) @Retention(RetentionPolicy.SOURCE) public @interface EnabledFlags {} @@ -931,6 +932,14 @@ public abstract class PackageManager { */ public static final int DONT_KILL_APP = 0x00000001; + /** + * Flag parameter for + * {@link #setComponentEnabledSetting(android.content.ComponentName, int, int)} to indicate + * that the given user's package restrictions state will be serialised to disk after the + * component state has been updated. + */ + public static final int SYNCHRONOUS = 0x00000002; + /** @hide */ @IntDef(prefix = { "INSTALL_REASON_" }, value = { INSTALL_REASON_UNKNOWN, diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 746549814c8d..3eef92fc0aa7 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -28,8 +28,6 @@ import android.content.pm.PackageManager.ApplicationInfoFlags; import android.content.pm.PackageManager.ComponentInfoFlags; import android.content.pm.PackageManager.PackageInfoFlags; import android.content.pm.PackageManager.ResolveInfoFlags; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ComponentParseUtils; import android.os.Bundle; import android.os.PersistableBundle; import android.util.ArraySet; @@ -193,11 +191,13 @@ public abstract class PackageManagerInternal { * suspended application. * * @param suspendedPackage The package that has been suspended. + * @param suspendingPackage * @param userId The user for which to check. * @return A {@link SuspendDialogInfo} object describing the dialog to be shown. */ @Nullable - public abstract SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage, int userId); + public abstract SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage, + String suspendingPackage, int userId); /** * Gets any distraction flags set via @@ -317,7 +317,7 @@ public abstract class PackageManagerInternal { * @param installed the new installed state * @return true if the installed state changed as a result */ - public abstract boolean setInstalled(AndroidPackage pkg, + public abstract boolean setInstalled(PackageParser.Package pkg, @UserIdInt int userId, boolean installed); /** @@ -396,7 +396,7 @@ public abstract class PackageManagerInternal { * Returns whether or not the given package represents a legacy system application released * prior to runtime permissions. */ - public abstract boolean isLegacySystemApp(AndroidPackage pkg); + public abstract boolean isLegacySystemApp(PackageParser.Package pkg); /** * Get all overlay packages for a user. @@ -488,17 +488,13 @@ public abstract class PackageManagerInternal { /** * Returns a package object for the given package name. */ - public abstract @Nullable AndroidPackage getPackage(@NonNull String packageName); - - // TODO(b/135203078): PackageSetting can't be referenced directly. Should move to a server side - // internal PM which is aware of PS. - public abstract @Nullable Object getPackageSetting(String packageName); + public abstract @Nullable PackageParser.Package getPackage(@NonNull String packageName); /** * Returns a package for the given UID. If the UID is part of a shared user ID, one * of the packages will be chosen to be returned. */ - public abstract @Nullable AndroidPackage getPackage(int uid); + public abstract @Nullable PackageParser.Package getPackage(int uid); /** * Returns a list without a change observer. @@ -529,19 +525,17 @@ public abstract class PackageManagerInternal { */ public abstract void removePackageListObserver(@NonNull PackageListObserver observer); - // TODO(b/135203078): PackageSetting can't be referenced directly /** * Returns a package object for the disabled system package name. */ - public abstract @Nullable Object getDisabledSystemPackage(@NonNull String packageName); + public abstract @Nullable PackageParser.Package getDisabledSystemPackage( + @NonNull String packageName); /** * Returns the package name for the disabled system package. * * This is equivalent to - * {@link #getDisabledSystemPackage(String)} - * .{@link com.android.server.pm.PackageSetting#pkg} - * .{@link AndroidPackage#getPackageName()} + * {@link #getDisabledSystemPackage(String)}.{@link PackageParser.Package#packageName} */ public abstract @Nullable String getDisabledSystemPackageName(@NonNull String packageName); @@ -575,7 +569,7 @@ public abstract class PackageManagerInternal { * @see #canAccessInstantApps */ public abstract boolean filterAppAccess( - @NonNull AndroidPackage pkg, int callingUid, int userId); + @NonNull PackageParser.Package pkg, int callingUid, int userId); /** * Returns whether or not access to the application should be filtered. @@ -649,8 +643,7 @@ public abstract class PackageManagerInternal { throws IOException; /** Returns {@code true} if the specified component is enabled and matches the given flags. */ - public abstract boolean isEnabledAndMatches( - @NonNull ComponentParseUtils.ParsedComponent component, int flags, int userId); + public abstract boolean isEnabledAndMatches(@NonNull ComponentInfo info, int flags, int userId); /** Returns {@code true} if the given user requires extra badging for icons. */ public abstract boolean userNeedsBadging(int userId); @@ -661,14 +654,14 @@ public abstract class PackageManagerInternal { * * @param actionLocked action to be performed */ - public abstract void forEachPackage(Consumer<AndroidPackage> actionLocked); + public abstract void forEachPackage(Consumer<PackageParser.Package> actionLocked); /** * Perform the given action for each installed package for a user. * Note that packages lock will be held while performin the actions. */ public abstract void forEachInstalledPackage( - @NonNull Consumer<AndroidPackage> actionLocked, @UserIdInt int userId); + @NonNull Consumer<PackageParser.Package> actionLocked, @UserIdInt int userId); /** Returns the list of enabled components */ public abstract ArraySet<String> getEnabledComponents(String packageName, int userId); @@ -802,7 +795,7 @@ public abstract class PackageManagerInternal { * Otherwise, {@code false}. */ public abstract boolean isCallerInstallerOfRecord( - @NonNull AndroidPackage pkg, int callingUid); + @NonNull PackageParser.Package pkg, int callingUid); /** Returns whether or not default runtime permissions are granted for the given user */ public abstract boolean areDefaultRuntimePermissionsGranted(@UserIdInt int userId); diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 2ded5dcae0d9..0b157fa3bb1e 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -57,12 +57,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageParserCacheHelper.ReadHelper; import android.content.pm.PackageParserCacheHelper.WriteHelper; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ApkParseUtils; -import android.content.pm.parsing.ComponentParseUtils; -import android.content.pm.parsing.PackageImpl; -import android.content.pm.parsing.PackageInfoUtils; -import android.content.pm.parsing.ParsedPackage; import android.content.pm.permission.SplitPermissionInfoParcelable; import android.content.pm.split.DefaultSplitAssetLoader; import android.content.pm.split.SplitAssetDependencyLoader; @@ -73,6 +67,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; +import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.FileUtils; @@ -161,22 +156,21 @@ import java.util.concurrent.atomic.AtomicInteger; * @hide */ public class PackageParser { - - public static final boolean DEBUG_JAR = false; - public static final boolean DEBUG_PARSER = false; - public static final boolean DEBUG_BACKUP = false; - public static final boolean LOG_PARSE_TIMINGS = Build.IS_DEBUGGABLE; - public static final int LOG_PARSE_TIMINGS_THRESHOLD_MS = 100; + private static final boolean DEBUG_JAR = false; + private static final boolean DEBUG_PARSER = false; + private static final boolean DEBUG_BACKUP = false; + private static final boolean LOG_PARSE_TIMINGS = Build.IS_DEBUGGABLE; + private static final int LOG_PARSE_TIMINGS_THRESHOLD_MS = 100; private static final String PROPERTY_CHILD_PACKAGES_ENABLED = "persist.sys.child_packages_enabled"; - public static final boolean MULTI_PACKAGE_APK_ENABLED = Build.IS_DEBUGGABLE && + private static final boolean MULTI_PACKAGE_APK_ENABLED = Build.IS_DEBUGGABLE && SystemProperties.getBoolean(PROPERTY_CHILD_PACKAGES_ENABLED, false); - public static final float DEFAULT_PRE_O_MAX_ASPECT_RATIO = 1.86f; - public static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO = 1.333f; - public static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH = 1f; + private static final float DEFAULT_PRE_O_MAX_ASPECT_RATIO = 1.86f; + private static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO = 1.333f; + private static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH = 1f; private static final int DEFAULT_MIN_SDK_VERSION = 1; private static final int DEFAULT_TARGET_SDK_VERSION = 0; @@ -188,38 +182,37 @@ public class PackageParser { public static final String ANDROID_MANIFEST_FILENAME = "AndroidManifest.xml"; /** Path prefix for apps on expanded storage */ - public static final String MNT_EXPAND = "/mnt/expand/"; - - public static final String TAG_ADOPT_PERMISSIONS = "adopt-permissions"; - public static final String TAG_APPLICATION = "application"; - public static final String TAG_COMPATIBLE_SCREENS = "compatible-screens"; - public static final String TAG_EAT_COMMENT = "eat-comment"; - public static final String TAG_FEATURE_GROUP = "feature-group"; - public static final String TAG_INSTRUMENTATION = "instrumentation"; - public static final String TAG_KEY_SETS = "key-sets"; - public static final String TAG_MANIFEST = "manifest"; - public static final String TAG_ORIGINAL_PACKAGE = "original-package"; - public static final String TAG_OVERLAY = "overlay"; - public static final String TAG_PACKAGE = "package"; - public static final String TAG_PACKAGE_VERIFIER = "package-verifier"; - public static final String TAG_PERMISSION = "permission"; - public static final String TAG_PERMISSION_GROUP = "permission-group"; - public static final String TAG_PERMISSION_TREE = "permission-tree"; - public static final String TAG_PROTECTED_BROADCAST = "protected-broadcast"; - public static final String TAG_QUERIES = "queries"; - public static final String TAG_RESTRICT_UPDATE = "restrict-update"; - public static final String TAG_SUPPORT_SCREENS = "supports-screens"; - public static final String TAG_SUPPORTS_INPUT = "supports-input"; - public static final String TAG_USES_CONFIGURATION = "uses-configuration"; - public static final String TAG_USES_FEATURE = "uses-feature"; - public static final String TAG_USES_GL_TEXTURE = "uses-gl-texture"; - public static final String TAG_USES_PERMISSION = "uses-permission"; - public static final String TAG_USES_PERMISSION_SDK_23 = "uses-permission-sdk-23"; - public static final String TAG_USES_PERMISSION_SDK_M = "uses-permission-sdk-m"; - public static final String TAG_USES_SDK = "uses-sdk"; - public static final String TAG_USES_SPLIT = "uses-split"; - - public static final String METADATA_MAX_ASPECT_RATIO = "android.max_aspect"; + private static final String MNT_EXPAND = "/mnt/expand/"; + + private static final String TAG_MANIFEST = "manifest"; + private static final String TAG_APPLICATION = "application"; + private static final String TAG_PACKAGE_VERIFIER = "package-verifier"; + private static final String TAG_OVERLAY = "overlay"; + private static final String TAG_KEY_SETS = "key-sets"; + private static final String TAG_PERMISSION_GROUP = "permission-group"; + private static final String TAG_PERMISSION = "permission"; + private static final String TAG_PERMISSION_TREE = "permission-tree"; + private static final String TAG_USES_PERMISSION = "uses-permission"; + private static final String TAG_USES_PERMISSION_SDK_M = "uses-permission-sdk-m"; + private static final String TAG_USES_PERMISSION_SDK_23 = "uses-permission-sdk-23"; + private static final String TAG_USES_CONFIGURATION = "uses-configuration"; + private static final String TAG_USES_FEATURE = "uses-feature"; + private static final String TAG_FEATURE_GROUP = "feature-group"; + private static final String TAG_USES_SDK = "uses-sdk"; + private static final String TAG_SUPPORT_SCREENS = "supports-screens"; + private static final String TAG_PROTECTED_BROADCAST = "protected-broadcast"; + private static final String TAG_INSTRUMENTATION = "instrumentation"; + private static final String TAG_ORIGINAL_PACKAGE = "original-package"; + private static final String TAG_ADOPT_PERMISSIONS = "adopt-permissions"; + private static final String TAG_USES_GL_TEXTURE = "uses-gl-texture"; + private static final String TAG_COMPATIBLE_SCREENS = "compatible-screens"; + private static final String TAG_SUPPORTS_INPUT = "supports-input"; + private static final String TAG_EAT_COMMENT = "eat-comment"; + private static final String TAG_PACKAGE = "package"; + private static final String TAG_RESTRICT_UPDATE = "restrict-update"; + private static final String TAG_USES_SPLIT = "uses-split"; + + private static final String METADATA_MAX_ASPECT_RATIO = "android.max_aspect"; /** * Bit mask of all the valid bits that can be set in recreateOnConfigChanges. @@ -229,25 +222,25 @@ public class PackageParser { ActivityInfo.CONFIG_MCC | ActivityInfo.CONFIG_MNC; // These are the tags supported by child packages - public static final Set<String> CHILD_PACKAGE_TAGS = new ArraySet<>(); + private static final Set<String> CHILD_PACKAGE_TAGS = new ArraySet<>(); static { CHILD_PACKAGE_TAGS.add(TAG_APPLICATION); - CHILD_PACKAGE_TAGS.add(TAG_COMPATIBLE_SCREENS); - CHILD_PACKAGE_TAGS.add(TAG_EAT_COMMENT); - CHILD_PACKAGE_TAGS.add(TAG_FEATURE_GROUP); - CHILD_PACKAGE_TAGS.add(TAG_INSTRUMENTATION); - CHILD_PACKAGE_TAGS.add(TAG_SUPPORT_SCREENS); - CHILD_PACKAGE_TAGS.add(TAG_SUPPORTS_INPUT); - CHILD_PACKAGE_TAGS.add(TAG_USES_CONFIGURATION); - CHILD_PACKAGE_TAGS.add(TAG_USES_FEATURE); - CHILD_PACKAGE_TAGS.add(TAG_USES_GL_TEXTURE); CHILD_PACKAGE_TAGS.add(TAG_USES_PERMISSION); - CHILD_PACKAGE_TAGS.add(TAG_USES_PERMISSION_SDK_23); CHILD_PACKAGE_TAGS.add(TAG_USES_PERMISSION_SDK_M); + CHILD_PACKAGE_TAGS.add(TAG_USES_PERMISSION_SDK_23); + CHILD_PACKAGE_TAGS.add(TAG_USES_CONFIGURATION); + CHILD_PACKAGE_TAGS.add(TAG_USES_FEATURE); + CHILD_PACKAGE_TAGS.add(TAG_FEATURE_GROUP); CHILD_PACKAGE_TAGS.add(TAG_USES_SDK); + CHILD_PACKAGE_TAGS.add(TAG_SUPPORT_SCREENS); + CHILD_PACKAGE_TAGS.add(TAG_INSTRUMENTATION); + CHILD_PACKAGE_TAGS.add(TAG_USES_GL_TEXTURE); + CHILD_PACKAGE_TAGS.add(TAG_COMPATIBLE_SCREENS); + CHILD_PACKAGE_TAGS.add(TAG_SUPPORTS_INPUT); + CHILD_PACKAGE_TAGS.add(TAG_EAT_COMMENT); } - public static final boolean LOG_UNSAFE_BROADCASTS = false; + private static final boolean LOG_UNSAFE_BROADCASTS = false; /** * Total number of packages that were read from the cache. We use it only for logging. @@ -255,7 +248,7 @@ public class PackageParser { public static final AtomicInteger sCachedPackageReadCount = new AtomicInteger(); // Set of broadcast actions that are safe for manifest receivers - public static final Set<String> SAFE_BROADCASTS = new ArraySet<>(); + private static final Set<String> SAFE_BROADCASTS = new ArraySet<>(); static { SAFE_BROADCASTS.add(Intent.ACTION_BOOT_COMPLETED); } @@ -302,29 +295,26 @@ public class PackageParser { * @deprecated callers should move to explicitly passing around source path. */ @Deprecated - public String mArchiveSourcePath; + private String mArchiveSourcePath; - public String[] mSeparateProcesses; + private String[] mSeparateProcesses; private boolean mOnlyCoreApps; private DisplayMetrics mMetrics; @UnsupportedAppUsage - public Callback mCallback; + private Callback mCallback; private File mCacheDir; - public static final int SDK_VERSION = Build.VERSION.SDK_INT; - public static final String[] SDK_CODENAMES = Build.VERSION.ACTIVE_CODENAMES; - - public int mParseError = PackageManager.INSTALL_SUCCEEDED; + private static final int SDK_VERSION = Build.VERSION.SDK_INT; + private static final String[] SDK_CODENAMES = Build.VERSION.ACTIVE_CODENAMES; - public ThreadLocal<ApkParseUtils.ParseResult> mSharedResult - = ThreadLocal.withInitial(ApkParseUtils.ParseResult::new); + private int mParseError = PackageManager.INSTALL_SUCCEEDED; - public static boolean sCompatibilityModeEnabled = true; - public static boolean sUseRoundIcon = false; + private static boolean sCompatibilityModeEnabled = true; + private static boolean sUseRoundIcon = false; - public static final int PARSE_DEFAULT_INSTALL_LOCATION = + private static final int PARSE_DEFAULT_INSTALL_LOCATION = PackageInfo.INSTALL_LOCATION_UNSPECIFIED; - public static final int PARSE_DEFAULT_TARGET_SANDBOX = 1; + private static final int PARSE_DEFAULT_TARGET_SANDBOX = 1; static class ParsePackageItemArgs { final Package owner; @@ -546,7 +536,7 @@ public class PackageParser { * the DTD. Otherwise, we try to get as much from the package as we * can without failing. This should normally be set to false, to * support extensions to the DTD in future versions. */ - public static final boolean RIGID_PARSER = false; + private static final boolean RIGID_PARSER = false; private static final String TAG = "PackageParser"; @@ -907,7 +897,7 @@ public class PackageParser { @Retention(RetentionPolicy.SOURCE) public @interface ParseFlags {} - public static final Comparator<String> sSplitNameComparator = new SplitNameComparator(); + private static final Comparator<String> sSplitNameComparator = new SplitNameComparator(); /** * Used to sort a set of APKs based on their split names, always placing the @@ -1053,7 +1043,7 @@ public class PackageParser { * and unique split names. * <p> * Note that this <em>does not</em> perform signature verification; that - * must be done separately in {@link ApkParseUtils#collectCertificates(AndroidPackage, boolean)}. + * must be done separately in {@link #collectCertificates(Package, int)}. * * If {@code useCaches} is true, the package parser might return a cached * result from a previous parse of the same {@code packageFile} with the same @@ -1061,54 +1051,21 @@ public class PackageParser { * has changed since the last parse, it's up to callers to do so. * * @see #parsePackageLite(File, int) - * @deprecated use {@link #parseParsedPackage(File, int, boolean)} */ @UnsupportedAppUsage - @Deprecated public Package parsePackage(File packageFile, int flags, boolean useCaches) throws PackageParserException { - if (packageFile.isDirectory()) { - return parseClusterPackage(packageFile, flags); - } else { - return parseMonolithicPackage(packageFile, flags); - } - } - - /** - * Equivalent to {@link #parsePackage(File, int, boolean)} with {@code useCaches == false}. - * @deprecated use {@link #parseParsedPackage(File, int, boolean)} - */ - @UnsupportedAppUsage - @Deprecated - public Package parsePackage(File packageFile, int flags) throws PackageParserException { - return parsePackage(packageFile, flags, false /* useCaches */); - } - - /** - * Updated method which returns {@link ParsedPackage}, the current representation of a - * package parsed from disk. - * - * @see #parsePackage(File, int, boolean) - */ - public ParsedPackage parseParsedPackage(File packageFile, int flags, boolean useCaches) - throws PackageParserException { - ParsedPackage parsed = useCaches ? getCachedResult(packageFile, flags) : null; + Package parsed = useCaches ? getCachedResult(packageFile, flags) : null; if (parsed != null) { return parsed; } long parseTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0; - ApkParseUtils.ParseInput parseInput = mSharedResult.get().reset(); - parsed = ApkParseUtils.parsePackage( - parseInput, - mSeparateProcesses, - mCallback, - mMetrics, - mOnlyCoreApps, - packageFile, - flags - ) - .hideAsParsed(); + if (packageFile.isDirectory()) { + parsed = parseClusterPackage(packageFile, flags); + } else { + parsed = parseMonolithicPackage(packageFile, flags); + } long cacheTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0; cacheResult(packageFile, flags, parsed); @@ -1120,12 +1077,19 @@ public class PackageParser { + "ms, update_cache=" + cacheTime + " ms"); } } - return parsed; } /** - * Returns the cache key for a specified {@code packageFile} and {@code flags}. + * Equivalent to {@link #parsePackage(File, int, boolean)} with {@code useCaches == false}. + */ + @UnsupportedAppUsage + public Package parsePackage(File packageFile, int flags) throws PackageParserException { + return parsePackage(packageFile, flags, false /* useCaches */); + } + + /** + * Returns the cache key for a specificied {@code packageFile} and {@code flags}. */ private String getCacheKey(File packageFile, int flags) { StringBuilder sb = new StringBuilder(packageFile.getName()); @@ -1136,13 +1100,13 @@ public class PackageParser { } @VisibleForTesting - protected ParsedPackage fromCacheEntry(byte[] bytes) { + protected Package fromCacheEntry(byte[] bytes) { return fromCacheEntryStatic(bytes); } /** static version of {@link #fromCacheEntry} for unit tests. */ @VisibleForTesting - public static ParsedPackage fromCacheEntryStatic(byte[] bytes) { + public static Package fromCacheEntryStatic(byte[] bytes) { final Parcel p = Parcel.obtain(); p.unmarshall(bytes, 0, bytes.length); p.setDataPosition(0); @@ -1150,8 +1114,7 @@ public class PackageParser { final ReadHelper helper = new ReadHelper(p); helper.startAndInstall(); - // TODO(b/135203078): Hide PackageImpl constructor? - ParsedPackage pkg = new PackageImpl(p); + PackageParser.Package pkg = new PackageParser.Package(p); p.recycle(); @@ -1161,14 +1124,14 @@ public class PackageParser { } @VisibleForTesting - protected byte[] toCacheEntry(ParsedPackage pkg) { + protected byte[] toCacheEntry(Package pkg) { return toCacheEntryStatic(pkg); } /** static version of {@link #toCacheEntry} for unit tests. */ @VisibleForTesting - public static byte[] toCacheEntryStatic(ParsedPackage pkg) { + public static byte[] toCacheEntryStatic(Package pkg) { final Parcel p = Parcel.obtain(); final WriteHelper helper = new WriteHelper(p); @@ -1217,7 +1180,7 @@ public class PackageParser { * Returns the cached parse result for {@code packageFile} for parse flags {@code flags}, * or {@code null} if no cached result exists. */ - public ParsedPackage getCachedResult(File packageFile, int flags) { + private Package getCachedResult(File packageFile, int flags) { if (mCacheDir == null) { return null; } @@ -1232,9 +1195,9 @@ public class PackageParser { } final byte[] bytes = IoUtils.readFileAsByteArray(cacheFile.getAbsolutePath()); - ParsedPackage p = fromCacheEntry(bytes); + Package p = fromCacheEntry(bytes); if (mCallback != null) { - String[] overlayApks = mCallback.getOverlayApks(p.getPackageName()); + String[] overlayApks = mCallback.getOverlayApks(p.packageName); if (overlayApks != null && overlayApks.length > 0) { for (String overlayApk : overlayApks) { // If a static RRO is updated, return null. @@ -1258,7 +1221,7 @@ public class PackageParser { /** * Caches the parse result for {@code packageFile} with flags {@code flags}. */ - public void cacheResult(File packageFile, int flags, ParsedPackage parsed) { + private void cacheResult(File packageFile, int flags, Package parsed) { if (mCacheDir == null) { return; } @@ -1297,8 +1260,7 @@ public class PackageParser { * split names. * <p> * Note that this <em>does not</em> perform signature verification; that - * must be done separately in - * {@link ApkParseUtils#collectCertificates(AndroidPackage, boolean)}. + * must be done separately in {@link #collectCertificates(Package, int)}. */ private Package parseClusterPackage(File packageDir, int flags) throws PackageParserException { final PackageLite lite = parseClusterPackageLite(packageDir, 0); @@ -1362,11 +1324,10 @@ public class PackageParser { * Parse the given APK file, treating it as as a single monolithic package. * <p> * Note that this <em>does not</em> perform signature verification; that - * must be done separately in - * {@link ApkParseUtils#collectCertificates(AndroidPackage, boolean)}. + * must be done separately in {@link #collectCertificates(Package, int)}. * * @deprecated external callers should move to - * {@link #parseParsedPackage(File, int, boolean)}. Eventually this method will + * {@link #parsePackage(File, int)}. Eventually this method will * be marked private. */ @Deprecated @@ -1566,11 +1527,8 @@ public class PackageParser { * Collect certificates from all the APKs described in the given package, * populating {@link Package#mSigningDetails}. Also asserts that all APK * contents are signed correctly and consistently. - * - * @deprecated use {@link ApkParseUtils#collectCertificates(AndroidPackage, boolean)} */ @UnsupportedAppUsage - @Deprecated public static void collectCertificates(Package pkg, boolean skipVerify) throws PackageParserException { collectCertificatesInternal(pkg, skipVerify); @@ -1749,7 +1707,7 @@ public class PackageParser { ? null : "must have at least one '.' separator"; } - public static Pair<String, String> parsePackageSplitNames(XmlPullParser parser, + private static Pair<String, String> parsePackageSplitNames(XmlPullParser parser, AttributeSet attrs) throws IOException, XmlPullParserException, PackageParserException { @@ -2529,6 +2487,8 @@ public class PackageParser { mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; return null; + } else if (tagName.equals("queries")) { + parseQueries(pkg, res, parser, flags, outError); } else { Slog.w(TAG, "Unknown element under <manifest>: " + parser.getName() + " at " + mArchiveSourcePath + " " @@ -2998,7 +2958,7 @@ public class PackageParser { return true; } - public static String buildClassName(String pkg, CharSequence clsSeq, + private static String buildClassName(String pkg, CharSequence clsSeq, String[] outError) { if (clsSeq == null || clsSeq.length() <= 0) { outError[0] = "Empty class name in package " + pkg; @@ -3046,7 +3006,7 @@ public class PackageParser { return proc; } - public static String buildProcessName(String pkg, String defProc, + private static String buildProcessName(String pkg, String defProc, CharSequence procSeq, int flags, String[] separateProcesses, String[] outError) { if ((flags&PARSE_IGNORE_PROCESSES) != 0 && !"system".equals(procSeq)) { @@ -3066,7 +3026,7 @@ public class PackageParser { return TextUtils.safeIntern(buildCompoundName(pkg, procSeq, "process", outError)); } - public static String buildTaskAffinityName(String pkg, String defProc, + private static String buildTaskAffinityName(String pkg, String defProc, CharSequence procSeq, String[] outError) { if (procSeq == null) { return defProc; @@ -3628,6 +3588,9 @@ public class PackageParser { owner.mRequiredAccountType = requiredAccountType; } + owner.mForceQueryable = + sa.getBoolean(R.styleable.AndroidManifestApplication_forceQueryable, false); + if (sa.getBoolean( com.android.internal.R.styleable.AndroidManifestApplication_debuggable, false)) { @@ -4089,6 +4052,89 @@ public class PackageParser { return true; } + private boolean parseQueries(Package owner, Resources res, XmlResourceParser parser, int flags, + String[] outError) + throws IOException, XmlPullParserException { + + final int outerDepth = parser.getDepth(); + int type; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG + || parser.getDepth() > outerDepth)) { + if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + continue; + } + if (parser.getName().equals("intent")) { + QueriesIntentInfo intentInfo = new QueriesIntentInfo(); + if (!parseIntent(res, parser, true /*allowGlobs*/, true /*allowAutoVerify*/, + intentInfo, outError)) { + return false; + } + + Uri data = null; + String dataType = null; + String host = ""; + final int numActions = intentInfo.countActions(); + final int numSchemes = intentInfo.countDataSchemes(); + final int numTypes = intentInfo.countDataTypes(); + final int numHosts = intentInfo.getHosts().length; + if ((numSchemes == 0 && numTypes == 0 && numActions == 0)) { + outError[0] = "intent tags must contain either an action or data."; + return false; + } + if (numActions > 1) { + outError[0] = "intent tag may have at most one action."; + return false; + } + if (numTypes > 1) { + outError[0] = "intent tag may have at most one data type."; + return false; + } + if (numSchemes > 1) { + outError[0] = "intent tag may have at most one data scheme."; + return false; + } + if (numHosts > 1) { + outError[0] = "intent tag may have at most one data host."; + return false; + } + Intent intent = new Intent(); + for (int i = 0, max = intentInfo.countCategories(); i < max; i++) { + intent.addCategory(intentInfo.getCategory(i)); + } + if (numHosts == 1) { + host = intentInfo.getHosts()[0]; + } + if (numSchemes == 1) { + data = new Uri.Builder() + .scheme(intentInfo.getDataScheme(0)) + .authority(host) + .build(); + } + if (numTypes == 1) { + dataType = intentInfo.getDataType(0); + } + intent.setDataAndType(data, dataType); + if (numActions == 1) { + intent.setAction(intentInfo.getAction(0)); + } + owner.mQueriesIntents = ArrayUtils.add(owner.mQueriesIntents, intent); + } else if (parser.getName().equals("package")) { + final TypedArray sa = res.obtainAttributes(parser, + com.android.internal.R.styleable.AndroidManifestQueriesPackage); + final String packageName = + sa.getString(R.styleable.AndroidManifestQueriesPackage_name); + if (TextUtils.isEmpty(packageName)) { + outError[0] = "Package name is missing from package tag."; + return false; + } + owner.mQueriesPackages = + ArrayUtils.add(owner.mQueriesPackages, packageName.intern()); + } + } + return true; + } + /** * Check if one of the IntentFilter as both actions DEFAULT / VIEW and a HTTP/HTTPS data URI */ @@ -5800,7 +5846,7 @@ public class PackageParser { return null; } - public static final String ANDROID_RESOURCES + private static final String ANDROID_RESOURCES = "http://schemas.android.com/apk/res/android"; private boolean parseIntent(Resources res, XmlResourceParser parser, boolean allowGlobs, @@ -6495,10 +6541,7 @@ public class PackageParser { /** * Representation of a full package parsed from APK files on disk. A package * consists of a single base APK, and zero or more split APKs. - * - * @deprecated use an {@link AndroidPackage} */ - @Deprecated public final static class Package implements Parcelable { @UnsupportedAppUsage @@ -6606,6 +6649,9 @@ public class PackageParser { // The major version code declared for this package. public int mVersionCodeMajor; + // Whether the package declares that it should be queryable by all normal apps on device. + public boolean mForceQueryable; + // Return long containing mVersionCode and mVersionCodeMajor. public long getLongVersionCode() { return PackageInfo.composeLongVersionCode(mVersionCodeMajor, mVersionCode); @@ -6711,6 +6757,9 @@ public class PackageParser { /** Whether or not the package is a stub and must be replaced by the full version. */ public boolean isStub; + public ArrayList<String> mQueriesPackages; + public ArrayList<Intent> mQueriesIntents; + @UnsupportedAppUsage public Package(String packageName) { this.packageName = packageName; @@ -7214,6 +7263,9 @@ public class PackageParser { use32bitAbi = (dest.readInt() == 1); restrictUpdateHash = dest.createByteArray(); visibleToInstantApps = dest.readInt() == 1; + mForceQueryable = dest.readBoolean(); + mQueriesIntents = dest.createTypedArrayList(Intent.CREATOR); + mQueriesPackages = dest.createStringArrayList(); } private static void internStringArrayList(List<String> list) { @@ -7229,7 +7281,7 @@ public class PackageParser { * Sets the package owner and the the {@code applicationInfo} for every component * owner by this package. */ - public void fixupOwner(List<? extends Component<?>> list) { + private void fixupOwner(List<? extends Component<?>> list) { if (list != null) { for (Component<?> c : list) { c.owner = this; @@ -7339,8 +7391,12 @@ public class PackageParser { dest.writeInt(use32bitAbi ? 1 : 0); dest.writeByteArray(restrictUpdateHash); dest.writeInt(visibleToInstantApps ? 1 : 0); + dest.writeBoolean(mForceQueryable); + dest.writeTypedList(mQueriesIntents); + dest.writeList(mQueriesPackages); } + /** * Writes the keyset mapping to the provided package. {@code null} mappings are permitted. */ @@ -7412,10 +7468,6 @@ public class PackageParser { }; } - /** - * @deprecated use a {@link ComponentParseUtils.ParsedComponent} - */ - @Deprecated public static abstract class Component<II extends IntentInfo> { @UnsupportedAppUsage public final ArrayList<II> intents; @@ -7596,10 +7648,6 @@ public class PackageParser { } } - /** - * @deprecated use {@link ComponentParseUtils.ParsedPermission} - */ - @Deprecated public final static class Permission extends Component<IntentInfo> implements Parcelable { @UnsupportedAppUsage public final PermissionInfo info; @@ -7674,10 +7722,6 @@ public class PackageParser { }; } - /** - * @deprecated use {@link ComponentParseUtils.ParsedPermissionGroup} - */ - @Deprecated public final static class PermissionGroup extends Component<IntentInfo> implements Parcelable { @UnsupportedAppUsage public final PermissionGroupInfo info; @@ -7777,12 +7821,7 @@ public class PackageParser { return false; } - /** - * @deprecated use {@link PackageInfoUtils#generateApplicationInfo( - * AndroidPackage, int, PackageUserState, int)} - */ @UnsupportedAppUsage - @Deprecated public static ApplicationInfo generateApplicationInfo(Package p, int flags, PackageUserState state) { return generateApplicationInfo(p, flags, state, UserHandle.getCallingUserId()); @@ -7839,12 +7878,7 @@ public class PackageParser { ai.icon = (sUseRoundIcon && ai.roundIconRes != 0) ? ai.roundIconRes : ai.iconRes; } - /** - * @deprecated use {@link PackageInfoUtils#generateApplicationInfo( - * AndroidPackage, int, PackageUserState, int)} - */ @UnsupportedAppUsage - @Deprecated public static ApplicationInfo generateApplicationInfo(Package p, int flags, PackageUserState state, int userId) { if (p == null) return null; @@ -7884,11 +7918,6 @@ public class PackageParser { return ai; } - /** - * @deprecated use {@link PackageInfoUtils#generateApplicationInfo( - * AndroidPackage, int, PackageUserState, int)} - */ - @Deprecated public static ApplicationInfo generateApplicationInfo(ApplicationInfo ai, int flags, PackageUserState state, int userId) { if (ai == null) return null; @@ -7908,12 +7937,7 @@ public class PackageParser { return ai; } - /** - * @deprecated use {@link PackageInfoUtils#generatePermissionInfo( - * ComponentParseUtils.ParsedPermission, int)} - */ @UnsupportedAppUsage - @Deprecated public static final PermissionInfo generatePermissionInfo( Permission p, int flags) { if (p == null) return null; @@ -7925,12 +7949,7 @@ public class PackageParser { return pi; } - /** - * @deprecated use {@link PackageInfoUtils#generatePermissionGroupInfo( - * ComponentParseUtils.ParsedPermissionGroup, int)} - */ @UnsupportedAppUsage - @Deprecated public static final PermissionGroupInfo generatePermissionGroupInfo( PermissionGroup pg, int flags) { if (pg == null) return null; @@ -7942,10 +7961,6 @@ public class PackageParser { return pgi; } - /** - * @deprecated use {@link ComponentParseUtils.ParsedActivity} - */ - @Deprecated public final static class Activity extends Component<ActivityIntentInfo> implements Parcelable { @UnsupportedAppUsage public final ActivityInfo info; @@ -8061,12 +8076,7 @@ public class PackageParser { }; } - /** - * @deprecated use {@link PackageInfoUtils#generateActivityInfo( - * AndroidPackage, ComponentParseUtils.ParsedActivity, int, PackageUserState, int)} - */ @UnsupportedAppUsage - @Deprecated public static final ActivityInfo generateActivityInfo(Activity a, int flags, PackageUserState state, int userId) { if (a == null) return null; @@ -8084,11 +8094,6 @@ public class PackageParser { return ai; } - /** - * @deprecated use {@link PackageInfoUtils#generateActivityInfo( - * AndroidPackage, ComponentParseUtils.ParsedActivity, int, PackageUserState, int)} - */ - @Deprecated public static final ActivityInfo generateActivityInfo(ActivityInfo ai, int flags, PackageUserState state, int userId) { if (ai == null) return null; @@ -8102,10 +8107,6 @@ public class PackageParser { return ai; } - /** - * @deprecated use {@link ComponentParseUtils.ParsedService} - */ - @Deprecated public final static class Service extends Component<ServiceIntentInfo> implements Parcelable { @UnsupportedAppUsage public final ServiceInfo info; @@ -8167,12 +8168,7 @@ public class PackageParser { }; } - /** - * @deprecated use {@link PackageInfoUtils#generateServiceInfo( - * AndroidPackage, ComponentParseUtils.ParsedService, int, PackageUserState, int)} - */ @UnsupportedAppUsage - @Deprecated public static final ServiceInfo generateServiceInfo(Service s, int flags, PackageUserState state, int userId) { if (s == null) return null; @@ -8190,10 +8186,6 @@ public class PackageParser { return si; } - /** - * @deprecated use {@link ComponentParseUtils.ParsedProvider} - */ - @Deprecated public final static class Provider extends Component<ProviderIntentInfo> implements Parcelable { @UnsupportedAppUsage public final ProviderInfo info; @@ -8274,12 +8266,7 @@ public class PackageParser { }; } - /** - * @deprecated use {@link PackageInfoUtils#generateProviderInfo( - * AndroidPackage, ComponentParseUtils.ParsedProvider, int, PackageUserState, int)} - */ @UnsupportedAppUsage - @Deprecated public static final ProviderInfo generateProviderInfo(Provider p, int flags, PackageUserState state, int userId) { if (p == null) return null; @@ -8302,10 +8289,6 @@ public class PackageParser { return pi; } - /** - * @deprecated use {@link ComponentParseUtils.ParsedInstrumentation} - */ - @Deprecated public final static class Instrumentation extends Component<IntentInfo> implements Parcelable { @UnsupportedAppUsage @@ -8366,12 +8349,7 @@ public class PackageParser { }; } - /** - * @deprecated use {@link PackageInfoUtils#generateInstrumentationInfo( - * ComponentParseUtils.ParsedInstrumentation, int)} - */ @UnsupportedAppUsage - @Deprecated public static final InstrumentationInfo generateInstrumentationInfo( Instrumentation i, int flags) { if (i == null) return null; @@ -8383,10 +8361,6 @@ public class PackageParser { return ii; } - /** - * @deprecated use {@link ComponentParseUtils.ParsedIntentInfo} - */ - @Deprecated public static abstract class IntentInfo extends IntentFilter { @UnsupportedAppUsage public boolean hasDefault; @@ -8430,10 +8404,8 @@ public class PackageParser { } } - /** - * @deprecated use {@link ComponentParseUtils.ParsedActivityIntentInfo} - */ - @Deprecated + public static final class QueriesIntentInfo extends IntentInfo {} + public final static class ActivityIntentInfo extends IntentInfo { @UnsupportedAppUsage public Activity activity; @@ -8457,10 +8429,6 @@ public class PackageParser { } } - /** - * @deprecated use {@link ComponentParseUtils.ParsedServiceIntentInfo} - */ - @Deprecated public final static class ServiceIntentInfo extends IntentInfo { @UnsupportedAppUsage public Service service; @@ -8484,10 +8452,6 @@ public class PackageParser { } } - /** - * @deprecated use {@link ComponentParseUtils.ParsedProviderIntentInfo} - */ - @Deprecated public static final class ProviderIntentInfo extends IntentInfo { @UnsupportedAppUsage public Provider provider; diff --git a/core/java/android/content/pm/parsing/library/PackageSharedLibraryUpdater.java b/core/java/android/content/pm/PackageSharedLibraryUpdater.java index 8b27d140a8f4..1565d9ce77d4 100644 --- a/core/java/android/content/pm/parsing/library/PackageSharedLibraryUpdater.java +++ b/core/java/android/content/pm/PackageSharedLibraryUpdater.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2018 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. @@ -13,20 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.content.pm.parsing.library; +package android.content.pm; import android.annotation.NonNull; import android.annotation.Nullable; -import android.content.pm.parsing.ParsedPackage; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import java.util.ArrayList; -import java.util.List; /** - * Base for classes that update a {@link ParsedPackage}'s shared libraries. + * Base for classes that update a {@link PackageParser.Package}'s shared libraries. * * @hide */ @@ -36,13 +34,14 @@ public abstract class PackageSharedLibraryUpdater { /** * Update the package's shared libraries. * - * @param parsedPackage the package to update. + * @param pkg the package to update. */ - public abstract void updatePackage(ParsedPackage parsedPackage); + public abstract void updatePackage(PackageParser.Package pkg); - static void removeLibrary(ParsedPackage parsedPackage, String libraryName) { - parsedPackage.removeUsesLibrary(libraryName) - .removeUsesOptionalLibrary(libraryName); + static void removeLibrary(PackageParser.Package pkg, String libraryName) { + pkg.usesLibraries = ArrayUtils.remove(pkg.usesLibraries, libraryName); + pkg.usesOptionalLibraries = + ArrayUtils.remove(pkg.usesOptionalLibraries, libraryName); } static @NonNull @@ -54,8 +53,8 @@ public abstract class PackageSharedLibraryUpdater { return cur; } - private static boolean isLibraryPresent(List<String> usesLibraries, - List<String> usesOptionalLibraries, String apacheHttpLegacy) { + private static boolean isLibraryPresent(ArrayList<String> usesLibraries, + ArrayList<String> usesOptionalLibraries, String apacheHttpLegacy) { return ArrayUtils.contains(usesLibraries, apacheHttpLegacy) || ArrayUtils.contains(usesOptionalLibraries, apacheHttpLegacy); } @@ -66,32 +65,37 @@ public abstract class PackageSharedLibraryUpdater { * <p>If the package has an existing dependency on {@code existingLibrary} then prefix it with * the {@code implicitDependency} if it is not already in the list of libraries. * - * @param parsedPackage the {@link ParsedPackage} to update. + * @param pkg the {@link PackageParser.Package} to update. * @param existingLibrary the existing library. * @param implicitDependency the implicit dependency to add */ - void prefixImplicitDependency(ParsedPackage parsedPackage, String existingLibrary, + void prefixImplicitDependency(PackageParser.Package pkg, String existingLibrary, String implicitDependency) { - List<String> usesLibraries = parsedPackage.getUsesLibraries(); - List<String> usesOptionalLibraries = parsedPackage.getUsesOptionalLibraries(); + ArrayList<String> usesLibraries = pkg.usesLibraries; + ArrayList<String> usesOptionalLibraries = pkg.usesOptionalLibraries; if (!isLibraryPresent(usesLibraries, usesOptionalLibraries, implicitDependency)) { if (ArrayUtils.contains(usesLibraries, existingLibrary)) { - parsedPackage.addUsesLibrary(0, implicitDependency); + prefix(usesLibraries, implicitDependency); } else if (ArrayUtils.contains(usesOptionalLibraries, existingLibrary)) { - parsedPackage.addUsesOptionalLibrary(0, implicitDependency); + prefix(usesOptionalLibraries, implicitDependency); } + + pkg.usesLibraries = usesLibraries; + pkg.usesOptionalLibraries = usesOptionalLibraries; } } - void prefixRequiredLibrary(ParsedPackage parsedPackage, String libraryName) { - List<String> usesLibraries = parsedPackage.getUsesLibraries(); - List<String> usesOptionalLibraries = parsedPackage.getUsesOptionalLibraries(); + void prefixRequiredLibrary(PackageParser.Package pkg, String libraryName) { + ArrayList<String> usesLibraries = pkg.usesLibraries; + ArrayList<String> usesOptionalLibraries = pkg.usesOptionalLibraries; boolean alreadyPresent = isLibraryPresent( usesLibraries, usesOptionalLibraries, libraryName); if (!alreadyPresent) { - parsedPackage.addUsesLibrary(0, libraryName); + usesLibraries = prefix(usesLibraries, libraryName); + + pkg.usesLibraries = usesLibraries; } } } diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java index b271ccdad041..5c74efb8ff1b 100644 --- a/core/java/android/content/pm/PackageUserState.java +++ b/core/java/android/content/pm/PackageUserState.java @@ -28,10 +28,10 @@ import static android.content.pm.PackageManager.MATCH_DISABLED_UNTIL_USED_COMPON import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; import android.annotation.UnsupportedAppUsage; -import android.content.pm.parsing.ComponentParseUtils; import android.os.BaseBundle; import android.os.Debug; import android.os.PersistableBundle; +import android.util.ArrayMap; import android.util.ArraySet; import android.util.DebugUtils; import android.util.Slog; @@ -39,6 +39,11 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + +import java.io.IOException; import java.util.Arrays; import java.util.Objects; @@ -57,10 +62,7 @@ public class PackageUserState { public boolean hidden; // Is the app restricted by owner / admin public int distractionFlags; public boolean suspended; - public String suspendingPackage; - public SuspendDialogInfo dialogInfo; - public PersistableBundle suspendedAppExtras; - public PersistableBundle suspendedLauncherExtras; + public ArrayMap<String, SuspendParams> suspendParams; // Suspending package to suspend params public boolean instantApp; public boolean virtualPreload; public int enabled; @@ -96,10 +98,7 @@ public class PackageUserState { hidden = o.hidden; distractionFlags = o.distractionFlags; suspended = o.suspended; - suspendingPackage = o.suspendingPackage; - dialogInfo = o.dialogInfo; - suspendedAppExtras = o.suspendedAppExtras; - suspendedLauncherExtras = o.suspendedLauncherExtras; + suspendParams = new ArrayMap<>(o.suspendParams); instantApp = o.instantApp; virtualPreload = o.virtualPreload; enabled = o.enabled; @@ -128,18 +127,6 @@ public class PackageUserState { && (!this.hidden || matchUninstalled)); } - public boolean isMatch(ComponentInfo componentInfo, int flags) { - return isMatch(componentInfo.applicationInfo.isSystemApp(), - componentInfo.applicationInfo.enabled, componentInfo.enabled, - componentInfo.directBootAware, componentInfo.name, flags); - } - - public boolean isMatch(boolean isSystem, boolean isPackageEnabled, - ComponentParseUtils.ParsedComponent component, int flags) { - return isMatch(isSystem, isPackageEnabled, component.isEnabled(), - component.isDirectBootAware(), component.getName(), flags); - } - /** * Test if the given component is considered installed, enabled and a match * for the given flags. @@ -148,33 +135,28 @@ public class PackageUserState { * Expects at least one of {@link PackageManager#MATCH_DIRECT_BOOT_AWARE} and * {@link PackageManager#MATCH_DIRECT_BOOT_UNAWARE} are specified in {@code flags}. * </p> - * */ - public boolean isMatch(boolean isSystem, boolean isPackageEnabled, boolean isComponentEnabled, - boolean isComponentDirectBootAware, String componentName, int flags) { + public boolean isMatch(ComponentInfo componentInfo, int flags) { + final boolean isSystemApp = componentInfo.applicationInfo.isSystemApp(); final boolean matchUninstalled = (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0; - if (!isAvailable(flags) && !(isSystem && matchUninstalled)) { - return reportIfDebug(false, flags); - } - - if (!isEnabled(isPackageEnabled, isComponentEnabled, componentName, flags)) { - return reportIfDebug(false, flags); - } + if (!isAvailable(flags) + && !(isSystemApp && matchUninstalled)) return reportIfDebug(false, flags); + if (!isEnabled(componentInfo, flags)) return reportIfDebug(false, flags); if ((flags & MATCH_SYSTEM_ONLY) != 0) { - if (!isSystem) { + if (!isSystemApp) { return reportIfDebug(false, flags); } } final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) - && !isComponentDirectBootAware; + && !componentInfo.directBootAware; final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) - && isComponentDirectBootAware; + && componentInfo.directBootAware; return reportIfDebug(matchesUnaware || matchesAware, flags); } - public boolean reportIfDebug(boolean result, int flags) { + private boolean reportIfDebug(boolean result, int flags) { if (DEBUG && !result) { Slog.i(LOG_TAG, "No match!; flags: " + DebugUtils.flagsToString(PackageManager.class, "MATCH_", flags) + " " @@ -183,22 +165,10 @@ public class PackageUserState { return result; } - public boolean isEnabled(ComponentInfo componentInfo, int flags) { - return isEnabled(componentInfo.applicationInfo.enabled, componentInfo.enabled, - componentInfo.name, flags); - } - - public boolean isEnabled(boolean isPackageEnabled, - ComponentParseUtils.ParsedComponent parsedComponent, int flags) { - return isEnabled(isPackageEnabled, parsedComponent.isEnabled(), parsedComponent.getName(), - flags); - } - /** * Test if the given component is considered enabled. */ - public boolean isEnabled(boolean isPackageEnabled, boolean isComponentEnabled, - String componentName, int flags) { + public boolean isEnabled(ComponentInfo componentInfo, int flags) { if ((flags & MATCH_DISABLED_COMPONENTS) != 0) { return true; } @@ -213,26 +183,24 @@ public class PackageUserState { if ((flags & MATCH_DISABLED_UNTIL_USED_COMPONENTS) == 0) { return false; } - // fallthrough case COMPONENT_ENABLED_STATE_DEFAULT: - if (!isPackageEnabled) { + if (!componentInfo.applicationInfo.enabled) { return false; } - // fallthrough case COMPONENT_ENABLED_STATE_ENABLED: break; } // Check if component has explicit state before falling through to // the manifest default - if (ArrayUtils.contains(this.enabledComponents, componentName)) { + if (ArrayUtils.contains(this.enabledComponents, componentInfo.name)) { return true; } - if (ArrayUtils.contains(this.disabledComponents, componentName)) { + if (ArrayUtils.contains(this.disabledComponents, componentInfo.name)) { return false; } - return isComponentEnabled; + return componentInfo.enabled; } @Override @@ -263,19 +231,7 @@ public class PackageUserState { return false; } if (suspended) { - if (suspendingPackage == null - || !suspendingPackage.equals(oldState.suspendingPackage)) { - return false; - } - if (!Objects.equals(dialogInfo, oldState.dialogInfo)) { - return false; - } - if (!BaseBundle.kindofEquals(suspendedAppExtras, - oldState.suspendedAppExtras)) { - return false; - } - if (!BaseBundle.kindofEquals(suspendedLauncherExtras, - oldState.suspendedLauncherExtras)) { + if (!Objects.equals(suspendParams, oldState.suspendParams)) { return false; } } @@ -340,4 +296,171 @@ public class PackageUserState { } return true; } + + @Override + public int hashCode() { + int hashCode = Long.hashCode(ceDataInode); + hashCode = 31 * hashCode + Boolean.hashCode(installed); + hashCode = 31 * hashCode + Boolean.hashCode(stopped); + hashCode = 31 * hashCode + Boolean.hashCode(notLaunched); + hashCode = 31 * hashCode + Boolean.hashCode(hidden); + hashCode = 31 * hashCode + distractionFlags; + hashCode = 31 * hashCode + Boolean.hashCode(suspended); + hashCode = 31 * hashCode + Objects.hashCode(suspendParams); + hashCode = 31 * hashCode + Boolean.hashCode(instantApp); + hashCode = 31 * hashCode + Boolean.hashCode(virtualPreload); + hashCode = 31 * hashCode + enabled; + hashCode = 31 * hashCode + Objects.hashCode(lastDisableAppCaller); + hashCode = 31 * hashCode + domainVerificationStatus; + hashCode = 31 * hashCode + appLinkGeneration; + hashCode = 31 * hashCode + categoryHint; + hashCode = 31 * hashCode + installReason; + hashCode = 31 * hashCode + Objects.hashCode(disabledComponents); + hashCode = 31 * hashCode + Objects.hashCode(enabledComponents); + hashCode = 31 * hashCode + Objects.hashCode(harmfulAppWarning); + return hashCode; + } + + /** + * Container to describe suspension parameters. + */ + public static final class SuspendParams { + private static final String TAG_DIALOG_INFO = "dialog-info"; + private static final String TAG_APP_EXTRAS = "app-extras"; + private static final String TAG_LAUNCHER_EXTRAS = "launcher-extras"; + + public SuspendDialogInfo dialogInfo; + public PersistableBundle appExtras; + public PersistableBundle launcherExtras; + + private SuspendParams() { + } + + /** + * Returns a {@link SuspendParams} object with the given fields. Returns {@code null} if all + * the fields are {@code null}. + * + * @param dialogInfo + * @param appExtras + * @param launcherExtras + * @return A {@link SuspendParams} object or {@code null}. + */ + public static SuspendParams getInstanceOrNull(SuspendDialogInfo dialogInfo, + PersistableBundle appExtras, PersistableBundle launcherExtras) { + if (dialogInfo == null && appExtras == null && launcherExtras == null) { + return null; + } + final SuspendParams instance = new SuspendParams(); + instance.dialogInfo = dialogInfo; + instance.appExtras = appExtras; + instance.launcherExtras = launcherExtras; + return instance; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof SuspendParams)) { + return false; + } + final SuspendParams other = (SuspendParams) obj; + if (!Objects.equals(dialogInfo, other.dialogInfo)) { + return false; + } + if (!BaseBundle.kindofEquals(appExtras, other.appExtras)) { + return false; + } + if (!BaseBundle.kindofEquals(launcherExtras, other.launcherExtras)) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hashCode = Objects.hashCode(dialogInfo); + hashCode = 31 * hashCode + ((appExtras != null) ? appExtras.size() : 0); + hashCode = 31 * hashCode + ((launcherExtras != null) ? launcherExtras.size() : 0); + return hashCode; + } + + /** + * Serializes this object into an xml format + * @param out the {@link XmlSerializer} object + * @throws IOException + */ + public void saveToXml(XmlSerializer out) throws IOException { + if (dialogInfo != null) { + out.startTag(null, TAG_DIALOG_INFO); + dialogInfo.saveToXml(out); + out.endTag(null, TAG_DIALOG_INFO); + } + if (appExtras != null) { + out.startTag(null, TAG_APP_EXTRAS); + try { + appExtras.saveToXml(out); + } catch (XmlPullParserException e) { + Slog.e(LOG_TAG, "Exception while trying to write appExtras." + + " Will be lost on reboot", e); + } + out.endTag(null, TAG_APP_EXTRAS); + } + if (launcherExtras != null) { + out.startTag(null, TAG_LAUNCHER_EXTRAS); + try { + launcherExtras.saveToXml(out); + } catch (XmlPullParserException e) { + Slog.e(LOG_TAG, "Exception while trying to write launcherExtras." + + " Will be lost on reboot", e); + } + out.endTag(null, TAG_LAUNCHER_EXTRAS); + } + } + + /** + * Parses this object from the xml format. Returns {@code null} if no object related + * information could be read. + * @param in the reader + * @return + */ + public static SuspendParams restoreFromXml(XmlPullParser in) throws IOException { + SuspendDialogInfo readDialogInfo = null; + PersistableBundle readAppExtras = null; + PersistableBundle readLauncherExtras = null; + + final int currentDepth = in.getDepth(); + int type; + try { + while ((type = in.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG + || in.getDepth() > currentDepth)) { + if (type == XmlPullParser.END_TAG + || type == XmlPullParser.TEXT) { + continue; + } + switch (in.getName()) { + case TAG_DIALOG_INFO: + readDialogInfo = SuspendDialogInfo.restoreFromXml(in); + break; + case TAG_APP_EXTRAS: + readAppExtras = PersistableBundle.restoreFromXml(in); + break; + case TAG_LAUNCHER_EXTRAS: + readLauncherExtras = PersistableBundle.restoreFromXml(in); + break; + default: + Slog.w(LOG_TAG, "Unknown tag " + in.getName() + + " in SuspendParams. Ignoring"); + break; + } + } + } catch (XmlPullParserException e) { + Slog.e(LOG_TAG, "Exception while trying to parse SuspendParams," + + " some fields may default", e); + } + return getInstanceOrNull(readDialogInfo, readAppExtras, readLauncherExtras); + } + } } diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java index 2863b268e795..3488cc30892c 100644 --- a/core/java/android/content/pm/SharedLibraryInfo.java +++ b/core/java/android/content/pm/SharedLibraryInfo.java @@ -20,7 +20,6 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.content.pm.parsing.AndroidPackage; import android.os.Parcel; import android.os.Parcelable; @@ -39,24 +38,20 @@ import java.util.List; public final class SharedLibraryInfo implements Parcelable { /** @hide */ - public static SharedLibraryInfo createForStatic(AndroidPackage pkg) { - return new SharedLibraryInfo(null, pkg.getPackageName(), - pkg.makeListAllCodePaths(), - pkg.getStaticSharedLibName(), - pkg.getStaticSharedLibVersion(), + public static SharedLibraryInfo createForStatic(PackageParser.Package pkg) { + return new SharedLibraryInfo(null, pkg.packageName, pkg.getAllCodePaths(), + pkg.staticSharedLibName, + pkg.staticSharedLibVersion, TYPE_STATIC, - new VersionedPackage(pkg.getManifestPackageName(), - pkg.getLongVersionCode()), + new VersionedPackage(pkg.manifestPackageName, pkg.getLongVersionCode()), null, null); } /** @hide */ - public static SharedLibraryInfo createForDynamic(AndroidPackage pkg, String name) { - return new SharedLibraryInfo(null, pkg.getPackageName(), - pkg.makeListAllCodePaths(), name, + public static SharedLibraryInfo createForDynamic(PackageParser.Package pkg, String name) { + return new SharedLibraryInfo(null, pkg.packageName, pkg.getAllCodePaths(), name, (long) VERSION_UNDEFINED, - TYPE_DYNAMIC, new VersionedPackage(pkg.getPackageName(), - pkg.getLongVersionCode()), + TYPE_DYNAMIC, new VersionedPackage(pkg.packageName, pkg.getLongVersionCode()), null, null); } diff --git a/core/java/android/content/pm/parsing/library/SharedLibraryNames.java b/core/java/android/content/pm/SharedLibraryNames.java index 7b691c06718e..a607a9ff682b 100644 --- a/core/java/android/content/pm/parsing/library/SharedLibraryNames.java +++ b/core/java/android/content/pm/SharedLibraryNames.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2018 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. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.content.pm.parsing.library; +package android.content.pm; /** * A set of shared library names diff --git a/core/java/android/content/pm/dex/DexMetadataHelper.java b/core/java/android/content/pm/dex/DexMetadataHelper.java index 4cd201fbe538..5d10b8826b00 100644 --- a/core/java/android/content/pm/dex/DexMetadataHelper.java +++ b/core/java/android/content/pm/dex/DexMetadataHelper.java @@ -22,7 +22,6 @@ import static android.content.pm.PackageParser.APK_FILE_EXTENSION; import android.content.pm.PackageParser; import android.content.pm.PackageParser.PackageLite; import android.content.pm.PackageParser.PackageParserException; -import android.content.pm.parsing.AndroidPackage; import android.util.ArrayMap; import android.util.jar.StrictJarFile; @@ -87,8 +86,8 @@ public class DexMetadataHelper { * * NOTE: involves I/O checks. */ - public static Map<String, String> getPackageDexMetadata(AndroidPackage pkg) { - return buildPackageApkToDexMetadataMap(pkg.makeListAllCodePaths()); + public static Map<String, String> getPackageDexMetadata(PackageParser.Package pkg) { + return buildPackageApkToDexMetadataMap(pkg.getAllCodePaths()); } /** @@ -161,7 +160,7 @@ public class DexMetadataHelper { * * @throws PackageParserException in case of errors. */ - public static void validatePackageDexMetadata(AndroidPackage pkg) + public static void validatePackageDexMetadata(PackageParser.Package pkg) throws PackageParserException { Collection<String> apkToDexMetadataList = getPackageDexMetadata(pkg).values(); for (String dexMetadata : apkToDexMetadataList) { diff --git a/core/java/android/content/pm/parsing/AndroidPackage.aidl b/core/java/android/content/pm/parsing/AndroidPackage.aidl deleted file mode 100644 index ab3cf7cb8c65..000000000000 --- a/core/java/android/content/pm/parsing/AndroidPackage.aidl +++ /dev/null @@ -1,21 +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. -*/ - -package android.content.pm.parsing; - -/* @hide */ -parcelable AndroidPackage; diff --git a/core/java/android/content/pm/parsing/AndroidPackage.java b/core/java/android/content/pm/parsing/AndroidPackage.java deleted file mode 100644 index bef984df4c10..000000000000 --- a/core/java/android/content/pm/parsing/AndroidPackage.java +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Copyright (C) 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 - */ - -package android.content.pm.parsing; - -import android.annotation.Nullable; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.ConfigurationInfo; -import android.content.pm.FeatureGroupInfo; -import android.content.pm.FeatureInfo; -import android.content.pm.PackageParser; -import android.content.pm.SharedLibraryInfo; -import android.content.pm.parsing.ComponentParseUtils.ParsedActivity; -import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo; -import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermission; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup; -import android.content.pm.parsing.ComponentParseUtils.ParsedProvider; -import android.content.pm.parsing.ComponentParseUtils.ParsedService; -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.ArraySet; -import android.util.SparseArray; - -import java.security.PublicKey; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -/** - * The last state of a package during parsing/install before it is available in - * {@link com.android.server.pm.PackageManagerService#mPackages}. - * - * It is the responsibility of the caller to understand what data is available at what step of the - * parsing or install process. - * - * TODO(b/135203078): Nullability annotations - * TODO(b/135203078): Remove get/setAppInfo differences - * - * @hide - */ -public interface AndroidPackage extends Parcelable { - - /** - * This will eventually be removed. Avoid calling this at all costs. - */ - @Deprecated - AndroidPackageWrite mutate(); - - boolean canHaveOatDir(); - - boolean cantSaveState(); - - List<String> getAdoptPermissions(); - - List<String> getAllCodePaths(); - - List<String> getAllCodePathsExcludingResourceOnly(); - - String getAppComponentFactory(); - - /** - * TODO(b/135203078): Use non-AppInfo method - * @deprecated use {@link #getClassLoaderName()} - */ - @Deprecated - String getAppInfoClassLoaderName(); - - /** - * TODO(b/135203078): Use non-AppInfo method - * @deprecated use {@link #getCodePath()} - */ - @Deprecated - String getAppInfoCodePath(); - - /** - * TODO(b/135203078): Use non-AppInfo method - * @deprecated use {@link #getName()} - */ - @Deprecated - String getAppInfoName(); - - /** - * TODO(b/135203078): Use non-AppInfo method - * @deprecated use {@link #getPackageName()} - */ - @Deprecated - String getAppInfoPackageName(); - - /** - * TODO(b/135203078): Use non-AppInfo method - * @deprecated use {@link #getProcessName()} - */ - @Deprecated - String getAppInfoProcessName(); - - /** - * TODO(b/135203078): Use non-AppInfo method - * @deprecated use {@link #getCodePath()} - */ - @Deprecated - String getAppInfoResourcePath(); - - Bundle getAppMetaData(); - - /** - * TODO(b/135203078): Use non-AppInfo method - * @deprecated use {@link #getVolumeUuid()} - */ - @Deprecated - String getApplicationInfoVolumeUuid(); - - String getBackupAgentName(); - - int getBanner(); - - String getBaseCodePath(); - - int getBaseRevisionCode(); - - int getCategory(); - - String getClassLoaderName(); - - String getClassName(); - - String getCodePath(); - - int getCompatibleWidthLimitDp(); - - int getCompileSdkVersion(); - - String getCompileSdkVersionCodeName(); - - @Nullable - List<ConfigurationInfo> getConfigPreferences(); - - String getCpuAbiOverride(); - - String getCredentialProtectedDataDir(); - - String getDataDir(); - - int getDescriptionRes(); - - String getDeviceProtectedDataDir(); - - List<FeatureGroupInfo> getFeatureGroups(); - - int getFlags(); - - int getFullBackupContent(); - - int getHiddenApiEnforcementPolicy(); - - int getIcon(); - - int getIconRes(); - - List<String> getImplicitPermissions(); - - int getInstallLocation(); - - Map<String, ArraySet<PublicKey>> getKeySetMapping(); - - int getLabelRes(); - - int getLargestWidthLimitDp(); - - long[] getLastPackageUsageTimeInMills(); - - long getLatestForegroundPackageUseTimeInMills(); - - long getLatestPackageUseTimeInMills(); - - List<String> getLibraryNames(); - - int getLogo(); - - long getLongVersionCode(); - - String getManageSpaceActivityName(); - - String getManifestPackageName(); - - float getMaxAspectRatio(); - - Bundle getMetaData(); // TODO(b/135203078): Make all the Bundles immutable - - float getMinAspectRatio(); - - int getMinSdkVersion(); - - String getName(); - - String getNativeLibraryDir(); - - String getNativeLibraryRootDir(); - - int getNetworkSecurityConfigRes(); - - CharSequence getNonLocalizedLabel(); - - @Nullable - List<String> getOriginalPackages(); - - String getOverlayCategory(); - - int getOverlayPriority(); - - String getOverlayTarget(); - - String getOverlayTargetName(); - - // TODO(b/135203078): Does this and getAppInfoPackageName have to be separate methods? - // The refactor makes them the same value with no known consequences, so should be redundant. - String getPackageName(); - - @Nullable - List<ParsedActivity> getActivities(); - - @Nullable - List<ParsedInstrumentation> getInstrumentations(); - - @Nullable - List<ParsedPermissionGroup> getPermissionGroups(); - - @Nullable - List<ParsedPermission> getPermissions(); - - @Nullable - List<ParsedProvider> getProviders(); - - @Nullable - List<ParsedActivity> getReceivers(); - - @Nullable - List<ParsedService> getServices(); - - String getPermission(); - - @Nullable - List<ParsedActivityIntentInfo> getPreferredActivityFilters(); - - int getPreferredOrder(); - - String getPrimaryCpuAbi(); - - int getPrivateFlags(); - - String getProcessName(); - - @Nullable - List<String> getProtectedBroadcasts(); - - String getPublicSourceDir(); - - List<Intent> getQueriesIntents(); - - List<String> getQueriesPackages(); - - String getRealPackage(); - - // TODO(b/135203078): Rename to getRequiredFeatures? Somewhat ambigious whether "Req" is - // required or requested. - @Nullable - List<FeatureInfo> getReqFeatures(); - - List<String> getRequestedPermissions(); - - String getRequiredAccountType(); - - int getRequiresSmallestWidthDp(); - - byte[] getRestrictUpdateHash(); - - String getRestrictedAccountType(); - - int getRoundIconRes(); - - String getScanPublicSourceDir(); - - String getScanSourceDir(); - - String getSeInfo(); - - String getSeInfoUser(); - - String getSecondaryCpuAbi(); - - String getSecondaryNativeLibraryDir(); - - String getSharedUserId(); - - int getSharedUserLabel(); - - PackageParser.SigningDetails getSigningDetails(); - - String[] getSplitClassLoaderNames(); - - @Nullable - String[] getSplitCodePaths(); - - @Nullable - SparseArray<int[]> getSplitDependencies(); - - int[] getSplitFlags(); - - String[] getSplitNames(); - - String[] getSplitPublicSourceDirs(); - - int[] getSplitRevisionCodes(); - - String getStaticSharedLibName(); - - long getStaticSharedLibVersion(); - - // TODO(b/135203078): Return String directly - UUID getStorageUuid(); - - int getTargetSandboxVersion(); - - int getTargetSdkVersion(); - - String getTaskAffinity(); - - int getTheme(); - - int getUiOptions(); - - int getUid(); - - Set<String> getUpgradeKeySets(); - - @Nullable - List<String> getUsesLibraries(); - - @Nullable - String[] getUsesLibraryFiles(); - - List<SharedLibraryInfo> getUsesLibraryInfos(); - - @Nullable - List<String> getUsesOptionalLibraries(); - - @Nullable - List<String> getUsesStaticLibraries(); - - @Nullable - String[][] getUsesStaticLibrariesCertDigests(); - - @Nullable - long[] getUsesStaticLibrariesVersions(); - - int getVersionCode(); - - int getVersionCodeMajor(); - - String getVersionName(); - - String getVolumeUuid(); - - String getZygotePreloadName(); - - boolean hasComponentClassName(String className); - - // App Info - - boolean hasRequestedLegacyExternalStorage(); - - boolean isBaseHardwareAccelerated(); - - boolean isCoreApp(); - - boolean isDefaultToDeviceProtectedStorage(); - - boolean isDirectBootAware(); - - boolean isEmbeddedDexUsed(); - - boolean isEnabled(); - - boolean isEncryptionAware(); - - boolean isExternal(); - - boolean isForceQueryable(); - - boolean isForwardLocked(); - - boolean isHiddenUntilInstalled(); - - boolean isInstantApp(); - - boolean isInternal(); - - boolean isLibrary(); - - // TODO(b/135203078): Should probably be in a utility class - boolean isMatch(int flags); - - boolean isNativeLibraryRootRequiresIsa(); - - boolean isOem(); - - boolean isOverlayIsStatic(); - - boolean isPrivileged(); - - boolean isProduct(); - - boolean isProfileableByShell(); - - boolean isRequiredForAllUsers(); - - boolean isStaticSharedLibrary(); - - boolean isStub(); - - boolean isSystem(); // TODO(b/135203078): Collapse with isSystemApp, should be exactly the same. - - boolean isSystemApp(); - - boolean isSystemExt(); - - boolean isUpdatedSystemApp(); - - boolean isUse32BitAbi(); - - boolean isVendor(); - - boolean isVisibleToInstantApps(); - - List<String> makeListAllCodePaths(); // TODO(b/135203078): Collapse with getAllCodePaths - - boolean requestsIsolatedSplitLoading(); - - ApplicationInfo toAppInfo(); - - Creator<PackageImpl> CREATOR = new Creator<PackageImpl>() { - @Override - public PackageImpl createFromParcel(Parcel source) { - return new PackageImpl(source); - } - - @Override - public PackageImpl[] newArray(int size) { - return new PackageImpl[size]; - } - }; -} diff --git a/core/java/android/content/pm/parsing/AndroidPackageWrite.java b/core/java/android/content/pm/parsing/AndroidPackageWrite.java deleted file mode 100644 index b7595d2dd710..000000000000 --- a/core/java/android/content/pm/parsing/AndroidPackageWrite.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package android.content.pm.parsing; - -import android.annotation.Nullable; -import android.content.pm.PackageParser; -import android.content.pm.SharedLibraryInfo; - -import java.util.List; - -/** - * Contains remaining mutable fields after package parsing has completed. - * - * Most are state that can probably be tracked outside of the AndroidPackage object. New methods - * should never be added to this interface. - * - * TODO(b/135203078): Remove entirely - * - * @deprecated the eventual goal is that the object returned from parsing represents exactly what - * was parsed from the APK, and so further mutation should be disallowed, - * with any state being stored in another class - * - * @hide - */ -@Deprecated -public interface AndroidPackageWrite extends AndroidPackage { - - AndroidPackageWrite setUsesLibraryFiles(@Nullable String[] usesLibraryFiles); - - // TODO(b/135203078): Remove or use a non-system wide representation of the shared libraries; - // this doesn't represent what was parsed from the APK - AndroidPackageWrite setUsesLibraryInfos(@Nullable List<SharedLibraryInfo> usesLibraryInfos); - - AndroidPackageWrite setHiddenUntilInstalled(boolean hidden); - - AndroidPackageWrite setUpdatedSystemApp(boolean updatedSystemApp); - - AndroidPackageWrite setLastPackageUsageTimeInMills(int reason, long time); - - AndroidPackageWrite setPrimaryCpuAbi(String primaryCpuAbi); - - AndroidPackageWrite setSeInfo(String seInfo); - - AndroidPackageWrite setSigningDetails(PackageParser.SigningDetails signingDetails); -} diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java deleted file mode 100644 index ac2e373f000d..000000000000 --- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java +++ /dev/null @@ -1,428 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package android.content.pm.parsing; - -import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; - -import android.annotation.UnsupportedAppUsage; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageParser; -import android.content.pm.VerifierInfo; -import android.content.res.ApkAssets; -import android.content.res.XmlResourceParser; -import android.os.Trace; -import android.util.ArrayMap; -import android.util.AttributeSet; -import android.util.Pair; -import android.util.Slog; - -import com.android.internal.R; -import com.android.internal.util.ArrayUtils; - -import libcore.io.IoUtils; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.IOException; -import java.security.PublicKey; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** @hide */ -public class ApkLiteParseUtils { - - private static final String TAG = ApkParseUtils.TAG; - - // TODO(b/135203078): Consolidate constants - private static final int DEFAULT_MIN_SDK_VERSION = 1; - private static final int DEFAULT_TARGET_SDK_VERSION = 0; - - private static final int PARSE_DEFAULT_INSTALL_LOCATION = - PackageInfo.INSTALL_LOCATION_UNSPECIFIED; - - /** - * Parse only lightweight details about the package at the given location. - * Automatically detects if the package is a monolithic style (single APK - * file) or cluster style (directory of APKs). - * <p> - * This performs sanity checking on cluster style packages, such as - * requiring identical package name and version codes, a single base APK, - * and unique split names. - * - * @see PackageParser#parsePackage(File, int) - */ - @UnsupportedAppUsage - public static PackageParser.PackageLite parsePackageLite(File packageFile, int flags) - throws PackageParser.PackageParserException { - if (packageFile.isDirectory()) { - return parseClusterPackageLite(packageFile, flags); - } else { - return parseMonolithicPackageLite(packageFile, flags); - } - } - - public static PackageParser.PackageLite parseMonolithicPackageLite(File packageFile, int flags) - throws PackageParser.PackageParserException { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parseApkLite"); - final PackageParser.ApkLite baseApk = parseApkLite(packageFile, flags); - final String packagePath = packageFile.getAbsolutePath(); - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - return new PackageParser.PackageLite(packagePath, baseApk, null, null, null, null, - null, null); - } - - public static PackageParser.PackageLite parseClusterPackageLite(File packageDir, int flags) - throws PackageParser.PackageParserException { - final File[] files = packageDir.listFiles(); - if (ArrayUtils.isEmpty(files)) { - throw new PackageParser.PackageParserException( - PackageManager.INSTALL_PARSE_FAILED_NOT_APK, "No packages found in split"); - } - - String packageName = null; - int versionCode = 0; - - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parseApkLite"); - final ArrayMap<String, PackageParser.ApkLite> apks = new ArrayMap<>(); - for (File file : files) { - if (PackageParser.isApkFile(file)) { - final PackageParser.ApkLite lite = parseApkLite(file, flags); - - // Assert that all package names and version codes are - // consistent with the first one we encounter. - if (packageName == null) { - packageName = lite.packageName; - versionCode = lite.versionCode; - } else { - if (!packageName.equals(lite.packageName)) { - throw new PackageParser.PackageParserException( - PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST, - "Inconsistent package " + lite.packageName + " in " + file - + "; expected " + packageName); - } - if (versionCode != lite.versionCode) { - throw new PackageParser.PackageParserException( - PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST, - "Inconsistent version " + lite.versionCode + " in " + file - + "; expected " + versionCode); - } - } - - // Assert that each split is defined only oncuses-static-libe - if (apks.put(lite.splitName, lite) != null) { - throw new PackageParser.PackageParserException( - PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST, - "Split name " + lite.splitName - + " defined more than once; most recent was " + file); - } - } - } - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - - final PackageParser.ApkLite baseApk = apks.remove(null); - if (baseApk == null) { - throw new PackageParser.PackageParserException( - PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST, - "Missing base APK in " + packageDir); - } - - // Always apply deterministic ordering based on splitName - final int size = apks.size(); - - String[] splitNames = null; - boolean[] isFeatureSplits = null; - String[] usesSplitNames = null; - String[] configForSplits = null; - String[] splitCodePaths = null; - int[] splitRevisionCodes = null; - if (size > 0) { - splitNames = new String[size]; - isFeatureSplits = new boolean[size]; - usesSplitNames = new String[size]; - configForSplits = new String[size]; - splitCodePaths = new String[size]; - splitRevisionCodes = new int[size]; - - splitNames = apks.keySet().toArray(splitNames); - Arrays.sort(splitNames, PackageParser.sSplitNameComparator); - - for (int i = 0; i < size; i++) { - final PackageParser.ApkLite apk = apks.get(splitNames[i]); - usesSplitNames[i] = apk.usesSplitName; - isFeatureSplits[i] = apk.isFeatureSplit; - configForSplits[i] = apk.configForSplit; - splitCodePaths[i] = apk.codePath; - splitRevisionCodes[i] = apk.revisionCode; - } - } - - final String codePath = packageDir.getAbsolutePath(); - return new PackageParser.PackageLite(codePath, baseApk, splitNames, isFeatureSplits, - usesSplitNames, configForSplits, splitCodePaths, splitRevisionCodes); - } - - /** - * Utility method that retrieves lightweight details about a single APK - * file, including package name, split name, and install location. - * - * @param apkFile path to a single APK - * @param flags optional parse flags, such as - * {@link PackageParser#PARSE_COLLECT_CERTIFICATES} - */ - public static PackageParser.ApkLite parseApkLite(File apkFile, int flags) - throws PackageParser.PackageParserException { - return parseApkLiteInner(apkFile, null, null, flags); - } - - /** - * Utility method that retrieves lightweight details about a single APK - * file, including package name, split name, and install location. - * - * @param fd already open file descriptor of an apk file - * @param debugPathName arbitrary text name for this file, for debug output - * @param flags optional parse flags, such as - * {@link PackageParser#PARSE_COLLECT_CERTIFICATES} - */ - public static PackageParser.ApkLite parseApkLite(FileDescriptor fd, String debugPathName, - int flags) throws PackageParser.PackageParserException { - return parseApkLiteInner(null, fd, debugPathName, flags); - } - - private static PackageParser.ApkLite parseApkLiteInner(File apkFile, FileDescriptor fd, - String debugPathName, int flags) throws PackageParser.PackageParserException { - final String apkPath = fd != null ? debugPathName : apkFile.getAbsolutePath(); - - XmlResourceParser parser = null; - ApkAssets apkAssets = null; - try { - try { - apkAssets = fd != null - ? ApkAssets.loadFromFd(fd, debugPathName, false, false) - : ApkAssets.loadFromPath(apkPath); - } catch (IOException e) { - throw new PackageParser.PackageParserException( - PackageManager.INSTALL_PARSE_FAILED_NOT_APK, - "Failed to parse " + apkPath, e); - } - - parser = apkAssets.openXml(PackageParser.ANDROID_MANIFEST_FILENAME); - - final PackageParser.SigningDetails signingDetails; - if ((flags & PackageParser.PARSE_COLLECT_CERTIFICATES) != 0) { - final boolean skipVerify = (flags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0; - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); - try { - signingDetails = - ApkParseUtils.collectCertificates(apkFile.getAbsolutePath(), skipVerify, - false, PackageParser.SigningDetails.UNKNOWN); - } finally { - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - } - } else { - signingDetails = PackageParser.SigningDetails.UNKNOWN; - } - - final AttributeSet attrs = parser; - return parseApkLite(apkPath, parser, attrs, signingDetails); - - } catch (XmlPullParserException | IOException | RuntimeException e) { - Slog.w(TAG, "Failed to parse " + apkPath, e); - throw new PackageParser.PackageParserException( - PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION, - "Failed to parse " + apkPath, e); - } finally { - IoUtils.closeQuietly(parser); - if (apkAssets != null) { - try { - apkAssets.close(); - } catch (Throwable ignored) { - } - } - // TODO(b/72056911): Implement AutoCloseable on ApkAssets. - } - } - - private static PackageParser.ApkLite parseApkLite( - String codePath, XmlPullParser parser, AttributeSet attrs, - PackageParser.SigningDetails signingDetails) - throws IOException, XmlPullParserException, PackageParser.PackageParserException { - final Pair<String, String> packageSplit = PackageParser.parsePackageSplitNames( - parser, attrs); - - int installLocation = PARSE_DEFAULT_INSTALL_LOCATION; - int versionCode = 0; - int versionCodeMajor = 0; - int targetSdkVersion = DEFAULT_TARGET_SDK_VERSION; - int minSdkVersion = DEFAULT_MIN_SDK_VERSION; - int revisionCode = 0; - boolean coreApp = false; - boolean debuggable = false; - boolean multiArch = false; - boolean use32bitAbi = false; - boolean extractNativeLibs = true; - boolean isolatedSplits = false; - boolean isFeatureSplit = false; - boolean isSplitRequired = false; - boolean useEmbeddedDex = false; - String configForSplit = null; - String usesSplitName = null; - - for (int i = 0; i < attrs.getAttributeCount(); i++) { - final String attr = attrs.getAttributeName(i); - switch (attr) { - case "installLocation": - installLocation = attrs.getAttributeIntValue(i, - PARSE_DEFAULT_INSTALL_LOCATION); - break; - case "versionCode": - versionCode = attrs.getAttributeIntValue(i, 0); - break; - case "versionCodeMajor": - versionCodeMajor = attrs.getAttributeIntValue(i, 0); - break; - case "revisionCode": - revisionCode = attrs.getAttributeIntValue(i, 0); - break; - case "coreApp": - coreApp = attrs.getAttributeBooleanValue(i, false); - break; - case "isolatedSplits": - isolatedSplits = attrs.getAttributeBooleanValue(i, false); - break; - case "configForSplit": - configForSplit = attrs.getAttributeValue(i); - break; - case "isFeatureSplit": - isFeatureSplit = attrs.getAttributeBooleanValue(i, false); - break; - case "isSplitRequired": - isSplitRequired = attrs.getAttributeBooleanValue(i, false); - break; - } - } - - // Only search the tree when the tag is the direct child of <manifest> tag - int type; - final int searchDepth = parser.getDepth() + 1; - - final List<VerifierInfo> verifiers = new ArrayList<>(); - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() >= searchDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - if (parser.getDepth() != searchDepth) { - continue; - } - - if (PackageParser.TAG_PACKAGE_VERIFIER.equals(parser.getName())) { - final VerifierInfo verifier = parseVerifier(attrs); - if (verifier != null) { - verifiers.add(verifier); - } - } else if (PackageParser.TAG_APPLICATION.equals(parser.getName())) { - for (int i = 0; i < attrs.getAttributeCount(); ++i) { - final String attr = attrs.getAttributeName(i); - switch (attr) { - case "debuggable": - debuggable = attrs.getAttributeBooleanValue(i, false); - break; - case "multiArch": - multiArch = attrs.getAttributeBooleanValue(i, false); - break; - case "use32bitAbi": - use32bitAbi = attrs.getAttributeBooleanValue(i, false); - break; - case "extractNativeLibs": - extractNativeLibs = attrs.getAttributeBooleanValue(i, true); - break; - case "useEmbeddedDex": - useEmbeddedDex = attrs.getAttributeBooleanValue(i, false); - break; - } - } - } else if (PackageParser.TAG_USES_SPLIT.equals(parser.getName())) { - if (usesSplitName != null) { - Slog.w(TAG, "Only one <uses-split> permitted. Ignoring others."); - continue; - } - - usesSplitName = attrs.getAttributeValue(PackageParser.ANDROID_RESOURCES, "name"); - if (usesSplitName == null) { - throw new PackageParser.PackageParserException( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "<uses-split> tag requires 'android:name' attribute"); - } - } else if (PackageParser.TAG_USES_SDK.equals(parser.getName())) { - for (int i = 0; i < attrs.getAttributeCount(); ++i) { - final String attr = attrs.getAttributeName(i); - if ("targetSdkVersion".equals(attr)) { - targetSdkVersion = attrs.getAttributeIntValue(i, - DEFAULT_TARGET_SDK_VERSION); - } - if ("minSdkVersion".equals(attr)) { - minSdkVersion = attrs.getAttributeIntValue(i, DEFAULT_MIN_SDK_VERSION); - } - } - } - } - - return new PackageParser.ApkLite(codePath, packageSplit.first, packageSplit.second, - isFeatureSplit, configForSplit, usesSplitName, isSplitRequired, versionCode, - versionCodeMajor, revisionCode, installLocation, verifiers, signingDetails, - coreApp, debuggable, multiArch, use32bitAbi, useEmbeddedDex, extractNativeLibs, - isolatedSplits, minSdkVersion, targetSdkVersion); - } - - public static VerifierInfo parseVerifier(AttributeSet attrs) { - String packageName = null; - String encodedPublicKey = null; - - final int attrCount = attrs.getAttributeCount(); - for (int i = 0; i < attrCount; i++) { - final int attrResId = attrs.getAttributeNameResource(i); - switch (attrResId) { - case R.attr.name: - packageName = attrs.getAttributeValue(i); - break; - - case R.attr.publicKey: - encodedPublicKey = attrs.getAttributeValue(i); - break; - } - } - - if (packageName == null || packageName.length() == 0) { - Slog.i(TAG, "verifier package name was null; skipping"); - return null; - } - - final PublicKey publicKey = PackageParser.parsePublicKey(encodedPublicKey); - if (publicKey == null) { - Slog.i(TAG, "Unable to parse verifier public key for " + packageName); - return null; - } - - return new VerifierInfo(packageName, publicKey); - } -} diff --git a/core/java/android/content/pm/parsing/ApkParseUtils.java b/core/java/android/content/pm/parsing/ApkParseUtils.java deleted file mode 100644 index 0f35b27de7e2..000000000000 --- a/core/java/android/content/pm/parsing/ApkParseUtils.java +++ /dev/null @@ -1,3197 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package android.content.pm.parsing; - -import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE; -import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE; -import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; -import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; -import static android.content.pm.PackageManager.FEATURE_WATCH; -import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST; -import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; -import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; -import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NOT_APK; -import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION; -import static android.os.Build.VERSION_CODES.O; -import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; -import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.ActivityTaskManager; -import android.app.ActivityThread; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.ConfigurationInfo; -import android.content.pm.FeatureGroupInfo; -import android.content.pm.FeatureInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageItemInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageParser; -import android.content.pm.PackageParser.PackageParserException; -import android.content.pm.PackageParser.SigningDetails; -import android.content.pm.Signature; -import android.content.pm.permission.SplitPermissionInfoParcelable; -import android.content.pm.split.DefaultSplitAssetLoader; -import android.content.pm.split.SplitAssetDependencyLoader; -import android.content.pm.split.SplitAssetLoader; -import android.content.res.AssetManager; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.FileUtils; -import android.os.RemoteException; -import android.os.SystemProperties; -import android.os.Trace; -import android.text.TextUtils; -import android.util.ArrayMap; -import android.util.ArraySet; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.util.Pair; -import android.util.Slog; -import android.util.SparseArray; -import android.util.TypedValue; -import android.util.apk.ApkSignatureVerifier; - -import com.android.internal.R; -import com.android.internal.os.ClassLoaderFactory; -import com.android.internal.util.ArrayUtils; -import com.android.internal.util.XmlUtils; - -import libcore.io.IoUtils; -import libcore.util.EmptyArray; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.File; -import java.io.IOException; -import java.security.PublicKey; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Set; - -/** @hide */ -public class ApkParseUtils { - - // TODO(b/135203078): Consolidate log tags - static final String TAG = "PackageParsing"; - - /** - * Parse the package at the given location. Automatically detects if the - * package is a monolithic style (single APK file) or cluster style - * (directory of APKs). - * <p> - * This performs sanity checking on cluster style packages, such as - * requiring identical package name and version codes, a single base APK, - * and unique split names. - * <p> - * Note that this <em>does not</em> perform signature verification; that - * must be done separately in {@link #collectCertificates(ParsedPackage, boolean)}. - * - * If {@code useCaches} is true, the package parser might return a cached - * result from a previous parse of the same {@code packageFile} with the same - * {@code flags}. Note that this method does not check whether {@code packageFile} - * has changed since the last parse, it's up to callers to do so. - * - * @see PackageParser#parsePackageLite(File, int) - */ - public static ParsingPackage parsePackage( - ParseInput parseInput, - String[] separateProcesses, - PackageParser.Callback callback, - DisplayMetrics displayMetrics, - boolean onlyCoreApps, - File packageFile, - int flags - ) throws PackageParserException { - if (packageFile.isDirectory()) { - return parseClusterPackage(parseInput, separateProcesses, callback, displayMetrics, - onlyCoreApps, packageFile, flags); - } else { - return parseMonolithicPackage(parseInput, separateProcesses, callback, displayMetrics, - onlyCoreApps, packageFile, flags); - } - } - - /** - * Parse all APKs contained in the given directory, treating them as a - * single package. This also performs sanity checking, such as requiring - * identical package name and version codes, a single base APK, and unique - * split names. - * <p> - * Note that this <em>does not</em> perform signature verification; that - * must be done separately in {@link #collectCertificates(ParsedPackage, boolean)}. - */ - private static ParsingPackage parseClusterPackage( - ParseInput parseInput, - String[] separateProcesses, - PackageParser.Callback callback, - DisplayMetrics displayMetrics, - boolean onlyCoreApps, - File packageDir, - int flags - ) throws PackageParserException { - final PackageParser.PackageLite lite = ApkLiteParseUtils.parseClusterPackageLite(packageDir, - 0); - if (onlyCoreApps && !lite.coreApp) { - throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Not a coreApp: " + packageDir); - } - - // Build the split dependency tree. - SparseArray<int[]> splitDependencies = null; - final SplitAssetLoader assetLoader; - if (lite.isolatedSplits && !ArrayUtils.isEmpty(lite.splitNames)) { - try { - splitDependencies = SplitAssetDependencyLoader.createDependenciesFromPackage(lite); - assetLoader = new SplitAssetDependencyLoader(lite, splitDependencies, flags); - } catch (SplitAssetDependencyLoader.IllegalDependencyException e) { - throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST, e.getMessage()); - } - } else { - assetLoader = new DefaultSplitAssetLoader(lite, flags); - } - - try { - final AssetManager assets = assetLoader.getBaseAssetManager(); - final File baseApk = new File(lite.baseCodePath); - ParsingPackage parsingPackage = parseBaseApk(parseInput, separateProcesses, callback, - displayMetrics, baseApk, assets, flags); - if (parsingPackage == null) { - throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK, - "Failed to parse base APK: " + baseApk); - } - - if (!ArrayUtils.isEmpty(lite.splitNames)) { - parsingPackage.asSplit( - lite.splitNames, - lite.splitCodePaths, - lite.splitRevisionCodes, - splitDependencies - ); - final int num = lite.splitNames.length; - - for (int i = 0; i < num; i++) { - final AssetManager splitAssets = assetLoader.getSplitAssetManager(i); - parseSplitApk(parseInput, displayMetrics, separateProcesses, parsingPackage, i, - splitAssets, flags); - } - } - - return parsingPackage.setCodePath(packageDir.getCanonicalPath()) - .setUse32BitAbi(lite.use32bitAbi); - } catch (IOException e) { - throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION, - "Failed to get path: " + lite.baseCodePath, e); - } finally { - IoUtils.closeQuietly(assetLoader); - } - } - - /** - * Parse the given APK file, treating it as as a single monolithic package. - * <p> - * Note that this <em>does not</em> perform signature verification; that - * must be done separately in {@link #collectCertificates(AndroidPackage, boolean)}. - */ - public static ParsingPackage parseMonolithicPackage( - ParseInput parseInput, - String[] separateProcesses, - PackageParser.Callback callback, - DisplayMetrics displayMetrics, - boolean onlyCoreApps, - File apkFile, - int flags - ) throws PackageParserException { - final PackageParser.PackageLite lite = ApkLiteParseUtils.parseMonolithicPackageLite(apkFile, - flags); - if (onlyCoreApps) { - if (!lite.coreApp) { - throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Not a coreApp: " + apkFile); - } - } - - final SplitAssetLoader assetLoader = new DefaultSplitAssetLoader(lite, flags); - try { - return parseBaseApk(parseInput, separateProcesses, callback, - displayMetrics, apkFile, assetLoader.getBaseAssetManager(), flags) - .setCodePath(apkFile.getCanonicalPath()) - .setUse32BitAbi(lite.use32bitAbi); - } catch (IOException e) { - throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION, - "Failed to get path: " + apkFile, e); - } finally { - IoUtils.closeQuietly(assetLoader); - } - } - - private static ParsingPackage parseBaseApk( - ParseInput parseInput, - String[] separateProcesses, - PackageParser.Callback callback, - DisplayMetrics displayMetrics, - File apkFile, - AssetManager assets, - int flags - ) throws PackageParserException { - final String apkPath = apkFile.getAbsolutePath(); - - String volumeUuid = null; - if (apkPath.startsWith(PackageParser.MNT_EXPAND)) { - final int end = apkPath.indexOf('/', PackageParser.MNT_EXPAND.length()); - volumeUuid = apkPath.substring(PackageParser.MNT_EXPAND.length(), end); - } - - if (PackageParser.DEBUG_JAR) Slog.d(TAG, "Scanning base APK: " + apkPath); - - XmlResourceParser parser = null; - try { - final int cookie = assets.findCookieForPath(apkPath); - if (cookie == 0) { - throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST, - "Failed adding asset path: " + apkPath); - } - parser = assets.openXmlResourceParser(cookie, PackageParser.ANDROID_MANIFEST_FILENAME); - final Resources res = new Resources(assets, displayMetrics, null); - - ParseResult result = parseBaseApk(parseInput, separateProcesses, callback, apkPath, res, - parser, flags); - if (!result.isSuccess()) { - throw new PackageParserException(result.getParseError(), - apkPath + " (at " + parser.getPositionDescription() + "): " - + result.getErrorMessage()); - } - - return result.getResultAndNull() - .setVolumeUuid(volumeUuid) - .setApplicationVolumeUuid(volumeUuid) - .setSigningDetails(SigningDetails.UNKNOWN); - } catch (PackageParserException e) { - throw e; - } catch (Exception e) { - throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION, - "Failed to read manifest from " + apkPath, e); - } finally { - IoUtils.closeQuietly(parser); - } - } - - private static void parseSplitApk( - ParseInput parseInput, - DisplayMetrics displayMetrics, - String[] separateProcesses, - ParsingPackage parsingPackage, - int splitIndex, - AssetManager assets, - int flags - ) throws PackageParserException { - final String apkPath = parsingPackage.getSplitCodePaths()[splitIndex]; - - if (PackageParser.DEBUG_JAR) Slog.d(TAG, "Scanning split APK: " + apkPath); - - final Resources res; - XmlResourceParser parser = null; - try { - // This must always succeed, as the path has been added to the AssetManager before. - final int cookie = assets.findCookieForPath(apkPath); - if (cookie == 0) { - throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST, - "Failed adding asset path: " + apkPath); - } - - parser = assets.openXmlResourceParser(cookie, PackageParser.ANDROID_MANIFEST_FILENAME); - res = new Resources(assets, displayMetrics, null); - - final String[] outError = new String[1]; - ParseResult parseResult = parseSplitApk(parseInput, separateProcesses, parsingPackage, - res, parser, flags, splitIndex, outError); - if (!parseResult.isSuccess()) { - throw new PackageParserException(parseResult.getParseError(), - apkPath + " (at " + parser.getPositionDescription() + "): " - + parseResult.getErrorMessage()); - } - } catch (PackageParserException e) { - throw e; - } catch (Exception e) { - throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION, - "Failed to read manifest from " + apkPath, e); - } finally { - IoUtils.closeQuietly(parser); - } - } - - /** - * Parse the manifest of a <em>base APK</em>. When adding new features you - * need to consider whether they should be supported by split APKs and child - * packages. - * - * @param apkPath The package apk file path - * @param res The resources from which to resolve values - * @param parser The manifest parser - * @param flags Flags how to parse - * @return Parsed package or null on error. - */ - private static ParseResult parseBaseApk( - ParseInput parseInput, - String[] separateProcesses, - PackageParser.Callback callback, - String apkPath, - Resources res, - XmlResourceParser parser, - int flags - ) throws XmlPullParserException, IOException { - final String splitName; - final String pkgName; - - try { - Pair<String, String> packageSplit = PackageParser.parsePackageSplitNames(parser, - parser); - pkgName = packageSplit.first; - splitName = packageSplit.second; - - if (!TextUtils.isEmpty(splitName)) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, - "Expected base APK, but found split " + splitName - ); - } - } catch (PackageParserException e) { - return parseInput.error(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME); - } - - // TODO: Remove when manifest overlaying removed - if (callback != null) { - String[] overlayPaths = callback.getOverlayPaths(pkgName, apkPath); - if (overlayPaths != null && overlayPaths.length > 0) { - for (String overlayPath : overlayPaths) { - res.getAssets().addOverlayPath(overlayPath); - } - } - } - - TypedArray manifestArray = null; - - try { - manifestArray = res.obtainAttributes(parser, R.styleable.AndroidManifest); - - boolean isCoreApp = parser.getAttributeBooleanValue(null, "coreApp", false); - - ParsingPackage parsingPackage = PackageImpl.forParsing( - pkgName, - apkPath, - manifestArray, - isCoreApp - ); - - ParseResult result = parseBaseApkTags(parseInput, separateProcesses, callback, - parsingPackage, manifestArray, res, parser, flags); - if (!result.isSuccess()) { - return result; - } - - return parseInput.success(parsingPackage); - } finally { - if (manifestArray != null) { - manifestArray.recycle(); - } - } - } - - /** - * Parse the manifest of a <em>split APK</em>. - * <p> - * Note that split APKs have many more restrictions on what they're capable - * of doing, so many valid features of a base APK have been carefully - * omitted here. - * - * @param parsingPackage builder to fill - * @return false on failure - */ - private static ParseResult parseSplitApk( - ParseInput parseInput, - String[] separateProcesses, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser, - int flags, - int splitIndex, - String[] outError - ) throws XmlPullParserException, IOException, PackageParserException { - AttributeSet attrs = parser; - - // We parsed manifest tag earlier; just skip past it - PackageParser.parsePackageSplitNames(parser, attrs); - - int type; - - boolean foundApp = false; - - int outerDepth = parser.getDepth(); - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - String tagName = parser.getName(); - if (tagName.equals(PackageParser.TAG_APPLICATION)) { - if (foundApp) { - if (PackageParser.RIGID_PARSER) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "<manifest> has more than one <application>" - ); - } else { - Slog.w(TAG, "<manifest> has more than one <application>"); - XmlUtils.skipCurrentTag(parser); - continue; - } - } - - foundApp = true; - ParseResult parseResult = parseSplitApplication(parseInput, separateProcesses, - parsingPackage, res, - parser, flags, - splitIndex, outError); - if (!parseResult.isSuccess()) { - return parseResult; - } - - } else if (PackageParser.RIGID_PARSER) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Bad element under <manifest>: " + parser.getName() - ); - - } else { - Slog.w(TAG, "Unknown element under <manifest>: " + parser.getName() - + " at " + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - XmlUtils.skipCurrentTag(parser); - continue; - } - } - - if (!foundApp) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY, - "<manifest> does not contain an <application>" - ); - } - - return parseInput.success(parsingPackage); - } - - /** - * Parse the {@code application} XML tree at the current parse location in a - * <em>split APK</em> manifest. - * <p> - * Note that split APKs have many more restrictions on what they're capable - * of doing, so many valid features of a base APK have been carefully - * omitted here. - */ - private static ParseResult parseSplitApplication( - ParseInput parseInput, - String[] separateProcesses, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser, - int flags, - int splitIndex, - String[] outError - ) throws XmlPullParserException, IOException { - TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestApplication); - - parsingPackage.setSplitHasCode(splitIndex, sa.getBoolean( - R.styleable.AndroidManifestApplication_hasCode, true)); - - final String classLoaderName = sa.getString( - R.styleable.AndroidManifestApplication_classLoader); - if (classLoaderName == null || ClassLoaderFactory.isValidClassLoaderName(classLoaderName)) { - parsingPackage.setSplitClassLoaderName(splitIndex, classLoaderName); - } else { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Invalid class loader name: " + classLoaderName - ); - } - - final int innerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - ComponentParseUtils.ParsedComponent parsedComponent = null; - - String tagName = parser.getName(); - switch (tagName) { - case "activity": - ComponentParseUtils.ParsedActivity activity = - ComponentParseUtils.parseActivity(separateProcesses, - parsingPackage, - res, parser, flags, - outError, - false, - parsingPackage.isBaseHardwareAccelerated()); - if (activity == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - parsingPackage.addActivity(activity); - parsedComponent = activity; - break; - case "receiver": - activity = ComponentParseUtils.parseActivity( - separateProcesses, parsingPackage, - res, parser, flags, outError, - true, false); - if (activity == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - parsingPackage.addReceiver(activity); - parsedComponent = activity; - break; - case "service": - ComponentParseUtils.ParsedService s = ComponentParseUtils.parseService( - separateProcesses, - parsingPackage, - res, parser, flags, outError - ); - if (s == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - parsingPackage.addService(s); - parsedComponent = s; - break; - case "provider": - ComponentParseUtils.ParsedProvider p = ComponentParseUtils.parseProvider( - separateProcesses, - parsingPackage, - res, parser, flags, outError); - if (p == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - parsingPackage.addProvider(p); - parsedComponent = p; - break; - case "activity-alias": - activity = ComponentParseUtils.parseActivityAlias( - parsingPackage, - res, - parser, - outError - ); - if (activity == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - parsingPackage.addActivity(activity); - parsedComponent = activity; - break; - case "meta-data": - // note: application meta-data is stored off to the side, so it can - // remain null in the primary copy (we like to avoid extra copies because - // it can be large) - Bundle appMetaData = parseMetaData(parsingPackage, res, parser, - parsingPackage.getAppMetaData(), - outError); - if (appMetaData == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - parsingPackage.setAppMetaData(appMetaData); - break; - case "uses-static-library": - ParseResult parseResult = parseUsesStaticLibrary(parseInput, parsingPackage, - res, parser); - if (!parseResult.isSuccess()) { - return parseResult; - } - - break; - case "uses-library": - sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesLibrary); - - // Note: don't allow this value to be a reference to a resource - // that may change. - String lname = sa.getNonResourceString( - R.styleable.AndroidManifestUsesLibrary_name); - boolean req = sa.getBoolean( - R.styleable.AndroidManifestUsesLibrary_required, true); - - sa.recycle(); - - if (lname != null) { - lname = lname.intern(); - if (req) { - // Upgrade to treat as stronger constraint - parsingPackage.addUsesLibrary(lname) - .removeUsesOptionalLibrary(lname); - } else { - // Ignore if someone already defined as required - if (!ArrayUtils.contains(parsingPackage.getUsesLibraries(), lname)) { - parsingPackage.addUsesOptionalLibrary(lname); - } - } - } - - XmlUtils.skipCurrentTag(parser); - break; - case "uses-package": - // Dependencies for app installers; we don't currently try to - // enforce this. - XmlUtils.skipCurrentTag(parser); - break; - default: - if (!PackageParser.RIGID_PARSER) { - Slog.w(TAG, "Unknown element under <application>: " + tagName - + " at " + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - XmlUtils.skipCurrentTag(parser); - continue; - } else { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Bad element under <application>: " + tagName - ); - } - } - - if (parsedComponent != null && parsedComponent.getSplitName() == null) { - // If the loaded component did not specify a split, inherit the split name - // based on the split it is defined in. - // This is used to later load the correct split when starting this - // component. - parsedComponent.setSplitName(parsingPackage.getSplitNames()[splitIndex]); - } - } - - return parseInput.success(parsingPackage); - } - - private static ParseResult parseBaseApkTags( - ParseInput parseInput, - String[] separateProcesses, - PackageParser.Callback callback, - ParsingPackage parsingPackage, - TypedArray manifestArray, - Resources res, - XmlResourceParser parser, - int flags - ) throws XmlPullParserException, IOException { - int type; - boolean foundApp = false; - - TypedArray sa = manifestArray; - - ParseResult sharedUserResult = parseSharedUser(parseInput, parsingPackage, sa); - if (!sharedUserResult.isSuccess()) { - return sharedUserResult; - } - - parseManifestAttributes(sa, parsingPackage, flags); - - int outerDepth = parser.getDepth(); - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - String tagName = parser.getName(); - - // All methods return a boolean, even if they can't fail. This can be enforced - // by making this final and not assigned, forcing the switch to assign success - // once in every branch. - final boolean success; - ParseResult parseResult = null; - - // TODO(b/135203078): Either use all booleans or all ParseResults - // TODO(b/135203078): Convert to instance methods to share variables - switch (tagName) { - case PackageParser.TAG_APPLICATION: - if (foundApp) { - if (PackageParser.RIGID_PARSER) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "<manifest> has more than one <application>" - ); - } else { - Slog.w(TAG, "<manifest> has more than one <application>"); - XmlUtils.skipCurrentTag(parser); - success = true; - } - } else { - foundApp = true; - parseResult = parseBaseApplication(parseInput, separateProcesses, - callback, - parsingPackage, res, parser, flags); - success = parseResult.isSuccess(); - } - break; - case PackageParser.TAG_OVERLAY: - parseResult = parseOverlay(parseInput, parsingPackage, res, parser); - success = parseResult.isSuccess(); - break; - case PackageParser.TAG_KEY_SETS: - parseResult = parseKeySets(parseInput, parsingPackage, res, parser); - success = parseResult.isSuccess(); - break; - case PackageParser.TAG_PERMISSION_GROUP: - parseResult = parsePermissionGroup(parseInput, parsingPackage, res, - parser); - success = parseResult.isSuccess(); - break; - case PackageParser.TAG_PERMISSION: - parseResult = parsePermission(parseInput, parsingPackage, res, parser); - success = parseResult.isSuccess(); - break; - case PackageParser.TAG_PERMISSION_TREE: - parseResult = parsePermissionTree(parseInput, parsingPackage, res, parser); - success = parseResult.isSuccess(); - break; - case PackageParser.TAG_USES_PERMISSION: - case PackageParser.TAG_USES_PERMISSION_SDK_M: - case PackageParser.TAG_USES_PERMISSION_SDK_23: - parseResult = parseUsesPermission(parseInput, parsingPackage, res, parser, - callback); - success = parseResult.isSuccess(); - break; - case PackageParser.TAG_USES_CONFIGURATION: - success = parseUsesConfiguration(parsingPackage, res, parser); - break; - case PackageParser.TAG_USES_FEATURE: - success = parseUsesFeature(parsingPackage, res, parser); - break; - case PackageParser.TAG_FEATURE_GROUP: - success = parseFeatureGroup(parsingPackage, res, parser); - break; - case PackageParser.TAG_USES_SDK: - parseResult = parseUsesSdk(parseInput, parsingPackage, res, parser); - success = parseResult.isSuccess(); - break; - case PackageParser.TAG_SUPPORT_SCREENS: - success = parseSupportScreens(parsingPackage, res, parser); - break; - case PackageParser.TAG_PROTECTED_BROADCAST: - success = parseProtectedBroadcast(parsingPackage, res, parser); - break; - case PackageParser.TAG_INSTRUMENTATION: - parseResult = parseInstrumentation(parseInput, parsingPackage, res, - parser); - success = parseResult.isSuccess(); - break; - case PackageParser.TAG_ORIGINAL_PACKAGE: - success = parseOriginalPackage(parsingPackage, res, parser); - break; - case PackageParser.TAG_ADOPT_PERMISSIONS: - success = parseAdoptPermissions(parsingPackage, res, parser); - break; - case PackageParser.TAG_USES_GL_TEXTURE: - case PackageParser.TAG_COMPATIBLE_SCREENS: - case PackageParser.TAG_SUPPORTS_INPUT: - case PackageParser.TAG_EAT_COMMENT: - // Just skip this tag - XmlUtils.skipCurrentTag(parser); - success = true; - break; - case PackageParser.TAG_RESTRICT_UPDATE: - success = parseRestrictUpdateHash(flags, parsingPackage, res, parser); - break; - case PackageParser.TAG_QUERIES: - parseResult = parseQueries(parseInput, parsingPackage, res, parser); - success = parseResult.isSuccess(); - break; - default: - parseResult = parseUnknownTag(parseInput, parsingPackage, parser); - success = parseResult.isSuccess(); - break; - } - - if (parseResult != null && !parseResult.isSuccess()) { - return parseResult; - } - - if (!success) { - return parseResult; - } - } - - if (!foundApp && ArrayUtils.size(parsingPackage.getInstrumentations()) == 0) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY, - "<manifest> does not contain an <application> or <instrumentation>" - ); - } - - convertNewPermissions(parsingPackage); - - convertSplitPermissions(parsingPackage); - - // At this point we can check if an application is not supporting densities and hence - // cannot be windowed / resized. Note that an SDK version of 0 is common for - // pre-Doughnut applications. - if (parsingPackage.usesCompatibilityMode()) { - adjustPackageToBeUnresizeableAndUnpipable(parsingPackage); - } - - return parseInput.success(parsingPackage); - } - - private static ParseResult parseUnknownTag( - ParseInput parseInput, - ParsingPackage parsingPackage, - XmlResourceParser parser - ) throws IOException, XmlPullParserException { - if (PackageParser.RIGID_PARSER) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Bad element under <manifest>: " + parser.getName() - ); - } else { - Slog.w(TAG, "Unknown element under <manifest>: " + parser.getName() - + " at " + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - XmlUtils.skipCurrentTag(parser); - return parseInput.success(parsingPackage); - } - } - - private static ParseResult parseSharedUser( - ParseInput parseInput, - ParsingPackage parsingPackage, - TypedArray manifestArray - ) { - String str = manifestArray.getNonConfigurationString( - R.styleable.AndroidManifest_sharedUserId, 0); - if (TextUtils.isEmpty(str)) { - return parseInput.success(parsingPackage); - } - - String nameError = validateName(str, true, true); - if (nameError != null && !"android".equals(parsingPackage.getPackageName())) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID, - "<manifest> specifies bad sharedUserId name \"" + str + "\": " - + nameError - ); - } - - int sharedUserLabel = manifestArray.getResourceId( - R.styleable.AndroidManifest_sharedUserLabel, 0); - parsingPackage.setSharedUserId(str.intern()) - .setSharedUserLabel(sharedUserLabel); - - return parseInput.success(parsingPackage); - } - - private static void parseManifestAttributes( - TypedArray manifestArray, - ParsingPackage parsingPackage, - int flags - ) { - int installLocation = manifestArray.getInteger(R.styleable.AndroidManifest_installLocation, - PackageParser.PARSE_DEFAULT_INSTALL_LOCATION); - - final int targetSandboxVersion = manifestArray.getInteger( - R.styleable.AndroidManifest_targetSandboxVersion, - PackageParser.PARSE_DEFAULT_TARGET_SANDBOX); - - parsingPackage.setInstallLocation(installLocation) - .setTargetSandboxVersion(targetSandboxVersion); - - /* Set the global "on SD card" flag */ - parsingPackage.setExternalStorage((flags & PackageParser.PARSE_EXTERNAL_STORAGE) != 0); - - parsingPackage.setIsolatedSplitLoading(manifestArray.getBoolean( - R.styleable.AndroidManifest_isolatedSplits, false)); - } - - private static ParseResult parseKeySets( - ParseInput parseInput, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws XmlPullParserException, IOException { - // we've encountered the 'key-sets' tag - // all the keys and keysets that we want must be defined here - // so we're going to iterate over the parser and pull out the things we want - int outerDepth = parser.getDepth(); - int currentKeySetDepth = -1; - int type; - String currentKeySet = null; - ArrayMap<String, PublicKey> publicKeys = new ArrayMap<>(); - ArraySet<String> upgradeKeySets = new ArraySet<>(); - ArrayMap<String, ArraySet<String>> definedKeySets = - new ArrayMap<>(); - ArraySet<String> improperKeySets = new ArraySet<>(); - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG) { - if (parser.getDepth() == currentKeySetDepth) { - currentKeySet = null; - currentKeySetDepth = -1; - } - continue; - } - String tagName = parser.getName(); - if (tagName.equals("key-set")) { - if (currentKeySet != null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Improperly nested 'key-set' tag at " + parser.getPositionDescription() - ); - } - final TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestKeySet); - final String keysetName = sa.getNonResourceString( - R.styleable.AndroidManifestKeySet_name); - definedKeySets.put(keysetName, new ArraySet<>()); - currentKeySet = keysetName; - currentKeySetDepth = parser.getDepth(); - sa.recycle(); - } else if (tagName.equals("public-key")) { - if (currentKeySet == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Improperly nested 'key-set' tag at " + parser.getPositionDescription() - ); - } - final TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestPublicKey); - final String publicKeyName = sa.getNonResourceString( - R.styleable.AndroidManifestPublicKey_name); - final String encodedKey = sa.getNonResourceString( - R.styleable.AndroidManifestPublicKey_value); - if (encodedKey == null && publicKeys.get(publicKeyName) == null) { - sa.recycle(); - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "'public-key' " + publicKeyName + " must define a public-key value" - + " on first use at " + parser.getPositionDescription() - ); - } else if (encodedKey != null) { - PublicKey currentKey = PackageParser.parsePublicKey(encodedKey); - if (currentKey == null) { - Slog.w(TAG, "No recognized valid key in 'public-key' tag at " - + parser.getPositionDescription() + " key-set " + currentKeySet - + " will not be added to the package's defined key-sets."); - sa.recycle(); - improperKeySets.add(currentKeySet); - XmlUtils.skipCurrentTag(parser); - continue; - } - if (publicKeys.get(publicKeyName) == null - || publicKeys.get(publicKeyName).equals(currentKey)) { - - /* public-key first definition, or matches old definition */ - publicKeys.put(publicKeyName, currentKey); - } else { - sa.recycle(); - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Value of 'public-key' " + publicKeyName - + " conflicts with previously defined value at " - + parser.getPositionDescription() - ); - } - } - definedKeySets.get(currentKeySet).add(publicKeyName); - sa.recycle(); - XmlUtils.skipCurrentTag(parser); - } else if (tagName.equals("upgrade-key-set")) { - final TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestUpgradeKeySet); - String name = sa.getNonResourceString( - R.styleable.AndroidManifestUpgradeKeySet_name); - upgradeKeySets.add(name); - sa.recycle(); - XmlUtils.skipCurrentTag(parser); - } else if (PackageParser.RIGID_PARSER) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Bad element under <key-sets>: " + parser.getName() - + " at " + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription() - ); - } else { - Slog.w(TAG, "Unknown element under <key-sets>: " + parser.getName() - + " at " + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - XmlUtils.skipCurrentTag(parser); - continue; - } - } - String packageName = parsingPackage.getPackageName(); - Set<String> publicKeyNames = publicKeys.keySet(); - if (publicKeyNames.removeAll(definedKeySets.keySet())) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Package" + packageName + " AndroidManifest.xml " - + "'key-set' and 'public-key' names must be distinct." - ); - } - - for (ArrayMap.Entry<String, ArraySet<String>> e : definedKeySets.entrySet()) { - final String keySetName = e.getKey(); - if (e.getValue().size() == 0) { - Slog.w(TAG, "Package" + packageName + " AndroidManifest.xml " - + "'key-set' " + keySetName + " has no valid associated 'public-key'." - + " Not including in package's defined key-sets."); - continue; - } else if (improperKeySets.contains(keySetName)) { - Slog.w(TAG, "Package" + packageName + " AndroidManifest.xml " - + "'key-set' " + keySetName + " contained improper 'public-key'" - + " tags. Not including in package's defined key-sets."); - continue; - } - - for (String s : e.getValue()) { - parsingPackage.addKeySet(keySetName, publicKeys.get(s)); - } - } - if (parsingPackage.getKeySetMapping().keySet().containsAll(upgradeKeySets)) { - parsingPackage.setUpgradeKeySets(upgradeKeySets); - } else { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Package" + packageName + " AndroidManifest.xml " - + "does not define all 'upgrade-key-set's ." - ); - } - - return parseInput.success(parsingPackage); - } - - public static boolean parsePackageItemInfo(String packageName, PackageItemInfo outInfo, - String[] outError, String tag, TypedArray sa, boolean nameRequired, - int nameRes, int labelRes, int iconRes, int roundIconRes, int logoRes, int bannerRes) { - // This case can only happen in unit tests where we sometimes need to create fakes - // of various package parser data structures. - if (sa == null) { - outError[0] = tag + " does not contain any attributes"; - return false; - } - - String name = sa.getNonConfigurationString(nameRes, 0); - if (name == null) { - if (nameRequired) { - outError[0] = tag + " does not specify android:name"; - return false; - } - } else { - String outInfoName = buildClassName(packageName, name); - if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(outInfoName)) { - outError[0] = tag + " invalid android:name"; - return false; - } - outInfo.name = outInfoName; - if (outInfoName == null) { - return false; - } - } - - int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId(roundIconRes, 0) : 0; - if (roundIconVal != 0) { - outInfo.icon = roundIconVal; - outInfo.nonLocalizedLabel = null; - } else { - int iconVal = sa.getResourceId(iconRes, 0); - if (iconVal != 0) { - outInfo.icon = iconVal; - outInfo.nonLocalizedLabel = null; - } - } - - int logoVal = sa.getResourceId(logoRes, 0); - if (logoVal != 0) { - outInfo.logo = logoVal; - } - - int bannerVal = sa.getResourceId(bannerRes, 0); - if (bannerVal != 0) { - outInfo.banner = bannerVal; - } - - TypedValue v = sa.peekValue(labelRes); - if (v != null && (outInfo.labelRes = v.resourceId) == 0) { - outInfo.nonLocalizedLabel = v.coerceToString(); - } - - outInfo.packageName = packageName; - - return true; - } - - private static ParseResult parsePackageItemInfo( - ParseInput parseInput, - ParsingPackage parsingPackage, - String tag, - TypedArray sa, - boolean nameRequired, - int nameRes, - int labelRes, - int iconRes, - int roundIconRes, - int logoRes, - int bannerRes - ) { - // This case can only happen in unit tests where we sometimes need to create fakes - // of various package parser data structures. - if (sa == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - tag + " does not contain any attributes" - ); - } - - String name = sa.getNonConfigurationString(nameRes, 0); - if (name == null) { - if (nameRequired) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - tag + " does not specify android:name" - ); - } - } else { - String packageName = parsingPackage.getPackageName(); - String outInfoName = buildClassName(packageName, name); - if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(outInfoName)) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - tag + " invalid android:name" - ); - } else if (outInfoName == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Empty class name in package " + packageName - ); - } - - parsingPackage.setName(outInfoName); - } - - int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId(roundIconRes, 0) : 0; - if (roundIconVal != 0) { - parsingPackage.setIcon(roundIconVal) - .setNonLocalizedLabel(null); - } else { - int iconVal = sa.getResourceId(iconRes, 0); - if (iconVal != 0) { - parsingPackage.setIcon(iconVal) - .setNonLocalizedLabel(null); - } - } - - int logoVal = sa.getResourceId(logoRes, 0); - if (logoVal != 0) { - parsingPackage.setLogo(logoVal); - } - - int bannerVal = sa.getResourceId(bannerRes, 0); - if (bannerVal != 0) { - parsingPackage.setBanner(bannerVal); - } - - TypedValue v = sa.peekValue(labelRes); - if (v != null) { - parsingPackage.setLabelRes(v.resourceId); - if (v.resourceId == 0) { - parsingPackage.setNonLocalizedLabel(v.coerceToString()); - } - } - - return parseInput.success(parsingPackage); - } - - private static ParseResult parsePermissionGroup( - ParseInput parseInput, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws XmlPullParserException, IOException { - // TODO(b/135203078): Remove, replace with ParseResult - String[] outError = new String[1]; - - ComponentParseUtils.ParsedPermissionGroup parsedPermissionGroup = - ComponentParseUtils.parsePermissionGroup(parsingPackage, - res, parser, outError); - - if (parsedPermissionGroup == null || outError[0] != null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - parsingPackage.addPermissionGroup(parsedPermissionGroup); - - return parseInput.success(parsingPackage); - } - - private static ParseResult parsePermission( - ParseInput parseInput, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws XmlPullParserException, IOException { - // TODO(b/135203078): Remove, replace with ParseResult - String[] outError = new String[1]; - - ComponentParseUtils.ParsedPermission parsedPermission = - ComponentParseUtils.parsePermission(parsingPackage, - res, parser, outError); - - if (parsedPermission == null || outError[0] != null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - parsingPackage.addPermission(parsedPermission); - - return parseInput.success(parsingPackage); - } - - private static ParseResult parsePermissionTree( - ParseInput parseInput, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws XmlPullParserException, IOException { - // TODO(b/135203078): Remove, replace with ParseResult - String[] outError = new String[1]; - - ComponentParseUtils.ParsedPermission parsedPermission = - ComponentParseUtils.parsePermissionTree(parsingPackage, - res, parser, outError); - - if (parsedPermission == null || outError[0] != null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - parsingPackage.addPermission(parsedPermission); - - return parseInput.success(parsingPackage); - } - - private static ParseResult parseUsesPermission( - ParseInput parseInput, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser, - PackageParser.Callback callback - ) - throws XmlPullParserException, IOException { - TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestUsesPermission); - - // Note: don't allow this value to be a reference to a resource - // that may change. - String name = sa.getNonResourceString( - R.styleable.AndroidManifestUsesPermission_name); - - int maxSdkVersion = 0; - TypedValue val = sa.peekValue( - R.styleable.AndroidManifestUsesPermission_maxSdkVersion); - if (val != null) { - if (val.type >= TypedValue.TYPE_FIRST_INT && val.type <= TypedValue.TYPE_LAST_INT) { - maxSdkVersion = val.data; - } - } - - final String requiredFeature = sa.getNonConfigurationString( - R.styleable.AndroidManifestUsesPermission_requiredFeature, 0); - - final String requiredNotfeature = sa.getNonConfigurationString( - R.styleable.AndroidManifestUsesPermission_requiredNotFeature, - 0); - - sa.recycle(); - - XmlUtils.skipCurrentTag(parser); - - // Can only succeed from here on out - ParseResult success = parseInput.success(parsingPackage); - - if (name == null) { - return success; - } - - if ((maxSdkVersion != 0) && (maxSdkVersion < Build.VERSION.RESOURCES_SDK_INT)) { - return success; - } - - // Only allow requesting this permission if the platform supports the given feature. - if (requiredFeature != null && callback != null && !callback.hasFeature(requiredFeature)) { - return success; - } - - // Only allow requesting this permission if the platform doesn't support the given feature. - if (requiredNotfeature != null && callback != null - && callback.hasFeature(requiredNotfeature)) { - return success; - } - - if (!parsingPackage.getRequestedPermissions().contains(name)) { - parsingPackage.addRequestedPermission(name.intern()); - } else { - Slog.w(TAG, "Ignoring duplicate uses-permissions/uses-permissions-sdk-m: " - + name + " in package: " + parsingPackage.getPackageName() + " at: " - + parser.getPositionDescription()); - } - - return success; - } - - private static boolean parseUsesConfiguration( - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws IOException, XmlPullParserException { - ConfigurationInfo cPref = new ConfigurationInfo(); - TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestUsesConfiguration); - cPref.reqTouchScreen = sa.getInt( - R.styleable.AndroidManifestUsesConfiguration_reqTouchScreen, - Configuration.TOUCHSCREEN_UNDEFINED); - cPref.reqKeyboardType = sa.getInt( - R.styleable.AndroidManifestUsesConfiguration_reqKeyboardType, - Configuration.KEYBOARD_UNDEFINED); - if (sa.getBoolean( - R.styleable.AndroidManifestUsesConfiguration_reqHardKeyboard, - false)) { - cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; - } - cPref.reqNavigation = sa.getInt( - R.styleable.AndroidManifestUsesConfiguration_reqNavigation, - Configuration.NAVIGATION_UNDEFINED); - if (sa.getBoolean( - R.styleable.AndroidManifestUsesConfiguration_reqFiveWayNav, - false)) { - cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; - } - sa.recycle(); - parsingPackage.addConfigPreference(cPref); - - XmlUtils.skipCurrentTag(parser); - return true; - } - - private static boolean parseUsesFeature( - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws IOException, XmlPullParserException { - FeatureInfo fi = parseFeatureInfo(res, parser); - parsingPackage.addReqFeature(fi); - - if (fi.name == null) { - ConfigurationInfo cPref = new ConfigurationInfo(); - cPref.reqGlEsVersion = fi.reqGlEsVersion; - parsingPackage.addConfigPreference(cPref); - } - - XmlUtils.skipCurrentTag(parser); - return true; - } - - private static FeatureInfo parseFeatureInfo(Resources res, AttributeSet attrs) { - FeatureInfo fi = new FeatureInfo(); - TypedArray sa = res.obtainAttributes(attrs, - R.styleable.AndroidManifestUsesFeature); - // Note: don't allow this value to be a reference to a resource - // that may change. - fi.name = sa.getNonResourceString(R.styleable.AndroidManifestUsesFeature_name); - fi.version = sa.getInt(R.styleable.AndroidManifestUsesFeature_version, 0); - if (fi.name == null) { - fi.reqGlEsVersion = sa.getInt(R.styleable.AndroidManifestUsesFeature_glEsVersion, - FeatureInfo.GL_ES_VERSION_UNDEFINED); - } - if (sa.getBoolean(R.styleable.AndroidManifestUsesFeature_required, true)) { - fi.flags |= FeatureInfo.FLAG_REQUIRED; - } - sa.recycle(); - return fi; - } - - private static boolean parseFeatureGroup( - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws IOException, XmlPullParserException { - FeatureGroupInfo group = new FeatureGroupInfo(); - ArrayList<FeatureInfo> features = null; - final int innerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG - || parser.getDepth() > innerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - final String innerTagName = parser.getName(); - if (innerTagName.equals("uses-feature")) { - FeatureInfo featureInfo = parseFeatureInfo(res, parser); - // FeatureGroups are stricter and mandate that - // any <uses-feature> declared are mandatory. - featureInfo.flags |= FeatureInfo.FLAG_REQUIRED; - features = ArrayUtils.add(features, featureInfo); - } else { - Slog.w(TAG, - "Unknown element under <feature-group>: " + innerTagName + - " at " + parsingPackage.getBaseCodePath() + " " + - parser.getPositionDescription()); - } - XmlUtils.skipCurrentTag(parser); - } - - if (features != null) { - group.features = new FeatureInfo[features.size()]; - group.features = features.toArray(group.features); - } - - parsingPackage.addFeatureGroup(group); - return true; - } - - private static ParseResult parseUsesSdk( - ParseInput parseInput, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws IOException, XmlPullParserException { - if (PackageParser.SDK_VERSION > 0) { - TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestUsesSdk); - - int minVers = 1; - String minCode = null; - int targetVers = 0; - String targetCode = null; - - TypedValue val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_minSdkVersion); - if (val != null) { - if (val.type == TypedValue.TYPE_STRING && val.string != null) { - minCode = val.string.toString(); - } else { - // If it's not a string, it's an integer. - minVers = val.data; - } - } - - val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_targetSdkVersion); - if (val != null) { - if (val.type == TypedValue.TYPE_STRING && val.string != null) { - targetCode = val.string.toString(); - if (minCode == null) { - minCode = targetCode; - } - } else { - // If it's not a string, it's an integer. - targetVers = val.data; - } - } else { - targetVers = minVers; - targetCode = minCode; - } - - sa.recycle(); - - // TODO(b/135203078): Remove, replace with ParseResult - String[] outError = new String[1]; - final int minSdkVersion = PackageParser.computeMinSdkVersion(minVers, - minCode, - PackageParser.SDK_VERSION, PackageParser.SDK_CODENAMES, outError); - if (minSdkVersion < 0) { - return parseInput.error( - PackageManager.INSTALL_FAILED_OLDER_SDK - ); - } - - final int targetSdkVersion = PackageParser.computeTargetSdkVersion( - targetVers, - targetCode, PackageParser.SDK_CODENAMES, outError); - if (targetSdkVersion < 0) { - return parseInput.error( - PackageManager.INSTALL_FAILED_OLDER_SDK - ); - } - - parsingPackage.setMinSdkVersion(minSdkVersion) - .setTargetSdkVersion(targetSdkVersion); - } - - XmlUtils.skipCurrentTag(parser); - return parseInput.success(parsingPackage); - } - - private static boolean parseRestrictUpdateHash( - int flags, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws IOException, XmlPullParserException { - if ((flags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { - TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestRestrictUpdate); - final String hash = sa.getNonConfigurationString( - R.styleable.AndroidManifestRestrictUpdate_hash, - 0); - sa.recycle(); - - if (hash != null) { - final int hashLength = hash.length(); - final byte[] hashBytes = new byte[hashLength / 2]; - for (int i = 0; i < hashLength; i += 2) { - hashBytes[i / 2] = (byte) ((Character.digit(hash.charAt(i), 16) - << 4) - + Character.digit(hash.charAt(i + 1), 16)); - } - parsingPackage.setRestrictUpdateHash(hashBytes); - } else { - parsingPackage.setRestrictUpdateHash(null); - } - } - - XmlUtils.skipCurrentTag(parser); - return true; - } - - private static ParseResult parseQueries( - ParseInput parseInput, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws IOException, XmlPullParserException { - - final int outerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG - || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - if (parser.getName().equals("intent")) { - String[] outError = new String[1]; - ComponentParseUtils.ParsedQueriesIntentInfo intentInfo = - ComponentParseUtils.parsedParsedQueriesIntentInfo( - parsingPackage, res, parser, outError - ); - if (intentInfo == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - Uri data = null; - String dataType = null; - String host = ""; - final int numActions = intentInfo.countActions(); - final int numSchemes = intentInfo.countDataSchemes(); - final int numTypes = intentInfo.countDataTypes(); - final int numHosts = intentInfo.getHosts().length; - if ((numSchemes == 0 && numTypes == 0 && numActions == 0)) { - outError[0] = "intent tags must contain either an action or data."; - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - if (numActions > 1) { - outError[0] = "intent tag may have at most one action."; - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - if (numTypes > 1) { - outError[0] = "intent tag may have at most one data type."; - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - if (numSchemes > 1) { - outError[0] = "intent tag may have at most one data scheme."; - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - if (numHosts > 1) { - outError[0] = "intent tag may have at most one data host."; - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - Intent intent = new Intent(); - for (int i = 0, max = intentInfo.countCategories(); i < max; i++) { - intent.addCategory(intentInfo.getCategory(i)); - } - if (numHosts == 1) { - host = intentInfo.getHosts()[0]; - } - if (numSchemes == 1) { - data = new Uri.Builder() - .scheme(intentInfo.getDataScheme(0)) - .authority(host) - .build(); - } - if (numTypes == 1) { - dataType = intentInfo.getDataType(0); - } - intent.setDataAndType(data, dataType); - if (numActions == 1) { - intent.setAction(intentInfo.getAction(0)); - } - parsingPackage.addQueriesIntent(intent); - } else if (parser.getName().equals("package")) { - final TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestQueriesPackage); - final String packageName = - sa.getString(R.styleable.AndroidManifestQueriesPackage_name); - if (TextUtils.isEmpty(packageName)) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Package name is missing from package tag." - ); - } - parsingPackage.addQueriesPackage(packageName.intern()); - } - } - return parseInput.success(parsingPackage); - } - - /** - * Parse the {@code application} XML tree at the current parse location in a - * <em>base APK</em> manifest. - * <p> - * When adding new features, carefully consider if they should also be - * supported by split APKs. - * - * @hide - */ - public static ParseResult parseBaseApplication( - ParseInput parseInput, - String[] separateProcesses, - PackageParser.Callback callback, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser, - int flags - ) throws XmlPullParserException, IOException { - final String pkgName = parsingPackage.getPackageName(); - - // TODO(b/135203078): Remove, replace with ParseResult - String[] outError = new String[1]; - TypedArray sa = null; - - try { - sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestApplication); - - - parsingPackage - .setIconRes( - sa.getResourceId(R.styleable.AndroidManifestApplication_icon, 0)) - .setRoundIconRes( - sa.getResourceId(R.styleable.AndroidManifestApplication_roundIcon, 0)); - - ParseResult result = parsePackageItemInfo( - parseInput, - parsingPackage, - "<application>", - sa, false /*nameRequired*/, - R.styleable.AndroidManifestApplication_name, - R.styleable.AndroidManifestApplication_label, - R.styleable.AndroidManifestApplication_icon, - R.styleable.AndroidManifestApplication_roundIcon, - R.styleable.AndroidManifestApplication_logo, - R.styleable.AndroidManifestApplication_banner - ); - if (!result.isSuccess()) { - return result; - } - - String name = parsingPackage.getName(); - if (name != null) { - parsingPackage.setClassName(name); - } - - String manageSpaceActivity = sa.getNonConfigurationString( - R.styleable.AndroidManifestApplication_manageSpaceActivity, - Configuration.NATIVE_CONFIG_VERSION); - if (manageSpaceActivity != null) { - String manageSpaceActivityName = buildClassName(pkgName, manageSpaceActivity); - - if (manageSpaceActivityName == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Empty class name in package " + pkgName - ); - } - - parsingPackage.setManageSpaceActivityName(manageSpaceActivityName); - } - - boolean allowBackup = sa.getBoolean( - R.styleable.AndroidManifestApplication_allowBackup, true); - parsingPackage.setAllowBackup(allowBackup); - - if (allowBackup) { - // backupAgent, killAfterRestore, fullBackupContent, backupInForeground, - // and restoreAnyVersion are only relevant if backup is possible for the - // given application. - String backupAgent = sa.getNonConfigurationString( - R.styleable.AndroidManifestApplication_backupAgent, - Configuration.NATIVE_CONFIG_VERSION); - if (backupAgent != null) { - String backupAgentName = buildClassName(pkgName, backupAgent); - if (backupAgentName == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Empty class name in package " + pkgName - ); - } - - if (PackageParser.DEBUG_BACKUP) { - Slog.v(TAG, "android:backupAgent = " + backupAgentName - + " from " + pkgName + "+" + backupAgent); - } - - parsingPackage.setBackupAgentName(backupAgentName); - - parsingPackage.setKillAfterRestore(sa.getBoolean( - R.styleable.AndroidManifestApplication_killAfterRestore, true)); - - parsingPackage.setRestoreAnyVersion(sa.getBoolean( - R.styleable.AndroidManifestApplication_restoreAnyVersion, false)); - - parsingPackage.setFullBackupOnly(sa.getBoolean( - R.styleable.AndroidManifestApplication_fullBackupOnly, false)); - - parsingPackage.setBackupInForeground(sa.getBoolean( - R.styleable.AndroidManifestApplication_backupInForeground, - false)); - } - - TypedValue v = sa.peekValue( - R.styleable.AndroidManifestApplication_fullBackupContent); - int fullBackupContent = 0; - - if (v != null) { - fullBackupContent = v.resourceId; - - if (v.resourceId == 0) { - if (PackageParser.DEBUG_BACKUP) { - Slog.v(TAG, "fullBackupContent specified as boolean=" + - (v.data == 0 ? "false" : "true")); - } - // "false" => -1, "true" => 0 - fullBackupContent = v.data == 0 ? -1 : 0; - } - - parsingPackage.setFullBackupContent(fullBackupContent); - } - if (PackageParser.DEBUG_BACKUP) { - Slog.v(TAG, "fullBackupContent=" + fullBackupContent + " for " + pkgName); - } - } - - parsingPackage - .setTheme( - sa.getResourceId(R.styleable.AndroidManifestApplication_theme, 0)) - .setDescriptionRes( - sa.getResourceId(R.styleable.AndroidManifestApplication_description, - 0)); - - if (sa.getBoolean( - R.styleable.AndroidManifestApplication_persistent, - false)) { - // Check if persistence is based on a feature being present - final String requiredFeature = sa.getNonResourceString(R.styleable - .AndroidManifestApplication_persistentWhenFeatureAvailable); - parsingPackage.setPersistent(requiredFeature == null - || callback.hasFeature(requiredFeature)); - } - - boolean requiredForAllUsers = sa.getBoolean( - R.styleable.AndroidManifestApplication_requiredForAllUsers, - false); - parsingPackage.setRequiredForAllUsers(requiredForAllUsers); - - String restrictedAccountType = sa.getString(R.styleable - .AndroidManifestApplication_restrictedAccountType); - if (restrictedAccountType != null && restrictedAccountType.length() > 0) { - parsingPackage.setRestrictedAccountType(restrictedAccountType); - } - - String requiredAccountType = sa.getString(R.styleable - .AndroidManifestApplication_requiredAccountType); - if (requiredAccountType != null && requiredAccountType.length() > 0) { - parsingPackage.setRequiredAccountType(requiredAccountType); - } - - parsingPackage.setForceQueryable( - sa.getBoolean(R.styleable.AndroidManifestApplication_forceQueryable, false) - ); - - boolean debuggable = sa.getBoolean( - R.styleable.AndroidManifestApplication_debuggable, - false - ); - - parsingPackage.setDebuggable(debuggable); - - if (debuggable) { - // Debuggable implies profileable - parsingPackage.setProfileableByShell(true); - } - - parsingPackage.setVmSafeMode(sa.getBoolean( - R.styleable.AndroidManifestApplication_vmSafeMode, false)); - - boolean baseHardwareAccelerated = sa.getBoolean( - R.styleable.AndroidManifestApplication_hardwareAccelerated, - parsingPackage.getTargetSdkVersion() - >= Build.VERSION_CODES.ICE_CREAM_SANDWICH); - parsingPackage.setBaseHardwareAccelerated(baseHardwareAccelerated); - - parsingPackage.setHasCode(sa.getBoolean( - R.styleable.AndroidManifestApplication_hasCode, true)); - - parsingPackage.setAllowTaskReparenting(sa.getBoolean( - R.styleable.AndroidManifestApplication_allowTaskReparenting, false)); - - parsingPackage.setAllowClearUserData(sa.getBoolean( - R.styleable.AndroidManifestApplication_allowClearUserData, true)); - - parsingPackage.setTestOnly(sa.getBoolean( - com.android.internal.R.styleable.AndroidManifestApplication_testOnly, - false)); - - parsingPackage.setLargeHeap(sa.getBoolean( - R.styleable.AndroidManifestApplication_largeHeap, false)); - - parsingPackage.setUsesCleartextTraffic(sa.getBoolean( - R.styleable.AndroidManifestApplication_usesCleartextTraffic, - parsingPackage.getTargetSdkVersion() < Build.VERSION_CODES.P)); - - parsingPackage.setSupportsRtl(sa.getBoolean( - R.styleable.AndroidManifestApplication_supportsRtl, - false /* default is no RTL support*/)); - - parsingPackage.setMultiArch(sa.getBoolean( - R.styleable.AndroidManifestApplication_multiArch, false)); - - parsingPackage.setExtractNativeLibs(sa.getBoolean( - R.styleable.AndroidManifestApplication_extractNativeLibs, true)); - - parsingPackage.setUseEmbeddedDex(sa.getBoolean( - R.styleable.AndroidManifestApplication_useEmbeddedDex, false)); - - parsingPackage.setDefaultToDeviceProtectedStorage(sa.getBoolean( - R.styleable.AndroidManifestApplication_defaultToDeviceProtectedStorage, - false)); - - parsingPackage.setDirectBootAware(sa.getBoolean( - R.styleable.AndroidManifestApplication_directBootAware, false)); - - if (sa.hasValueOrEmpty(R.styleable.AndroidManifestApplication_resizeableActivity)) { - parsingPackage.setActivitiesResizeModeResizeable(sa.getBoolean( - R.styleable.AndroidManifestApplication_resizeableActivity, true)); - } else { - parsingPackage.setActivitiesResizeModeResizeableViaSdkVersion( - parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.N); - } - - parsingPackage.setAllowClearUserDataOnFailedRestore(sa.getBoolean( - R.styleable.AndroidManifestApplication_allowClearUserDataOnFailedRestore, - true)); - - - parsingPackage.setAllowAudioPlaybackCapture(sa.getBoolean( - R.styleable.AndroidManifestApplication_allowAudioPlaybackCapture, - parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q)); - - parsingPackage.setRequestLegacyExternalStorage(sa.getBoolean( - R.styleable.AndroidManifestApplication_requestLegacyExternalStorage, - parsingPackage.getTargetSdkVersion() < Build.VERSION_CODES.Q)); - - parsingPackage - .setMaxAspectRatio( - sa.getFloat(R.styleable.AndroidManifestApplication_maxAspectRatio, 0)) - .setMinAspectRatio( - sa.getFloat(R.styleable.AndroidManifestApplication_minAspectRatio, 0)) - .setNetworkSecurityConfigRes(sa.getResourceId( - R.styleable.AndroidManifestApplication_networkSecurityConfig, 0)) - .setCategory(sa.getInt(R.styleable.AndroidManifestApplication_appCategory, - ApplicationInfo.CATEGORY_UNDEFINED)); - - String str; - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestApplication_permission, 0); - parsingPackage.setPermission((str != null && str.length() > 0) ? str.intern() : null); - - if (parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.FROYO) { - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestApplication_taskAffinity, - Configuration.NATIVE_CONFIG_VERSION); - } else { - // Some older apps have been seen to use a resource reference - // here that on older builds was ignored (with a warning). We - // need to continue to do this for them so they don't break. - str = sa.getNonResourceString( - R.styleable.AndroidManifestApplication_taskAffinity); - } - String packageName = parsingPackage.getPackageName(); - String taskAffinity = PackageParser.buildTaskAffinityName(packageName, - packageName, - str, outError); - - if (outError[0] != null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - parsingPackage.setTaskAffinity(taskAffinity); - String factory = sa.getNonResourceString( - R.styleable.AndroidManifestApplication_appComponentFactory); - if (factory != null) { - String appComponentFactory = buildClassName(packageName, factory); - if (appComponentFactory == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Empty class name in package " + pkgName - ); - } - - parsingPackage.setAppComponentFactory(appComponentFactory); - } - - parsingPackage.setUsesNonSdkApi(sa.getBoolean( - R.styleable.AndroidManifestApplication_usesNonSdkApi, false)); - - parsingPackage.setHasFragileUserData(sa.getBoolean( - R.styleable.AndroidManifestApplication_hasFragileUserData, false)); - - CharSequence pname; - if (parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.FROYO) { - pname = sa.getNonConfigurationString( - R.styleable.AndroidManifestApplication_process, - Configuration.NATIVE_CONFIG_VERSION); - } else { - // Some older apps have been seen to use a resource reference - // here that on older builds was ignored (with a warning). We - // need to continue to do this for them so they don't break. - pname = sa.getNonResourceString( - R.styleable.AndroidManifestApplication_process); - } - String processName = PackageParser.buildProcessName(packageName, null, pname, flags, - separateProcesses, outError); - - if (outError[0] != null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - parsingPackage - .setProcessName(processName) - .setEnabled( - sa.getBoolean(R.styleable.AndroidManifestApplication_enabled, - true)); - - parsingPackage.setIsGame(sa.getBoolean( - R.styleable.AndroidManifestApplication_isGame, false)); - - boolean cantSaveState = sa.getBoolean( - R.styleable.AndroidManifestApplication_cantSaveState, false); - parsingPackage.setCantSaveState(cantSaveState); - if (cantSaveState) { - // A heavy-weight application can not be in a custom process. - // We can do direct compare because we intern all strings. - if (processName != null && !processName.equals(packageName)) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "cantSaveState applications can not use custom processes" - ); - } - } - - String classLoaderName = sa.getString( - R.styleable.AndroidManifestApplication_classLoader); - parsingPackage - .setUiOptions(sa.getInt(R.styleable.AndroidManifestApplication_uiOptions, 0)) - .setClassLoaderName(classLoaderName) - .setZygotePreloadName( - sa.getString(R.styleable.AndroidManifestApplication_zygotePreloadName)); - - if (classLoaderName != null - && !ClassLoaderFactory.isValidClassLoaderName(classLoaderName)) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Invalid class loader name: " + classLoaderName - ); - } - } finally { - if (sa != null) { - sa.recycle(); - } - } - - final int innerDepth = parser.getDepth(); - int type; - boolean hasActivityOrder = false; - boolean hasReceiverOrder = false; - boolean hasServiceOrder = false; - - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - String tagName = parser.getName(); - switch (tagName) { - case "activity": - ComponentParseUtils.ParsedActivity activity = - ComponentParseUtils.parseActivity(separateProcesses, - parsingPackage, - res, parser, flags, - outError, false, - parsingPackage.isBaseHardwareAccelerated()); - if (activity == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - hasActivityOrder |= (activity.order != 0); - parsingPackage.addActivity(activity); - break; - case "receiver": - activity = ComponentParseUtils.parseActivity(separateProcesses, - parsingPackage, - res, parser, - flags, outError, - true, false); - if (activity == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - hasReceiverOrder |= (activity.order != 0); - parsingPackage.addReceiver(activity); - break; - case "service": - ComponentParseUtils.ParsedService s = ComponentParseUtils.parseService( - separateProcesses, - parsingPackage, - res, parser, flags, - outError); - if (s == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - hasServiceOrder |= (s.order != 0); - parsingPackage.addService(s); - break; - case "provider": - ComponentParseUtils.ParsedProvider p = ComponentParseUtils.parseProvider( - separateProcesses, - parsingPackage, - res, parser, flags, - outError - ); - if (p == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - parsingPackage.addProvider(p); - break; - case "activity-alias": - activity = ComponentParseUtils.parseActivityAlias( - parsingPackage, - res, - parser, - outError - ); - if (activity == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - hasActivityOrder |= (activity.order != 0); - parsingPackage.addActivity(activity); - break; - case "meta-data": - // note: application meta-data is stored off to the side, so it can - // remain null in the primary copy (we like to avoid extra copies because - // it can be large) - Bundle appMetaData = parseMetaData(parsingPackage, res, parser, - parsingPackage.getAppMetaData(), - outError); - if (appMetaData == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - parsingPackage.setAppMetaData(appMetaData); - break; - case "static-library": - sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestStaticLibrary); - - // Note: don't allow this value to be a reference to a resource - // that may change. - String lname = sa.getNonResourceString( - R.styleable.AndroidManifestStaticLibrary_name); - final int version = sa.getInt( - R.styleable.AndroidManifestStaticLibrary_version, -1); - final int versionMajor = sa.getInt( - R.styleable.AndroidManifestStaticLibrary_versionMajor, - 0); - - sa.recycle(); - - // Since the app canot run without a static lib - fail if malformed - if (lname == null || version < 0) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Bad static-library declaration name: " + lname - + " version: " + version - ); - } - - if (parsingPackage.getSharedUserId() != null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID, - "sharedUserId not allowed in static shared library" - ); - } - - if (parsingPackage.getStaticSharedLibName() != null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Multiple static-shared libs for package " + pkgName - ); - } - - parsingPackage.setStaticSharedLibName(lname.intern()); - if (version >= 0) { - parsingPackage.setStaticSharedLibVersion( - PackageInfo.composeLongVersionCode(versionMajor, version)); - } else { - parsingPackage.setStaticSharedLibVersion(version); - } - parsingPackage.setStaticSharedLibrary(true); - - XmlUtils.skipCurrentTag(parser); - - break; - case "library": - sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestLibrary); - - // Note: don't allow this value to be a reference to a resource - // that may change. - lname = sa.getNonResourceString( - R.styleable.AndroidManifestLibrary_name); - - sa.recycle(); - - if (lname != null) { - lname = lname.intern(); - if (!ArrayUtils.contains(parsingPackage.getLibraryNames(), lname)) { - parsingPackage.addLibraryName(lname); - } - } - - XmlUtils.skipCurrentTag(parser); - - break; - case "uses-static-library": - ParseResult parseResult = parseUsesStaticLibrary(parseInput, parsingPackage, - res, parser); - if (!parseResult.isSuccess()) { - return parseResult; - } - break; - case "uses-library": - sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestUsesLibrary); - - // Note: don't allow this value to be a reference to a resource - // that may change. - lname = sa.getNonResourceString( - R.styleable.AndroidManifestUsesLibrary_name); - boolean req = sa.getBoolean( - R.styleable.AndroidManifestUsesLibrary_required, - true); - - sa.recycle(); - - if (lname != null) { - lname = lname.intern(); - if (req) { - parsingPackage.addUsesLibrary(lname); - } else { - parsingPackage.addUsesOptionalLibrary(lname); - } - } - - XmlUtils.skipCurrentTag(parser); - - break; - case "uses-package": - // Dependencies for app installers; we don't currently try to - // enforce this. - XmlUtils.skipCurrentTag(parser); - break; - case "profileable": - sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestProfileable); - if (sa.getBoolean( - R.styleable.AndroidManifestProfileable_shell, false)) { - parsingPackage.setProfileableByShell(true); - } - XmlUtils.skipCurrentTag(parser); - - default: - if (!PackageParser.RIGID_PARSER) { - Slog.w(TAG, "Unknown element under <application>: " + tagName - + " at " + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - XmlUtils.skipCurrentTag(parser); - continue; - } else { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Bad element under <application>: " + tagName - ); - } - } - } - - if (TextUtils.isEmpty(parsingPackage.getStaticSharedLibName())) { - // Add a hidden app detail activity to normal apps which forwards user to App Details - // page. - ComponentParseUtils.ParsedActivity a = generateAppDetailsHiddenActivity( - parsingPackage, - outError - ); - // Ignore errors here - parsingPackage.addActivity(a); - } - - if (hasActivityOrder) { - parsingPackage.sortActivities(); - } - if (hasReceiverOrder) { - parsingPackage.sortReceivers(); - } - if (hasServiceOrder) { - parsingPackage.sortServices(); - } - // Must be ran after the entire {@link ApplicationInfo} has been fully processed and after - // every activity info has had a chance to set it from its attributes. - setMaxAspectRatio(parsingPackage); - setMinAspectRatio(parsingPackage, callback); - - parsingPackage.setHasDomainUrls(hasDomainURLs(parsingPackage)); - - return parseInput.success(parsingPackage); - } - - private static ParseResult parseUsesStaticLibrary( - ParseInput parseInput, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws XmlPullParserException, IOException { - TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestUsesStaticLibrary); - - // Note: don't allow this value to be a reference to a resource that may change. - String lname = sa.getNonResourceString( - R.styleable.AndroidManifestUsesLibrary_name); - final int version = sa.getInt( - R.styleable.AndroidManifestUsesStaticLibrary_version, -1); - String certSha256Digest = sa.getNonResourceString(com.android.internal.R.styleable - .AndroidManifestUsesStaticLibrary_certDigest); - sa.recycle(); - - // Since an APK providing a static shared lib can only provide the lib - fail if malformed - if (lname == null || version < 0 || certSha256Digest == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Bad uses-static-library declaration name: " + lname + " version: " - + version + " certDigest" + certSha256Digest - ); - } - - // Can depend only on one version of the same library - List<String> usesStaticLibraries = parsingPackage.getUsesStaticLibraries(); - if (usesStaticLibraries != null && usesStaticLibraries.contains(lname)) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Depending on multiple versions of static library " + lname - ); - } - - lname = lname.intern(); - // We allow ":" delimiters in the SHA declaration as this is the format - // emitted by the certtool making it easy for developers to copy/paste. - certSha256Digest = certSha256Digest.replace(":", "").toLowerCase(); - - // Fot apps targeting O-MR1 we require explicit enumeration of all certs. - String[] additionalCertSha256Digests = EmptyArray.STRING; - if (parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.O_MR1) { - // TODO(b/135203078): Remove, replace with ParseResult - String[] outError = new String[1]; - additionalCertSha256Digests = parseAdditionalCertificates(res, parser, outError); - if (additionalCertSha256Digests == null || outError[0] != null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - } else { - XmlUtils.skipCurrentTag(parser); - } - - final String[] certSha256Digests = new String[additionalCertSha256Digests.length + 1]; - certSha256Digests[0] = certSha256Digest; - System.arraycopy(additionalCertSha256Digests, 0, certSha256Digests, - 1, additionalCertSha256Digests.length); - - parsingPackage.addUsesStaticLibrary(lname) - .addUsesStaticLibraryVersion(version) - .addUsesStaticLibraryCertDigests(certSha256Digests); - - return parseInput.success(parsingPackage); - } - - private static String[] parseAdditionalCertificates( - Resources resources, - XmlResourceParser parser, - String[] outError - ) throws XmlPullParserException, IOException { - String[] certSha256Digests = EmptyArray.STRING; - - int outerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - final String nodeName = parser.getName(); - if (nodeName.equals("additional-certificate")) { - final TypedArray sa = resources.obtainAttributes(parser, com.android.internal. - R.styleable.AndroidManifestAdditionalCertificate); - String certSha256Digest = sa.getNonResourceString(com.android.internal. - R.styleable.AndroidManifestAdditionalCertificate_certDigest); - sa.recycle(); - - if (TextUtils.isEmpty(certSha256Digest)) { - outError[0] = "Bad additional-certificate declaration with empty" - + " certDigest:" + certSha256Digest; - XmlUtils.skipCurrentTag(parser); - sa.recycle(); - return null; - } - - // We allow ":" delimiters in the SHA declaration as this is the format - // emitted by the certtool making it easy for developers to copy/paste. - certSha256Digest = certSha256Digest.replace(":", "").toLowerCase(); - certSha256Digests = ArrayUtils.appendElement(String.class, - certSha256Digests, certSha256Digest); - } else { - XmlUtils.skipCurrentTag(parser); - } - } - - return certSha256Digests; - } - - /** - * Generate activity object that forwards user to App Details page automatically. - * This activity should be invisible to user and user should not know or see it. - * - * @hide - */ - @NonNull - private static ComponentParseUtils.ParsedActivity generateAppDetailsHiddenActivity( - ParsingPackage parsingPackage, - String[] outError - ) { - String packageName = parsingPackage.getPackageName(); - String processName = parsingPackage.getProcessName(); - boolean hardwareAccelerated = parsingPackage.isBaseHardwareAccelerated(); - int uiOptions = parsingPackage.getUiOptions(); - - // Build custom App Details activity info instead of parsing it from xml - ComponentParseUtils.ParsedActivity activity = new ComponentParseUtils.ParsedActivity(); - activity.setPackageName(packageName); - - activity.theme = android.R.style.Theme_NoDisplay; - activity.exported = true; - activity.className = PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME; - activity.setProcessName(processName, processName); - activity.uiOptions = uiOptions; - activity.taskAffinity = PackageParser.buildTaskAffinityName(packageName, - packageName, - ":app_details", outError); - activity.enabled = true; - activity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; - activity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NONE; - activity.maxRecents = ActivityTaskManager.getDefaultAppRecentsLimitStatic(); - activity.configChanges = PackageParser.getActivityConfigChanges(0, 0); - activity.softInputMode = 0; - activity.persistableMode = ActivityInfo.PERSIST_NEVER; - activity.screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED; - activity.resizeMode = RESIZE_MODE_FORCE_RESIZEABLE; - activity.lockTaskLaunchMode = 0; - activity.directBootAware = false; - activity.rotationAnimation = ROTATION_ANIMATION_UNSPECIFIED; - activity.colorMode = ActivityInfo.COLOR_MODE_DEFAULT; - if (hardwareAccelerated) { - activity.flags |= ActivityInfo.FLAG_HARDWARE_ACCELERATED; - } - - return activity; - } - - /** - * Check if one of the IntentFilter as both actions DEFAULT / VIEW and a HTTP/HTTPS data URI - */ - private static boolean hasDomainURLs( - ParsingPackage parsingPackage) { - final List<ComponentParseUtils.ParsedActivity> activities = parsingPackage.getActivities(); - final int countActivities = activities.size(); - for (int n = 0; n < countActivities; n++) { - ComponentParseUtils.ParsedActivity activity = activities.get(n); - List<ComponentParseUtils.ParsedActivityIntentInfo> filters = activity.intents; - if (filters == null) continue; - final int countFilters = filters.size(); - for (int m = 0; m < countFilters; m++) { - ComponentParseUtils.ParsedActivityIntentInfo aii = filters.get(m); - if (!aii.hasAction(Intent.ACTION_VIEW)) continue; - if (!aii.hasAction(Intent.ACTION_DEFAULT)) continue; - if (aii.hasDataScheme(IntentFilter.SCHEME_HTTP) || - aii.hasDataScheme(IntentFilter.SCHEME_HTTPS)) { - return true; - } - } - } - return false; - } - - /** - * Sets the max aspect ratio of every child activity that doesn't already have an aspect - * ratio set. - */ - private static void setMaxAspectRatio( - ParsingPackage parsingPackage) { - // Default to (1.86) 16.7:9 aspect ratio for pre-O apps and unset for O and greater. - // NOTE: 16.7:9 was the max aspect ratio Android devices can support pre-O per the CDD. - float maxAspectRatio = parsingPackage.getTargetSdkVersion() < O - ? PackageParser.DEFAULT_PRE_O_MAX_ASPECT_RATIO : 0; - - float packageMaxAspectRatio = parsingPackage.getMaxAspectRatio(); - if (packageMaxAspectRatio != 0) { - // Use the application max aspect ration as default if set. - maxAspectRatio = packageMaxAspectRatio; - } else { - Bundle appMetaData = parsingPackage.getAppMetaData(); - if (appMetaData != null && appMetaData.containsKey( - PackageParser.METADATA_MAX_ASPECT_RATIO)) { - maxAspectRatio = appMetaData.getFloat(PackageParser.METADATA_MAX_ASPECT_RATIO, - maxAspectRatio); - } - } - - if (parsingPackage.getActivities() != null) { - for (ComponentParseUtils.ParsedActivity activity : parsingPackage.getActivities()) { - // If the max aspect ratio for the activity has already been set, skip. - if (activity.hasMaxAspectRatio()) { - continue; - } - - // By default we prefer to use a values defined on the activity directly than values - // defined on the application. We do not check the styled attributes on the activity - // as it would have already been set when we processed the activity. We wait to - // process the meta data here since this method is called at the end of processing - // the application and all meta data is guaranteed. - final float activityAspectRatio = activity.metaData != null - ? activity.metaData.getFloat(PackageParser.METADATA_MAX_ASPECT_RATIO, - maxAspectRatio) - : maxAspectRatio; - - activity.setMaxAspectRatio(activity.resizeMode, activityAspectRatio); - } - } - } - - /** - * Sets the min aspect ratio of every child activity that doesn't already have an aspect - * ratio set. - */ - private static void setMinAspectRatio( - ParsingPackage parsingPackage, - PackageParser.Callback callback - ) { - final float minAspectRatio; - float packageMinAspectRatio = parsingPackage.getMinAspectRatio(); - if (packageMinAspectRatio != 0) { - // Use the application max aspect ration as default if set. - minAspectRatio = packageMinAspectRatio; - } else { - // Default to (1.33) 4:3 aspect ratio for pre-Q apps and unset for Q and greater. - // NOTE: 4:3 was the min aspect ratio Android devices can support pre-Q per the CDD, - // except for watches which always supported 1:1. - minAspectRatio = parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q - ? 0 - : (callback != null && callback.hasFeature(FEATURE_WATCH)) - ? PackageParser.DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH - : PackageParser.DEFAULT_PRE_Q_MIN_ASPECT_RATIO; - } - - if (parsingPackage.getActivities() != null) { - for (ComponentParseUtils.ParsedActivity activity : parsingPackage.getActivities()) { - if (activity.hasMinAspectRatio()) { - continue; - } - activity.setMinAspectRatio(activity.resizeMode, minAspectRatio); - } - } - } - - private static ParseResult parseOverlay( - ParseInput parseInput, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws IOException, XmlPullParserException { - - TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestResourceOverlay); - String target = sa.getString( - R.styleable.AndroidManifestResourceOverlay_targetPackage); - String targetName = sa.getString( - R.styleable.AndroidManifestResourceOverlay_targetName); - String category = sa.getString( - R.styleable.AndroidManifestResourceOverlay_category); - int priority = sa.getInt(R.styleable.AndroidManifestResourceOverlay_priority, - 0); - boolean isStatic = sa.getBoolean( - R.styleable.AndroidManifestResourceOverlay_isStatic, false); - - if (target == null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "<overlay> does not specify a target package" - ); - } - - if (priority < 0 || priority > 9999) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "<overlay> priority must be between 0 and 9999" - ); - } - - // check to see if overlay should be excluded based on system property condition - String propName = sa.getString( - R.styleable.AndroidManifestResourceOverlay_requiredSystemPropertyName); - String propValue = sa.getString( - R.styleable.AndroidManifestResourceOverlay_requiredSystemPropertyValue); - if (!checkOverlayRequiredSystemProperty(propName, propValue)) { - Slog.i(TAG, "Skipping target and overlay pair " + target + " and " - + parsingPackage.getBaseCodePath() - + ": overlay ignored due to required system property: " - + propName + " with value: " + propValue); - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - "Skipping target and overlay pair " + target + " and " - + parsingPackage.getBaseCodePath() - + ": overlay ignored due to required system property: " - + propName + " with value: " + propValue - ); - } - - parsingPackage - .setIsOverlay(true) - .setOverlayTarget(target) - .setOverlayTargetName(targetName) - .setOverlayCategory(category) - .setOverlayPriority(priority) - .setOverlayIsStatic(isStatic); - - sa.recycle(); - - XmlUtils.skipCurrentTag(parser); - return parseInput.success(parsingPackage); - } - - private static boolean parseProtectedBroadcast( - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws IOException, XmlPullParserException { - TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestProtectedBroadcast); - - // Note: don't allow this value to be a reference to a resource - // that may change. - String name = sa.getNonResourceString(R.styleable.AndroidManifestProtectedBroadcast_name); - - sa.recycle(); - - if (name != null) { - parsingPackage.addProtectedBroadcast(name); - } - - XmlUtils.skipCurrentTag(parser); - return true; - } - - private static boolean parseSupportScreens( - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws IOException, XmlPullParserException { - TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestSupportsScreens); - - int requiresSmallestWidthDp = sa.getInteger( - R.styleable.AndroidManifestSupportsScreens_requiresSmallestWidthDp, - 0); - int compatibleWidthLimitDp = sa.getInteger( - R.styleable.AndroidManifestSupportsScreens_compatibleWidthLimitDp, - 0); - int largestWidthLimitDp = sa.getInteger( - R.styleable.AndroidManifestSupportsScreens_largestWidthLimitDp, - 0); - - // This is a trick to get a boolean and still able to detect - // if a value was actually set. - parsingPackage - .setSupportsSmallScreens( - sa.getInteger(R.styleable.AndroidManifestSupportsScreens_smallScreens, 1)) - .setSupportsNormalScreens( - sa.getInteger(R.styleable.AndroidManifestSupportsScreens_normalScreens, 1)) - .setSupportsLargeScreens( - sa.getInteger(R.styleable.AndroidManifestSupportsScreens_largeScreens, 1)) - .setSupportsXLargeScreens( - sa.getInteger(R.styleable.AndroidManifestSupportsScreens_xlargeScreens, 1)) - .setResizeable( - sa.getInteger(R.styleable.AndroidManifestSupportsScreens_resizeable, 1)) - .setAnyDensity( - sa.getInteger(R.styleable.AndroidManifestSupportsScreens_anyDensity, 1)) - .setRequiresSmallestWidthDp(requiresSmallestWidthDp) - .setCompatibleWidthLimitDp(compatibleWidthLimitDp) - .setLargestWidthLimitDp(largestWidthLimitDp); - - sa.recycle(); - - XmlUtils.skipCurrentTag(parser); - return true; - } - - private static ParseResult parseInstrumentation( - ParseInput parseInput, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws XmlPullParserException, IOException { - // TODO(b/135203078): Remove, replace with ParseResult - String[] outError = new String[1]; - - ComponentParseUtils.ParsedInstrumentation parsedInstrumentation = - ComponentParseUtils.parseInstrumentation(parsingPackage, - res, parser, outError); - - if (parsedInstrumentation == null || outError[0] != null) { - return parseInput.error( - PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, - outError[0] - ); - } - - parsingPackage.addInstrumentation(parsedInstrumentation); - - return parseInput.success(parsingPackage); - } - - private static boolean parseOriginalPackage( - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws IOException, XmlPullParserException { - TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestOriginalPackage); - - String orig = sa.getNonConfigurationString( - R.styleable.AndroidManifestOriginalPackage_name, - 0); - if (!parsingPackage.getPackageName().equals(orig)) { - if (parsingPackage.getOriginalPackages() == null) { - parsingPackage.setRealPackage(parsingPackage.getPackageName()); - } - parsingPackage.addOriginalPackage(orig); - } - - sa.recycle(); - - XmlUtils.skipCurrentTag(parser); - return true; - } - - private static boolean parseAdoptPermissions( - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser - ) throws IOException, XmlPullParserException { - TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestOriginalPackage); - - String name = sa.getNonConfigurationString( - R.styleable.AndroidManifestOriginalPackage_name, - 0); - - sa.recycle(); - - if (name != null) { - parsingPackage.addAdoptPermission(name); - } - - XmlUtils.skipCurrentTag(parser); - return true; - } - - private static void convertNewPermissions( - ParsingPackage packageToParse) { - final int NP = PackageParser.NEW_PERMISSIONS.length; - StringBuilder newPermsMsg = null; - for (int ip = 0; ip < NP; ip++) { - final PackageParser.NewPermissionInfo npi - = PackageParser.NEW_PERMISSIONS[ip]; - if (packageToParse.getTargetSdkVersion() >= npi.sdkVersion) { - break; - } - if (!packageToParse.getRequestedPermissions().contains(npi.name)) { - if (newPermsMsg == null) { - newPermsMsg = new StringBuilder(128); - newPermsMsg.append(packageToParse.getPackageName()); - newPermsMsg.append(": compat added "); - } else { - newPermsMsg.append(' '); - } - newPermsMsg.append(npi.name); - packageToParse.addRequestedPermission(npi.name); - packageToParse.addImplicitPermission(npi.name); - } - } - if (newPermsMsg != null) { - Slog.i(TAG, newPermsMsg.toString()); - } - } - - private static void convertSplitPermissions(ParsingPackage packageToParse) { - List<SplitPermissionInfoParcelable> splitPermissions; - - try { - splitPermissions = ActivityThread.getPermissionManager().getSplitPermissions(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - - final int listSize = splitPermissions.size(); - for (int is = 0; is < listSize; is++) { - final SplitPermissionInfoParcelable spi = splitPermissions.get(is); - List<String> requestedPermissions = packageToParse.getRequestedPermissions(); - if (packageToParse.getTargetSdkVersion() >= spi.getTargetSdk() - || !requestedPermissions.contains(spi.getSplitPermission())) { - continue; - } - final List<String> newPerms = spi.getNewPermissions(); - for (int in = 0; in < newPerms.size(); in++) { - final String perm = newPerms.get(in); - if (!requestedPermissions.contains(perm)) { - packageToParse.addRequestedPermission(perm); - packageToParse.addImplicitPermission(perm); - } - } - } - } - - private static boolean checkOverlayRequiredSystemProperty(String propName, String propValue) { - if (TextUtils.isEmpty(propName) || TextUtils.isEmpty(propValue)) { - if (!TextUtils.isEmpty(propName) || !TextUtils.isEmpty(propValue)) { - // malformed condition - incomplete - Slog.w(TAG, "Disabling overlay - incomplete property :'" + propName - + "=" + propValue + "' - require both requiredSystemPropertyName" - + " AND requiredSystemPropertyValue to be specified."); - return false; - } - // no valid condition set - so no exclusion criteria, overlay will be included. - return true; - } - - // check property value - make sure it is both set and equal to expected value - final String currValue = SystemProperties.get(propName); - return (currValue != null && currValue.equals(propValue)); - } - - /** - * This is a pre-density application which will get scaled - instead of being pixel perfect. - * This type of application is not resizable. - * - * @param parsingPackage The package which needs to be marked as unresizable. - */ - private static void adjustPackageToBeUnresizeableAndUnpipable( - ParsingPackage parsingPackage) { - if (parsingPackage.getActivities() != null) { - for (ComponentParseUtils.ParsedActivity a : parsingPackage.getActivities()) { - a.resizeMode = RESIZE_MODE_UNRESIZEABLE; - a.flags &= ~FLAG_SUPPORTS_PICTURE_IN_PICTURE; - } - } - } - - private static String validateName(String name, boolean requireSeparator, - boolean requireFilename) { - final int N = name.length(); - boolean hasSep = false; - boolean front = true; - for (int i = 0; i < N; i++) { - final char c = name.charAt(i); - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { - front = false; - continue; - } - if (!front) { - if ((c >= '0' && c <= '9') || c == '_') { - continue; - } - } - if (c == '.') { - hasSep = true; - front = true; - continue; - } - return "bad character '" + c + "'"; - } - if (requireFilename && !FileUtils.isValidExtFilename(name)) { - return "Invalid filename"; - } - return hasSep || !requireSeparator - ? null : "must have at least one '.' separator"; - } - - public static Bundle parseMetaData( - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser, Bundle data, String[] outError) - throws XmlPullParserException, IOException { - - TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestMetaData); - - if (data == null) { - data = new Bundle(); - } - - String name = sa.getNonConfigurationString( - R.styleable.AndroidManifestMetaData_name, 0); - if (name == null) { - outError[0] = "<meta-data> requires an android:name attribute"; - sa.recycle(); - return null; - } - - name = name.intern(); - - TypedValue v = sa.peekValue( - R.styleable.AndroidManifestMetaData_resource); - if (v != null && v.resourceId != 0) { - //Slog.i(TAG, "Meta data ref " + name + ": " + v); - data.putInt(name, v.resourceId); - } else { - v = sa.peekValue( - R.styleable.AndroidManifestMetaData_value); - //Slog.i(TAG, "Meta data " + name + ": " + v); - if (v != null) { - if (v.type == TypedValue.TYPE_STRING) { - CharSequence cs = v.coerceToString(); - data.putString(name, cs != null ? cs.toString() : null); - } else if (v.type == TypedValue.TYPE_INT_BOOLEAN) { - data.putBoolean(name, v.data != 0); - } else if (v.type >= TypedValue.TYPE_FIRST_INT - && v.type <= TypedValue.TYPE_LAST_INT) { - data.putInt(name, v.data); - } else if (v.type == TypedValue.TYPE_FLOAT) { - data.putFloat(name, v.getFloat()); - } else { - if (!PackageParser.RIGID_PARSER) { - Slog.w(TAG, - "<meta-data> only supports string, integer, float, color, " - + "boolean, and resource reference types: " - + parser.getName() + " at " - + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - } else { - outError[0] = - "<meta-data> only supports string, integer, float, color, " - + "boolean, and resource reference types"; - data = null; - } - } - } else { - outError[0] = "<meta-data> requires an android:value or android:resource attribute"; - data = null; - } - } - - sa.recycle(); - - XmlUtils.skipCurrentTag(parser); - - return data; - } - - /** - * Collect certificates from all the APKs described in the given package, - * populating {@link AndroidPackageWrite#setSigningDetails(SigningDetails)}. Also asserts that - * all APK contents are signed correctly and consistently. - */ - public static void collectCertificates(AndroidPackage pkg, boolean skipVerify) - throws PackageParserException { - pkg.mutate().setSigningDetails(SigningDetails.UNKNOWN); - - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); - try { - pkg.mutate().setSigningDetails(collectCertificates( - pkg.getBaseCodePath(), - skipVerify, - pkg.isStaticSharedLibrary(), - pkg.getSigningDetails() - )); - - String[] splitCodePaths = pkg.getSplitCodePaths(); - if (!ArrayUtils.isEmpty(splitCodePaths)) { - for (int i = 0; i < splitCodePaths.length; i++) { - pkg.mutate().setSigningDetails(collectCertificates( - splitCodePaths[i], - skipVerify, - pkg.isStaticSharedLibrary(), - pkg.getSigningDetails() - )); - } - } - } finally { - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - } - } - - public static SigningDetails collectCertificates( - String baseCodePath, - boolean skipVerify, - boolean isStaticSharedLibrary, - @NonNull SigningDetails existingSigningDetails - ) throws PackageParserException { - int minSignatureScheme = SigningDetails.SignatureSchemeVersion.JAR; - if (isStaticSharedLibrary) { - // must use v2 signing scheme - minSignatureScheme = SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2; - } - SigningDetails verified; - if (skipVerify) { - // systemDir APKs are already trusted, save time by not verifying - verified = ApkSignatureVerifier.unsafeGetCertsWithoutVerification( - baseCodePath, minSignatureScheme); - } else { - verified = ApkSignatureVerifier.verify(baseCodePath, minSignatureScheme); - } - - // Verify that entries are signed consistently with the first pkg - // we encountered. Note that for splits, certificates may have - // already been populated during an earlier parse of a base APK. - if (existingSigningDetails == SigningDetails.UNKNOWN) { - return verified; - } else { - if (!Signature.areExactMatch(existingSigningDetails.signatures, verified.signatures)) { - throw new PackageParserException( - INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, - baseCodePath + " has mismatched certificates"); - } - - return existingSigningDetails; - } - } - - @Nullable - public static String buildClassName(String pkg, CharSequence clsSeq) { - if (clsSeq == null || clsSeq.length() <= 0) { - return null; - } - String cls = clsSeq.toString(); - char c = cls.charAt(0); - if (c == '.') { - return pkg + cls; - } - if (cls.indexOf('.') < 0) { - StringBuilder b = new StringBuilder(pkg); - b.append('.'); - b.append(cls); - return b.toString(); - } - return cls; - } - - public interface ParseInput { - ParseResult success(ParsingPackage result); - - ParseResult error(int parseError); - - ParseResult error(int parseError, String errorMessage); - } - - public static class ParseResult implements ParseInput { - - private static final boolean DEBUG_FILL_STACK_TRACE = false; - - private ParsingPackage result; - - private int parseError; - private String errorMessage; - - public ParseInput reset() { - this.result = null; - this.parseError = PackageManager.INSTALL_SUCCEEDED; - this.errorMessage = null; - return this; - } - - @Override - public ParseResult success(ParsingPackage result) { - if (parseError != PackageManager.INSTALL_SUCCEEDED || errorMessage != null) { - throw new IllegalStateException("Cannot set to success after set to error"); - } - this.result = result; - return this; - } - - @Override - public ParseResult error(int parseError) { - return error(parseError, null); - } - - @Override - public ParseResult error(int parseError, String errorMessage) { - this.parseError = parseError; - this.errorMessage = errorMessage; - - if (DEBUG_FILL_STACK_TRACE) { - this.errorMessage += Arrays.toString(new Exception().getStackTrace()); - } - - return this; - } - - public ParsingPackage getResultAndNull() { - ParsingPackage result = this.result; - this.result = null; - return result; - } - - public boolean isSuccess() { - return parseError == PackageManager.INSTALL_SUCCEEDED; - } - - public int getParseError() { - return parseError; - } - - public String getErrorMessage() { - return errorMessage; - } - } -} diff --git a/core/java/android/content/pm/parsing/ComponentParseUtils.java b/core/java/android/content/pm/parsing/ComponentParseUtils.java deleted file mode 100644 index adf2a4f85780..000000000000 --- a/core/java/android/content/pm/parsing/ComponentParseUtils.java +++ /dev/null @@ -1,3289 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package android.content.pm.parsing; - -import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; -import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE; -import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; -import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION; -import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; -import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED; - -import android.annotation.CallSuper; -import android.annotation.UnsupportedAppUsage; -import android.app.ActivityTaskManager; -import android.content.ComponentName; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageParser; -import android.content.pm.PathPermission; -import android.content.pm.PermissionInfo; -import android.content.pm.ProviderInfo; -import android.content.pm.ServiceInfo; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.os.Build; -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.PatternMatcher; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.util.Log; -import android.util.Slog; -import android.util.SparseArray; -import android.util.TypedValue; -import android.view.Gravity; - -import com.android.internal.R; -import com.android.internal.util.XmlUtils; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; - -/** - * TODO(b/135203078): Move the inner classes out to separate files. - * TODO(b/135203078): Expose inner classes as immutable through interface methods. - * - * @hide - */ -public class ComponentParseUtils { - - private static final String TAG = ApkParseUtils.TAG; - - // TODO(b/135203078): None of this class's subclasses do anything. Remove in favor of base? - public static class ParsedIntentInfo extends IntentFilter { - - /** - * <p> - * Implementation note: The serialized form for the intent list also contains the name - * of the concrete class that's stored in the list, and assumes that every element of the - * list is of the same type. This is very similar to the original parcelable mechanism. - * We cannot use that directly because IntentInfo extends IntentFilter, which is parcelable - * and is public API. It also declares Parcelable related methods as final which means - * we can't extend them. The approach of using composition instead of inheritance leads to - * a large set of cascading changes in the PackageManagerService, which seem undesirable. - * - * <p> - * <b>WARNING: </b> The list of objects returned by this function might need to be fixed up - * to make sure their owner fields are consistent. See {@code fixupOwner}. - */ - public static void writeIntentsList(List<? extends ParsedIntentInfo> list, Parcel out, - int flags) { - if (list == null) { - out.writeInt(-1); - return; - } - - final int size = list.size(); - out.writeInt(size); - - // Don't bother writing the component name if the list is empty. - if (size > 0) { - ParsedIntentInfo info = list.get(0); - out.writeString(info.getClass().getName()); - - for (int i = 0; i < size; i++) { - list.get(i).writeIntentInfoToParcel(out, flags); - } - } - } - - public static <T extends ParsedIntentInfo> ArrayList<T> createIntentsList(Parcel in) { - int size = in.readInt(); - if (size == -1) { - return null; - } - - if (size == 0) { - return new ArrayList<>(0); - } - - String className = in.readString(); - final ArrayList<T> intentsList; - try { - final Class<T> cls = (Class<T>) Class.forName(className); - final Constructor<T> cons = cls.getConstructor(Parcel.class); - - intentsList = new ArrayList<>(size); - for (int i = 0; i < size; ++i) { - intentsList.add(cons.newInstance(in)); - } - } catch (ReflectiveOperationException ree) { - throw new AssertionError("Unable to construct intent list for: " - + className, ree); - } - - return intentsList; - } - - protected String packageName; - protected final String className; - - public boolean hasDefault; - public int labelRes; - public CharSequence nonLocalizedLabel; - public int icon; - - protected List<String> rawDataTypes; - - public void addRawDataType(String dataType) throws MalformedMimeTypeException { - if (rawDataTypes == null) { - rawDataTypes = new ArrayList<>(); - } - - rawDataTypes.add(dataType); - addDataType(dataType); - } - - public ParsedIntentInfo(String packageName, String className) { - this.packageName = packageName; - this.className = className; - } - - public ParsedIntentInfo(Parcel in) { - super(in); - packageName = in.readString(); - className = in.readString(); - hasDefault = (in.readInt() == 1); - labelRes = in.readInt(); - nonLocalizedLabel = in.readCharSequence(); - icon = in.readInt(); - } - - public void writeIntentInfoToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeString(packageName); - dest.writeString(className); - dest.writeInt(hasDefault ? 1 : 0); - dest.writeInt(labelRes); - dest.writeCharSequence(nonLocalizedLabel); - dest.writeInt(icon); - } - - public String getPackageName() { - return packageName; - } - - public String getClassName() { - return className; - } - } - - public static class ParsedActivityIntentInfo extends ParsedIntentInfo { - - public ParsedActivityIntentInfo(String packageName, String className) { - super(packageName, className); - } - - public ParsedActivityIntentInfo(Parcel in) { - super(in); - } - - public static final Creator<ParsedActivityIntentInfo> CREATOR = - new Creator<ParsedActivityIntentInfo>() { - @Override - public ParsedActivityIntentInfo createFromParcel(Parcel source) { - return new ParsedActivityIntentInfo(source); - } - - @Override - public ParsedActivityIntentInfo[] newArray(int size) { - return new ParsedActivityIntentInfo[size]; - } - }; - } - - public static class ParsedServiceIntentInfo extends ParsedIntentInfo { - - public ParsedServiceIntentInfo(String packageName, String className) { - super(packageName, className); - } - - public ParsedServiceIntentInfo(Parcel in) { - super(in); - } - - public static final Creator<ParsedServiceIntentInfo> CREATOR = - new Creator<ParsedServiceIntentInfo>() { - @Override - public ParsedServiceIntentInfo createFromParcel(Parcel source) { - return new ParsedServiceIntentInfo(source); - } - - @Override - public ParsedServiceIntentInfo[] newArray(int size) { - return new ParsedServiceIntentInfo[size]; - } - }; - } - - public static class ParsedProviderIntentInfo extends ParsedIntentInfo { - - public ParsedProviderIntentInfo(String packageName, String className) { - super(packageName, className); - } - - public ParsedProviderIntentInfo(Parcel in) { - super(in); - } - - public static final Creator<ParsedProviderIntentInfo> CREATOR = - new Creator<ParsedProviderIntentInfo>() { - @Override - public ParsedProviderIntentInfo createFromParcel(Parcel source) { - return new ParsedProviderIntentInfo(source); - } - - @Override - public ParsedProviderIntentInfo[] newArray(int size) { - return new ParsedProviderIntentInfo[size]; - } - }; - } - - public static class ParsedQueriesIntentInfo extends ParsedIntentInfo { - - public ParsedQueriesIntentInfo(String packageName, String className) { - super(packageName, className); - } - - public ParsedQueriesIntentInfo(Parcel in) { - super(in); - } - - public static final Creator<ParsedQueriesIntentInfo> CREATOR = - new Creator<ParsedQueriesIntentInfo>() { - @Override - public ParsedQueriesIntentInfo createFromParcel(Parcel source) { - return new ParsedQueriesIntentInfo(source); - } - - @Override - public ParsedQueriesIntentInfo[] newArray(int size) { - return new ParsedQueriesIntentInfo[size]; - } - }; - } - - public static class ParsedComponent<IntentInfoType extends ParsedIntentInfo> implements - Parcelable { - - // TODO(b/135203078): Replace with "name", as not all usages are an actual class - public String className; - public int icon; - public int labelRes; - public CharSequence nonLocalizedLabel; - public int logo; - public int banner; - - public int descriptionRes; - - // TODO(b/135203078): Make subclass that contains these fields only for the necessary - // subtypes - protected boolean enabled = true; - protected boolean directBootAware; - public int flags; - - private String packageName; - private String splitName; - - // TODO(b/135203078): Make nullable - public List<IntentInfoType> intents = new ArrayList<>(); - - private transient ComponentName componentName; - - protected Bundle metaData; - - public void setSplitName(String splitName) { - this.splitName = splitName; - } - - public String getSplitName() { - return splitName; - } - - @CallSuper - public void setPackageName(String packageName) { - this.packageName = packageName; - this.componentName = null; - } - - void setPackageNameInternal(String packageName) { - this.packageName = packageName; - this.componentName = null; - } - - public String getPackageName() { - return packageName; - } - - public final boolean isDirectBootAware() { - return directBootAware; - } - - public final boolean isEnabled() { - return enabled; - } - - public final String getName() { - return className; - } - - public final Bundle getMetaData() { - return metaData; - } - - @UnsupportedAppUsage - public ComponentName getComponentName() { - if (componentName != null) { - return componentName; - } - if (className != null) { - componentName = new ComponentName(getPackageName(), - className); - } - return componentName; - } - - public void setFrom(ParsedComponent other) { - this.metaData = other.metaData; - this.className = other.className; - this.icon = other.icon; - this.labelRes = other.labelRes; - this.nonLocalizedLabel = other.nonLocalizedLabel; - this.logo = other.logo; - this.banner = other.banner; - - this.descriptionRes = other.descriptionRes; - - this.enabled = other.enabled; - this.directBootAware = other.directBootAware; - this.flags = other.flags; - - this.setPackageName(other.packageName); - this.setSplitName(other.getSplitName()); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(this.className); - dest.writeInt(this.icon); - dest.writeInt(this.labelRes); - dest.writeCharSequence(this.nonLocalizedLabel); - dest.writeInt(this.logo); - dest.writeInt(this.banner); - dest.writeInt(this.descriptionRes); - dest.writeBoolean(this.enabled); - dest.writeBoolean(this.directBootAware); - dest.writeInt(this.flags); - dest.writeString(this.packageName); - dest.writeString(this.splitName); - ParsedIntentInfo.writeIntentsList(this.intents, dest, flags); - dest.writeBundle(this.metaData); - } - - public ParsedComponent() { - } - - protected ParsedComponent(Parcel in) { - // We use the boot classloader for all classes that we load. - final ClassLoader boot = Object.class.getClassLoader(); - this.className = in.readString(); - this.icon = in.readInt(); - this.labelRes = in.readInt(); - this.nonLocalizedLabel = in.readCharSequence(); - this.logo = in.readInt(); - this.banner = in.readInt(); - this.descriptionRes = in.readInt(); - this.enabled = in.readByte() != 0; - this.directBootAware = in.readByte() != 0; - this.flags = in.readInt(); - this.packageName = in.readString(); - this.splitName = in.readString(); - this.intents = ParsedIntentInfo.createIntentsList(in); - this.metaData = in.readBundle(boot); - } - } - - // TODO(b/135203078): Document this. Maybe split out ParsedComponent to be actual components - // that can have their own processes, rather than something like permission which cannot. - public static class ParsedMainComponent<IntentInfoType extends ParsedIntentInfo> extends - ParsedComponent<IntentInfoType> { - - private String processName; - private String permission; - - public void setProcessName(String appProcessName, String processName) { - // TODO(b/135203078): Is this even necessary anymore? - this.processName = TextUtils.safeIntern( - processName == null ? appProcessName : processName); - } - - public String getProcessName() { - return processName; - } - - public void setPermission(String permission) { - this.permission = TextUtils.safeIntern(permission); - } - - public String getPermission() { - return permission; - } - - @Override - public void setFrom(ParsedComponent other) { - super.setFrom(other); - if (other instanceof ParsedMainComponent) { - ParsedMainComponent otherMainComponent = (ParsedMainComponent) other; - this.setProcessName(otherMainComponent.getProcessName(), - otherMainComponent.getProcessName()); - this.setPermission(otherMainComponent.getPermission()); - } - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeString(this.processName); - dest.writeString(this.permission); - } - - public ParsedMainComponent() { - } - - protected ParsedMainComponent(Parcel in) { - super(in); - this.processName = TextUtils.safeIntern(in.readString()); - this.permission = TextUtils.safeIntern(in.readString()); - } - - public static final Creator<ParsedMainComponent> CREATOR = - new Creator<ParsedMainComponent>() { - @Override - public ParsedMainComponent createFromParcel(Parcel source) { - return new ParsedMainComponent(source); - } - - @Override - public ParsedMainComponent[] newArray(int size) { - return new ParsedMainComponent[size]; - } - }; - } - - public static class ParsedActivity extends ParsedMainComponent<ParsedActivityIntentInfo> - implements Parcelable { - - public boolean exported; - public int theme; - public int uiOptions; - - public String targetActivity; - - public String parentActivityName; - public String taskAffinity; - public int privateFlags; - - public int launchMode; - public int documentLaunchMode; - public int maxRecents; - public int configChanges; - public int softInputMode; - public int persistableMode; - public int lockTaskLaunchMode; - - public int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; - public int resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; - - public float maxAspectRatio; - public boolean hasMaxAspectRatio; - - public float minAspectRatio; - public boolean hasMinAspectRatio; - - public String requestedVrComponent; - public int rotationAnimation = -1; - public int colorMode; - public int order; - - public ActivityInfo.WindowLayout windowLayout; - - @Override - public void setPackageName(String packageName) { - super.setPackageName(packageName); - for (ParsedIntentInfo intent : this.intents) { - intent.packageName = packageName; - } - } - - public boolean hasMaxAspectRatio() { - return hasMaxAspectRatio; - } - - public boolean hasMinAspectRatio() { - return hasMinAspectRatio; - } - - public void setMaxAspectRatio(int resizeMode, float maxAspectRatio) { - if (resizeMode == ActivityInfo.RESIZE_MODE_RESIZEABLE - || resizeMode == ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) { - // Resizeable activities can be put in any aspect ratio. - return; - } - - if (maxAspectRatio < 1.0f && maxAspectRatio != 0) { - // Ignore any value lesser than 1.0. - return; - } - - this.maxAspectRatio = maxAspectRatio; - hasMaxAspectRatio = true; - } - - public void setMinAspectRatio(int resizeMode, float minAspectRatio) { - if (resizeMode == RESIZE_MODE_RESIZEABLE - || resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) { - // Resizeable activities can be put in any aspect ratio. - return; - } - - if (minAspectRatio < 1.0f && minAspectRatio != 0) { - // Ignore any value lesser than 1.0. - return; - } - - this.minAspectRatio = minAspectRatio; - hasMinAspectRatio = true; - } - - public void addIntent(ParsedActivityIntentInfo intent) { - this.intents.add(intent); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeBoolean(this.exported); - dest.writeInt(this.theme); - dest.writeInt(this.uiOptions); - dest.writeString(this.targetActivity); - dest.writeString(this.parentActivityName); - dest.writeString(this.taskAffinity); - dest.writeInt(this.privateFlags); - dest.writeInt(this.launchMode); - dest.writeInt(this.documentLaunchMode); - dest.writeInt(this.maxRecents); - dest.writeInt(this.configChanges); - dest.writeInt(this.softInputMode); - dest.writeInt(this.persistableMode); - dest.writeInt(this.lockTaskLaunchMode); - dest.writeInt(this.screenOrientation); - dest.writeInt(this.resizeMode); - dest.writeFloat(this.maxAspectRatio); - dest.writeBoolean(this.hasMaxAspectRatio); - dest.writeFloat(this.minAspectRatio); - dest.writeBoolean(this.hasMinAspectRatio); - dest.writeString(this.requestedVrComponent); - dest.writeInt(this.rotationAnimation); - dest.writeInt(this.colorMode); - dest.writeInt(this.order); - dest.writeBundle(this.metaData); - - if (windowLayout != null) { - dest.writeInt(1); - dest.writeInt(windowLayout.width); - dest.writeFloat(windowLayout.widthFraction); - dest.writeInt(windowLayout.height); - dest.writeFloat(windowLayout.heightFraction); - dest.writeInt(windowLayout.gravity); - dest.writeInt(windowLayout.minWidth); - dest.writeInt(windowLayout.minHeight); - } else { - dest.writeInt(0); - } - } - - public ParsedActivity() { - } - - protected ParsedActivity(Parcel in) { - super(in); - this.exported = in.readByte() != 0; - this.theme = in.readInt(); - this.uiOptions = in.readInt(); - this.targetActivity = in.readString(); - this.parentActivityName = in.readString(); - this.taskAffinity = in.readString(); - this.privateFlags = in.readInt(); - this.launchMode = in.readInt(); - this.documentLaunchMode = in.readInt(); - this.maxRecents = in.readInt(); - this.configChanges = in.readInt(); - this.softInputMode = in.readInt(); - this.persistableMode = in.readInt(); - this.lockTaskLaunchMode = in.readInt(); - this.screenOrientation = in.readInt(); - this.resizeMode = in.readInt(); - this.maxAspectRatio = in.readFloat(); - this.hasMaxAspectRatio = in.readByte() != 0; - this.minAspectRatio = in.readFloat(); - this.hasMinAspectRatio = in.readByte() != 0; - this.requestedVrComponent = in.readString(); - this.rotationAnimation = in.readInt(); - this.colorMode = in.readInt(); - this.order = in.readInt(); - this.metaData = in.readBundle(); - if (in.readInt() == 1) { - windowLayout = new ActivityInfo.WindowLayout(in); - } - } - - public static final Creator<ParsedActivity> CREATOR = new Creator<ParsedActivity>() { - @Override - public ParsedActivity createFromParcel(Parcel source) { - return new ParsedActivity(source); - } - - @Override - public ParsedActivity[] newArray(int size) { - return new ParsedActivity[size]; - } - }; - } - - public static class ParsedService extends ParsedMainComponent<ParsedServiceIntentInfo> { - - public boolean exported; - public int flags; - public int foregroundServiceType; - public int order; - - @Override - public void setPackageName(String packageName) { - super.setPackageName(packageName); - for (ParsedIntentInfo intent : this.intents) { - intent.packageName = packageName; - } - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeBoolean(this.exported); - dest.writeBundle(this.metaData); - dest.writeInt(this.flags); - dest.writeInt(this.foregroundServiceType); - dest.writeInt(this.order); - } - - public ParsedService() { - } - - protected ParsedService(Parcel in) { - super(in); - this.exported = in.readByte() != 0; - this.metaData = in.readBundle(); - this.flags = in.readInt(); - this.foregroundServiceType = in.readInt(); - this.order = in.readInt(); - } - - public static final Creator<ParsedService> CREATOR = new Creator<ParsedService>() { - @Override - public ParsedService createFromParcel(Parcel source) { - return new ParsedService(source); - } - - @Override - public ParsedService[] newArray(int size) { - return new ParsedService[size]; - } - }; - } - - public static class ParsedProvider extends ParsedMainComponent<ParsedProviderIntentInfo> { - - protected boolean exported; - protected int flags; - protected int order; - private String authority; - protected boolean isSyncable; - private String readPermission; - private String writePermission; - protected boolean grantUriPermissions; - protected boolean forceUriPermissions; - protected boolean multiProcess; - protected int initOrder; - protected PatternMatcher[] uriPermissionPatterns; - protected PathPermission[] pathPermissions; - - protected void setFrom(ParsedProvider other) { - super.setFrom(other); - this.exported = other.exported; - - this.intents.clear(); - if (other.intents != null) { - this.intents.addAll(other.intents); - } - - this.flags = other.flags; - this.order = other.order; - this.setAuthority(other.getAuthority()); - this.isSyncable = other.isSyncable; - this.setReadPermission(other.getReadPermission()); - this.setWritePermission(other.getWritePermission()); - this.grantUriPermissions = other.grantUriPermissions; - this.forceUriPermissions = other.forceUriPermissions; - this.multiProcess = other.multiProcess; - this.initOrder = other.initOrder; - this.uriPermissionPatterns = other.uriPermissionPatterns; - this.pathPermissions = other.pathPermissions; - } - - @Override - public void setPackageName(String packageName) { - super.setPackageName(packageName); - for (ParsedIntentInfo intent : this.intents) { - intent.packageName = packageName; - } - } - - public boolean isExported() { - return exported; - } - - public List<ParsedProviderIntentInfo> getIntents() { - return intents; - } - - public int getFlags() { - return flags; - } - - public int getOrder() { - return order; - } - - public void setAuthority(String authority) { - this.authority = TextUtils.safeIntern(authority); - } - - public String getAuthority() { - return authority; - } - - public boolean isSyncable() { - return isSyncable; - } - - public void setReadPermission(String readPermission) { - this.readPermission = TextUtils.safeIntern(readPermission); - } - - public String getReadPermission() { - return readPermission; - } - - public void setWritePermission(String writePermission) { - this.writePermission = TextUtils.safeIntern(writePermission); - } - - public String getWritePermission() { - return writePermission; - } - - public boolean isGrantUriPermissions() { - return grantUriPermissions; - } - - public boolean isForceUriPermissions() { - return forceUriPermissions; - } - - public boolean isMultiProcess() { - return multiProcess; - } - - public int getInitOrder() { - return initOrder; - } - - public PatternMatcher[] getUriPermissionPatterns() { - return uriPermissionPatterns; - } - - public PathPermission[] getPathPermissions() { - return pathPermissions; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeBoolean(this.exported); - dest.writeInt(this.flags); - dest.writeInt(this.order); - dest.writeString(this.authority); - dest.writeBoolean(this.isSyncable); - dest.writeString(this.readPermission); - dest.writeString(this.writePermission); - dest.writeBoolean(this.grantUriPermissions); - dest.writeBoolean(this.forceUriPermissions); - dest.writeBoolean(this.multiProcess); - dest.writeInt(this.initOrder); - dest.writeTypedArray(this.uriPermissionPatterns, flags); - dest.writeTypedArray(this.pathPermissions, flags); - } - - public ParsedProvider() { - } - - protected ParsedProvider(Parcel in) { - super(in); - this.exported = in.readByte() != 0; - this.flags = in.readInt(); - this.order = in.readInt(); - this.authority = TextUtils.safeIntern(in.readString()); - this.isSyncable = in.readByte() != 0; - this.readPermission = TextUtils.safeIntern(in.readString()); - this.writePermission = TextUtils.safeIntern(in.readString()); - this.grantUriPermissions = in.readByte() != 0; - this.forceUriPermissions = in.readByte() != 0; - this.multiProcess = in.readByte() != 0; - this.initOrder = in.readInt(); - this.uriPermissionPatterns = in.createTypedArray(PatternMatcher.CREATOR); - this.pathPermissions = in.createTypedArray(PathPermission.CREATOR); - } - - public static final Creator<ParsedProvider> CREATOR = new Creator<ParsedProvider>() { - @Override - public ParsedProvider createFromParcel(Parcel source) { - return new ParsedProvider(source); - } - - @Override - public ParsedProvider[] newArray(int size) { - return new ParsedProvider[size]; - } - }; - } - - public static class ParsedPermission extends ParsedComponent<ParsedIntentInfo> { - - public String backgroundPermission; - private String group; - public int requestRes; - public int protectionLevel; - public boolean tree; - - public ParsedPermissionGroup parsedPermissionGroup; - - public void setName(String className) { - this.className = className; - } - - public void setGroup(String group) { - this.group = TextUtils.safeIntern(group); - } - - public String getGroup() { - return group; - } - - public boolean isRuntime() { - return protectionLevel == PermissionInfo.PROTECTION_DANGEROUS; - } - - public boolean isAppOp() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0; - } - - @PermissionInfo.Protection - public int getProtection() { - return protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; - } - - public int getProtectionFlags() { - return protectionLevel & ~PermissionInfo.PROTECTION_MASK_BASE; - } - - public int calculateFootprint() { - int size = getName().length(); - if (nonLocalizedLabel != null) { - size += nonLocalizedLabel.length(); - } - return size; - } - - public ParsedPermission() { - } - - public ParsedPermission(ParsedPermission other) { - // TODO(b/135203078): Better way to copy this? Maybe refactor to the point where copy - // isn't needed. - this.className = other.className; - this.icon = other.icon; - this.labelRes = other.labelRes; - this.nonLocalizedLabel = other.nonLocalizedLabel; - this.logo = other.logo; - this.banner = other.banner; - this.descriptionRes = other.descriptionRes; - this.enabled = other.enabled; - this.directBootAware = other.directBootAware; - this.flags = other.flags; - this.setSplitName(other.getSplitName()); - this.setPackageName(other.getPackageName()); - - this.intents.addAll(other.intents); - - if (other.metaData != null) { - this.metaData = new Bundle(); - this.metaData.putAll(other.metaData); - } - - this.backgroundPermission = other.backgroundPermission; - this.setGroup(other.group); - this.requestRes = other.requestRes; - this.protectionLevel = other.protectionLevel; - this.tree = other.tree; - - this.parsedPermissionGroup = other.parsedPermissionGroup; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeString(this.backgroundPermission); - dest.writeString(this.group); - dest.writeInt(this.requestRes); - dest.writeInt(this.protectionLevel); - dest.writeBoolean(this.tree); - dest.writeParcelable(this.parsedPermissionGroup, flags); - } - - protected ParsedPermission(Parcel in) { - super(in); - // We use the boot classloader for all classes that we load. - final ClassLoader boot = Object.class.getClassLoader(); - this.backgroundPermission = in.readString(); - this.group = TextUtils.safeIntern(in.readString()); - this.requestRes = in.readInt(); - this.protectionLevel = in.readInt(); - this.tree = in.readBoolean(); - this.parsedPermissionGroup = in.readParcelable(boot); - } - - public static final Creator<ParsedPermission> CREATOR = new Creator<ParsedPermission>() { - @Override - public ParsedPermission createFromParcel(Parcel source) { - return new ParsedPermission(source); - } - - @Override - public ParsedPermission[] newArray(int size) { - return new ParsedPermission[size]; - } - }; - } - - public static class ParsedPermissionGroup extends ParsedComponent<ParsedIntentInfo> { - - public int requestDetailResourceId; - public int backgroundRequestResourceId; - public int backgroundRequestDetailResourceId; - - public int requestRes; - public int priority; - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeInt(this.requestDetailResourceId); - dest.writeInt(this.backgroundRequestResourceId); - dest.writeInt(this.backgroundRequestDetailResourceId); - dest.writeInt(this.requestRes); - dest.writeInt(this.priority); - } - - public ParsedPermissionGroup() { - } - - protected ParsedPermissionGroup(Parcel in) { - super(in); - this.requestDetailResourceId = in.readInt(); - this.backgroundRequestResourceId = in.readInt(); - this.backgroundRequestDetailResourceId = in.readInt(); - this.requestRes = in.readInt(); - this.priority = in.readInt(); - } - - public static final Creator<ParsedPermissionGroup> CREATOR = - new Creator<ParsedPermissionGroup>() { - @Override - public ParsedPermissionGroup createFromParcel(Parcel source) { - return new ParsedPermissionGroup(source); - } - - @Override - public ParsedPermissionGroup[] newArray(int size) { - return new ParsedPermissionGroup[size]; - } - }; - } - - public static class ParsedInstrumentation extends ParsedComponent<ParsedIntentInfo> { - - private String targetPackage; - private String targetProcesses; - public boolean handleProfiling; - public boolean functionalTest; - - public String sourceDir; - public String publicSourceDir; - public String[] splitNames; - public String[] splitSourceDirs; - public String[] splitPublicSourceDirs; - public SparseArray<int[]> splitDependencies; - public String dataDir; - public String deviceProtectedDataDir; - public String credentialProtectedDataDir; - public String primaryCpuAbi; - public String secondaryCpuAbi; - public String nativeLibraryDir; - public String secondaryNativeLibraryDir; - - public ParsedInstrumentation() { - } - - public void setTargetPackage(String targetPackage) { - this.targetPackage = TextUtils.safeIntern(targetPackage); - } - - public String getTargetPackage() { - return targetPackage; - } - - public void setTargetProcesses(String targetProcesses) { - this.targetProcesses = TextUtils.safeIntern(targetProcesses); - } - - public String getTargetProcesses() { - return targetProcesses; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeString(this.targetPackage); - dest.writeString(this.targetProcesses); - dest.writeBoolean(this.handleProfiling); - dest.writeBoolean(this.functionalTest); - dest.writeString(this.sourceDir); - dest.writeString(this.publicSourceDir); - dest.writeStringArray(this.splitNames); - dest.writeStringArray(this.splitSourceDirs); - dest.writeStringArray(this.splitPublicSourceDirs); - dest.writeSparseArray(this.splitDependencies); - dest.writeString(this.dataDir); - dest.writeString(this.deviceProtectedDataDir); - dest.writeString(this.credentialProtectedDataDir); - dest.writeString(this.primaryCpuAbi); - dest.writeString(this.secondaryCpuAbi); - dest.writeString(this.nativeLibraryDir); - dest.writeString(this.secondaryNativeLibraryDir); - } - - protected ParsedInstrumentation(Parcel in) { - super(in); - // We use the boot classloader for all classes that we load. - final ClassLoader boot = Object.class.getClassLoader(); - this.targetPackage = TextUtils.safeIntern(in.readString()); - this.targetProcesses = TextUtils.safeIntern(in.readString()); - this.handleProfiling = in.readByte() != 0; - this.functionalTest = in.readByte() != 0; - this.sourceDir = in.readString(); - this.publicSourceDir = in.readString(); - this.splitNames = in.createStringArray(); - this.splitSourceDirs = in.createStringArray(); - this.splitPublicSourceDirs = in.createStringArray(); - this.splitDependencies = in.readSparseArray(boot); - this.dataDir = in.readString(); - this.deviceProtectedDataDir = in.readString(); - this.credentialProtectedDataDir = in.readString(); - this.primaryCpuAbi = in.readString(); - this.secondaryCpuAbi = in.readString(); - this.nativeLibraryDir = in.readString(); - this.secondaryNativeLibraryDir = in.readString(); - } - - public static final Creator<ParsedInstrumentation> CREATOR = - new Creator<ParsedInstrumentation>() { - @Override - public ParsedInstrumentation createFromParcel(Parcel source) { - return new ParsedInstrumentation(source); - } - - @Override - public ParsedInstrumentation[] newArray(int size) { - return new ParsedInstrumentation[size]; - } - }; - } - - public static ParsedActivity parseActivity( - String[] separateProcesses, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser, int flags, String[] outError, - boolean receiver, boolean hardwareAccelerated) - throws XmlPullParserException, IOException { - - TypedArray sa = null; - boolean visibleToEphemeral; - boolean setExported; - - int targetSdkVersion = parsingPackage.getTargetSdkVersion(); - String packageName = parsingPackage.getPackageName(); - String packageProcessName = parsingPackage.getProcessName(); - ParsedActivity result = new ParsedActivity(); - - try { - sa = res.obtainAttributes(parser, R.styleable.AndroidManifestActivity); - - String tag = receiver ? "<receiver>" : "<activity>"; - - String name = sa.getNonConfigurationString(R.styleable.AndroidManifestActivity_name, 0); - if (name == null) { - outError[0] = tag + " does not specify android:name"; - return null; - } else { - String className = ApkParseUtils.buildClassName(packageName, name); - if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) { - outError[0] = tag + " invalid android:name"; - return null; - } else if (className == null) { - outError[0] = "Empty class name in package " + packageName; - return null; - } - - result.className = className; - } - - int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId( - R.styleable.AndroidManifestActivity_roundIcon, 0) : 0; - if (roundIconVal != 0) { - result.icon = roundIconVal; - result.nonLocalizedLabel = null; - } else { - int iconVal = sa.getResourceId(R.styleable.AndroidManifestActivity_icon, 0); - if (iconVal != 0) { - result.icon = iconVal; - result.nonLocalizedLabel = null; - } - } - - int logoVal = sa.getResourceId(R.styleable.AndroidManifestActivity_logo, 0); - if (logoVal != 0) { - result.logo = logoVal; - } - - int bannerVal = sa.getResourceId(R.styleable.AndroidManifestActivity_banner, 0); - if (bannerVal != 0) { - result.banner = bannerVal; - } - - TypedValue v = sa.peekValue(R.styleable.AndroidManifestActivity_label); - if (v != null && (result.labelRes = v.resourceId) == 0) { - result.nonLocalizedLabel = v.coerceToString(); - } - - result.setPackageNameInternal(packageName); - - CharSequence pname; - if (parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.FROYO) { - pname = sa.getNonConfigurationString(R.styleable.AndroidManifestActivity_process, - Configuration.NATIVE_CONFIG_VERSION); - } else { - // Some older apps have been seen to use a resource reference - // here that on older builds was ignored (with a warning). We - // need to continue to do this for them so they don't break. - pname = sa.getNonResourceString(R.styleable.AndroidManifestActivity_process); - } - - result.setProcessName(packageProcessName, PackageParser.buildProcessName(packageName, - packageProcessName, pname, - flags, separateProcesses, outError)); - - result.descriptionRes = sa.getResourceId( - R.styleable.AndroidManifestActivity_description, 0); - - result.enabled = sa.getBoolean(R.styleable.AndroidManifestActivity_enabled, true); - - setExported = sa.hasValue(R.styleable.AndroidManifestActivity_exported); - if (setExported) { - result.exported = sa.getBoolean(R.styleable.AndroidManifestActivity_exported, - false); - } - - result.theme = sa.getResourceId(R.styleable.AndroidManifestActivity_theme, 0); - - result.uiOptions = sa.getInt(R.styleable.AndroidManifestActivity_uiOptions, - parsingPackage.getUiOptions()); - - String parentName = sa.getNonConfigurationString( - R.styleable.AndroidManifestActivity_parentActivityName, - Configuration.NATIVE_CONFIG_VERSION); - if (parentName != null) { - String parentClassName = ApkParseUtils.buildClassName(packageName, parentName); - if (parentClassName == null) { - Log.e(TAG, - "Activity " + result.className - + " specified invalid parentActivityName " + - parentName); - } else { - result.parentActivityName = parentClassName; - } - } - - String str; - str = sa.getNonConfigurationString(R.styleable.AndroidManifestActivity_permission, 0); - if (str == null) { - result.setPermission(parsingPackage.getPermission()); - } else { - result.setPermission(str); - } - - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestActivity_taskAffinity, - Configuration.NATIVE_CONFIG_VERSION); - result.taskAffinity = PackageParser.buildTaskAffinityName( - packageName, - parsingPackage.getTaskAffinity(), str, outError); - - result.setSplitName( - sa.getNonConfigurationString(R.styleable.AndroidManifestActivity_splitName, 0)); - - result.flags = 0; - if (sa.getBoolean( - R.styleable.AndroidManifestActivity_multiprocess, false)) { - result.flags |= ActivityInfo.FLAG_MULTIPROCESS; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_finishOnTaskLaunch, false)) { - result.flags |= ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_clearTaskOnLaunch, false)) { - result.flags |= ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_noHistory, false)) { - result.flags |= ActivityInfo.FLAG_NO_HISTORY; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_alwaysRetainTaskState, false)) { - result.flags |= ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_stateNotNeeded, false)) { - result.flags |= ActivityInfo.FLAG_STATE_NOT_NEEDED; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_excludeFromRecents, false)) { - result.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_allowTaskReparenting, - (parsingPackage.getFlags() & ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING) - != 0)) { - result.flags |= ActivityInfo.FLAG_ALLOW_TASK_REPARENTING; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_finishOnCloseSystemDialogs, - false)) { - result.flags |= ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_showOnLockScreen, false) - || sa.getBoolean(R.styleable.AndroidManifestActivity_showForAllUsers, false)) { - result.flags |= ActivityInfo.FLAG_SHOW_FOR_ALL_USERS; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_immersive, false)) { - result.flags |= ActivityInfo.FLAG_IMMERSIVE; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_systemUserOnly, false)) { - result.flags |= ActivityInfo.FLAG_SYSTEM_USER_ONLY; - } - - boolean directBootAware; - - if (!receiver) { - if (sa.getBoolean(R.styleable.AndroidManifestActivity_hardwareAccelerated, - hardwareAccelerated)) { - result.flags |= ActivityInfo.FLAG_HARDWARE_ACCELERATED; - } - - result.launchMode = sa.getInt( - R.styleable.AndroidManifestActivity_launchMode, - ActivityInfo.LAUNCH_MULTIPLE); - result.documentLaunchMode = sa.getInt( - R.styleable.AndroidManifestActivity_documentLaunchMode, - ActivityInfo.DOCUMENT_LAUNCH_NONE); - result.maxRecents = sa.getInt( - R.styleable.AndroidManifestActivity_maxRecents, - ActivityTaskManager.getDefaultAppRecentsLimitStatic()); - result.configChanges = PackageParser.getActivityConfigChanges( - sa.getInt(R.styleable.AndroidManifestActivity_configChanges, 0), - sa.getInt(R.styleable.AndroidManifestActivity_recreateOnConfigChanges, 0)); - result.softInputMode = sa.getInt( - R.styleable.AndroidManifestActivity_windowSoftInputMode, 0); - - result.persistableMode = sa.getInteger( - R.styleable.AndroidManifestActivity_persistableMode, - ActivityInfo.PERSIST_ROOT_ONLY); - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_allowEmbedded, false)) { - result.flags |= ActivityInfo.FLAG_ALLOW_EMBEDDED; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_autoRemoveFromRecents, - false)) { - result.flags |= ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_relinquishTaskIdentity, - false)) { - result.flags |= ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_resumeWhilePausing, false)) { - result.flags |= ActivityInfo.FLAG_RESUME_WHILE_PAUSING; - } - - int screenOrientation = sa.getInt( - R.styleable.AndroidManifestActivity_screenOrientation, - SCREEN_ORIENTATION_UNSPECIFIED); - result.screenOrientation = screenOrientation; - - int resizeMode = getActivityResizeMode(parsingPackage, sa, screenOrientation); - result.resizeMode = resizeMode; - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_supportsPictureInPicture, - false)) { - result.flags |= FLAG_SUPPORTS_PICTURE_IN_PICTURE; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_alwaysFocusable, false)) { - result.flags |= FLAG_ALWAYS_FOCUSABLE; - } - - if (sa.hasValue(R.styleable.AndroidManifestActivity_maxAspectRatio) - && sa.getType(R.styleable.AndroidManifestActivity_maxAspectRatio) - == TypedValue.TYPE_FLOAT) { - result.setMaxAspectRatio(resizeMode, - sa.getFloat(R.styleable.AndroidManifestActivity_maxAspectRatio, - 0 /*default*/)); - } - - if (sa.hasValue(R.styleable.AndroidManifestActivity_minAspectRatio) - && sa.getType(R.styleable.AndroidManifestActivity_minAspectRatio) - == TypedValue.TYPE_FLOAT) { - result.setMinAspectRatio(resizeMode, - sa.getFloat(R.styleable.AndroidManifestActivity_minAspectRatio, - 0 /*default*/)); - } - - result.lockTaskLaunchMode = - sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0); - - directBootAware = sa.getBoolean( - R.styleable.AndroidManifestActivity_directBootAware, - false); - - result.requestedVrComponent = - sa.getString(R.styleable.AndroidManifestActivity_enableVrMode); - - result.rotationAnimation = - sa.getInt(R.styleable.AndroidManifestActivity_rotationAnimation, - ROTATION_ANIMATION_UNSPECIFIED); - - result.colorMode = sa.getInt(R.styleable.AndroidManifestActivity_colorMode, - ActivityInfo.COLOR_MODE_DEFAULT); - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_showWhenLocked, false)) { - result.flags |= ActivityInfo.FLAG_SHOW_WHEN_LOCKED; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_turnScreenOn, false)) { - result.flags |= ActivityInfo.FLAG_TURN_SCREEN_ON; - } - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_inheritShowWhenLocked, - false)) { - result.privateFlags |= ActivityInfo.FLAG_INHERIT_SHOW_WHEN_LOCKED; - } - } else { - result.launchMode = ActivityInfo.LAUNCH_MULTIPLE; - result.configChanges = 0; - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_singleUser, false)) { - result.flags |= ActivityInfo.FLAG_SINGLE_USER; - } - directBootAware = sa.getBoolean( - R.styleable.AndroidManifestActivity_directBootAware, - false); - } - - result.directBootAware = directBootAware; - - if (directBootAware) { - parsingPackage.setPartiallyDirectBootAware(true); - } - - // can't make this final; we may set it later via meta-data - visibleToEphemeral = sa.getBoolean( - R.styleable.AndroidManifestActivity_visibleToInstantApps, false); - if (visibleToEphemeral) { - result.flags |= ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP; - parsingPackage.setVisibleToInstantApps(true); - } - } finally { - if (sa != null) { - sa.recycle(); - } - } - - - if (receiver && (parsingPackage.getPrivateFlags() - & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) { - // A heavy-weight application can not have receives in its main process - if (result.getProcessName().equals(packageName)) { - outError[0] = "Heavy-weight applications can not have receivers in main process"; - return null; - } - } - - if (outError[0] != null) { - return null; - } - - int outerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG - || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - if (parser.getName().equals("intent-filter")) { - ParsedActivityIntentInfo intentInfo = new ParsedActivityIntentInfo(packageName, - result.className); - if (!parseIntentInfo(intentInfo, parsingPackage, res, parser, - true /*allowGlobs*/, - true /*allowAutoVerify*/, outError)) { - return null; - } - if (intentInfo.countActions() == 0) { - Slog.w(TAG, "No actions in intent filter at " - + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - } else { - result.order = Math.max(intentInfo.getOrder(), result.order); - result.addIntent(intentInfo); - } - // adjust activity flags when we implicitly expose it via a browsable filter - final int visibility = visibleToEphemeral - ? IntentFilter.VISIBILITY_EXPLICIT - : !receiver && isImplicitlyExposedIntent(intentInfo) - ? IntentFilter.VISIBILITY_IMPLICIT - : IntentFilter.VISIBILITY_NONE; - intentInfo.setVisibilityToInstantApp(visibility); - if (intentInfo.isVisibleToInstantApp()) { - result.flags |= ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP; - } - if (intentInfo.isImplicitlyVisibleToInstantApp()) { - result.flags |= ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP; - } - if (PackageParser.LOG_UNSAFE_BROADCASTS && receiver - && (targetSdkVersion >= Build.VERSION_CODES.O)) { - for (int i = 0; i < intentInfo.countActions(); i++) { - final String action = intentInfo.getAction(i); - if (action == null || !action.startsWith("android.")) continue; - if (!PackageParser.SAFE_BROADCASTS.contains(action)) { - Slog.w(TAG, "Broadcast " + action + " may never be delivered to " - + packageName + " as requested at: " - + parser.getPositionDescription()); - } - } - } - } else if (!receiver && parser.getName().equals("preferred")) { - ParsedActivityIntentInfo intentInfo = new ParsedActivityIntentInfo(packageName, - result.className); - if (!parseIntentInfo(intentInfo, parsingPackage, res, parser, - false /*allowGlobs*/, - false /*allowAutoVerify*/, outError)) { - return null; - } - // adjust activity flags when we implicitly expose it via a browsable filter - final int visibility = visibleToEphemeral - ? IntentFilter.VISIBILITY_EXPLICIT - : !receiver && isImplicitlyExposedIntent(intentInfo) - ? IntentFilter.VISIBILITY_IMPLICIT - : IntentFilter.VISIBILITY_NONE; - intentInfo.setVisibilityToInstantApp(visibility); - if (intentInfo.isVisibleToInstantApp()) { - result.flags |= ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP; - } - if (intentInfo.isImplicitlyVisibleToInstantApp()) { - result.flags |= ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP; - } - - if (intentInfo.countActions() == 0) { - Slog.w(TAG, "No actions in preferred at " - + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - } else { - parsingPackage.addPreferredActivityFilter(intentInfo); - } - } else if (parser.getName().equals("meta-data")) { - if ((result.metaData = ApkParseUtils.parseMetaData(parsingPackage, res, parser, - result.metaData, - outError)) == null) { - return null; - } - } else if (!receiver && parser.getName().equals("layout")) { - result.windowLayout = parseLayout(res, parser); - } else { - if (!PackageParser.RIGID_PARSER) { - Slog.w(TAG, "Problem in package " + parsingPackage.getBaseCodePath() + ":"); - if (receiver) { - Slog.w(TAG, "Unknown element under <receiver>: " + parser.getName() - + " at " + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - } else { - Slog.w(TAG, "Unknown element under <activity>: " + parser.getName() - + " at " + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - } - XmlUtils.skipCurrentTag(parser); - continue; - } else { - if (receiver) { - outError[0] = "Bad element under <receiver>: " + parser.getName(); - } else { - outError[0] = "Bad element under <activity>: " + parser.getName(); - } - return null; - } - } - } - - if (!setExported) { - result.exported = result.intents.size() > 0; - } - - return result; - } - - public static boolean isImplicitlyExposedIntent(ParsedIntentInfo intentInfo) { - return intentInfo.hasCategory(Intent.CATEGORY_BROWSABLE) - || intentInfo.hasAction(Intent.ACTION_SEND) - || intentInfo.hasAction(Intent.ACTION_SENDTO) - || intentInfo.hasAction(Intent.ACTION_SEND_MULTIPLE); - } - - public static int getActivityResizeMode( - ParsingPackage parsingPackage, - TypedArray sa, - int screenOrientation - ) { - int privateFlags = parsingPackage.getPrivateFlags(); - final boolean appExplicitDefault = (privateFlags - & (ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE - | ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE)) != 0; - - if (sa.hasValue(R.styleable.AndroidManifestActivity_resizeableActivity) - || appExplicitDefault) { - // Activity or app explicitly set if it is resizeable or not; - final boolean appResizeable = (privateFlags - & ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE) != 0; - if (sa.getBoolean(R.styleable.AndroidManifestActivity_resizeableActivity, - appResizeable)) { - return ActivityInfo.RESIZE_MODE_RESIZEABLE; - } else { - return ActivityInfo.RESIZE_MODE_UNRESIZEABLE; - } - } - - if ((privateFlags - & ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) - != 0) { - // The activity or app didn't explicitly set the resizing option, however we want to - // make it resize due to the sdk version it is targeting. - return ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION; - } - - // resize preference isn't set and target sdk version doesn't support resizing apps by - // default. For the app to be resizeable if it isn't fixed orientation or immersive. - if (ActivityInfo.isFixedOrientationPortrait(screenOrientation)) { - return ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY; - } else if (ActivityInfo.isFixedOrientationLandscape(screenOrientation)) { - return ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY; - } else if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) { - return ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION; - } else { - return ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE; - } - } - - public static ParsedService parseService( - String[] separateProcesses, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser, int flags, String[] outError - ) throws XmlPullParserException, IOException { - TypedArray sa = null; - boolean visibleToEphemeral; - boolean setExported; - - String packageName = parsingPackage.getPackageName(); - String packageProcessName = parsingPackage.getProcessName(); - ParsedService result = new ParsedService(); - - try { - sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestService); - - String name = sa.getNonConfigurationString(R.styleable.AndroidManifestService_name, 0); - if (name == null) { - outError[0] = "<service> does not specify android:name"; - return null; - } else { - String className = ApkParseUtils.buildClassName(packageName, name); - if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) { - outError[0] = "<service> invalid android:name"; - return null; - } else if (className == null) { - outError[0] = "Empty class name in package " + packageName; - return null; - } - - result.className = className; - } - - int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId( - R.styleable.AndroidManifestService_roundIcon, 0) : 0; - if (roundIconVal != 0) { - result.icon = roundIconVal; - result.nonLocalizedLabel = null; - } else { - int iconVal = sa.getResourceId(R.styleable.AndroidManifestService_icon, 0); - if (iconVal != 0) { - result.icon = iconVal; - result.nonLocalizedLabel = null; - } - } - - int logoVal = sa.getResourceId(R.styleable.AndroidManifestService_logo, 0); - if (logoVal != 0) { - result.logo = logoVal; - } - - int bannerVal = sa.getResourceId(R.styleable.AndroidManifestService_banner, 0); - if (bannerVal != 0) { - result.banner = bannerVal; - } - - TypedValue v = sa.peekValue(R.styleable.AndroidManifestService_label); - if (v != null && (result.labelRes = v.resourceId) == 0) { - result.nonLocalizedLabel = v.coerceToString(); - } - - result.setPackageNameInternal(packageName); - - CharSequence pname; - if (parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.FROYO) { - pname = sa.getNonConfigurationString(R.styleable.AndroidManifestService_process, - Configuration.NATIVE_CONFIG_VERSION); - } else { - // Some older apps have been seen to use a resource reference - // here that on older builds was ignored (with a warning). We - // need to continue to do this for them so they don't break. - pname = sa.getNonResourceString(R.styleable.AndroidManifestService_process); - } - - result.setProcessName(packageProcessName, PackageParser.buildProcessName(packageName, - packageProcessName, pname, - flags, separateProcesses, outError)); - - result.descriptionRes = sa.getResourceId( - R.styleable.AndroidManifestService_description, 0); - - result.enabled = sa.getBoolean(R.styleable.AndroidManifestService_enabled, true); - - setExported = sa.hasValue( - R.styleable.AndroidManifestService_exported); - if (setExported) { - result.exported = sa.getBoolean( - R.styleable.AndroidManifestService_exported, false); - } - - String str = sa.getNonConfigurationString( - R.styleable.AndroidManifestService_permission, 0); - if (str == null) { - result.setPermission(parsingPackage.getPermission()); - } else { - result.setPermission(str); - } - - result.setSplitName( - sa.getNonConfigurationString(R.styleable.AndroidManifestService_splitName, 0)); - - result.foregroundServiceType = sa.getInt( - R.styleable.AndroidManifestService_foregroundServiceType, - ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE); - - result.flags = 0; - if (sa.getBoolean( - R.styleable.AndroidManifestService_stopWithTask, - false)) { - result.flags |= ServiceInfo.FLAG_STOP_WITH_TASK; - } - if (sa.getBoolean( - R.styleable.AndroidManifestService_isolatedProcess, - false)) { - result.flags |= ServiceInfo.FLAG_ISOLATED_PROCESS; - } - if (sa.getBoolean( - R.styleable.AndroidManifestService_externalService, - false)) { - result.flags |= ServiceInfo.FLAG_EXTERNAL_SERVICE; - } - if (sa.getBoolean( - R.styleable.AndroidManifestService_useAppZygote, - false)) { - result.flags |= ServiceInfo.FLAG_USE_APP_ZYGOTE; - } - if (sa.getBoolean( - R.styleable.AndroidManifestService_singleUser, - false)) { - result.flags |= ServiceInfo.FLAG_SINGLE_USER; - } - - result.directBootAware = sa.getBoolean( - R.styleable.AndroidManifestService_directBootAware, - false); - if (result.directBootAware) { - parsingPackage.setPartiallyDirectBootAware(true); - } - - visibleToEphemeral = sa.getBoolean( - R.styleable.AndroidManifestService_visibleToInstantApps, false); - if (visibleToEphemeral) { - result.flags |= ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP; - parsingPackage.setVisibleToInstantApps(true); - } - } finally { - if (sa != null) { - sa.recycle(); - } - } - - if (parsingPackage.cantSaveState()) { - // A heavy-weight application can not have services in its main process - // We can do direct compare because we intern all strings. - if (Objects.equals(result.getProcessName(), parsingPackage.getPackageName())) { - outError[0] = "Heavy-weight applications can not have services in main process"; - return null; - } - } - - int outerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG - || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - if (parser.getName().equals("intent-filter")) { - ParsedServiceIntentInfo intent = new ParsedServiceIntentInfo(packageName, - result.className); - if (!parseIntentInfo(intent, parsingPackage, res, parser, true /*allowGlobs*/, - false /*allowAutoVerify*/, - outError)) { - return null; - } - if (visibleToEphemeral) { - intent.setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT); - result.flags |= ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP; - } - result.order = Math.max(intent.getOrder(), result.order); - result.intents.add(intent); - } else if (parser.getName().equals("meta-data")) { - if ((result.metaData = ApkParseUtils.parseMetaData(parsingPackage, res, parser, - result.metaData, - outError)) == null) { - return null; - } - } else { - if (!PackageParser.RIGID_PARSER) { - Slog.w(TAG, "Unknown element under <service>: " - + parser.getName() + " at " + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - XmlUtils.skipCurrentTag(parser); - continue; - } else { - outError[0] = "Bad element under <service>: " + parser.getName(); - return null; - } - } - } - - if (!setExported) { - result.exported = result.intents.size() > 0; - } - - return result; - } - - public static ParsedProvider parseProvider( - String[] separateProcesses, - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser, int flags, String[] outError) - throws XmlPullParserException, IOException { - TypedArray sa = null; - String cpname; - boolean visibleToEphemeral; - - int targetSdkVersion = parsingPackage.getTargetSdkVersion(); - String packageName = parsingPackage.getPackageName(); - String packageProcessName = parsingPackage.getProcessName(); - ParsedProvider result = new ParsedProvider(); - - try { - sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestProvider); - - String name = sa.getNonConfigurationString(R.styleable.AndroidManifestProvider_name, 0); - if (name == null) { - outError[0] = "<provider> does not specify android:name"; - return null; - } else { - String className = ApkParseUtils.buildClassName(packageName, name); - if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) { - outError[0] = "<provider> invalid android:name"; - return null; - } else if (className == null) { - outError[0] = "Empty class name in package " + packageName; - return null; - } - - result.className = className; - } - - int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId( - R.styleable.AndroidManifestProvider_roundIcon, 0) : 0; - if (roundIconVal != 0) { - result.icon = roundIconVal; - result.nonLocalizedLabel = null; - } else { - int iconVal = sa.getResourceId(R.styleable.AndroidManifestProvider_icon, 0); - if (iconVal != 0) { - result.icon = iconVal; - result.nonLocalizedLabel = null; - } - } - - int logoVal = sa.getResourceId(R.styleable.AndroidManifestProvider_logo, 0); - if (logoVal != 0) { - result.logo = logoVal; - } - - int bannerVal = sa.getResourceId(R.styleable.AndroidManifestProvider_banner, 0); - if (bannerVal != 0) { - result.banner = bannerVal; - } - - TypedValue v = sa.peekValue(R.styleable.AndroidManifestProvider_label); - if (v != null && (result.labelRes = v.resourceId) == 0) { - result.nonLocalizedLabel = v.coerceToString(); - } - - result.setPackageNameInternal(packageName); - - CharSequence pname; - if (parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.FROYO) { - pname = sa.getNonConfigurationString(R.styleable.AndroidManifestProvider_process, - Configuration.NATIVE_CONFIG_VERSION); - } else { - // Some older apps have been seen to use a resource reference - // here that on older builds was ignored (with a warning). We - // need to continue to do this for them so they don't break. - pname = sa.getNonResourceString(R.styleable.AndroidManifestProvider_process); - } - - result.setProcessName(packageProcessName, PackageParser.buildProcessName(packageName, - packageProcessName, pname, - flags, separateProcesses, outError)); - - result.descriptionRes = sa.getResourceId( - R.styleable.AndroidManifestProvider_description, 0); - - result.enabled = sa.getBoolean(R.styleable.AndroidManifestProvider_enabled, true); - - boolean providerExportedDefault = false; - - if (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR1) { - // For compatibility, applications targeting API level 16 or lower - // should have their content providers exported by default, unless they - // specify otherwise. - providerExportedDefault = true; - } - - result.exported = sa.getBoolean( - R.styleable.AndroidManifestProvider_exported, - providerExportedDefault); - - cpname = sa.getNonConfigurationString( - R.styleable.AndroidManifestProvider_authorities, 0); - - result.isSyncable = sa.getBoolean( - R.styleable.AndroidManifestProvider_syncable, - false); - - String permission = sa.getNonConfigurationString( - R.styleable.AndroidManifestProvider_permission, 0); - String str = sa.getNonConfigurationString( - R.styleable.AndroidManifestProvider_readPermission, 0); - if (str == null) { - str = permission; - } - if (str == null) { - result.setReadPermission(parsingPackage.getPermission()); - } else { - result.setReadPermission(str); - } - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestProvider_writePermission, 0); - if (str == null) { - str = permission; - } - if (str == null) { - result.setWritePermission(parsingPackage.getPermission()); - } else { - result.setWritePermission(str); - } - - result.grantUriPermissions = sa.getBoolean( - R.styleable.AndroidManifestProvider_grantUriPermissions, - false); - - result.forceUriPermissions = sa.getBoolean( - R.styleable.AndroidManifestProvider_forceUriPermissions, - false); - - result.multiProcess = sa.getBoolean( - R.styleable.AndroidManifestProvider_multiprocess, - false); - - result.initOrder = sa.getInt( - R.styleable.AndroidManifestProvider_initOrder, - 0); - - result.setSplitName( - sa.getNonConfigurationString(R.styleable.AndroidManifestProvider_splitName, 0)); - - result.flags = 0; - - if (sa.getBoolean( - R.styleable.AndroidManifestProvider_singleUser, - false)) { - result.flags |= ProviderInfo.FLAG_SINGLE_USER; - } - - result.directBootAware = sa.getBoolean( - R.styleable.AndroidManifestProvider_directBootAware, - false); - if (result.directBootAware) { - parsingPackage.setPartiallyDirectBootAware(true); - } - - visibleToEphemeral = - sa.getBoolean(R.styleable.AndroidManifestProvider_visibleToInstantApps, false); - if (visibleToEphemeral) { - result.flags |= ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP; - parsingPackage.setVisibleToInstantApps(true); - } - } finally { - if (sa != null) { - sa.recycle(); - } - } - - if ((parsingPackage.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) - != 0) { - // A heavy-weight application can not have providers in its main process - if (result.getProcessName().equals(packageName)) { - outError[0] = "Heavy-weight applications can not have providers in main process"; - return null; - } - } - - if (cpname == null) { - outError[0] = "<provider> does not include authorities attribute"; - return null; - } - if (cpname.length() <= 0) { - outError[0] = "<provider> has empty authorities attribute"; - return null; - } - result.setAuthority(cpname); - - if (!parseProviderTags(parsingPackage, res, parser, visibleToEphemeral, result, outError)) { - return null; - } - - return result; - } - - public static ParsedQueriesIntentInfo parsedParsedQueriesIntentInfo( - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser, - String[] outError - ) throws IOException, XmlPullParserException { - ParsedQueriesIntentInfo intentInfo = new ParsedQueriesIntentInfo( - parsingPackage.getPackageName(), - null - ); - if (!parseIntentInfo( - intentInfo, - parsingPackage, - res, - parser, - true /*allowGlobs*/, - true /*allowAutoVerify*/, - outError - )) { - return null; - } - return intentInfo; - } - - private static boolean parseProviderTags( - ParsingPackage parsingPackage, - Resources res, XmlResourceParser parser, - boolean visibleToEphemeral, ParsedProvider outInfo, String[] outError) - throws XmlPullParserException, IOException { - int outerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG - || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - if (parser.getName().equals("intent-filter")) { - ParsedProviderIntentInfo intent = new ParsedProviderIntentInfo( - parsingPackage.getPackageName(), outInfo.className); - if (!parseIntentInfo(intent, parsingPackage, res, parser, true /*allowGlobs*/, - false /*allowAutoVerify*/, - outError)) { - return false; - } - if (visibleToEphemeral) { - intent.setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT); - outInfo.flags |= ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP; - } - outInfo.order = Math.max(intent.getOrder(), outInfo.order); - outInfo.intents.add(intent); - - } else if (parser.getName().equals("meta-data")) { - Bundle metaData = ApkParseUtils.parseMetaData(parsingPackage, res, parser, - outInfo.metaData, outError); - if (metaData == null) { - return false; - } else { - outInfo.metaData = metaData; - } - - } else if (parser.getName().equals("grant-uri-permission")) { - TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestGrantUriPermission); - - PatternMatcher pa = null; - - String str = sa.getNonConfigurationString( - R.styleable.AndroidManifestGrantUriPermission_path, 0); - if (str != null) { - pa = new PatternMatcher(str, PatternMatcher.PATTERN_LITERAL); - } - - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestGrantUriPermission_pathPrefix, 0); - if (str != null) { - pa = new PatternMatcher(str, PatternMatcher.PATTERN_PREFIX); - } - - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestGrantUriPermission_pathPattern, 0); - if (str != null) { - pa = new PatternMatcher(str, PatternMatcher.PATTERN_SIMPLE_GLOB); - } - - sa.recycle(); - - if (pa != null) { - if (outInfo.uriPermissionPatterns == null) { - outInfo.uriPermissionPatterns = new PatternMatcher[1]; - outInfo.uriPermissionPatterns[0] = pa; - } else { - final int N = outInfo.uriPermissionPatterns.length; - PatternMatcher[] newp = new PatternMatcher[N + 1]; - System.arraycopy(outInfo.uriPermissionPatterns, 0, newp, 0, N); - newp[N] = pa; - outInfo.uriPermissionPatterns = newp; - } - outInfo.grantUriPermissions = true; - } else { - if (!PackageParser.RIGID_PARSER) { - Slog.w(TAG, "Unknown element under <path-permission>: " - + parser.getName() + " at " + parsingPackage.getBaseCodePath() - + " " - + parser.getPositionDescription()); - XmlUtils.skipCurrentTag(parser); - continue; - } else { - outError[0] = "No path, pathPrefix, or pathPattern for <path-permission>"; - return false; - } - } - XmlUtils.skipCurrentTag(parser); - - } else if (parser.getName().equals("path-permission")) { - TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestPathPermission); - - PathPermission pa = null; - - String permission = sa.getNonConfigurationString( - R.styleable.AndroidManifestPathPermission_permission, 0); - String readPermission = sa.getNonConfigurationString( - R.styleable.AndroidManifestPathPermission_readPermission, 0); - if (readPermission == null) { - readPermission = permission; - } - String writePermission = sa.getNonConfigurationString( - R.styleable.AndroidManifestPathPermission_writePermission, 0); - if (writePermission == null) { - writePermission = permission; - } - - boolean havePerm = false; - if (readPermission != null) { - readPermission = readPermission.intern(); - havePerm = true; - } - if (writePermission != null) { - writePermission = writePermission.intern(); - havePerm = true; - } - - if (!havePerm) { - if (!PackageParser.RIGID_PARSER) { - Slog.w(TAG, "No readPermission or writePermssion for <path-permission>: " - + parser.getName() + " at " + parsingPackage.getBaseCodePath() - + " " - + parser.getPositionDescription()); - XmlUtils.skipCurrentTag(parser); - continue; - } else { - outError[0] = "No readPermission or writePermssion for <path-permission>"; - return false; - } - } - - String path = sa.getNonConfigurationString( - R.styleable.AndroidManifestPathPermission_path, 0); - if (path != null) { - pa = new PathPermission(path, - PatternMatcher.PATTERN_LITERAL, readPermission, writePermission); - } - - path = sa.getNonConfigurationString( - R.styleable.AndroidManifestPathPermission_pathPrefix, 0); - if (path != null) { - pa = new PathPermission(path, - PatternMatcher.PATTERN_PREFIX, readPermission, writePermission); - } - - path = sa.getNonConfigurationString( - R.styleable.AndroidManifestPathPermission_pathPattern, 0); - if (path != null) { - pa = new PathPermission(path, - PatternMatcher.PATTERN_SIMPLE_GLOB, readPermission, writePermission); - } - - path = sa.getNonConfigurationString( - R.styleable.AndroidManifestPathPermission_pathAdvancedPattern, 0); - if (path != null) { - pa = new PathPermission(path, - PatternMatcher.PATTERN_ADVANCED_GLOB, readPermission, writePermission); - } - - sa.recycle(); - - if (pa != null) { - if (outInfo.pathPermissions == null) { - outInfo.pathPermissions = new PathPermission[1]; - outInfo.pathPermissions[0] = pa; - } else { - final int N = outInfo.pathPermissions.length; - PathPermission[] newp = new PathPermission[N + 1]; - System.arraycopy(outInfo.pathPermissions, 0, newp, 0, N); - newp[N] = pa; - outInfo.pathPermissions = newp; - } - } else { - if (!PackageParser.RIGID_PARSER) { - Slog.w(TAG, "No path, pathPrefix, or pathPattern for <path-permission>: " - + parser.getName() + " at " + parsingPackage.getBaseCodePath() - + " " - + parser.getPositionDescription()); - XmlUtils.skipCurrentTag(parser); - continue; - } - outError[0] = "No path, pathPrefix, or pathPattern for <path-permission>"; - return false; - } - XmlUtils.skipCurrentTag(parser); - - } else { - if (!PackageParser.RIGID_PARSER) { - Slog.w(TAG, "Unknown element under <provider>: " - + parser.getName() + " at " + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - XmlUtils.skipCurrentTag(parser); - continue; - } else { - outError[0] = "Bad element under <provider>: " + parser.getName(); - return false; - } - } - } - return true; - } - - public static ParsedActivity parseActivityAlias( - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser, - String[] outError) - throws XmlPullParserException, IOException { - TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestActivityAlias); - - String targetActivity = sa.getNonConfigurationString( - R.styleable.AndroidManifestActivityAlias_targetActivity, - Configuration.NATIVE_CONFIG_VERSION); - if (targetActivity == null) { - outError[0] = "<activity-alias> does not specify android:targetActivity"; - sa.recycle(); - return null; - } - - String packageName = parsingPackage.getPackageName(); - targetActivity = ApkParseUtils.buildClassName(packageName, targetActivity); - if (targetActivity == null) { - outError[0] = "Empty class name in package " + packageName; - sa.recycle(); - return null; - } - - ParsedActivity target = null; - - List<ParsedActivity> activities = parsingPackage.getActivities(); - final int NA = activities.size(); - for (int i = 0; i < NA; i++) { - ParsedActivity t = activities.get(i); - if (targetActivity.equals(t.className)) { - target = t; - break; - } - } - - if (target == null) { - outError[0] = "<activity-alias> target activity " + targetActivity - + " not found in manifest with activities = " + parsingPackage.getActivities() - + ", parsedActivities = " + activities; - sa.recycle(); - return null; - } - - ParsedActivity result = new ParsedActivity(); - result.setPackageNameInternal(target.getPackageName()); - result.targetActivity = targetActivity; - result.configChanges = target.configChanges; - result.flags = target.flags; - result.privateFlags = target.privateFlags; - result.icon = target.icon; - result.logo = target.logo; - result.banner = target.banner; - result.labelRes = target.labelRes; - result.nonLocalizedLabel = target.nonLocalizedLabel; - result.launchMode = target.launchMode; - result.lockTaskLaunchMode = target.lockTaskLaunchMode; - result.descriptionRes = target.descriptionRes; - result.screenOrientation = target.screenOrientation; - result.taskAffinity = target.taskAffinity; - result.theme = target.theme; - result.softInputMode = target.softInputMode; - result.uiOptions = target.uiOptions; - result.parentActivityName = target.parentActivityName; - result.maxRecents = target.maxRecents; - result.windowLayout = target.windowLayout; - result.resizeMode = target.resizeMode; - result.maxAspectRatio = target.maxAspectRatio; - result.hasMaxAspectRatio = target.hasMaxAspectRatio; - result.minAspectRatio = target.minAspectRatio; - result.hasMinAspectRatio = target.hasMinAspectRatio; - result.requestedVrComponent = target.requestedVrComponent; - result.directBootAware = target.directBootAware; - - result.setProcessName(parsingPackage.getAppInfoProcessName(), target.getProcessName()); - - // Not all attributes from the target ParsedActivity are copied to the alias. - // Careful when adding an attribute and determine whether or not it should be copied. -// result.enabled = target.enabled; -// result.exported = target.exported; -// result.permission = target.permission; -// result.splitName = target.splitName; -// result.documentLaunchMode = target.documentLaunchMode; -// result.persistableMode = target.persistableMode; -// result.rotationAnimation = target.rotationAnimation; -// result.colorMode = target.colorMode; -// result.intents.addAll(target.intents); -// result.order = target.order; -// result.metaData = target.metaData; - - String name = sa.getNonConfigurationString(R.styleable.AndroidManifestActivityAlias_name, - 0); - if (name == null) { - outError[0] = "<activity-alias> does not specify android:name"; - return null; - } else { - String className = ApkParseUtils.buildClassName(packageName, name); - if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) { - outError[0] = "<activity-alias> invalid android:name"; - return null; - } else if (className == null) { - outError[0] = "Empty class name in package " + packageName; - return null; - } - - result.className = className; - } - - int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId( - R.styleable.AndroidManifestActivityAlias_roundIcon, 0) : 0; - if (roundIconVal != 0) { - result.icon = roundIconVal; - result.nonLocalizedLabel = null; - } else { - int iconVal = sa.getResourceId(R.styleable.AndroidManifestActivityAlias_icon, 0); - if (iconVal != 0) { - result.icon = iconVal; - result.nonLocalizedLabel = null; - } - } - - int logoVal = sa.getResourceId(R.styleable.AndroidManifestActivityAlias_logo, 0); - if (logoVal != 0) { - result.logo = logoVal; - } - - int bannerVal = sa.getResourceId(R.styleable.AndroidManifestActivityAlias_banner, 0); - if (bannerVal != 0) { - result.banner = bannerVal; - } - - TypedValue v = sa.peekValue(R.styleable.AndroidManifestActivityAlias_label); - if (v != null && (result.labelRes = v.resourceId) == 0) { - result.nonLocalizedLabel = v.coerceToString(); - } - - result.setPackageNameInternal(packageName); - - result.descriptionRes = sa.getResourceId( - R.styleable.AndroidManifestActivityAlias_description, 0); - - result.enabled = sa.getBoolean(R.styleable.AndroidManifestActivityAlias_enabled, true); - - final boolean setExported = sa.hasValue( - R.styleable.AndroidManifestActivityAlias_exported); - if (setExported) { - result.exported = sa.getBoolean( - R.styleable.AndroidManifestActivityAlias_exported, false); - } - - String str; - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestActivityAlias_permission, 0); - if (str != null) { - result.setPermission(str); - } - - String parentName = sa.getNonConfigurationString( - R.styleable.AndroidManifestActivityAlias_parentActivityName, - Configuration.NATIVE_CONFIG_VERSION); - if (parentName != null) { - String parentClassName = ApkParseUtils.buildClassName(result.getPackageName(), - parentName); - if (parentClassName == null) { - Log.e(TAG, "Activity alias " + result.className + - " specified invalid parentActivityName " + parentName); - outError[0] = null; - } else { - result.parentActivityName = parentClassName; - } - } - - // TODO add visibleToInstantApps attribute to activity alias - final boolean visibleToEphemeral = - ((result.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0); - - sa.recycle(); - - if (outError[0] != null) { - return null; - } - - int outerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG - || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - String tagName = parser.getName(); - if (tagName.equals("intent-filter")) { - ParsedActivityIntentInfo intent = new ParsedActivityIntentInfo(packageName, - result.className); - if (!parseIntentInfo(intent, parsingPackage, res, parser, true /*allowGlobs*/, - true /*allowAutoVerify*/, outError)) { - return null; - } - if (intent.countActions() == 0) { - Slog.w(TAG, "No actions in intent filter at " - + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - } else { - result.order = Math.max(intent.getOrder(), result.order); - result.addIntent(intent); - } - // adjust activity flags when we implicitly expose it via a browsable filter - final int visibility = visibleToEphemeral - ? IntentFilter.VISIBILITY_EXPLICIT - : isImplicitlyExposedIntent(intent) - ? IntentFilter.VISIBILITY_IMPLICIT - : IntentFilter.VISIBILITY_NONE; - intent.setVisibilityToInstantApp(visibility); - if (intent.isVisibleToInstantApp()) { - result.flags |= ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP; - } - if (intent.isImplicitlyVisibleToInstantApp()) { - result.flags |= ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP; - } - } else if (tagName.equals("meta-data")) { - if ((result.metaData = ApkParseUtils.parseMetaData(parsingPackage, res, parser, - result.metaData, - outError)) == null) { - return null; - } - } else { - if (!PackageParser.RIGID_PARSER) { - Slog.w(TAG, "Unknown element under <activity-alias>: " + tagName - + " at " + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - XmlUtils.skipCurrentTag(parser); - continue; - } else { - outError[0] = "Bad element under <activity-alias>: " + tagName; - return null; - } - } - } - - if (!setExported) { - result.exported = result.intents.size() > 0; - } - - return result; - } - - public static ParsedPermission parsePermission( - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser, - String[] outError - ) throws IOException, XmlPullParserException { - TypedArray sa = null; - String packageName = parsingPackage.getPackageName(); - ParsedPermission result = new ParsedPermission(); - - try { - sa = res.obtainAttributes(parser, R.styleable.AndroidManifestPermission); - - String name = sa.getNonConfigurationString(R.styleable.AndroidManifestPermission_name, - 0); - if (name == null) { - outError[0] = "<permission> does not specify android:name"; - return null; - } else { - String className = ApkParseUtils.buildClassName(packageName, name); - if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) { - outError[0] = "<permission> invalid android:name"; - return null; - } else if (className == null) { - outError[0] = "Empty class name in package " + packageName; - return null; - } - - result.className = className; - } - - int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId( - R.styleable.AndroidManifestPermission_roundIcon, 0) : 0; - if (roundIconVal != 0) { - result.icon = roundIconVal; - result.nonLocalizedLabel = null; - } else { - int iconVal = sa.getResourceId(R.styleable.AndroidManifestPermission_icon, 0); - if (iconVal != 0) { - result.icon = iconVal; - result.nonLocalizedLabel = null; - } - } - - int logoVal = sa.getResourceId(R.styleable.AndroidManifestPermission_logo, 0); - if (logoVal != 0) { - result.logo = logoVal; - } - - int bannerVal = sa.getResourceId(R.styleable.AndroidManifestPermission_banner, 0); - if (bannerVal != 0) { - result.banner = bannerVal; - } - - TypedValue v = sa.peekValue(R.styleable.AndroidManifestPermission_label); - if (v != null && (result.labelRes = v.resourceId) == 0) { - result.nonLocalizedLabel = v.coerceToString(); - } - - result.setPackageNameInternal(packageName); - - result.descriptionRes = sa.getResourceId( - R.styleable.AndroidManifestPermission_description, 0); - - if (sa.hasValue( - R.styleable.AndroidManifestPermission_backgroundPermission)) { - if ("android".equals(packageName)) { - result.backgroundPermission = sa.getNonResourceString( - R.styleable - .AndroidManifestPermission_backgroundPermission); - } else { - Slog.w(TAG, packageName + " defines a background permission. Only the " - + "'android' package can do that."); - } - } - - // Note: don't allow this value to be a reference to a resource - // that may change. - result.setGroup(sa.getNonResourceString( - R.styleable.AndroidManifestPermission_permissionGroup)); - - result.requestRes = sa.getResourceId( - R.styleable.AndroidManifestPermission_request, 0); - - result.protectionLevel = sa.getInt( - R.styleable.AndroidManifestPermission_protectionLevel, - PermissionInfo.PROTECTION_NORMAL); - - result.flags = sa.getInt( - R.styleable.AndroidManifestPermission_permissionFlags, 0); - - // For now only platform runtime permissions can be restricted - if (!result.isRuntime() || !"android".equals(result.getPackageName())) { - result.flags &= ~PermissionInfo.FLAG_HARD_RESTRICTED; - result.flags &= ~PermissionInfo.FLAG_SOFT_RESTRICTED; - } else { - // The platform does not get to specify conflicting permissions - if ((result.flags & PermissionInfo.FLAG_HARD_RESTRICTED) != 0 - && (result.flags & PermissionInfo.FLAG_SOFT_RESTRICTED) != 0) { - throw new IllegalStateException("Permission cannot be both soft and hard" - + " restricted: " + result.getName()); - } - } - - } finally { - if (sa != null) { - sa.recycle(); - } - } - - if (result.protectionLevel == -1) { - outError[0] = "<permission> does not specify protectionLevel"; - return null; - } - - result.protectionLevel = PermissionInfo.fixProtectionLevel(result.protectionLevel); - - if (result.getProtectionFlags() != 0) { - if ((result.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) == 0 - && (result.protectionLevel & PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) - == 0 - && (result.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) != - PermissionInfo.PROTECTION_SIGNATURE) { - outError[0] = "<permission> protectionLevel specifies a non-instant flag but is " - + "not based on signature type"; - return null; - } - } - - boolean success = parseAllMetaData(parsingPackage, res, parser, - "<permission>", result, outError); - if (!success || outError[0] != null) { - return null; - } - - return result; - } - - public static ParsedPermission parsePermissionTree( - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser, - String[] outError - ) throws IOException, XmlPullParserException { - TypedArray sa = null; - String packageName = parsingPackage.getPackageName(); - ParsedPermission result = new ParsedPermission(); - - try { - sa = res.obtainAttributes(parser, R.styleable.AndroidManifestPermissionTree); - - String name = sa.getNonConfigurationString( - R.styleable.AndroidManifestPermissionTree_name, 0); - if (name == null) { - outError[0] = "<permission-tree> does not specify android:name"; - return null; - } else { - String className = ApkParseUtils.buildClassName(packageName, name); - if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) { - outError[0] = "<permission-tree> invalid android:name"; - return null; - } else if (className == null) { - outError[0] = "Empty class name in package " + packageName; - return null; - } - - result.className = className; - } - - int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId( - R.styleable.AndroidManifestPermissionTree_roundIcon, 0) : 0; - if (roundIconVal != 0) { - result.icon = roundIconVal; - result.nonLocalizedLabel = null; - } else { - int iconVal = sa.getResourceId(R.styleable.AndroidManifestPermissionTree_icon, 0); - if (iconVal != 0) { - result.icon = iconVal; - result.nonLocalizedLabel = null; - } - } - - int logoVal = sa.getResourceId(R.styleable.AndroidManifestPermissionTree_logo, 0); - if (logoVal != 0) { - result.logo = logoVal; - } - - int bannerVal = sa.getResourceId(R.styleable.AndroidManifestPermissionTree_banner, 0); - if (bannerVal != 0) { - result.banner = bannerVal; - } - - TypedValue v = sa.peekValue(R.styleable.AndroidManifestPermissionTree_label); - if (v != null && (result.labelRes = v.resourceId) == 0) { - result.nonLocalizedLabel = v.coerceToString(); - } - - result.setPackageNameInternal(packageName); - } finally { - if (sa != null) { - sa.recycle(); - } - } - - int index = result.getName().indexOf('.'); - if (index > 0) { - index = result.getName().indexOf('.', index + 1); - } - if (index < 0) { - outError[0] = - "<permission-tree> name has less than three segments: " + result.getName(); - return null; - } - - result.descriptionRes = 0; - result.requestRes = 0; - result.protectionLevel = PermissionInfo.PROTECTION_NORMAL; - result.tree = true; - - boolean success = parseAllMetaData(parsingPackage, res, parser, - "<permission-tree>", result, outError); - if (!success || outError[0] != null) { - return null; - } - - return result; - } - - public static ParsedPermissionGroup parsePermissionGroup( - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser, - String[] outError - ) throws IOException, XmlPullParserException { - TypedArray sa = null; - String packageName = parsingPackage.getPackageName(); - ParsedPermissionGroup result = new ParsedPermissionGroup(); - - try { - sa = res.obtainAttributes(parser, R.styleable.AndroidManifestPermissionGroup); - - String name = sa.getNonConfigurationString( - R.styleable.AndroidManifestPermissionGroup_name, 0); - if (name == null) { - outError[0] = "<permission> does not specify android:name"; - return null; - } else { - String className = ApkParseUtils.buildClassName(packageName, name); - if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) { - outError[0] = "<permission> invalid android:name"; - return null; - } else if (className == null) { - outError[0] = "Empty class name in package " + packageName; - return null; - } - - result.className = className; - } - - int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId( - R.styleable.AndroidManifestPermissionGroup_roundIcon, 0) : 0; - if (roundIconVal != 0) { - result.icon = roundIconVal; - result.nonLocalizedLabel = null; - } else { - int iconVal = sa.getResourceId(R.styleable.AndroidManifestPermissionGroup_icon, 0); - if (iconVal != 0) { - result.icon = iconVal; - result.nonLocalizedLabel = null; - } - } - - int logoVal = sa.getResourceId(R.styleable.AndroidManifestPermissionGroup_logo, 0); - if (logoVal != 0) { - result.logo = logoVal; - } - - int bannerVal = sa.getResourceId(R.styleable.AndroidManifestPermissionGroup_banner, 0); - if (bannerVal != 0) { - result.banner = bannerVal; - } - - TypedValue v = sa.peekValue(R.styleable.AndroidManifestPermissionGroup_label); - if (v != null && (result.labelRes = v.resourceId) == 0) { - result.nonLocalizedLabel = v.coerceToString(); - } - - result.setPackageNameInternal(packageName); - - result.descriptionRes = sa.getResourceId( - R.styleable.AndroidManifestPermissionGroup_description, 0); - - result.requestDetailResourceId = sa.getResourceId( - R.styleable.AndroidManifestPermissionGroup_requestDetail, 0); - result.backgroundRequestResourceId = sa.getResourceId( - R.styleable.AndroidManifestPermissionGroup_backgroundRequest, - 0); - result.backgroundRequestDetailResourceId = sa.getResourceId( - R.styleable - .AndroidManifestPermissionGroup_backgroundRequestDetail, 0); - - result.requestRes = sa.getResourceId( - R.styleable.AndroidManifestPermissionGroup_request, 0); - result.flags = sa.getInt( - R.styleable.AndroidManifestPermissionGroup_permissionGroupFlags, - 0); - result.priority = sa.getInt( - R.styleable.AndroidManifestPermissionGroup_priority, 0); - - } finally { - if (sa != null) { - sa.recycle(); - } - } - - boolean success = parseAllMetaData(parsingPackage, res, parser, - "<permission-group>", result, outError); - if (!success || outError[0] != null) { - return null; - } - - return result; - } - - public static ParsedInstrumentation parseInstrumentation( - ParsingPackage parsingPackage, - Resources res, - XmlResourceParser parser, - String[] outError - ) throws IOException, XmlPullParserException { - TypedArray sa = null; - String packageName = parsingPackage.getPackageName(); - ParsedInstrumentation result = new ParsedInstrumentation(); - - try { - sa = res.obtainAttributes(parser, R.styleable.AndroidManifestInstrumentation); - - // TODO(b/135203078): Re-share all of the configuration for this. ParseComponentArgs was - // un-used for this, but can be adjusted and re-added to share all the initial result - // parsing for icon/logo/name/etc in all of these parse methods. - String name = sa.getNonConfigurationString( - R.styleable.AndroidManifestInstrumentation_name, 0); - if (name == null) { - outError[0] = "<instrumentation> does not specify android:name"; - return null; - } else { - String className = ApkParseUtils.buildClassName(packageName, name); - if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) { - outError[0] = "<instrumentation> invalid android:name"; - return null; - } else if (className == null) { - outError[0] = "Empty class name in package " + packageName; - return null; - } - - result.className = className; - } - - int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId( - R.styleable.AndroidManifestInstrumentation_roundIcon, 0) : 0; - if (roundIconVal != 0) { - result.icon = roundIconVal; - result.nonLocalizedLabel = null; - } else { - int iconVal = sa.getResourceId(R.styleable.AndroidManifestInstrumentation_icon, 0); - if (iconVal != 0) { - result.icon = iconVal; - result.nonLocalizedLabel = null; - } - } - - int logoVal = sa.getResourceId(R.styleable.AndroidManifestInstrumentation_logo, 0); - if (logoVal != 0) { - result.logo = logoVal; - } - - int bannerVal = sa.getResourceId(R.styleable.AndroidManifestInstrumentation_banner, 0); - if (bannerVal != 0) { - result.banner = bannerVal; - } - - TypedValue v = sa.peekValue(R.styleable.AndroidManifestInstrumentation_label); - if (v != null && (result.labelRes = v.resourceId) == 0) { - result.nonLocalizedLabel = v.coerceToString(); - } - - result.setPackageNameInternal(packageName); - - String str; - // Note: don't allow this value to be a reference to a resource - // that may change. - str = sa.getNonResourceString(R.styleable.AndroidManifestInstrumentation_targetPackage); - result.setTargetPackage(str); - - str = sa.getNonResourceString( - R.styleable.AndroidManifestInstrumentation_targetProcesses); - result.setTargetProcesses(str); - result.handleProfiling = sa.getBoolean( - R.styleable.AndroidManifestInstrumentation_handleProfiling, false); - result.functionalTest = sa.getBoolean( - R.styleable.AndroidManifestInstrumentation_functionalTest, false); - - } finally { - if (sa != null) { - sa.recycle(); - } - } - - boolean success = parseAllMetaData(parsingPackage, res, parser, - "<instrumentation>", result, outError); - if (!success || outError[0] != null) { - return null; - } - - return result; - } - - public static ActivityInfo.WindowLayout parseLayout(Resources res, AttributeSet attrs) { - TypedArray sw = res.obtainAttributes(attrs, - R.styleable.AndroidManifestLayout); - int width = -1; - float widthFraction = -1f; - int height = -1; - float heightFraction = -1f; - final int widthType = sw.getType( - R.styleable.AndroidManifestLayout_defaultWidth); - if (widthType == TypedValue.TYPE_FRACTION) { - widthFraction = sw.getFraction( - R.styleable.AndroidManifestLayout_defaultWidth, - 1, 1, -1); - } else if (widthType == TypedValue.TYPE_DIMENSION) { - width = sw.getDimensionPixelSize( - R.styleable.AndroidManifestLayout_defaultWidth, - -1); - } - final int heightType = sw.getType( - R.styleable.AndroidManifestLayout_defaultHeight); - if (heightType == TypedValue.TYPE_FRACTION) { - heightFraction = sw.getFraction( - R.styleable.AndroidManifestLayout_defaultHeight, - 1, 1, -1); - } else if (heightType == TypedValue.TYPE_DIMENSION) { - height = sw.getDimensionPixelSize( - R.styleable.AndroidManifestLayout_defaultHeight, - -1); - } - int gravity = sw.getInt( - R.styleable.AndroidManifestLayout_gravity, - Gravity.CENTER); - int minWidth = sw.getDimensionPixelSize( - R.styleable.AndroidManifestLayout_minWidth, - -1); - int minHeight = sw.getDimensionPixelSize( - R.styleable.AndroidManifestLayout_minHeight, - -1); - sw.recycle(); - return new ActivityInfo.WindowLayout(width, widthFraction, - height, heightFraction, gravity, minWidth, minHeight); - } - - public static boolean parseIntentInfo( - ParsedIntentInfo intentInfo, - ParsingPackage parsingPackage, - Resources res, XmlResourceParser parser, boolean allowGlobs, - boolean allowAutoVerify, String[] outError - ) throws XmlPullParserException, IOException { - TypedArray sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestIntentFilter); - - int priority = sa.getInt( - R.styleable.AndroidManifestIntentFilter_priority, 0); - intentInfo.setPriority(priority); - - int order = sa.getInt( - R.styleable.AndroidManifestIntentFilter_order, 0); - intentInfo.setOrder(order); - - TypedValue v = sa.peekValue( - R.styleable.AndroidManifestIntentFilter_label); - if (v != null && (intentInfo.labelRes = v.resourceId) == 0) { - intentInfo.nonLocalizedLabel = v.coerceToString(); - } - - int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId( - R.styleable.AndroidManifestIntentFilter_roundIcon, 0) : 0; - if (roundIconVal != 0) { - intentInfo.icon = roundIconVal; - } else { - intentInfo.icon = sa.getResourceId( - R.styleable.AndroidManifestIntentFilter_icon, 0); - } - - if (allowAutoVerify) { - intentInfo.setAutoVerify(sa.getBoolean( - R.styleable.AndroidManifestIntentFilter_autoVerify, - false)); - } - - sa.recycle(); - - int outerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - String nodeName = parser.getName(); - if (nodeName.equals("action")) { - String value = parser.getAttributeValue( - PackageParser.ANDROID_RESOURCES, "name"); - if (TextUtils.isEmpty(value)) { - outError[0] = "No value supplied for <android:name>"; - return false; - } - XmlUtils.skipCurrentTag(parser); - - intentInfo.addAction(value); - } else if (nodeName.equals("category")) { - String value = parser.getAttributeValue( - PackageParser.ANDROID_RESOURCES, "name"); - if (TextUtils.isEmpty(value)) { - outError[0] = "No value supplied for <android:name>"; - return false; - } - XmlUtils.skipCurrentTag(parser); - - intentInfo.addCategory(value); - - } else if (nodeName.equals("data")) { - sa = res.obtainAttributes(parser, - R.styleable.AndroidManifestData); - - String str = sa.getNonConfigurationString( - R.styleable.AndroidManifestData_mimeType, 0); - if (str != null) { - try { - intentInfo.addRawDataType(str); - } catch (IntentFilter.MalformedMimeTypeException e) { - outError[0] = e.toString(); - sa.recycle(); - return false; - } - } - - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestData_scheme, 0); - if (str != null) { - intentInfo.addDataScheme(str); - } - - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestData_ssp, 0); - if (str != null) { - intentInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_LITERAL); - } - - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestData_sspPrefix, 0); - if (str != null) { - intentInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_PREFIX); - } - - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestData_sspPattern, 0); - if (str != null) { - if (!allowGlobs) { - outError[0] = "sspPattern not allowed here; ssp must be literal"; - return false; - } - intentInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_SIMPLE_GLOB); - } - - String host = sa.getNonConfigurationString( - R.styleable.AndroidManifestData_host, 0); - String port = sa.getNonConfigurationString( - R.styleable.AndroidManifestData_port, 0); - if (host != null) { - intentInfo.addDataAuthority(host, port); - } - - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestData_path, 0); - if (str != null) { - intentInfo.addDataPath(str, PatternMatcher.PATTERN_LITERAL); - } - - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestData_pathPrefix, 0); - if (str != null) { - intentInfo.addDataPath(str, PatternMatcher.PATTERN_PREFIX); - } - - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestData_pathPattern, 0); - if (str != null) { - if (!allowGlobs) { - outError[0] = "pathPattern not allowed here; path must be literal"; - return false; - } - intentInfo.addDataPath(str, PatternMatcher.PATTERN_SIMPLE_GLOB); - } - - str = sa.getNonConfigurationString( - R.styleable.AndroidManifestData_pathAdvancedPattern, 0); - if (str != null) { - if (!allowGlobs) { - outError[0] = "pathAdvancedPattern not allowed here; path must be literal"; - return false; - } - intentInfo.addDataPath(str, PatternMatcher.PATTERN_ADVANCED_GLOB); - } - - sa.recycle(); - XmlUtils.skipCurrentTag(parser); - } else if (!PackageParser.RIGID_PARSER) { - Slog.w(TAG, "Unknown element under <intent-filter>: " - + parser.getName() + " at " + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - XmlUtils.skipCurrentTag(parser); - } else { - outError[0] = "Bad element under <intent-filter>: " + parser.getName(); - return false; - } - } - - intentInfo.hasDefault = intentInfo.hasCategory(Intent.CATEGORY_DEFAULT); - - if (PackageParser.DEBUG_PARSER) { - final StringBuilder cats = new StringBuilder("Intent d="); - cats.append(intentInfo.hasDefault); - cats.append(", cat="); - - final Iterator<String> it = intentInfo.categoriesIterator(); - if (it != null) { - while (it.hasNext()) { - cats.append(' '); - cats.append(it.next()); - } - } - Slog.d(TAG, cats.toString()); - } - - return true; - } - - private static boolean parseAllMetaData( - ParsingPackage parsingPackage, - Resources res, XmlResourceParser parser, String tag, - ParsedComponent outInfo, - String[] outError - ) throws XmlPullParserException, IOException { - int outerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG - || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - if (parser.getName().equals("meta-data")) { - if ((outInfo.metaData = ApkParseUtils.parseMetaData(parsingPackage, res, parser, - outInfo.metaData, outError)) == null) { - return false; - } - } else { - if (!PackageParser.RIGID_PARSER) { - Slog.w(TAG, "Unknown element under " + tag + ": " - + parser.getName() + " at " + parsingPackage.getBaseCodePath() + " " - + parser.getPositionDescription()); - XmlUtils.skipCurrentTag(parser); - continue; - } else { - outError[0] = "Bad element under " + tag + ": " + parser.getName(); - } - } - } - - return true; - } - - public static boolean isImplicitlyExposedIntent(IntentFilter intent) { - return intent.hasCategory(Intent.CATEGORY_BROWSABLE) - || intent.hasAction(Intent.ACTION_SEND) - || intent.hasAction(Intent.ACTION_SENDTO) - || intent.hasAction(Intent.ACTION_SEND_MULTIPLE); - } -} diff --git a/core/java/android/content/pm/parsing/PackageImpl.java b/core/java/android/content/pm/parsing/PackageImpl.java deleted file mode 100644 index 363cf80a0a1d..000000000000 --- a/core/java/android/content/pm/parsing/PackageImpl.java +++ /dev/null @@ -1,3213 +0,0 @@ -/* - * Copyright (C) 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 - */ - -package android.content.pm.parsing; - -import static android.os.Build.VERSION_CODES.DONUT; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.ConfigurationInfo; -import android.content.pm.FeatureGroupInfo; -import android.content.pm.FeatureInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageParser; -import android.content.pm.ProviderInfo; -import android.content.pm.ServiceInfo; -import android.content.pm.SharedLibraryInfo; -import android.content.pm.parsing.ComponentParseUtils.ParsedActivity; -import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo; -import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation; -import android.content.pm.parsing.ComponentParseUtils.ParsedIntentInfo; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermission; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup; -import android.content.pm.parsing.ComponentParseUtils.ParsedProvider; -import android.content.pm.parsing.ComponentParseUtils.ParsedService; -import android.content.res.TypedArray; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.os.Parcel; -import android.os.UserHandle; -import android.os.storage.StorageManager; -import android.text.TextUtils; -import android.util.ArrayMap; -import android.util.ArraySet; -import android.util.SparseArray; - -import com.android.internal.R; -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.ArrayUtils; -import com.android.server.SystemConfig; - -import java.security.PublicKey; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; - -/** - * The backing data for a package that was parsed from disk. - * - * TODO(b/135203078): Convert Lists used as sets into Sets, to better express intended use case - * TODO(b/135203078): Field nullability annotations - * TODO(b/135203078): Convert = 1 fields into Booleans - * TODO(b/135203078): Make all lists nullable and Collections.unmodifiable immutable when returned. - * Prefer add/set methods if adding is necessary. - * TODO(b/135203078): Consider comments to disable auto-format and single-line, single-space all the - * get/set methods to make this class far more compact. Maybe even separate some logic into parent - * classes, assuming there is no overhead. - * TODO(b/135203078): Copy documentation from PackageParser#Package for the relevant fields included - * here. Should clarify and clean up any differences. Also consider renames if it helps make - * things clearer. - * TODO(b/135203078): Intern all possibl e String values? Initial refactor just mirrored old - * behavior. - * - * @hide - */ -public final class PackageImpl implements ParsingPackage, ParsedPackage, AndroidPackage, - AndroidPackageWrite { - - private static final String TAG = "PackageImpl"; - - // Resource boolean are -1, so 1 means we don't know the value. - private int supportsSmallScreens = 1; - private int supportsNormalScreens = 1; - private int supportsLargeScreens = 1; - private int supportsXLargeScreens = 1; - private int resizeable = 1; - private int anyDensity = 1; - - private long[] lastPackageUsageTimeInMills = - new long[PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT]; - - private int versionCode; - private int versionCodeMajor; - private int baseRevisionCode; - private String versionName; - - private boolean coreApp; - private int compileSdkVersion; - private String compileSdkVersionCodename; - - private String packageName; - private String realPackage; - private String manifestPackageName; - private String baseCodePath; - - private boolean requiredForAllUsers; - private String restrictedAccountType; - private String requiredAccountType; - - private boolean baseHardwareAccelerated; - - private String overlayTarget; - private String overlayTargetName; - private String overlayCategory; - private int overlayPriority; - private boolean overlayIsStatic; - - private String staticSharedLibName; - private long staticSharedLibVersion; - private ArrayList<String> libraryNames; - private ArrayList<String> usesLibraries; - private ArrayList<String> usesOptionalLibraries; - - private ArrayList<String> usesStaticLibraries; - private long[] usesStaticLibrariesVersions; - private String[][] usesStaticLibrariesCertDigests; - - private String sharedUserId; - - private int sharedUserLabel; - private ArrayList<ConfigurationInfo> configPreferences; - private ArrayList<FeatureInfo> reqFeatures; - private ArrayList<FeatureGroupInfo> featureGroups; - - private byte[] restrictUpdateHash; - - private ArrayList<String> originalPackages; - private ArrayList<String> adoptPermissions; - - private ArrayList<String> requestedPermissions; - private ArrayList<String> implicitPermissions; - - private ArraySet<String> upgradeKeySets; - private Map<String, ArraySet<PublicKey>> keySetMapping; - - private ArrayList<String> protectedBroadcasts; - - @Nullable - private ArrayList<ComponentParseUtils.ParsedActivity> activities; - - @Nullable - private ArrayList<ComponentParseUtils.ParsedActivity> receivers; - - @Nullable - private ArrayList<ComponentParseUtils.ParsedService> services; - - @Nullable - private ArrayList<ComponentParseUtils.ParsedProvider> providers; - - @Nullable - private ArrayList<ComponentParseUtils.ParsedPermission> permissions; - - @Nullable - private ArrayList<ComponentParseUtils.ParsedPermissionGroup> permissionGroups; - - @Nullable - private ArrayList<ComponentParseUtils.ParsedInstrumentation> instrumentations; - - private ArrayList<ParsedActivityIntentInfo> preferredActivityFilters; - - private Bundle appMetaData; - - private String volumeUuid; - private String applicationVolumeUuid; - private PackageParser.SigningDetails signingDetails; - - private String codePath; - - private boolean use32BitAbi; - private boolean visibleToInstantApps; - - private String cpuAbiOverride; - - private boolean isStub; - - // TODO(b/135203078): Remove, should be unused - private int preferredOrder; - - private boolean forceQueryable; - - @Nullable - private ArrayList<Intent> queriesIntents; - - @Nullable - private ArrayList<String> queriesPackages; - - private String[] splitClassLoaderNames; - private String[] splitCodePaths; - private SparseArray<int[]> splitDependencies; - private int[] splitFlags; - private String[] splitNames; - private int[] splitRevisionCodes; - - // TODO(b/135203078): Audit applicationInfo.something usages, which may be different from - // package.something usages. There were differing cases of package.field = versus - // package.appInfo.field =. This class assumes some obvious ones, like packageName, - // were collapsible, but kept the following separate. - - private String applicationInfoBaseResourcePath; - private String applicationInfoCodePath; - private String applicationInfoResourcePath; - private String[] applicationInfoSplitResourcePaths; - - private String appComponentFactory; - private String backupAgentName; - private int banner; - private int category; - private String classLoaderName; - private String className; - private int compatibleWidthLimitDp; - private String credentialProtectedDataDir; - private String dataDir; - private int descriptionRes; - private String deviceProtectedDataDir; - private boolean enabled; - private int flags; - private int fullBackupContent; - private boolean hiddenUntilInstalled; - private int icon; - private int iconRes; - private int installLocation = PackageParser.PARSE_DEFAULT_INSTALL_LOCATION; - private int labelRes; - private int largestWidthLimitDp; - private int logo; - private String manageSpaceActivityName; - private float maxAspectRatio; - private float minAspectRatio; - private int minSdkVersion; - private String name; - private String nativeLibraryDir; - private String nativeLibraryRootDir; - private boolean nativeLibraryRootRequiresIsa; - private int networkSecurityConfigRes; - private CharSequence nonLocalizedLabel; - private String permission; - private String primaryCpuAbi; - private int privateFlags; - private String processName; - private int requiresSmallestWidthDp; - private int roundIconRes; - private String secondaryCpuAbi; - private String secondaryNativeLibraryDir; - private String seInfo; - private String seInfoUser; - private int targetSandboxVersion; - private int targetSdkVersion; - private String taskAffinity; - private int theme; - private int uid = -1; - private int uiOptions; - private String[] usesLibraryFiles; - private List<SharedLibraryInfo> usesLibraryInfos; - private String zygotePreloadName; - - @VisibleForTesting - public PackageImpl( - String packageName, - String baseCodePath, - TypedArray manifestArray, - boolean isCoreApp - ) { - this.packageName = TextUtils.safeIntern(packageName); - this.manifestPackageName = this.packageName; - this.baseCodePath = baseCodePath; - - this.versionCode = manifestArray.getInteger(R.styleable.AndroidManifest_versionCode, 0); - this.versionCodeMajor = manifestArray.getInteger( - R.styleable.AndroidManifest_versionCodeMajor, 0); - this.baseRevisionCode = manifestArray.getInteger(R.styleable.AndroidManifest_revisionCode, - 0); - setVersionName(manifestArray.getNonConfigurationString( - R.styleable.AndroidManifest_versionName, 0)); - this.coreApp = isCoreApp; - - this.compileSdkVersion = manifestArray.getInteger( - R.styleable.AndroidManifest_compileSdkVersion, 0); - setCompileSdkVersionCodename(manifestArray.getNonConfigurationString( - R.styleable.AndroidManifest_compileSdkVersionCodename, 0)); - } - - private PackageImpl(String packageName) { - this.packageName = TextUtils.safeIntern(packageName); - this.manifestPackageName = this.packageName; - } - - @VisibleForTesting - public static ParsingPackage forParsing(String packageName) { - return new PackageImpl(packageName); - } - - @VisibleForTesting - public static ParsingPackage forParsing( - String packageName, - String baseCodePath, - TypedArray manifestArray, - boolean isCoreApp) { - return new PackageImpl(packageName, baseCodePath, manifestArray, isCoreApp); - } - - /** - * Mock an unavailable {@link AndroidPackage} to use when removing a package from the system. - * This can occur if the package was installed on a storage device that has since been removed. - * Since the infrastructure uses {@link AndroidPackage}, but for this case only cares about - * volumeUuid, just fake it rather than having separate method paths. - */ - public static AndroidPackage buildFakeForDeletion(String packageName, String volumeUuid) { - return new PackageImpl(packageName) - .setVolumeUuid(volumeUuid) - .hideAsParsed() - .hideAsFinal(); - } - - @Override - public ParsedPackage hideAsParsed() { - return this; - } - - @Override - public AndroidPackage hideAsFinal() { - updateFlags(); - return this; - } - - @Override - @Deprecated - public AndroidPackageWrite mutate() { - return this; - } - - private void updateFlags() { - if (supportsSmallScreens < 0 || (supportsSmallScreens > 0 - && targetSdkVersion - >= Build.VERSION_CODES.DONUT)) { - this.flags |= ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS; - } - if (supportsNormalScreens != 0) { - this.flags |= ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS; - } - if (supportsLargeScreens < 0 || (supportsLargeScreens > 0 - && targetSdkVersion - >= Build.VERSION_CODES.DONUT)) { - this.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS; - } - if (supportsXLargeScreens < 0 || (supportsXLargeScreens > 0 - && targetSdkVersion - >= Build.VERSION_CODES.GINGERBREAD)) { - this.flags |= ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS; - } - if (resizeable < 0 || (resizeable > 0 - && targetSdkVersion - >= Build.VERSION_CODES.DONUT)) { - this.flags |= ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS; - } - if (anyDensity < 0 || (anyDensity > 0 - && targetSdkVersion - >= Build.VERSION_CODES.DONUT)) { - this.flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES; - } - } - - @Override - public boolean usesCompatibilityMode() { - int flags = 0; - - if (supportsSmallScreens < 0 || (supportsSmallScreens > 0 - && targetSdkVersion - >= Build.VERSION_CODES.DONUT)) { - flags |= ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS; - } - if (supportsNormalScreens != 0) { - flags |= ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS; - } - if (supportsLargeScreens < 0 || (supportsLargeScreens > 0 - && targetSdkVersion - >= Build.VERSION_CODES.DONUT)) { - flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS; - } - if (supportsXLargeScreens < 0 || (supportsXLargeScreens > 0 - && targetSdkVersion - >= Build.VERSION_CODES.GINGERBREAD)) { - flags |= ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS; - } - if (resizeable < 0 || (resizeable > 0 - && targetSdkVersion - >= Build.VERSION_CODES.DONUT)) { - flags |= ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS; - } - if (anyDensity < 0 || (anyDensity > 0 - && targetSdkVersion - >= Build.VERSION_CODES.DONUT)) { - flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES; - } - - return targetSdkVersion < DONUT - || (flags & (ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS - | ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS - | ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS - | ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS - | ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES - | ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS)) == 0; - } - - @Override - public String getBaseCodePath() { - return baseCodePath; - } - - @Override - public int getTargetSdkVersion() { - return targetSdkVersion; - } - - @Override - public String getPackageName() { - return packageName; - } - - @Override - public String getProcessName() { - return processName; - } - - @Override - public String getPermission() { - return permission; - } - - @Override - public String getStaticSharedLibName() { - return staticSharedLibName; - } - - @Override - public long getStaticSharedLibVersion() { - return staticSharedLibVersion; - } - - @Override - public String getSharedUserId() { - return sharedUserId; - } - - @Override - public List<String> getRequestedPermissions() { - return requestedPermissions == null ? Collections.emptyList() : requestedPermissions; - } - - @Nullable - @Override - public List<ParsedInstrumentation> getInstrumentations() { - return instrumentations; - } - - @Override - public Map<String, ArraySet<PublicKey>> getKeySetMapping() { - return keySetMapping == null ? Collections.emptyMap() : keySetMapping; - } - - @Override - public float getMaxAspectRatio() { - return maxAspectRatio; - } - - @Override - public float getMinAspectRatio() { - return minAspectRatio; - } - - @NonNull - @Override - public List<String> getLibraryNames() { - return libraryNames == null ? Collections.emptyList() : libraryNames; - } - - @Override - public List<ParsedActivity> getActivities() { - return activities == null ? Collections.emptyList() - : activities; - } - - @Override - public Bundle getAppMetaData() { - return appMetaData; - } - - @Nullable - @Override - public List<String> getUsesLibraries() { - return usesLibraries; - } - - @Nullable - @Override - public List<String> getUsesStaticLibraries() { - return usesStaticLibraries; - } - - @Override - public boolean isBaseHardwareAccelerated() { - return baseHardwareAccelerated; - } - - @Override - public int getUiOptions() { - return uiOptions; - } - - // TODO(b/135203078): Checking flags directly can be error prone, - // consider separate interface methods? - @Override - public int getFlags() { - return flags; - } - - // TODO(b/135203078): Checking flags directly can be error prone, - // consider separate interface methods? - @Override - public int getPrivateFlags() { - return privateFlags; - } - - @Override - public String getTaskAffinity() { - return taskAffinity; - } - - @Nullable - @Override - public List<String> getOriginalPackages() { - return originalPackages; - } - - @Override - public PackageParser.SigningDetails getSigningDetails() { - return signingDetails; - } - - @Override - public String getVolumeUuid() { - return volumeUuid; - } - - @Nullable - @Override - public List<ParsedPermissionGroup> getPermissionGroups() { - return permissionGroups; - } - - @Nullable - @Override - public List<ParsedPermission> getPermissions() { - return permissions; - } - - @Override - public String getCpuAbiOverride() { - return cpuAbiOverride; - } - - @Override - public String getPrimaryCpuAbi() { - return primaryCpuAbi; - } - - @Override - public String getSecondaryCpuAbi() { - return secondaryCpuAbi; - } - - @Override - public boolean isUse32BitAbi() { - return use32BitAbi; - } - - @Override - public boolean isForceQueryable() { - return forceQueryable; - } - - @Override - public String getCodePath() { - return codePath; - } - - @Override - public String getNativeLibraryDir() { - return nativeLibraryDir; - } - - @Override - public String getNativeLibraryRootDir() { - return nativeLibraryRootDir; - } - - @Override - public boolean isNativeLibraryRootRequiresIsa() { - return nativeLibraryRootRequiresIsa; - } - - // TODO(b/135203078): Does nothing, remove? - @Override - public int getPreferredOrder() { - return preferredOrder; - } - - @Override - public long getLongVersionCode() { - return PackageInfo.composeLongVersionCode(versionCodeMajor, versionCode); - } - - @Override - public PackageImpl setIsOverlay(boolean isOverlay) { - this.privateFlags = isOverlay - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY; - return this; - } - - @Override - public PackageImpl setExternalStorage(boolean externalStorage) { - this.flags = externalStorage - ? this.flags | ApplicationInfo.FLAG_EXTERNAL_STORAGE - : this.flags & ~ApplicationInfo.FLAG_EXTERNAL_STORAGE; - return this; - } - - @Override - public PackageImpl setIsolatedSplitLoading(boolean isolatedSplitLoading) { - this.privateFlags = isolatedSplitLoading - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING; - return this; - } - - @Override - public PackageImpl sortActivities() { - Collections.sort(this.activities, (a1, a2) -> Integer.compare(a2.order, a1.order)); - return this; - } - - @Override - public PackageImpl sortReceivers() { - Collections.sort(this.receivers, (a1, a2) -> Integer.compare(a2.order, a1.order)); - return this; - } - - @Override - public PackageImpl sortServices() { - Collections.sort(this.services, (a1, a2) -> Integer.compare(a2.order, a1.order)); - return this; - } - - @Override - public PackageImpl setBaseRevisionCode(int baseRevisionCode) { - this.baseRevisionCode = baseRevisionCode; - return this; - } - - @Override - public PackageImpl setPreferredOrder(int preferredOrder) { - this.preferredOrder = preferredOrder; - return this; - } - - @Override - public PackageImpl setVersionName(String versionName) { - this.versionName = TextUtils.safeIntern(versionName); - return this; - } - - @Override - public ParsingPackage setCompileSdkVersion(int compileSdkVersion) { - this.compileSdkVersion = compileSdkVersion; - return this; - } - - @Override - public ParsingPackage setCompileSdkVersionCodename(String compileSdkVersionCodename) { - this.compileSdkVersionCodename = TextUtils.safeIntern(compileSdkVersionCodename); - return this; - } - - @Override - public PackageImpl setMaxAspectRatio(float maxAspectRatio) { - this.maxAspectRatio = maxAspectRatio; - return this; - } - - @Override - public PackageImpl setMinAspectRatio(float minAspectRatio) { - this.minAspectRatio = minAspectRatio; - return this; - } - - @Override - public PackageImpl setMinSdkVersion(int minSdkVersion) { - this.minSdkVersion = minSdkVersion; - return this; - } - - @Override - public PackageImpl setTargetSdkVersion(int targetSdkVersion) { - this.targetSdkVersion = targetSdkVersion; - return this; - } - - @Override - public PackageImpl setRealPackage(String realPackage) { - this.realPackage = realPackage; - return this; - } - - @Override - public PackageImpl addConfigPreference(ConfigurationInfo configPreference) { - this.configPreferences = ArrayUtils.add(this.configPreferences, configPreference); - return this; - } - - @Override - public PackageImpl addReqFeature(FeatureInfo reqFeature) { - this.reqFeatures = ArrayUtils.add(this.reqFeatures, reqFeature); - return this; - } - - @Override - public PackageImpl addFeatureGroup(FeatureGroupInfo featureGroup) { - this.featureGroups = ArrayUtils.add(this.featureGroups, featureGroup); - return this; - } - - @Override - public PackageImpl addProtectedBroadcast(String protectedBroadcast) { - if (this.protectedBroadcasts == null - || !this.protectedBroadcasts.contains(protectedBroadcast)) { - this.protectedBroadcasts = ArrayUtils.add(this.protectedBroadcasts, - TextUtils.safeIntern(protectedBroadcast)); - } - return this; - } - - @Override - public PackageImpl addInstrumentation(ParsedInstrumentation instrumentation) { - this.instrumentations = ArrayUtils.add(this.instrumentations, instrumentation); - return this; - } - - @Override - public PackageImpl addOriginalPackage(String originalPackage) { - this.originalPackages = ArrayUtils.add(this.originalPackages, originalPackage); - return this; - } - - @Override - public PackageImpl addAdoptPermission(String adoptPermission) { - this.adoptPermissions = ArrayUtils.add(this.adoptPermissions, adoptPermission); - return this; - } - - @Override - public PackageImpl addPermission(ParsedPermission permission) { - this.permissions = ArrayUtils.add(this.permissions, permission); - return this; - } - - @Override - public PackageImpl removePermission(int index) { - this.permissions.remove(index); - return this; - } - - @Override - public PackageImpl addPermissionGroup(ParsedPermissionGroup permissionGroup) { - this.permissionGroups = ArrayUtils.add(this.permissionGroups, permissionGroup); - return this; - } - - @Override - public PackageImpl addRequestedPermission(String permission) { - this.requestedPermissions = ArrayUtils.add(this.requestedPermissions, - TextUtils.safeIntern(permission)); - return this; - } - - @Override - public PackageImpl addImplicitPermission(String permission) { - this.implicitPermissions = ArrayUtils.add(this.implicitPermissions, - TextUtils.safeIntern(permission)); - return this; - } - - @Override - public PackageImpl addKeySet(String keySetName, PublicKey publicKey) { - if (keySetMapping == null) { - keySetMapping = new ArrayMap<>(); - } - - ArraySet<PublicKey> publicKeys = keySetMapping.get(keySetName); - if (publicKeys == null) { - publicKeys = new ArraySet<>(); - keySetMapping.put(keySetName, publicKeys); - } - - publicKeys.add(publicKey); - - return this; - } - - @Override - public ParsingPackage addActivity(ParsedActivity parsedActivity) { - this.activities = ArrayUtils.add(this.activities, parsedActivity); - return this; - } - - @Override - public ParsingPackage addReceiver(ParsedActivity parsedReceiver) { - this.receivers = ArrayUtils.add(this.receivers, parsedReceiver); - return this; - } - - @Override - public ParsingPackage addService(ParsedService parsedService) { - this.services = ArrayUtils.add(this.services, parsedService); - return this; - } - - @Override - public ParsingPackage addProvider(ParsedProvider parsedProvider) { - this.providers = ArrayUtils.add(this.providers, parsedProvider); - return this; - } - - @Override - public PackageImpl addLibraryName(String libraryName) { - this.libraryNames = ArrayUtils.add(this.libraryNames, TextUtils.safeIntern(libraryName)); - return this; - } - - @Override - public PackageImpl addUsesLibrary(String libraryName) { - this.usesLibraries = ArrayUtils.add(this.usesLibraries, TextUtils.safeIntern(libraryName)); - return this; - } - - @Override - public PackageImpl addUsesOptionalLibrary(String libraryName) { - this.usesOptionalLibraries = ArrayUtils.add(this.usesOptionalLibraries, - TextUtils.safeIntern(libraryName)); - return this; - } - - @Override - public PackageImpl removeUsesOptionalLibrary(String libraryName) { - this.usesOptionalLibraries = ArrayUtils.remove(this.usesOptionalLibraries, libraryName); - return this; - } - - @Override - public PackageImpl addUsesStaticLibrary(String libraryName) { - this.usesStaticLibraries = ArrayUtils.add(this.usesStaticLibraries, - TextUtils.safeIntern(libraryName)); - return this; - } - - @Override - public PackageImpl addUsesStaticLibraryVersion(long version) { - this.usesStaticLibrariesVersions = ArrayUtils.appendLong(this.usesStaticLibrariesVersions, - version, true); - return this; - } - - @Override - public PackageImpl addUsesStaticLibraryCertDigests(String[] certSha256Digests) { - this.usesStaticLibrariesCertDigests = ArrayUtils.appendElement(String[].class, - this.usesStaticLibrariesCertDigests, certSha256Digests, true); - return this; - } - - @Override - public PackageImpl addPreferredActivityFilter( - ParsedActivityIntentInfo parsedActivityIntentInfo) { - this.preferredActivityFilters = ArrayUtils.add(this.preferredActivityFilters, - parsedActivityIntentInfo); - return this; - } - - @Override - public PackageImpl addQueriesIntent(Intent intent) { - this.queriesIntents = ArrayUtils.add(this.queriesIntents, intent); - return this; - } - - @Override - public PackageImpl addQueriesPackage(String packageName) { - this.queriesPackages = ArrayUtils.add(this.queriesPackages, - TextUtils.safeIntern(packageName)); - return this; - } - - @Override - public PackageImpl setSupportsSmallScreens(int supportsSmallScreens) { - if (supportsSmallScreens == 1) { - return this; - } - - this.supportsSmallScreens = supportsSmallScreens; - return this; - } - - @Override - public PackageImpl setSupportsNormalScreens(int supportsNormalScreens) { - if (supportsNormalScreens == 1) { - return this; - } - - this.supportsNormalScreens = supportsNormalScreens; - return this; - } - - @Override - public PackageImpl setSupportsLargeScreens(int supportsLargeScreens) { - if (supportsLargeScreens == 1) { - return this; - } - - this.supportsLargeScreens = supportsLargeScreens; - return this; - } - - @Override - public PackageImpl setSupportsXLargeScreens(int supportsXLargeScreens) { - if (supportsXLargeScreens == 1) { - return this; - } - - this.supportsXLargeScreens = supportsXLargeScreens; - return this; - } - - @Override - public PackageImpl setResizeable(int resizeable) { - if (resizeable == 1) { - return this; - } - - this.resizeable = resizeable; - return this; - } - - @Override - public PackageImpl setAnyDensity(int anyDensity) { - if (anyDensity == 1) { - return this; - } - - this.anyDensity = anyDensity; - return this; - } - - @Override - public PackageImpl setRequiresSmallestWidthDp(int requiresSmallestWidthDp) { - this.requiresSmallestWidthDp = requiresSmallestWidthDp; - return this; - } - - @Override - public PackageImpl setCompatibleWidthLimitDp(int compatibleWidthLimitDp) { - this.compatibleWidthLimitDp = compatibleWidthLimitDp; - return this; - } - - @Override - public PackageImpl setLargestWidthLimitDp(int largestWidthLimitDp) { - this.largestWidthLimitDp = largestWidthLimitDp; - return this; - } - - @Override - public PackageImpl setInstallLocation(int installLocation) { - this.installLocation = installLocation; - return this; - } - - @Override - public PackageImpl setTargetSandboxVersion(int targetSandboxVersion) { - this.targetSandboxVersion = targetSandboxVersion; - return this; - } - - @Override - public PackageImpl setRequiredForAllUsers(boolean requiredForAllUsers) { - this.requiredForAllUsers = requiredForAllUsers; - return this; - } - - @Override - public PackageImpl setRestrictedAccountType(String restrictedAccountType) { - this.restrictedAccountType = restrictedAccountType; - return this; - } - - @Override - public PackageImpl setRequiredAccountType(String requiredAccountType) { - this.requiredAccountType = requiredAccountType; - return this; - } - - @Override - public PackageImpl setBaseHardwareAccelerated(boolean baseHardwareAccelerated) { - this.baseHardwareAccelerated = baseHardwareAccelerated; - - this.flags = baseHardwareAccelerated - ? this.flags | ApplicationInfo.FLAG_HARDWARE_ACCELERATED - : this.flags & ~ApplicationInfo.FLAG_HARDWARE_ACCELERATED; - - return this; - } - - @Override - public PackageImpl setHasDomainUrls(boolean hasDomainUrls) { - this.privateFlags = hasDomainUrls - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS; - return this; - } - - @Override - public PackageImpl setAppMetaData(Bundle appMetaData) { - this.appMetaData = appMetaData; - return this; - } - - @Override - public PackageImpl setOverlayTarget(String overlayTarget) { - this.overlayTarget = overlayTarget; - return this; - } - - @Override - public PackageImpl setOverlayTargetName(String overlayTargetName) { - this.overlayTargetName = overlayTargetName; - return this; - } - - @Override - public PackageImpl setOverlayCategory(String overlayCategory) { - this.overlayCategory = overlayCategory; - return this; - } - - @Override - public PackageImpl setOverlayPriority(int overlayPriority) { - this.overlayPriority = overlayPriority; - return this; - } - - @Override - public PackageImpl setOverlayIsStatic(boolean overlayIsStatic) { - this.overlayIsStatic = overlayIsStatic; - return this; - } - - @Override - public PackageImpl setStaticSharedLibName(String staticSharedLibName) { - this.staticSharedLibName = TextUtils.safeIntern(staticSharedLibName); - return this; - } - - @Override - public PackageImpl setStaticSharedLibVersion(long staticSharedLibVersion) { - this.staticSharedLibVersion = staticSharedLibVersion; - return this; - } - - @Override - public PackageImpl setSharedUserId(String sharedUserId) { - this.sharedUserId = TextUtils.safeIntern(sharedUserId); - return this; - } - - @Override - public PackageImpl setSharedUserLabel(int sharedUserLabel) { - this.sharedUserLabel = sharedUserLabel; - return this; - } - - @Override - public PackageImpl setRestrictUpdateHash(byte[] restrictUpdateHash) { - this.restrictUpdateHash = restrictUpdateHash; - return this; - } - - @Override - public PackageImpl setUpgradeKeySets(ArraySet<String> upgradeKeySets) { - this.upgradeKeySets = upgradeKeySets; - return this; - } - - @Override - public PackageImpl setVolumeUuid(String volumeUuid) { - this.volumeUuid = volumeUuid; - return this; - } - - @Deprecated - @Override - public PackageImpl setApplicationVolumeUuid(String applicationVolumeUuid) { - this.applicationVolumeUuid = applicationVolumeUuid; - return this; - } - - @Override - public PackageImpl setSigningDetails(PackageParser.SigningDetails signingDetails) { - this.signingDetails = signingDetails; - return this; - } - - @Override - public PackageImpl setCodePath(String codePath) { - this.codePath = codePath; - return this; - } - - @Override - public PackageImpl setUse32BitAbi(boolean use32BitAbi) { - this.use32BitAbi = use32BitAbi; - return this; - } - - @Override - public PackageImpl setCpuAbiOverride(String cpuAbiOverride) { - this.cpuAbiOverride = cpuAbiOverride; - return this; - } - - @Override - public PackageImpl setForceQueryable(boolean forceQueryable) { - this.forceQueryable = forceQueryable; - return this; - } - - // TODO(b/135203078): Remove and move PackageManagerService#renameStaticSharedLibraryPackage - // into initial package parsing - @Override - public PackageImpl setPackageName(String packageName) { - this.packageName = packageName.intern(); - - if (permissions != null) { - for (ParsedPermission permission : permissions) { - permission.setPackageName(this.packageName); - } - } - - if (permissionGroups != null) { - for (ParsedPermissionGroup permissionGroup : permissionGroups) { - permissionGroup.setPackageName(this.packageName); - } - } - - if (activities != null) { - for (ParsedActivity parsedActivity : activities) { - parsedActivity.setPackageName(this.packageName); - } - } - - if (receivers != null) { - for (ParsedActivity receiver : receivers) { - receiver.setPackageName(this.packageName); - } - } - - if (providers != null) { - for (ParsedProvider provider : providers) { - provider.setPackageName(this.packageName); - } - } - - if (services != null) { - for (ParsedService service : services) { - service.setPackageName(this.packageName); - } - } - - if (instrumentations != null) { - for (ParsedInstrumentation instrumentation : instrumentations) { - instrumentation.setPackageName(this.packageName); - } - } - - return this; - } - - // Under this is parseBaseApplication - - @Override - public PackageImpl setAllowBackup(boolean allowBackup) { - this.flags = allowBackup - ? this.flags | ApplicationInfo.FLAG_ALLOW_BACKUP - : this.flags & ~ApplicationInfo.FLAG_ALLOW_BACKUP; - return this; - } - - @Override - public PackageImpl setKillAfterRestore(boolean killAfterRestore) { - this.flags = killAfterRestore - ? this.flags | ApplicationInfo.FLAG_KILL_AFTER_RESTORE - : this.flags & ~ApplicationInfo.FLAG_KILL_AFTER_RESTORE; - return this; - } - - @Override - public PackageImpl setRestoreAnyVersion(boolean restoreAnyVersion) { - this.flags = restoreAnyVersion - ? this.flags | ApplicationInfo.FLAG_RESTORE_ANY_VERSION - : this.flags & ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION; - return this; - } - - @Override - public PackageImpl setFullBackupOnly(boolean fullBackupOnly) { - this.flags = fullBackupOnly - ? this.flags | ApplicationInfo.FLAG_FULL_BACKUP_ONLY - : this.flags & ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY; - return this; - } - - @Override - public PackageImpl setPersistent(boolean persistent) { - this.flags = persistent - ? this.flags | ApplicationInfo.FLAG_PERSISTENT - : this.flags & ~ApplicationInfo.FLAG_PERSISTENT; - return this; - } - - @Override - public PackageImpl setDebuggable(boolean debuggable) { - this.flags = debuggable - ? this.flags | ApplicationInfo.FLAG_DEBUGGABLE - : this.flags & ~ApplicationInfo.FLAG_DEBUGGABLE; - return this; - } - - @Override - public PackageImpl setProfileableByShell(boolean profileableByShell) { - this.privateFlags = profileableByShell - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL; - return this; - } - - @Override - public PackageImpl setVmSafeMode(boolean vmSafeMode) { - this.flags = vmSafeMode - ? this.flags | ApplicationInfo.FLAG_VM_SAFE_MODE - : this.flags & ~ApplicationInfo.FLAG_VM_SAFE_MODE; - return this; - } - - @Override - public PackageImpl setHasCode(boolean hasCode) { - this.flags = hasCode - ? this.flags | ApplicationInfo.FLAG_HAS_CODE - : this.flags & ~ApplicationInfo.FLAG_HAS_CODE; - return this; - } - - @Override - public PackageImpl setAllowTaskReparenting(boolean allowTaskReparenting) { - this.flags = allowTaskReparenting - ? this.flags | ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING - : this.flags & ~ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING; - return this; - } - - @Override - public PackageImpl setAllowClearUserData(boolean allowClearUserData) { - this.flags = allowClearUserData - ? this.flags | ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA - : this.flags & ~ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA; - return this; - } - - @Override - public PackageImpl setLargeHeap(boolean largeHeap) { - this.flags = largeHeap - ? this.flags | ApplicationInfo.FLAG_LARGE_HEAP - : this.flags & ~ApplicationInfo.FLAG_LARGE_HEAP; - return this; - } - - @Override - public PackageImpl setUsesCleartextTraffic(boolean usesCleartextTraffic) { - this.flags = usesCleartextTraffic - ? this.flags | ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC - : this.flags & ~ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC; - return this; - } - - @Override - public PackageImpl setSupportsRtl(boolean supportsRtl) { - this.flags = supportsRtl - ? this.flags | ApplicationInfo.FLAG_SUPPORTS_RTL - : this.flags & ~ApplicationInfo.FLAG_SUPPORTS_RTL; - return this; - } - - @Override - public PackageImpl setTestOnly(boolean testOnly) { - this.flags = testOnly - ? this.flags | ApplicationInfo.FLAG_TEST_ONLY - : this.flags & ~ApplicationInfo.FLAG_TEST_ONLY; - return this; - } - - @Override - public PackageImpl setMultiArch(boolean multiArch) { - this.flags = multiArch - ? this.flags | ApplicationInfo.FLAG_MULTIARCH - : this.flags & ~ApplicationInfo.FLAG_MULTIARCH; - return this; - } - - @Override - public PackageImpl setExtractNativeLibs(boolean extractNativeLibs) { - this.flags = extractNativeLibs - ? this.flags | ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS - : this.flags & ~ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS; - return this; - } - - @Override - public PackageImpl setIsGame(boolean isGame) { - this.flags = isGame - ? this.flags | ApplicationInfo.FLAG_IS_GAME - : this.flags & ~ApplicationInfo.FLAG_IS_GAME; - return this; - } - - @Override - public PackageImpl setBackupInForeground(boolean backupInForeground) { - this.privateFlags = backupInForeground - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND; - return this; - } - - @Override - public PackageImpl setUseEmbeddedDex(boolean useEmbeddedDex) { - this.privateFlags = useEmbeddedDex - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX; - return this; - } - - @Override - public PackageImpl setDefaultToDeviceProtectedStorage(boolean defaultToDeviceProtectedStorage) { - this.privateFlags = defaultToDeviceProtectedStorage - ? this.privateFlags | ApplicationInfo - .PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE - : this.privateFlags & ~ApplicationInfo - .PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; - return this; - } - - @Override - public PackageImpl setDirectBootAware(boolean directBootAware) { - this.privateFlags = directBootAware - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; - return this; - } - - @Override - public PackageImpl setPartiallyDirectBootAware(boolean partiallyDirectBootAware) { - this.privateFlags = partiallyDirectBootAware - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE; - return this; - } - - @Override - public PackageImpl setActivitiesResizeModeResizeableViaSdkVersion( - boolean resizeableViaSdkVersion - ) { - this.privateFlags = resizeableViaSdkVersion - ? this.privateFlags | ApplicationInfo - .PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION - : this.privateFlags & ~ApplicationInfo - .PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION; - return this; - } - - @Override - public PackageImpl setActivitiesResizeModeResizeable(boolean resizeable) { - this.privateFlags = resizeable - ? this.privateFlags | ApplicationInfo - .PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE - : this.privateFlags & ~ApplicationInfo - .PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE; - - this.privateFlags = !resizeable - ? this.privateFlags | ApplicationInfo - .PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE - : this.privateFlags & ~ApplicationInfo - .PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE; - return this; - } - - @Override - public PackageImpl setAllowClearUserDataOnFailedRestore( - boolean allowClearUserDataOnFailedRestore - ) { - this.privateFlags = allowClearUserDataOnFailedRestore - ? this.privateFlags | ApplicationInfo - .PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE - : this.privateFlags & ~ApplicationInfo - .PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE; - return this; - } - - @Override - public PackageImpl setAllowAudioPlaybackCapture(boolean allowAudioPlaybackCapture) { - this.privateFlags = allowAudioPlaybackCapture - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE; - return this; - } - - @Override - public PackageImpl setRequestLegacyExternalStorage(boolean requestLegacyExternalStorage) { - this.privateFlags = requestLegacyExternalStorage - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE; - return this; - } - - @Override - public PackageImpl setUsesNonSdkApi(boolean usesNonSdkApi) { - this.privateFlags = usesNonSdkApi - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API; - return this; - } - - @Override - public PackageImpl setHasFragileUserData(boolean hasFragileUserData) { - this.privateFlags = hasFragileUserData - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA; - return this; - } - - @Override - public PackageImpl setCantSaveState(boolean cantSaveState) { - this.privateFlags = cantSaveState - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE; - return this; - } - - @Override - public boolean cantSaveState() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0; - } - - @Override - public boolean isLibrary() { - return staticSharedLibName != null || !ArrayUtils.isEmpty(libraryNames); - } - - // TODO(b/135203078): This does nothing until the final stage without applyPolicy being - // part of PackageParser - @Override - public boolean isSystemApp() { - return (flags & ApplicationInfo.FLAG_SYSTEM) != 0; - } - - // TODO(b/135203078): This does nothing until the final stage without applyPolicy being - // part of PackageParser - @Override - public boolean isSystemExt() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0; - } - - // TODO(b/135203078): This does nothing until the final stage without applyPolicy being - // part of PackageParser - @Override - public boolean isUpdatedSystemApp() { - return (flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; - } - - @Override - public PackageImpl setStaticSharedLibrary(boolean staticSharedLibrary) { - this.privateFlags = staticSharedLibrary - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY; - return this; - } - - @Override - public boolean isStaticSharedLibrary() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY) != 0; - } - - @Override - public PackageImpl setVisibleToInstantApps(boolean visibleToInstantApps) { - this.visibleToInstantApps = visibleToInstantApps; - return this; - } - - @Override - public PackageImpl setIconRes(int iconRes) { - this.iconRes = iconRes; - return this; - } - - @Override - public PackageImpl setRoundIconRes(int roundIconRes) { - this.roundIconRes = roundIconRes; - return this; - } - - @Override - public PackageImpl setClassName(String className) { - this.className = className; - return this; - } - - @Override - public PackageImpl setManageSpaceActivityName(String manageSpaceActivityName) { - this.manageSpaceActivityName = manageSpaceActivityName; - return this; - } - - @Override - public PackageImpl setBackupAgentName(String backupAgentName) { - this.backupAgentName = backupAgentName; - return this; - } - - @Override - public PackageImpl setFullBackupContent(int fullBackupContent) { - this.fullBackupContent = fullBackupContent; - return this; - } - - @Override - public PackageImpl setTheme(int theme) { - this.theme = theme; - return this; - } - - @Override - public PackageImpl setDescriptionRes(int descriptionRes) { - this.descriptionRes = descriptionRes; - return this; - } - - @Override - public PackageImpl setNetworkSecurityConfigRes(int networkSecurityConfigRes) { - this.networkSecurityConfigRes = networkSecurityConfigRes; - return this; - } - - @Override - public PackageImpl setCategory(int category) { - this.category = category; - return this; - } - - @Override - public PackageImpl setPermission(String permission) { - this.permission = permission; - return this; - } - - @Override - public PackageImpl setTaskAffinity(String taskAffinity) { - this.taskAffinity = taskAffinity; - return this; - } - - @Override - public PackageImpl setAppComponentFactory(String appComponentFactory) { - this.appComponentFactory = appComponentFactory; - return this; - } - - @Override - public PackageImpl setProcessName(String processName) { - if (processName == null) { - this.processName = packageName; - } else { - this.processName = processName; - } - return this; - } - - @Override - public PackageImpl setEnabled(boolean enabled) { - this.enabled = enabled; - return this; - } - - @Override - public PackageImpl setUiOptions(int uiOptions) { - this.uiOptions = uiOptions; - return this; - } - - @Override - public PackageImpl setClassLoaderName(String classLoaderName) { - this.classLoaderName = classLoaderName; - return this; - } - - @Override - public PackageImpl setZygotePreloadName(String zygotePreloadName) { - this.zygotePreloadName = zygotePreloadName; - return this; - } - - // parsePackageItemInfo - - @Override - public String getName() { - return name; - } - - @Override - public PackageImpl setName(String name) { - this.name = name; - return this; - } - - @Override - public PackageImpl setIcon(int icon) { - this.icon = icon; - return this; - } - - @Override - public PackageImpl setNonLocalizedLabel(CharSequence nonLocalizedLabel) { - this.nonLocalizedLabel = nonLocalizedLabel; - return this; - } - - @Override - public PackageImpl setLogo(int logo) { - this.logo = logo; - return this; - } - - @Override - public PackageImpl setBanner(int banner) { - this.banner = banner; - return this; - } - - @Override - public PackageImpl setLabelRes(int labelRes) { - this.labelRes = labelRes; - return this; - } - - @Override - public PackageImpl asSplit( - String[] splitNames, - String[] splitCodePaths, - int[] splitRevisionCodes, - SparseArray<int[]> splitDependencies - ) { - this.splitNames = splitNames; - - if (this.splitNames != null) { - for (int index = 0; index < this.splitNames.length; index++) { - splitNames[index] = TextUtils.safeIntern(splitNames[index]); - } - } - - this.splitCodePaths = splitCodePaths; - this.splitRevisionCodes = splitRevisionCodes; - this.splitDependencies = splitDependencies; - - int count = splitNames.length; - this.splitFlags = new int[count]; - this.splitClassLoaderNames = new String[count]; - return this; - } - - @Override - public String[] getSplitNames() { - return splitNames; - } - - @Override - public String[] getSplitCodePaths() { - return splitCodePaths; - } - - @Override - public PackageImpl setSplitHasCode(int splitIndex, boolean splitHasCode) { - this.splitFlags[splitIndex] = splitHasCode - ? this.splitFlags[splitIndex] | ApplicationInfo.FLAG_HAS_CODE - : this.splitFlags[splitIndex] & ~ApplicationInfo.FLAG_HAS_CODE; - return this; - } - - @Override - public PackageImpl setSplitClassLoaderName(int splitIndex, String classLoaderName) { - this.splitClassLoaderNames[splitIndex] = classLoaderName; - return this; - } - - @Override - public List<String> makeListAllCodePaths() { - ArrayList<String> paths = new ArrayList<>(); - paths.add(baseCodePath); - - if (!ArrayUtils.isEmpty(splitCodePaths)) { - Collections.addAll(paths, splitCodePaths); - } - return paths; - } - - @Override - public PackageImpl setBaseCodePath(String baseCodePath) { - this.baseCodePath = baseCodePath; - return this; - } - - @Override - public PackageImpl setSplitCodePaths(String[] splitCodePaths) { - this.splitCodePaths = splitCodePaths; - return this; - } - - @Override - public String toString() { - return "Package{" - + Integer.toHexString(System.identityHashCode(this)) - + " " + packageName + "}"; - } - - @Override - public PackageImpl setPrimaryCpuAbi(String primaryCpuAbi) { - this.primaryCpuAbi = primaryCpuAbi; - return this; - } - - @Override - public PackageImpl setSecondaryCpuAbi(String secondaryCpuAbi) { - this.secondaryCpuAbi = secondaryCpuAbi; - return this; - } - - @Override - public PackageImpl setNativeLibraryRootDir(String nativeLibraryRootDir) { - this.nativeLibraryRootDir = nativeLibraryRootDir; - return this; - } - - @Override - public PackageImpl setNativeLibraryRootRequiresIsa(boolean nativeLibraryRootRequiresIsa) { - this.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa; - return this; - } - - @Override - public PackageImpl setNativeLibraryDir(String nativeLibraryDir) { - this.nativeLibraryDir = nativeLibraryDir; - return this; - } - - @Override - public PackageImpl setSecondaryNativeLibraryDir(String secondaryNativeLibraryDir) { - this.secondaryNativeLibraryDir = secondaryNativeLibraryDir; - return this; - } - - @Deprecated - @Override - public PackageImpl setApplicationInfoCodePath(String applicationInfoCodePath) { - this.applicationInfoCodePath = applicationInfoCodePath; - return this; - } - - @Deprecated - @Override - public PackageImpl setApplicationInfoResourcePath(String applicationInfoResourcePath) { - this.applicationInfoResourcePath = applicationInfoResourcePath; - return this; - } - - @Deprecated - @Override - public PackageImpl setApplicationInfoBaseResourcePath( - String applicationInfoBaseResourcePath) { - this.applicationInfoBaseResourcePath = applicationInfoBaseResourcePath; - return this; - } - - @Deprecated - @Override - public PackageImpl setApplicationInfoSplitResourcePaths( - String[] applicationInfoSplitResourcePaths) { - this.applicationInfoSplitResourcePaths = applicationInfoSplitResourcePaths; - return this; - } - - @Override - public boolean isDirectBootAware() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE) != 0; - } - - @Override - public PackageImpl setAllComponentsDirectBootAware(boolean allComponentsDirectBootAware) { - if (activities != null) { - for (ParsedActivity parsedActivity : activities) { - parsedActivity.directBootAware = allComponentsDirectBootAware; - } - } - - if (receivers != null) { - for (ParsedActivity parsedReceiver : receivers) { - parsedReceiver.directBootAware = allComponentsDirectBootAware; - } - } - - if (providers != null) { - for (ParsedProvider parsedProvider : providers) { - parsedProvider.directBootAware = allComponentsDirectBootAware; - } - } - - if (services != null) { - for (ParsedService parsedService : services) { - parsedService.directBootAware = allComponentsDirectBootAware; - } - } - - return this; - } - - @Override - public PackageImpl setSystem(boolean system) { - this.flags = system - ? this.flags | ApplicationInfo.FLAG_SYSTEM - : this.flags & ~ApplicationInfo.FLAG_SYSTEM; - return this; - } - - @Override - public PackageImpl setSystemExt(boolean systemExt) { - this.privateFlags = systemExt - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT; - return this; - } - - @Override - public PackageImpl setIsStub(boolean isStub) { - this.isStub = isStub; - return this; - } - - @Override - public PackageImpl setCoreApp(boolean coreApp) { - this.coreApp = coreApp; - return this; - } - - @Override - public ParsedPackage capPermissionPriorities() { - if (permissionGroups != null && !permissionGroups.isEmpty()) { - for (int i = permissionGroups.size() - 1; i >= 0; --i) { - // TODO(b/135203078): Builder/immutability - permissionGroups.get(i).priority = 0; - } - } - return this; - } - - @Override - public ParsedPackage clearProtectedBroadcasts() { - if (protectedBroadcasts != null) { - protectedBroadcasts.clear(); - } - return this; - } - - @Override - public ParsedPackage markNotActivitiesAsNotExportedIfSingleUser() { - // ignore export request for single user receivers - if (receivers != null) { - for (ParsedActivity receiver : receivers) { - if ((receiver.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) { - receiver.exported = false; - } - } - } - // ignore export request for single user services - if (services != null) { - for (ParsedService service : services) { - if ((service.flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { - service.exported = false; - } - } - } - // ignore export request for single user providers - if (providers != null) { - for (ParsedProvider provider : providers) { - if ((provider.flags & ProviderInfo.FLAG_SINGLE_USER) != 0) { - provider.exported = false; - } - } - } - - return this; - } - - @Override - public ParsedPackage setPrivileged(boolean privileged) { - this.privateFlags = privileged - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_PRIVILEGED - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; - return this; - } - - @Override - public ParsedPackage setOem(boolean oem) { - this.privateFlags = oem - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_OEM - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_OEM; - return this; - } - - @Override - public ParsedPackage setVendor(boolean vendor) { - this.privateFlags = vendor - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_VENDOR - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_VENDOR; - return this; - } - - @Override - public ParsedPackage setProduct(boolean product) { - this.privateFlags = product - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_PRODUCT - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_PRODUCT; - return this; - } - - @Override - public ParsedPackage setOdm(boolean odm) { - this.privateFlags = odm - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_ODM - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_ODM; - return this; - } - - @Override - public ParsedPackage setSignedWithPlatformKey(boolean signedWithPlatformKey) { - this.privateFlags = signedWithPlatformKey - ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY - : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY; - return this; - } - - @Override - public ParsedPackage clearOriginalPackages() { - if (originalPackages != null) { - originalPackages.clear(); - } - return this; - } - - @Override - public ParsedPackage clearAdoptPermissions() { - if (adoptPermissions != null) { - adoptPermissions.clear(); - } - return this; - } - - @Override - public PackageImpl addUsesLibrary(int index, String libraryName) { - this.usesLibraries = ArrayUtils.add(usesLibraries, index, libraryName); - return this; - } - - @Override - public ParsedPackage removeUsesLibrary(String libraryName) { - this.usesLibraries = ArrayUtils.remove(this.usesLibraries, libraryName); - return this; - } - - @Override - public PackageImpl addUsesOptionalLibrary(int index, String libraryName) { - this.usesOptionalLibraries = ArrayUtils.add(usesOptionalLibraries, index, libraryName); - return this; - } - - @Nullable - @Override - public List<String> getUsesOptionalLibraries() { - return usesOptionalLibraries; - } - - @Override - public int getVersionCode() { - return versionCode; - } - - @Nullable - @Override - public long[] getUsesStaticLibrariesVersions() { - return usesStaticLibrariesVersions; - } - - @Override - public PackageImpl setPackageSettingCallback(PackageSettingCallback packageSettingCallback) { - packageSettingCallback.setAndroidPackage(this); - return this; - } - - @Override - public PackageImpl setUpdatedSystemApp(boolean updatedSystemApp) { - this.flags = updatedSystemApp - ? this.flags | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP - : this.flags & ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; - return this; - } - - @Override - public boolean isPrivileged() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; - } - - @Override - public PackageImpl setSeInfo(String seInfo) { - this.seInfo = seInfo; - return this; - } - - @Override - public PackageImpl setSeInfoUser(String seInfoUser) { - this.seInfoUser = seInfoUser; - return this; - } - - @Override - public PackageImpl initForUser(int userId) { - // TODO(b/135203078): Move this user state to some other data structure - this.uid = UserHandle.getUid(userId, UserHandle.getAppId(this.uid)); - - if ("android".equals(packageName)) { - dataDir = Environment.getDataSystemDirectory().getAbsolutePath(); - return this; - } - - deviceProtectedDataDir = Environment - .getDataUserDePackageDirectory(applicationVolumeUuid, userId, packageName) - .getAbsolutePath(); - credentialProtectedDataDir = Environment - .getDataUserCePackageDirectory(applicationVolumeUuid, userId, packageName) - .getAbsolutePath(); - - if ((privateFlags & ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) != 0 - && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { - dataDir = deviceProtectedDataDir; - } else { - dataDir = credentialProtectedDataDir; - } - return this; - } - - @Override - public ParsedPackage setFactoryTest(boolean factoryTest) { - this.flags = factoryTest - ? this.flags | ApplicationInfo.FLAG_FACTORY_TEST - : this.flags & ~ApplicationInfo.FLAG_FACTORY_TEST; - return this; - } - - @Override - public String getManifestPackageName() { - return manifestPackageName; - } - - @Override - public String getRealPackage() { - return realPackage; - } - - @Override - public String getOverlayTarget() { - return overlayTarget; - } - - @Override - public String getOverlayTargetName() { - return overlayTargetName; - } - - @Override - public boolean isOverlayIsStatic() { - return overlayIsStatic; - } - - @Override - public int[] getSplitFlags() { - return splitFlags; - } - - @Deprecated - @Override - public String getApplicationInfoVolumeUuid() { - return applicationVolumeUuid; - } - - @Nullable - @Override - public List<String> getProtectedBroadcasts() { - return protectedBroadcasts; - } - - @Nullable - @Override - public Set<String> getUpgradeKeySets() { - return upgradeKeySets; - } - - @Nullable - @Override - public String[][] getUsesStaticLibrariesCertDigests() { - return usesStaticLibrariesCertDigests; - } - - @Override - public int getOverlayPriority() { - return overlayPriority; - } - - @Deprecated - @Override - public String getAppInfoPackageName() { - return packageName; - } - - @Override - public UUID getStorageUuid() { - return StorageManager.convert(applicationVolumeUuid); - } - - @Override - public int getUid() { - return uid; - } - - @Override - public boolean isStub() { - return isStub; - } - - @Deprecated - @Override - public String getAppInfoCodePath() { - return applicationInfoCodePath; - } - - @Override - public boolean isSystem() { - return (flags & ApplicationInfo.FLAG_SYSTEM) != 0; - } - - @Override - public boolean isMatch(int flags) { - if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) { - return isSystem(); - } - return true; - } - - @Override - public boolean isVisibleToInstantApps() { - return visibleToInstantApps; - } - - @Override - public PackageImpl setLastPackageUsageTimeInMills(int reason, long time) { - lastPackageUsageTimeInMills[reason] = time; - return this; - } - - @Override - public List<SharedLibraryInfo> getUsesLibraryInfos() { - return usesLibraryInfos; - } - - @NonNull - @Override - public List<String> getAllCodePaths() { - return makeListAllCodePaths(); - } - - @Nullable - @Override - public String[] getUsesLibraryFiles() { - return usesLibraryFiles; - } - - @Override - public PackageImpl setUsesLibraryInfos( - @Nullable List<SharedLibraryInfo> usesLibraryInfos) { - this.usesLibraryInfos = usesLibraryInfos; - return this; - } - - @Override - public PackageImpl setUsesLibraryFiles(@Nullable String[] usesLibraryFiles) { - this.usesLibraryFiles = usesLibraryFiles; - return this; - } - - @Override - public PackageImpl setUid(int uid) { - this.uid = uid; - return this; - } - - @Override - public List<String> getAdoptPermissions() { - return adoptPermissions; - } - - @Override - public ApplicationInfo toAppInfo() { - updateFlags(); - - ApplicationInfo applicationInfo = new ApplicationInfo(); - applicationInfo.packageName = packageName; - applicationInfo.flags = flags; - applicationInfo.privateFlags = privateFlags; - applicationInfo.sharedLibraryFiles = usesLibraryFiles; - applicationInfo.sharedLibraryInfos = usesLibraryInfos; - - applicationInfo.appComponentFactory = appComponentFactory; - applicationInfo.backupAgentName = backupAgentName; - applicationInfo.banner = banner; - applicationInfo.category = category; - applicationInfo.classLoaderName = classLoaderName; - applicationInfo.className = className; - applicationInfo.compatibleWidthLimitDp = compatibleWidthLimitDp; - applicationInfo.credentialProtectedDataDir = credentialProtectedDataDir; - applicationInfo.dataDir = dataDir; - applicationInfo.descriptionRes = descriptionRes; - applicationInfo.deviceProtectedDataDir = deviceProtectedDataDir; - applicationInfo.enabled = enabled; - applicationInfo.fullBackupContent = fullBackupContent; - applicationInfo.icon = icon; - applicationInfo.iconRes = iconRes; - applicationInfo.installLocation = installLocation; - applicationInfo.labelRes = labelRes; - applicationInfo.largestWidthLimitDp = largestWidthLimitDp; - applicationInfo.logo = logo; - applicationInfo.manageSpaceActivityName = manageSpaceActivityName; - applicationInfo.maxAspectRatio = maxAspectRatio; - applicationInfo.minAspectRatio = minAspectRatio; - applicationInfo.minSdkVersion = minSdkVersion; - applicationInfo.name = name; - applicationInfo.nativeLibraryDir = nativeLibraryDir; - applicationInfo.nativeLibraryRootDir = nativeLibraryRootDir; - applicationInfo.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa; - applicationInfo.networkSecurityConfigRes = networkSecurityConfigRes; - applicationInfo.nonLocalizedLabel = nonLocalizedLabel; - applicationInfo.permission = permission; - applicationInfo.primaryCpuAbi = primaryCpuAbi; - applicationInfo.processName = processName; - applicationInfo.requiresSmallestWidthDp = requiresSmallestWidthDp; - applicationInfo.roundIconRes = roundIconRes; - applicationInfo.secondaryCpuAbi = secondaryCpuAbi; - applicationInfo.secondaryNativeLibraryDir = secondaryNativeLibraryDir; - applicationInfo.seInfo = seInfo; - applicationInfo.seInfoUser = seInfoUser; - applicationInfo.splitClassLoaderNames = splitClassLoaderNames; - applicationInfo.splitDependencies = splitDependencies; - applicationInfo.splitNames = splitNames; - applicationInfo.storageUuid = StorageManager.convert(applicationVolumeUuid); - applicationInfo.targetSandboxVersion = targetSandboxVersion; - applicationInfo.targetSdkVersion = targetSdkVersion; - applicationInfo.taskAffinity = taskAffinity; - applicationInfo.theme = theme; - applicationInfo.uid = uid; - applicationInfo.uiOptions = uiOptions; - applicationInfo.volumeUuid = applicationVolumeUuid; - applicationInfo.zygotePreloadName = zygotePreloadName; - - applicationInfo.setBaseCodePath(baseCodePath); - applicationInfo.setBaseResourcePath(applicationInfoBaseResourcePath); - applicationInfo.setCodePath(applicationInfoCodePath); - applicationInfo.setResourcePath(applicationInfoResourcePath); - applicationInfo.setSplitCodePaths(splitCodePaths); - applicationInfo.setSplitResourcePaths(applicationInfoSplitResourcePaths); - - return applicationInfo; - } - - @Override - public PackageImpl setVersionCode(int versionCode) { - this.versionCode = versionCode; - return this; - } - - @Override - public PackageImpl setHiddenUntilInstalled(boolean hidden) { - this.hiddenUntilInstalled = hidden; - return this; - } - - @Override - public String getSeInfo() { - return seInfo; - } - - @Deprecated - @Override - public String getAppInfoResourcePath() { - return applicationInfoResourcePath; - } - - @Override - public boolean isForwardLocked() { - // TODO(b/135203078): Unused? Move to debug flag? - return false; - } - - @Override - public byte[] getRestrictUpdateHash() { - return restrictUpdateHash; - } - - @Override - public boolean hasComponentClassName(String className) { - if (activities != null) { - for (ParsedActivity parsedActivity : activities) { - if (Objects.equals(className, parsedActivity.className)) { - return true; - } - } - } - - if (receivers != null) { - for (ParsedActivity receiver : receivers) { - if (Objects.equals(className, receiver.className)) { - return true; - } - } - } - - if (providers != null) { - for (ParsedProvider provider : providers) { - if (Objects.equals(className, provider.className)) { - return true; - } - } - } - - if (services != null) { - for (ParsedService service : services) { - if (Objects.equals(className, service.className)) { - return true; - } - } - } - - if (instrumentations != null) { - for (ParsedInstrumentation instrumentation : instrumentations) { - if (Objects.equals(className, instrumentation.className)) { - return true; - } - } - } - - return false; - } - - @Override - public boolean isDefaultToDeviceProtectedStorage() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) - != 0; - } - - @Override - public boolean isInternal() { - return (flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0; - } - - @Override - public int getBaseRevisionCode() { - return baseRevisionCode; - } - - @Override - public int[] getSplitRevisionCodes() { - return splitRevisionCodes; - } - - @Override - public boolean canHaveOatDir() { - // The following app types CANNOT have oat directory - // - non-updated system apps - return !isSystem() || isUpdatedSystemApp(); - } - - @Override - public long getLatestPackageUseTimeInMills() { - long latestUse = 0L; - for (long use : lastPackageUsageTimeInMills) { - latestUse = Math.max(latestUse, use); - } - return latestUse; - } - - @Override - public long getLatestForegroundPackageUseTimeInMills() { - int[] foregroundReasons = { - PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY, - PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE - }; - - long latestUse = 0L; - for (int reason : foregroundReasons) { - latestUse = Math.max(latestUse, lastPackageUsageTimeInMills[reason]); - } - return latestUse; - } - - @Override - public boolean isCoreApp() { - return coreApp; - } - - @Override - public String getVersionName() { - return versionName; - } - - @Override - public PackageImpl setVersionCodeMajor(int versionCodeMajor) { - this.versionCodeMajor = versionCodeMajor; - return this; - } - - @Override - public long[] getLastPackageUsageTimeInMills() { - return lastPackageUsageTimeInMills; - } - - @Override - public String getDataDir() { - return dataDir; - } - - @Override - public boolean isExternal() { - return (flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; - } - - @Override - public List<String> getImplicitPermissions() { - return implicitPermissions == null ? Collections.emptyList() : implicitPermissions; - } - - /** - * TODO(b/135203078): Remove, ensure b/140256621 is fixed or irrelevant - * TODO(b/140256621): Remove after fixing instant app check - * @deprecated This method always returns false because there's no paired set method - */ - @Deprecated - @Override - public boolean isInstantApp() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0; - } - - @Override - public boolean hasRequestedLegacyExternalStorage() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE) != 0; - } - - @Override - public boolean isVendor() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0; - } - - @Override - public boolean isProduct() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0; - } - - @Override - public boolean isOem() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0; - } - - @Override - public boolean isEncryptionAware() { - boolean isPartiallyDirectBootAware = - (privateFlags & ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE) != 0; - return isDirectBootAware() || isPartiallyDirectBootAware; - } - - @Override - public boolean isEmbeddedDexUsed() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX) != 0; - } - - @Deprecated - @Override - public String getAppInfoProcessName() { - return processName; - } - - @Override - public List<String> getAllCodePathsExcludingResourceOnly() { - ArrayList<String> paths = new ArrayList<>(); - if ((flags & ApplicationInfo.FLAG_HAS_CODE) != 0) { - paths.add(baseCodePath); - } - if (!ArrayUtils.isEmpty(splitCodePaths)) { - for (int i = 0; i < splitCodePaths.length; i++) { - if ((splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0) { - paths.add(splitCodePaths[i]); - } - } - } - return paths; - } - - @Deprecated - @Override - public String getAppInfoName() { - return name; - } - - private boolean isSignedWithPlatformKey() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY) != 0; - } - - private boolean usesNonSdkApi() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API) != 0; - } - - private boolean isPackageWhitelistedForHiddenApis() { - return SystemConfig.getInstance().getHiddenApiWhitelistedApps().contains(packageName); - } - - private boolean isAllowedToUseHiddenApis() { - if (isSignedWithPlatformKey()) { - return true; - } else if (isSystemApp() || isUpdatedSystemApp()) { - return usesNonSdkApi() || isPackageWhitelistedForHiddenApis(); - } else { - return false; - } - } - - @Override - public int getHiddenApiEnforcementPolicy() { - if (isAllowedToUseHiddenApis()) { - return ApplicationInfo.HIDDEN_API_ENFORCEMENT_DISABLED; - } - - // TODO(b/135203078): Handle maybeUpdateHiddenApiEnforcementPolicy. Right now it's done - // entirely through ApplicationInfo and shouldn't touch this specific class, but that - // may not always hold true. -// if (mHiddenApiPolicy != ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT) { -// return mHiddenApiPolicy; -// } - return ApplicationInfo.HIDDEN_API_ENFORCEMENT_ENABLED; - } - - @Nullable - @Override - public SparseArray<int[]> getSplitDependencies() { - return splitDependencies; - } - - @Override - public boolean requestsIsolatedSplitLoading() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING) != 0; - } - - @Deprecated - @Override - public String getAppInfoClassLoaderName() { - return classLoaderName; - } - - @Override - public String getClassLoaderName() { - return classLoaderName; - } - - @Override - public String[] getSplitClassLoaderNames() { - return splitClassLoaderNames; - } - - @Override - public String getOverlayCategory() { - return overlayCategory; - } - - @Override - public boolean isProfileableByShell() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) != 0; - } - - @Nullable - @Override - public List<ParsedActivityIntentInfo> getPreferredActivityFilters() { - return preferredActivityFilters; - } - - @Override - public boolean isHiddenUntilInstalled() { - return hiddenUntilInstalled; - } - - @Override - public int getMinSdkVersion() { - return minSdkVersion; - } - - @Override - public String getRestrictedAccountType() { - return restrictedAccountType; - } - - @Override - public String getRequiredAccountType() { - return requiredAccountType; - } - - @Override - public int getInstallLocation() { - return installLocation; - } - - @Override - public List<ParsedActivity> getReceivers() { - return receivers; - } - - @Override - public List<ParsedService> getServices() { - return services; - } - - @Override - public List<ParsedProvider> getProviders() { - return providers; - } - - @Override - public int getSharedUserLabel() { - return sharedUserLabel; - } - - @Override - public int getVersionCodeMajor() { - return versionCodeMajor; - } - - @Override - public boolean isRequiredForAllUsers() { - return requiredForAllUsers; - } - - @Override - public int getCompileSdkVersion() { - return compileSdkVersion; - } - - @Override - public String getCompileSdkVersionCodeName() { - return compileSdkVersionCodename; - } - - @Nullable - @Override - public List<ConfigurationInfo> getConfigPreferences() { - return configPreferences; - } - - @Nullable - @Override - public List<FeatureInfo> getReqFeatures() { - return reqFeatures; - } - - @Override - public List<FeatureGroupInfo> getFeatureGroups() { - return featureGroups; - } - - @Override - public String getDeviceProtectedDataDir() { - return deviceProtectedDataDir; - } - - @Override - public String getCredentialProtectedDataDir() { - return credentialProtectedDataDir; - } - - @Override - public String getSeInfoUser() { - return seInfoUser; - } - - @Override - public String getClassName() { - return className; - } - - @Override - public int getTheme() { - return theme; - } - - @Override - public int getRequiresSmallestWidthDp() { - return requiresSmallestWidthDp; - } - - @Override - public int getCompatibleWidthLimitDp() { - return compatibleWidthLimitDp; - } - - @Override - public int getLargestWidthLimitDp() { - return largestWidthLimitDp; - } - - @Override - public String getScanSourceDir() { - return applicationInfoCodePath; - } - - @Override - public String getScanPublicSourceDir() { - return applicationInfoResourcePath; - } - - @Override - public String getPublicSourceDir() { - return applicationInfoBaseResourcePath; - } - - @Override - public String[] getSplitPublicSourceDirs() { - return applicationInfoSplitResourcePaths; - } - - @Override - public String getSecondaryNativeLibraryDir() { - return secondaryNativeLibraryDir; - } - - @Override - public boolean isEnabled() { - return enabled; - } - - @Override - public String getManageSpaceActivityName() { - return manageSpaceActivityName; - } - - @Override - public int getDescriptionRes() { - return descriptionRes; - } - - @Override - public String getBackupAgentName() { - return backupAgentName; - } - - @Override - public int getFullBackupContent() { - return fullBackupContent; - } - - @Override - public int getNetworkSecurityConfigRes() { - return networkSecurityConfigRes; - } - - @Override - public int getCategory() { - return category; - } - - @Override - public int getTargetSandboxVersion() { - return targetSandboxVersion; - } - - @Override - public String getAppComponentFactory() { - return appComponentFactory; - } - - @Override - public int getIconRes() { - return iconRes; - } - - @Override - public int getRoundIconRes() { - return roundIconRes; - } - - @Override - public String getZygotePreloadName() { - return zygotePreloadName; - } - - @Override - public int getLabelRes() { - return labelRes; - } - - @Override - public CharSequence getNonLocalizedLabel() { - return nonLocalizedLabel; - } - - @Override - public int getIcon() { - return icon; - } - - @Override - public int getBanner() { - return banner; - } - - @Override - public int getLogo() { - return logo; - } - - @Override - public Bundle getMetaData() { - return appMetaData; - } - - @Override - @Nullable - public List<Intent> getQueriesIntents() { - return queriesIntents; - } - - @Override - @Nullable - public List<String> getQueriesPackages() { - return queriesPackages; - } - - private static void internStringArrayList(List<String> list) { - if (list != null) { - final int N = list.size(); - for (int i = 0; i < N; ++i) { - list.set(i, list.get(i).intern()); - } - } - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(this.supportsSmallScreens); - dest.writeInt(this.supportsNormalScreens); - dest.writeInt(this.supportsLargeScreens); - dest.writeInt(this.supportsXLargeScreens); - dest.writeInt(this.resizeable); - dest.writeInt(this.anyDensity); - dest.writeLongArray(this.lastPackageUsageTimeInMills); - dest.writeInt(this.versionCode); - dest.writeInt(this.versionCodeMajor); - dest.writeInt(this.baseRevisionCode); - dest.writeString(this.versionName); - dest.writeBoolean(this.coreApp); - dest.writeInt(this.compileSdkVersion); - dest.writeString(this.compileSdkVersionCodename); - dest.writeString(this.packageName); - dest.writeString(this.realPackage); - dest.writeString(this.manifestPackageName); - dest.writeString(this.baseCodePath); - dest.writeBoolean(this.requiredForAllUsers); - dest.writeString(this.restrictedAccountType); - dest.writeString(this.requiredAccountType); - dest.writeBoolean(this.baseHardwareAccelerated); - dest.writeString(this.overlayTarget); - dest.writeString(this.overlayTargetName); - dest.writeString(this.overlayCategory); - dest.writeInt(this.overlayPriority); - dest.writeBoolean(this.overlayIsStatic); - dest.writeString(this.staticSharedLibName); - dest.writeLong(this.staticSharedLibVersion); - dest.writeStringList(this.libraryNames); - dest.writeStringList(this.usesLibraries); - dest.writeStringList(this.usesOptionalLibraries); - dest.writeStringList(this.usesStaticLibraries); - dest.writeLongArray(this.usesStaticLibrariesVersions); - - if (this.usesStaticLibrariesCertDigests == null) { - dest.writeInt(-1); - } else { - dest.writeInt(this.usesStaticLibrariesCertDigests.length); - for (int index = 0; index < this.usesStaticLibrariesCertDigests.length; index++) { - dest.writeStringArray(this.usesStaticLibrariesCertDigests[index]); - } - } - - dest.writeString(this.sharedUserId); - dest.writeInt(this.sharedUserLabel); - dest.writeTypedList(this.configPreferences); - dest.writeTypedList(this.reqFeatures); - dest.writeTypedList(this.featureGroups); - dest.writeByteArray(this.restrictUpdateHash); - dest.writeStringList(this.originalPackages); - dest.writeStringList(this.adoptPermissions); - dest.writeStringList(this.requestedPermissions); - dest.writeStringList(this.implicitPermissions); - dest.writeArraySet(this.upgradeKeySets); - dest.writeMap(this.keySetMapping); - dest.writeStringList(this.protectedBroadcasts); - dest.writeTypedList(this.activities); - dest.writeTypedList(this.receivers); - dest.writeTypedList(this.services); - dest.writeTypedList(this.providers); - dest.writeTypedList(this.permissions); - dest.writeTypedList(this.permissionGroups); - dest.writeTypedList(this.instrumentations); - ParsedIntentInfo.writeIntentsList(this.preferredActivityFilters, dest, flags); - dest.writeBundle(this.appMetaData); - dest.writeString(this.volumeUuid); - dest.writeString(this.applicationVolumeUuid); - dest.writeParcelable(this.signingDetails, flags); - dest.writeString(this.codePath); - dest.writeBoolean(this.use32BitAbi); - dest.writeBoolean(this.visibleToInstantApps); - dest.writeString(this.cpuAbiOverride); - dest.writeBoolean(this.isStub); - dest.writeInt(this.preferredOrder); - dest.writeBoolean(this.forceQueryable); - dest.writeParcelableList(this.queriesIntents, flags); - dest.writeStringList(this.queriesPackages); - dest.writeString(this.applicationInfoBaseResourcePath); - dest.writeString(this.applicationInfoCodePath); - dest.writeString(this.applicationInfoResourcePath); - dest.writeStringArray(this.applicationInfoSplitResourcePaths); - dest.writeString(this.appComponentFactory); - dest.writeString(this.backupAgentName); - dest.writeInt(this.banner); - dest.writeInt(this.category); - dest.writeString(this.classLoaderName); - dest.writeString(this.className); - dest.writeInt(this.compatibleWidthLimitDp); - dest.writeString(this.credentialProtectedDataDir); - dest.writeString(this.dataDir); - dest.writeInt(this.descriptionRes); - dest.writeString(this.deviceProtectedDataDir); - dest.writeBoolean(this.enabled); - dest.writeInt(this.flags); - dest.writeInt(this.fullBackupContent); - dest.writeBoolean(this.hiddenUntilInstalled); - dest.writeInt(this.icon); - dest.writeInt(this.iconRes); - dest.writeInt(this.installLocation); - dest.writeInt(this.labelRes); - dest.writeInt(this.largestWidthLimitDp); - dest.writeInt(this.logo); - dest.writeString(this.manageSpaceActivityName); - dest.writeFloat(this.maxAspectRatio); - dest.writeFloat(this.minAspectRatio); - dest.writeInt(this.minSdkVersion); - dest.writeString(this.name); - dest.writeString(this.nativeLibraryDir); - dest.writeString(this.nativeLibraryRootDir); - dest.writeBoolean(this.nativeLibraryRootRequiresIsa); - dest.writeInt(this.networkSecurityConfigRes); - dest.writeCharSequence(this.nonLocalizedLabel); - dest.writeString(this.permission); - dest.writeString(this.primaryCpuAbi); - dest.writeInt(this.privateFlags); - dest.writeString(this.processName); - dest.writeInt(this.requiresSmallestWidthDp); - dest.writeInt(this.roundIconRes); - dest.writeString(this.secondaryCpuAbi); - dest.writeString(this.secondaryNativeLibraryDir); - dest.writeString(this.seInfo); - dest.writeString(this.seInfoUser); - dest.writeInt(this.targetSandboxVersion); - dest.writeInt(this.targetSdkVersion); - dest.writeString(this.taskAffinity); - dest.writeInt(this.theme); - dest.writeInt(this.uid); - dest.writeInt(this.uiOptions); - dest.writeStringArray(this.usesLibraryFiles); - dest.writeTypedList(this.usesLibraryInfos); - dest.writeString(this.zygotePreloadName); - dest.writeStringArray(this.splitClassLoaderNames); - dest.writeStringArray(this.splitCodePaths); - dest.writeSparseArray(this.splitDependencies); - dest.writeIntArray(this.splitFlags); - dest.writeStringArray(this.splitNames); - dest.writeIntArray(this.splitRevisionCodes); - } - - public PackageImpl(Parcel in) { - // We use the boot classloader for all classes that we load. - final ClassLoader boot = Object.class.getClassLoader(); - this.supportsSmallScreens = in.readInt(); - this.supportsNormalScreens = in.readInt(); - this.supportsLargeScreens = in.readInt(); - this.supportsXLargeScreens = in.readInt(); - this.resizeable = in.readInt(); - this.anyDensity = in.readInt(); - this.lastPackageUsageTimeInMills = in.createLongArray(); - this.versionCode = in.readInt(); - this.versionCodeMajor = in.readInt(); - this.baseRevisionCode = in.readInt(); - this.versionName = TextUtils.safeIntern(in.readString()); - this.coreApp = in.readBoolean(); - this.compileSdkVersion = in.readInt(); - this.compileSdkVersionCodename = TextUtils.safeIntern(in.readString()); - this.packageName = TextUtils.safeIntern(in.readString()); - this.realPackage = in.readString(); - this.manifestPackageName = in.readString(); - this.baseCodePath = in.readString(); - this.requiredForAllUsers = in.readBoolean(); - this.restrictedAccountType = in.readString(); - this.requiredAccountType = in.readString(); - this.baseHardwareAccelerated = in.readBoolean(); - this.overlayTarget = in.readString(); - this.overlayTargetName = in.readString(); - this.overlayCategory = in.readString(); - this.overlayPriority = in.readInt(); - this.overlayIsStatic = in.readBoolean(); - this.staticSharedLibName = TextUtils.safeIntern(in.readString()); - this.staticSharedLibVersion = in.readLong(); - this.libraryNames = in.createStringArrayList(); - internStringArrayList(this.libraryNames); - this.usesLibraries = in.createStringArrayList(); - internStringArrayList(this.usesLibraries); - this.usesOptionalLibraries = in.createStringArrayList(); - internStringArrayList(this.usesOptionalLibraries); - this.usesStaticLibraries = in.createStringArrayList(); - internStringArrayList(usesStaticLibraries); - this.usesStaticLibrariesVersions = in.createLongArray(); - - int digestsSize = in.readInt(); - if (digestsSize >= 0) { - this.usesStaticLibrariesCertDigests = new String[digestsSize][]; - for (int index = 0; index < digestsSize; index++) { - this.usesStaticLibrariesCertDigests[index] = in.readStringArray(); - } - } - - this.sharedUserId = TextUtils.safeIntern(in.readString()); - this.sharedUserLabel = in.readInt(); - this.configPreferences = in.createTypedArrayList(ConfigurationInfo.CREATOR); - this.reqFeatures = in.createTypedArrayList(FeatureInfo.CREATOR); - this.featureGroups = in.createTypedArrayList(FeatureGroupInfo.CREATOR); - this.restrictUpdateHash = in.createByteArray(); - this.originalPackages = in.createStringArrayList(); - this.adoptPermissions = in.createStringArrayList(); - this.requestedPermissions = in.createStringArrayList(); - internStringArrayList(this.requestedPermissions); - this.implicitPermissions = in.createStringArrayList(); - internStringArrayList(this.implicitPermissions); - this.upgradeKeySets = (ArraySet<String>) in.readArraySet(boot); - this.keySetMapping = in.readHashMap(boot); - this.protectedBroadcasts = in.createStringArrayList(); - internStringArrayList(this.protectedBroadcasts); - this.activities = in.createTypedArrayList(ParsedActivity.CREATOR); - this.receivers = in.createTypedArrayList(ParsedActivity.CREATOR); - this.services = in.createTypedArrayList(ParsedService.CREATOR); - this.providers = in.createTypedArrayList(ParsedProvider.CREATOR); - this.permissions = in.createTypedArrayList(ParsedPermission.CREATOR); - this.permissionGroups = in.createTypedArrayList(ParsedPermissionGroup.CREATOR); - this.instrumentations = in.createTypedArrayList(ParsedInstrumentation.CREATOR); - this.preferredActivityFilters = ParsedIntentInfo.createIntentsList(in); - this.appMetaData = in.readBundle(boot); - this.volumeUuid = in.readString(); - this.applicationVolumeUuid = in.readString(); - this.signingDetails = in.readParcelable(boot); - this.codePath = in.readString(); - this.use32BitAbi = in.readBoolean(); - this.visibleToInstantApps = in.readBoolean(); - this.cpuAbiOverride = in.readString(); - this.isStub = in.readBoolean(); - this.preferredOrder = in.readInt(); - this.forceQueryable = in.readBoolean(); - this.queriesIntents = in.createTypedArrayList(Intent.CREATOR); - this.queriesPackages = in.createStringArrayList(); - internStringArrayList(this.queriesPackages); - this.applicationInfoBaseResourcePath = in.readString(); - this.applicationInfoCodePath = in.readString(); - this.applicationInfoResourcePath = in.readString(); - this.applicationInfoSplitResourcePaths = in.createStringArray(); - this.appComponentFactory = in.readString(); - this.backupAgentName = in.readString(); - this.banner = in.readInt(); - this.category = in.readInt(); - this.classLoaderName = in.readString(); - this.className = in.readString(); - this.compatibleWidthLimitDp = in.readInt(); - this.credentialProtectedDataDir = in.readString(); - this.dataDir = in.readString(); - this.descriptionRes = in.readInt(); - this.deviceProtectedDataDir = in.readString(); - this.enabled = in.readBoolean(); - this.flags = in.readInt(); - this.fullBackupContent = in.readInt(); - this.hiddenUntilInstalled = in.readBoolean(); - this.icon = in.readInt(); - this.iconRes = in.readInt(); - this.installLocation = in.readInt(); - this.labelRes = in.readInt(); - this.largestWidthLimitDp = in.readInt(); - this.logo = in.readInt(); - this.manageSpaceActivityName = in.readString(); - this.maxAspectRatio = in.readFloat(); - this.minAspectRatio = in.readFloat(); - this.minSdkVersion = in.readInt(); - this.name = in.readString(); - this.nativeLibraryDir = in.readString(); - this.nativeLibraryRootDir = in.readString(); - this.nativeLibraryRootRequiresIsa = in.readBoolean(); - this.networkSecurityConfigRes = in.readInt(); - this.nonLocalizedLabel = in.readCharSequence(); - this.permission = TextUtils.safeIntern(in.readString()); - this.primaryCpuAbi = in.readString(); - this.privateFlags = in.readInt(); - this.processName = in.readString(); - this.requiresSmallestWidthDp = in.readInt(); - this.roundIconRes = in.readInt(); - this.secondaryCpuAbi = in.readString(); - this.secondaryNativeLibraryDir = in.readString(); - this.seInfo = in.readString(); - this.seInfoUser = in.readString(); - this.targetSandboxVersion = in.readInt(); - this.targetSdkVersion = in.readInt(); - this.taskAffinity = in.readString(); - this.theme = in.readInt(); - this.uid = in.readInt(); - this.uiOptions = in.readInt(); - this.usesLibraryFiles = in.createStringArray(); - this.usesLibraryInfos = in.createTypedArrayList(SharedLibraryInfo.CREATOR); - this.zygotePreloadName = in.readString(); - this.splitClassLoaderNames = in.createStringArray(); - this.splitCodePaths = in.createStringArray(); - this.splitDependencies = in.readSparseArray(boot); - this.splitFlags = in.createIntArray(); - this.splitNames = in.createStringArray(); - this.splitRevisionCodes = in.createIntArray(); - } - - public static final Creator<PackageImpl> CREATOR = new Creator<PackageImpl>() { - @Override - public PackageImpl createFromParcel(Parcel source) { - return new PackageImpl(source); - } - - @Override - public PackageImpl[] newArray(int size) { - return new PackageImpl[size]; - } - }; -} diff --git a/core/java/android/content/pm/parsing/PackageInfoUtils.java b/core/java/android/content/pm/parsing/PackageInfoUtils.java deleted file mode 100644 index 7b329ebc5b83..000000000000 --- a/core/java/android/content/pm/parsing/PackageInfoUtils.java +++ /dev/null @@ -1,732 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package android.content.pm.parsing; - -import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED; - -import android.annotation.Nullable; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.ComponentInfo; -import android.content.pm.ConfigurationInfo; -import android.content.pm.FallbackCategoryProvider; -import android.content.pm.FeatureGroupInfo; -import android.content.pm.FeatureInfo; -import android.content.pm.InstrumentationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageItemInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageParser; -import android.content.pm.PackageUserState; -import android.content.pm.PermissionGroupInfo; -import android.content.pm.PermissionInfo; -import android.content.pm.ProviderInfo; -import android.content.pm.SELinuxUtil; -import android.content.pm.ServiceInfo; -import android.content.pm.Signature; -import android.content.pm.SigningInfo; -import android.content.pm.parsing.ComponentParseUtils.ParsedActivity; -import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermission; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup; -import android.os.Bundle; -import android.os.UserHandle; - -import com.android.internal.util.ArrayUtils; - -import java.util.Set; - -/** @hide */ -public class PackageInfoUtils { - - private static final String TAG = ApkParseUtils.TAG; - - /** - * Returns true if the package is installed and not hidden, or if the caller - * explicitly wanted all uninstalled and hidden packages as well. - */ - private static boolean checkUseInstalledOrHidden(AndroidPackage pkg, PackageUserState state, - @PackageManager.PackageInfoFlags int flags) { - // Returns false if the package is hidden system app until installed. - if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0 - && !state.installed - && pkg.isHiddenUntilInstalled()) { - return false; - } - - // If available for the target user, or trying to match uninstalled packages and it's - // a system app. - return state.isAvailable(flags) - || (pkg.isSystemApp() - && ((flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0 - || (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0)); - } - - public static PackageInfo generate(AndroidPackage pkg, int[] gids, - @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime, - Set<String> grantedPermissions, PackageUserState state, int userId) { - if (!checkUseInstalledOrHidden(pkg, state, flags) || !pkg.isMatch(flags)) { - return null; - } - ApplicationInfo applicationInfo = generateApplicationInfo(pkg, flags, state, userId); - - PackageInfo pi = new PackageInfo(); - pi.packageName = pkg.getPackageName(); - pi.splitNames = pkg.getSplitNames(); - pi.versionCode = pkg.getVersionCode(); - pi.versionCodeMajor = pkg.getVersionCodeMajor(); - pi.baseRevisionCode = pkg.getBaseRevisionCode(); - pi.splitRevisionCodes = pkg.getSplitRevisionCodes(); - pi.versionName = pkg.getVersionName(); - pi.sharedUserId = pkg.getSharedUserId(); - pi.sharedUserLabel = pkg.getSharedUserLabel(); - pi.applicationInfo = applicationInfo; - pi.installLocation = pkg.getInstallLocation(); - pi.isStub = pkg.isStub(); - pi.coreApp = pkg.isCoreApp(); - if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 - || (pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { - pi.requiredForAllUsers = pkg.isRequiredForAllUsers(); - } - pi.restrictedAccountType = pkg.getRestrictedAccountType(); - pi.requiredAccountType = pkg.getRequiredAccountType(); - pi.overlayTarget = pkg.getOverlayTarget(); - pi.targetOverlayableName = pkg.getOverlayTargetName(); - pi.overlayCategory = pkg.getOverlayCategory(); - pi.overlayPriority = pkg.getOverlayPriority(); - pi.mOverlayIsStatic = pkg.isOverlayIsStatic(); - pi.compileSdkVersion = pkg.getCompileSdkVersion(); - pi.compileSdkVersionCodename = pkg.getCompileSdkVersionCodeName(); - pi.firstInstallTime = firstInstallTime; - pi.lastUpdateTime = lastUpdateTime; - if ((flags & PackageManager.GET_GIDS) != 0) { - pi.gids = gids; - } - if ((flags & PackageManager.GET_CONFIGURATIONS) != 0) { - int size = pkg.getConfigPreferences() != null ? pkg.getConfigPreferences().size() : 0; - if (size > 0) { - pi.configPreferences = new ConfigurationInfo[size]; - pkg.getConfigPreferences().toArray(pi.configPreferences); - } - size = pkg.getReqFeatures() != null ? pkg.getReqFeatures().size() : 0; - if (size > 0) { - pi.reqFeatures = new FeatureInfo[size]; - pkg.getReqFeatures().toArray(pi.reqFeatures); - } - size = pkg.getFeatureGroups() != null ? pkg.getFeatureGroups().size() : 0; - if (size > 0) { - pi.featureGroups = new FeatureGroupInfo[size]; - pkg.getFeatureGroups().toArray(pi.featureGroups); - } - } - if ((flags & PackageManager.GET_ACTIVITIES) != 0) { - if (pkg.getActivities() != null) { - final int N = pkg.getActivities().size(); - if (N > 0) { - int num = 0; - final ActivityInfo[] res = new ActivityInfo[N]; - for (int i = 0; i < N; i++) { - final ParsedActivity a = pkg.getActivities().get(i); - if (state.isMatch(pkg.isSystem(), pkg.isEnabled(), a, flags)) { - if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals( - a.className)) { - continue; - } - res[num++] = generateActivityInfo(pkg, a, flags, state, applicationInfo, - userId); - } - } - pi.activities = ArrayUtils.trimToSize(res, num); - } - } - } - if ((flags & PackageManager.GET_RECEIVERS) != 0) { - if (pkg.getReceivers() != null) { - final int size = pkg.getReceivers().size(); - if (size > 0) { - int num = 0; - final ActivityInfo[] res = new ActivityInfo[size]; - for (int i = 0; i < size; i++) { - final ParsedActivity a = pkg.getReceivers().get(i); - if (state.isMatch(pkg.isSystem(), pkg.isEnabled(), a, flags)) { - res[num++] = generateActivityInfo(pkg, a, flags, state, applicationInfo, - userId); - } - } - pi.receivers = ArrayUtils.trimToSize(res, num); - } - } - } - if ((flags & PackageManager.GET_SERVICES) != 0) { - if (pkg.getServices() != null) { - final int size = pkg.getServices().size(); - if (size > 0) { - int num = 0; - final ServiceInfo[] res = new ServiceInfo[size]; - for (int i = 0; i < size; i++) { - final ComponentParseUtils.ParsedService s = pkg.getServices().get(i); - if (state.isMatch(pkg.isSystem(), pkg.isEnabled(), s, flags)) { - res[num++] = generateServiceInfo(pkg, s, flags, state, applicationInfo, - userId); - } - } - pi.services = ArrayUtils.trimToSize(res, num); - } - } - } - if ((flags & PackageManager.GET_PROVIDERS) != 0) { - if (pkg.getProviders() != null) { - final int size = pkg.getProviders().size(); - if (size > 0) { - int num = 0; - final ProviderInfo[] res = new ProviderInfo[size]; - for (int i = 0; i < size; i++) { - final ComponentParseUtils.ParsedProvider pr = pkg.getProviders() - .get(i); - if (state.isMatch(pkg.isSystem(), pkg.isEnabled(), pr, flags)) { - res[num++] = generateProviderInfo(pkg, pr, flags, state, - applicationInfo, userId); - } - } - pi.providers = ArrayUtils.trimToSize(res, num); - } - } - } - if ((flags & PackageManager.GET_INSTRUMENTATION) != 0) { - if (pkg.getInstrumentations() != null) { - int N = pkg.getInstrumentations().size(); - if (N > 0) { - pi.instrumentation = new InstrumentationInfo[N]; - for (int i = 0; i < N; i++) { - pi.instrumentation[i] = generateInstrumentationInfo( - pkg.getInstrumentations().get(i), flags); - } - } - } - } - if ((flags & PackageManager.GET_PERMISSIONS) != 0) { - if (pkg.getPermissions() != null) { - int N = ArrayUtils.size(pkg.getPermissions()); - if (N > 0) { - pi.permissions = new PermissionInfo[N]; - for (int i = 0; i < N; i++) { - pi.permissions[i] = generatePermissionInfo( - pkg.getPermissions().get(i), - flags - ); - } - } - } - if (pkg.getRequestedPermissions() != null) { - int N = pkg.getRequestedPermissions().size(); - if (N > 0) { - pi.requestedPermissions = new String[N]; - pi.requestedPermissionsFlags = new int[N]; - for (int i = 0; i < N; i++) { - final String perm = pkg.getRequestedPermissions().get(i); - pi.requestedPermissions[i] = perm; - // The notion of required permissions is deprecated but for compatibility. - pi.requestedPermissionsFlags[i] |= - PackageInfo.REQUESTED_PERMISSION_REQUIRED; - if (grantedPermissions != null && grantedPermissions.contains(perm)) { - pi.requestedPermissionsFlags[i] |= - PackageInfo.REQUESTED_PERMISSION_GRANTED; - } - } - } - } - } - - PackageParser.SigningDetails signingDetails = pkg.getSigningDetails(); - // deprecated method of getting signing certificates - if ((flags & PackageManager.GET_SIGNATURES) != 0) { - if (signingDetails.hasPastSigningCertificates()) { - // Package has included signing certificate rotation information. Return the oldest - // cert so that programmatic checks keep working even if unaware of key rotation. - pi.signatures = new Signature[1]; - pi.signatures[0] = signingDetails.pastSigningCertificates[0]; - } else if (signingDetails.hasSignatures()) { - // otherwise keep old behavior - int numberOfSigs = signingDetails.signatures.length; - pi.signatures = new Signature[numberOfSigs]; - System.arraycopy(signingDetails.signatures, 0, pi.signatures, 0, - numberOfSigs); - } - } - - // replacement for GET_SIGNATURES - if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) { - if (signingDetails != PackageParser.SigningDetails.UNKNOWN) { - // only return a valid SigningInfo if there is signing information to report - pi.signingInfo = new SigningInfo(signingDetails); - } else { - pi.signingInfo = null; - } - } - - return pi; - } - - // TODO(b/135203078): Remove this in favor of AndroidPackage.toAppInfo() - private static ApplicationInfo appInfoFromFinalPackage(AndroidPackage pkg) { - ApplicationInfo appInfo = new ApplicationInfo(); - appInfo.name = pkg.getName(); - if (appInfo.name != null) appInfo.name = appInfo.name.trim(); - appInfo.packageName = pkg.getPackageName(); - appInfo.labelRes = pkg.getLabelRes(); - appInfo.nonLocalizedLabel = pkg.getNonLocalizedLabel(); - if (appInfo.nonLocalizedLabel != null) { - appInfo.nonLocalizedLabel = appInfo.nonLocalizedLabel.toString().trim(); - } - appInfo.icon = pkg.getIcon(); - appInfo.banner = pkg.getBanner(); - appInfo.logo = pkg.getLogo(); - appInfo.metaData = pkg.getMetaData(); - - // TODO(b/135203078): Can this be removed? Looks only used in ActivityInfo. -// appInfo.showUserIcon = pkg.getShowUserIcon(); - - appInfo.taskAffinity = pkg.getTaskAffinity(); - appInfo.permission = pkg.getPermission(); - appInfo.processName = pkg.getProcessName(); - appInfo.className = pkg.getClassName(); - appInfo.theme = pkg.getTheme(); - appInfo.flags = pkg.getFlags(); - appInfo.privateFlags = pkg.getPrivateFlags(); - appInfo.requiresSmallestWidthDp = pkg.getRequiresSmallestWidthDp(); - appInfo.compatibleWidthLimitDp = pkg.getCompatibleWidthLimitDp(); - appInfo.largestWidthLimitDp = pkg.getLargestWidthLimitDp(); - appInfo.volumeUuid = pkg.getVolumeUuid(); - appInfo.storageUuid = pkg.getStorageUuid(); - appInfo.scanSourceDir = pkg.getScanSourceDir(); - appInfo.scanPublicSourceDir = pkg.getScanPublicSourceDir(); - appInfo.sourceDir = pkg.getBaseCodePath(); - appInfo.publicSourceDir = pkg.getPublicSourceDir(); - appInfo.splitNames = pkg.getSplitNames(); - appInfo.splitSourceDirs = pkg.getSplitCodePaths(); - appInfo.splitPublicSourceDirs = pkg.getSplitPublicSourceDirs(); - appInfo.splitDependencies = pkg.getSplitDependencies(); - appInfo.nativeLibraryDir = pkg.getNativeLibraryDir(); - appInfo.secondaryNativeLibraryDir = pkg.getSecondaryNativeLibraryDir(); - appInfo.nativeLibraryRootDir = pkg.getNativeLibraryRootDir(); - appInfo.nativeLibraryRootRequiresIsa = pkg.isNativeLibraryRootRequiresIsa(); - appInfo.primaryCpuAbi = pkg.getPrimaryCpuAbi(); - appInfo.secondaryCpuAbi = pkg.getSecondaryCpuAbi(); - - // TODO(b/135203078): Unused? -// appInfo.resourceDirs = pkg.getResourceDirs(); - appInfo.seInfo = pkg.getSeInfo(); - appInfo.seInfoUser = pkg.getSeInfoUser(); - appInfo.sharedLibraryFiles = pkg.getUsesLibraryFiles(); - appInfo.sharedLibraryInfos = pkg.getUsesLibraryInfos(); - appInfo.dataDir = pkg.getDataDir(); - appInfo.deviceProtectedDataDir = pkg.getDeviceProtectedDataDir(); - appInfo.credentialProtectedDataDir = pkg.getCredentialProtectedDataDir(); - appInfo.uid = pkg.getUid(); - appInfo.minSdkVersion = pkg.getMinSdkVersion(); - appInfo.targetSdkVersion = pkg.getTargetSdkVersion(); - appInfo.setVersionCode(pkg.getLongVersionCode()); - appInfo.enabled = pkg.isEnabled(); - - // TODO(b/135203078): Unused? -// appInfo.enabledSetting = pkg.getEnabledSetting(); - appInfo.installLocation = pkg.getInstallLocation(); - appInfo.manageSpaceActivityName = pkg.getManageSpaceActivityName(); - appInfo.descriptionRes = pkg.getDescriptionRes(); - appInfo.uiOptions = pkg.getUiOptions(); - appInfo.backupAgentName = pkg.getBackupAgentName(); - appInfo.fullBackupContent = pkg.getFullBackupContent(); - appInfo.networkSecurityConfigRes = pkg.getNetworkSecurityConfigRes(); - appInfo.category = pkg.getCategory(); - appInfo.targetSandboxVersion = pkg.getTargetSandboxVersion(); - appInfo.classLoaderName = pkg.getClassLoaderName(); - appInfo.splitClassLoaderNames = pkg.getSplitClassLoaderNames(); - appInfo.appComponentFactory = pkg.getAppComponentFactory(); - appInfo.iconRes = pkg.getIconRes(); - appInfo.roundIconRes = pkg.getRoundIconRes(); - appInfo.compileSdkVersion = pkg.getCompileSdkVersion(); - appInfo.compileSdkVersionCodename = pkg.getCompileSdkVersionCodeName(); - - // TODO(b/135203078): See PackageImpl#getHiddenApiEnforcementPolicy -// appInfo.mHiddenApiPolicy = pkg.getHiddenApiPolicy(); - appInfo.hiddenUntilInstalled = pkg.isHiddenUntilInstalled(); - appInfo.zygotePreloadName = pkg.getZygotePreloadName(); - return appInfo; - } - - public static ApplicationInfo generateApplicationInfo(AndroidPackage pkg, - @PackageManager.ApplicationInfoFlags int flags, PackageUserState state, int userId) { - - if (pkg == null) return null; - if (!checkUseInstalledOrHidden(pkg, state, flags) || !pkg.isMatch(flags)) { - return null; - } - if (!copyNeeded(flags, pkg, state, null, userId) - && ((flags & PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) == 0 - || state.enabled != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { - // TODO(b/135203078): This isn't applicable anymore, as AppInfo isn't cached and - // always built new in toAppInfo(). Remove entire copyNeeded flow? Or find a way to - // transiently cache AppInfo, since multiple calls in quick secession probably need - // the same AppInfo. - // In this case it is safe to directly modify the internal ApplicationInfo state: - // - CompatibilityMode is global state, so will be the same for every call. - // - We only come in to here if the app should reported as installed; this is the - // default state, and we will do a copy otherwise. - // - The enable state will always be reported the same for the application across - // calls; the only exception is for the UNTIL_USED mode, and in that case we will - // be doing a copy. - ApplicationInfo applicationInfo = pkg.toAppInfo(); - updateApplicationInfo(applicationInfo, flags, state); - return applicationInfo; - } - - // Make shallow copy so we can store the metadata/libraries safely - ApplicationInfo ai = appInfoFromFinalPackage(pkg); - ai.initForUser(userId); - if ((flags & PackageManager.GET_META_DATA) != 0) { - ai.metaData = pkg.getAppMetaData(); - } - if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) != 0) { - ai.sharedLibraryFiles = pkg.getUsesLibraryFiles(); - ai.sharedLibraryInfos = pkg.getUsesLibraryInfos(); - } - if (state.stopped) { - ai.flags |= ApplicationInfo.FLAG_STOPPED; - } else { - ai.flags &= ~ApplicationInfo.FLAG_STOPPED; - } - updateApplicationInfo(ai, flags, state); - - return ai; - } - - private static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a, - @PackageManager.ComponentInfoFlags int flags, PackageUserState state, - @Nullable ApplicationInfo applicationInfo, int userId) { - if (a == null) return null; - if (!checkUseInstalledOrHidden(pkg, state, flags)) { - return null; - } - if (applicationInfo == null) { - applicationInfo = generateApplicationInfo(pkg, flags, state, userId); - } - if (!copyNeeded(flags, pkg, state, a.metaData, userId)) { - updateApplicationInfo(applicationInfo, flags, state); - } - // Make shallow copies so we can store the metadata safely - ActivityInfo ai = new ActivityInfo(); - assignSharedFieldsForComponentInfo(ai, a); - ai.targetActivity = a.targetActivity; - ai.processName = a.getProcessName(); - ai.exported = a.exported; - ai.theme = a.theme; - ai.uiOptions = a.uiOptions; - ai.parentActivityName = a.parentActivityName; - ai.permission = a.getPermission(); - ai.taskAffinity = a.taskAffinity; - ai.flags = a.flags; - ai.privateFlags = a.privateFlags; - ai.launchMode = a.launchMode; - ai.documentLaunchMode = a.documentLaunchMode; - ai.maxRecents = a.maxRecents; - ai.configChanges = a.configChanges; - ai.softInputMode = a.softInputMode; - ai.persistableMode = a.persistableMode; - ai.lockTaskLaunchMode = a.lockTaskLaunchMode; - ai.screenOrientation = a.screenOrientation; - ai.resizeMode = a.resizeMode; - ai.maxAspectRatio = a.maxAspectRatio; - ai.minAspectRatio = a.minAspectRatio; - ai.requestedVrComponent = a.requestedVrComponent; - ai.rotationAnimation = a.rotationAnimation; - ai.colorMode = a.colorMode; - ai.windowLayout = a.windowLayout; - ai.metaData = a.metaData; - ai.applicationInfo = applicationInfo; - return ai; - } - - public static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a, - @PackageManager.ComponentInfoFlags int flags, PackageUserState state, int userId) { - return generateActivityInfo(pkg, a, flags, state, null, userId); - } - - private static ServiceInfo generateServiceInfo(AndroidPackage pkg, - ComponentParseUtils.ParsedService s, @PackageManager.ComponentInfoFlags int flags, - PackageUserState state, @Nullable ApplicationInfo applicationInfo, int userId) { - if (s == null) return null; - if (!checkUseInstalledOrHidden(pkg, state, flags)) { - return null; - } - if (applicationInfo == null) { - applicationInfo = generateApplicationInfo(pkg, flags, state, userId); - } - if (!copyNeeded(flags, pkg, state, s.metaData, userId)) { - updateApplicationInfo(applicationInfo, flags, state); - } - // Make shallow copies so we can store the metadata safely - ServiceInfo si = new ServiceInfo(); - assignSharedFieldsForComponentInfo(si, s); - si.exported = s.exported; - si.flags = s.flags; - si.metaData = s.metaData; - si.permission = s.getPermission(); - si.processName = s.getProcessName(); - si.mForegroundServiceType = s.foregroundServiceType; - si.metaData = s.metaData; - si.applicationInfo = applicationInfo; - return si; - } - - public static ServiceInfo generateServiceInfo(AndroidPackage pkg, - ComponentParseUtils.ParsedService s, @PackageManager.ComponentInfoFlags int flags, - PackageUserState state, int userId) { - return generateServiceInfo(pkg, s, flags, state, null, userId); - } - - private static ProviderInfo generateProviderInfo(AndroidPackage pkg, - ComponentParseUtils.ParsedProvider p, @PackageManager.ComponentInfoFlags int flags, - PackageUserState state, @Nullable ApplicationInfo applicationInfo, int userId) { - if (p == null) return null; - if (!checkUseInstalledOrHidden(pkg, state, flags)) { - return null; - } - if (applicationInfo == null) { - applicationInfo = generateApplicationInfo(pkg, flags, state, userId); - } - if (!copyNeeded(flags, pkg, state, p.metaData, userId) - && ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) != 0 - || p.uriPermissionPatterns == null)) { - updateApplicationInfo(applicationInfo, flags, state); - } - // Make shallow copies so we can store the metadata safely - ProviderInfo pi = new ProviderInfo(); - assignSharedFieldsForComponentInfo(pi, p); - pi.exported = p.exported; - pi.flags = p.flags; - pi.processName = p.getProcessName(); - pi.authority = p.getAuthority(); - pi.isSyncable = p.isSyncable; - pi.readPermission = p.getReadPermission(); - pi.writePermission = p.getWritePermission(); - pi.grantUriPermissions = p.grantUriPermissions; - pi.forceUriPermissions = p.forceUriPermissions; - pi.multiprocess = p.multiProcess; - pi.initOrder = p.initOrder; - pi.uriPermissionPatterns = p.uriPermissionPatterns; - pi.pathPermissions = p.pathPermissions; - pi.metaData = p.metaData; - if ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) == 0) { - pi.uriPermissionPatterns = null; - } - pi.applicationInfo = applicationInfo; - return pi; - } - - public static ProviderInfo generateProviderInfo(AndroidPackage pkg, - ComponentParseUtils.ParsedProvider p, @PackageManager.ComponentInfoFlags int flags, - PackageUserState state, int userId) { - return generateProviderInfo(pkg, p, flags, state, null, userId); - } - - public static InstrumentationInfo generateInstrumentationInfo(ParsedInstrumentation i, - @PackageManager.ComponentInfoFlags int flags) { - if (i == null) return null; - - InstrumentationInfo ii = new InstrumentationInfo(); - assignSharedFieldsForPackageItemInfo(ii, i); - ii.targetPackage = i.getTargetPackage(); - ii.targetProcesses = i.getTargetProcesses(); - ii.handleProfiling = i.handleProfiling; - ii.functionalTest = i.functionalTest; - - ii.sourceDir = i.sourceDir; - ii.publicSourceDir = i.publicSourceDir; - ii.splitNames = i.splitNames; - ii.splitSourceDirs = i.splitSourceDirs; - ii.splitPublicSourceDirs = i.splitPublicSourceDirs; - ii.splitDependencies = i.splitDependencies; - ii.dataDir = i.dataDir; - ii.deviceProtectedDataDir = i.deviceProtectedDataDir; - ii.credentialProtectedDataDir = i.credentialProtectedDataDir; - ii.primaryCpuAbi = i.primaryCpuAbi; - ii.secondaryCpuAbi = i.secondaryCpuAbi; - ii.nativeLibraryDir = i.nativeLibraryDir; - ii.secondaryNativeLibraryDir = i.secondaryNativeLibraryDir; - - if ((flags & PackageManager.GET_META_DATA) == 0) { - return ii; - } - ii.metaData = i.metaData; - return ii; - } - - public static PermissionInfo generatePermissionInfo(ParsedPermission p, - @PackageManager.ComponentInfoFlags int flags) { - if (p == null) return null; - - PermissionInfo pi = new PermissionInfo(p.backgroundPermission); - assignSharedFieldsForPackageItemInfo(pi, p); - pi.group = p.getGroup(); - pi.requestRes = p.requestRes; - pi.protectionLevel = p.protectionLevel; - pi.descriptionRes = p.descriptionRes; - pi.flags = p.flags; - - if ((flags & PackageManager.GET_META_DATA) == 0) { - return pi; - } - pi.metaData = p.metaData; - return pi; - } - - public static PermissionGroupInfo generatePermissionGroupInfo(ParsedPermissionGroup pg, - @PackageManager.ComponentInfoFlags int flags) { - if (pg == null) return null; - - PermissionGroupInfo pgi = new PermissionGroupInfo( - pg.requestDetailResourceId, - pg.backgroundRequestResourceId, - pg.backgroundRequestDetailResourceId - ); - assignSharedFieldsForPackageItemInfo(pgi, pg); - pgi.priority = pg.priority; - pgi.requestRes = pg.requestRes; - pgi.flags = pg.flags; - - if ((flags & PackageManager.GET_META_DATA) == 0) { - return pgi; - } - pgi.metaData = pg.metaData; - return pgi; - } - - private static boolean copyNeeded(@PackageManager.ComponentInfoFlags int flags, - AndroidPackage pkg, PackageUserState state, Bundle metaData, int userId) { - if (userId != UserHandle.USER_SYSTEM) { - // We always need to copy for other users, since we need - // to fix up the uid. - return true; - } - if (state.enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) { - boolean enabled = state.enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED; - if (pkg.isEnabled() != enabled) { - return true; - } - } - boolean suspended = (pkg.getFlags() & FLAG_SUSPENDED) != 0; - if (state.suspended != suspended) { - return true; - } - if (!state.installed || state.hidden) { - return true; - } - if (state.stopped) { - return true; - } - if (state.instantApp != pkg.isInstantApp()) { - return true; - } - if ((flags & PackageManager.GET_META_DATA) != 0 - && (metaData != null || pkg.getAppMetaData() != null)) { - return true; - } - if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) != 0 - && pkg.getUsesLibraryFiles() != null) { - return true; - } - if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) != 0 - && pkg.getUsesLibraryInfos() != null) { - return true; - } - return pkg.getStaticSharedLibName() != null; - } - - private static void updateApplicationInfo(ApplicationInfo ai, - @PackageManager.ApplicationInfoFlags int flags, - PackageUserState state) { - // CompatibilityMode is global state. - if (!PackageParser.sCompatibilityModeEnabled) { - ai.disableCompatibilityMode(); - } - if (state.installed) { - ai.flags |= ApplicationInfo.FLAG_INSTALLED; - } else { - ai.flags &= ~ApplicationInfo.FLAG_INSTALLED; - } - if (state.suspended) { - ai.flags |= ApplicationInfo.FLAG_SUSPENDED; - } else { - ai.flags &= ~ApplicationInfo.FLAG_SUSPENDED; - } - if (state.instantApp) { - ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_INSTANT; - } else { - ai.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_INSTANT; - } - if (state.virtualPreload) { - ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD; - } else { - ai.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD; - } - if (state.hidden) { - ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN; - } else { - ai.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_HIDDEN; - } - if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { - ai.enabled = true; - } else if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) { - ai.enabled = (flags & PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0; - } else if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED - || state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) { - ai.enabled = false; - } - ai.enabledSetting = state.enabled; - if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) { - ai.category = state.categoryHint; - } - if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) { - ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName); - } - ai.seInfoUser = SELinuxUtil.assignSeinfoUser(state); - ai.resourceDirs = state.overlayPaths; - ai.icon = (PackageParser.sUseRoundIcon && ai.roundIconRes != 0) - ? ai.roundIconRes : ai.iconRes; - } - - private static void assignSharedFieldsForPackageItemInfo(PackageItemInfo packageItemInfo, - ComponentParseUtils.ParsedComponent parsedComponent) { - packageItemInfo.banner = parsedComponent.banner; - packageItemInfo.icon = parsedComponent.icon; - packageItemInfo.labelRes = parsedComponent.labelRes; - packageItemInfo.logo = parsedComponent.logo; - packageItemInfo.name = parsedComponent.className; - packageItemInfo.nonLocalizedLabel = parsedComponent.nonLocalizedLabel; - packageItemInfo.packageName = parsedComponent.getPackageName(); - } - - private static void assignSharedFieldsForComponentInfo(ComponentInfo componentInfo, - ComponentParseUtils.ParsedComponent parsedComponent) { - assignSharedFieldsForPackageItemInfo(componentInfo, parsedComponent); - componentInfo.descriptionRes = parsedComponent.descriptionRes; - componentInfo.directBootAware = parsedComponent.directBootAware; - componentInfo.enabled = parsedComponent.enabled; - componentInfo.splitName = parsedComponent.getSplitName(); - } - -} diff --git a/core/java/android/content/pm/parsing/ParsedPackage.java b/core/java/android/content/pm/parsing/ParsedPackage.java deleted file mode 100644 index 05cf586522f2..000000000000 --- a/core/java/android/content/pm/parsing/ParsedPackage.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package android.content.pm.parsing; - -import android.content.pm.PackageParser; - -/** - * Methods used for mutation after direct package parsing, mostly done inside - * {@link com.android.server.pm.PackageManagerService}. - * - * Java disallows defining this as an inner interface, so this must be a separate file. - * - * @hide - */ -public interface ParsedPackage extends AndroidPackage { - - AndroidPackage hideAsFinal(); - - ParsedPackage addUsesLibrary(int index, String libraryName); - - ParsedPackage addUsesOptionalLibrary(int index, String libraryName); - - ParsedPackage capPermissionPriorities(); - - ParsedPackage clearAdoptPermissions(); - - ParsedPackage clearOriginalPackages(); - - ParsedPackage clearProtectedBroadcasts(); - - /** - * TODO(b/135203078): Use non-AppInfo method - * @deprecated use {@link #setCodePath(String)} - */ - @Deprecated - ParsedPackage setApplicationInfoCodePath(String applicationInfoCodePath); - - /** - * TODO(b/135203078): Use non-AppInfo method - * @deprecated use {@link #setCodePath(String)} - */ - @Deprecated - ParsedPackage setApplicationInfoResourcePath(String applicationInfoResourcePath); - - ParsedPackage setBaseCodePath(String baseCodePath); - - ParsedPackage setCodePath(String codePath); - - ParsedPackage setCpuAbiOverride(String cpuAbiOverride); - - ParsedPackage setNativeLibraryDir(String nativeLibraryDir); - - ParsedPackage setNativeLibraryRootDir(String nativeLibraryRootDir); - - ParsedPackage setPackageName(String packageName); - - ParsedPackage setPrimaryCpuAbi(String primaryCpuAbi); - - ParsedPackage setProcessName(String processName); - - ParsedPackage setRealPackage(String realPackage); - - ParsedPackage setSecondaryCpuAbi(String secondaryCpuAbi); - - ParsedPackage setSigningDetails(PackageParser.SigningDetails signingDetails); - - ParsedPackage setSplitCodePaths(String[] splitCodePaths); - - ParsedPackage initForUser(int userId); - - ParsedPackage setNativeLibraryRootRequiresIsa(boolean nativeLibraryRootRequiresIsa); - - ParsedPackage setAllComponentsDirectBootAware(boolean allComponentsDirectBootAware); - - ParsedPackage setFactoryTest(boolean factoryTest); - - ParsedPackage markNotActivitiesAsNotExportedIfSingleUser(); - - ParsedPackage setOdm(boolean odm); - - ParsedPackage setOem(boolean oem); - - ParsedPackage setPrivileged(boolean privileged); - - ParsedPackage setProduct(boolean product); - - ParsedPackage setSignedWithPlatformKey(boolean signedWithPlatformKey); - - ParsedPackage setSystem(boolean system); - - ParsedPackage setSystemExt(boolean systemExt); - - ParsedPackage setUpdatedSystemApp(boolean updatedSystemApp); - - ParsedPackage setVendor(boolean vendor); - - ParsedPackage removePermission(int index); - - ParsedPackage removeUsesLibrary(String libraryName); - - ParsedPackage removeUsesOptionalLibrary(String libraryName); - - ParsedPackage setApplicationInfoBaseResourcePath(String applicationInfoBaseResourcePath); - - ParsedPackage setApplicationInfoSplitResourcePaths( - String[] applicationInfoSplitResourcePaths); - - ParsedPackage setApplicationVolumeUuid(String applicationVolumeUuid); - - ParsedPackage setCoreApp(boolean coreApp); - - ParsedPackage setIsStub(boolean isStub); - - // TODO(b/135203078): Remove entirely - ParsedPackage setPackageSettingCallback(PackageSettingCallback packageSettingCallback); - - ParsedPackage setRestrictUpdateHash(byte[] restrictUpdateHash); - - ParsedPackage setSeInfo(String seInfo); - - ParsedPackage setSeInfoUser(String seInfoUser); - - ParsedPackage setSecondaryNativeLibraryDir(String secondaryNativeLibraryDir); - - ParsedPackage setUid(int uid); - - ParsedPackage setVersionCode(int versionCode); - - ParsedPackage setVersionCodeMajor(int versionCodeMajor); - - // TODO(b/135203078): Move logic earlier in parse chain so nothing needs to be reverted - ParsedPackage setDefaultToDeviceProtectedStorage(boolean defaultToDeviceProtectedStorage); - - ParsedPackage setDirectBootAware(boolean directBootAware); - - ParsedPackage setPersistent(boolean persistent); - - interface PackageSettingCallback { - default void setAndroidPackage(AndroidPackage pkg){} - } -} diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java deleted file mode 100644 index 43c1f6e335b0..000000000000 --- a/core/java/android/content/pm/parsing/ParsingPackage.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package android.content.pm.parsing; - -import android.annotation.Nullable; -import android.content.Intent; -import android.content.pm.ConfigurationInfo; -import android.content.pm.FeatureGroupInfo; -import android.content.pm.FeatureInfo; -import android.content.pm.PackageParser; -import android.content.pm.parsing.ComponentParseUtils.ParsedActivity; -import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo; -import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermission; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup; -import android.content.pm.parsing.ComponentParseUtils.ParsedProvider; -import android.content.pm.parsing.ComponentParseUtils.ParsedService; -import android.os.Bundle; -import android.util.ArraySet; -import android.util.SparseArray; - -import java.security.PublicKey; - -/** - * Methods used for mutation during direct package parsing. - * - * Java disallows defining this as an inner interface, so this must be a separate file. - * - * @hide - */ -public interface ParsingPackage extends AndroidPackage { - - ParsingPackage addActivity(ParsedActivity parsedActivity); - - ParsingPackage addAdoptPermission(String adoptPermission); - - ParsingPackage addConfigPreference(ConfigurationInfo configPreference); - - ParsingPackage addFeatureGroup(FeatureGroupInfo featureGroup); - - ParsingPackage addImplicitPermission(String permission); - - ParsingPackage addInstrumentation(ParsedInstrumentation instrumentation); - - ParsingPackage addKeySet(String keySetName, PublicKey publicKey); - - ParsingPackage addLibraryName(String libraryName); - - ParsingPackage addOriginalPackage(String originalPackage); - - ParsingPackage addPermission(ParsedPermission permission); - - ParsingPackage addPermissionGroup(ParsedPermissionGroup permissionGroup); - - ParsingPackage addPreferredActivityFilter(ParsedActivityIntentInfo activityIntentInfo); - - ParsingPackage addProtectedBroadcast(String protectedBroadcast); - - ParsingPackage addProvider(ParsedProvider parsedProvider); - - ParsingPackage addReceiver(ParsedActivity parsedReceiver); - - ParsingPackage addReqFeature(FeatureInfo reqFeature); - - ParsingPackage addRequestedPermission(String permission); - - ParsingPackage addService(ParsedService parsedService); - - ParsingPackage addUsesLibrary(String libraryName); - - ParsingPackage addUsesOptionalLibrary(String libraryName); - - ParsingPackage addUsesStaticLibrary(String libraryName); - - ParsingPackage addUsesStaticLibraryCertDigests(String[] certSha256Digests); - - ParsingPackage addUsesStaticLibraryVersion(long version); - - ParsingPackage addQueriesIntent(Intent intent); - - ParsingPackage addQueriesPackage(String packageName); - - ParsingPackage asSplit( - String[] splitNames, - String[] splitCodePaths, - int[] splitRevisionCodes, - @Nullable SparseArray<int[]> splitDependencies - ); - - ParsingPackage setAppMetaData(Bundle appMetaData); - - ParsingPackage setForceQueryable(boolean forceQueryable); - - ParsingPackage setMaxAspectRatio(float maxAspectRatio); - - ParsingPackage setMinAspectRatio(float minAspectRatio); - - ParsingPackage setName(String name); - - ParsingPackage setPermission(String permission); - - ParsingPackage setProcessName(String processName); - - ParsingPackage setSharedUserId(String sharedUserId); - - ParsingPackage setStaticSharedLibName(String staticSharedLibName); - - ParsingPackage setTaskAffinity(String taskAffinity); - - ParsingPackage setTargetSdkVersion(int targetSdkVersion); - - ParsingPackage setUiOptions(int uiOptions); - - ParsingPackage setBaseHardwareAccelerated(boolean baseHardwareAccelerated); - - ParsingPackage setActivitiesResizeModeResizeable(boolean resizeable); - - ParsingPackage setActivitiesResizeModeResizeableViaSdkVersion(boolean resizeableViaSdkVersion); - - ParsingPackage setAllowAudioPlaybackCapture(boolean allowAudioPlaybackCapture); - - ParsingPackage setAllowBackup(boolean allowBackup); - - ParsingPackage setAllowClearUserData(boolean allowClearUserData); - - ParsingPackage setAllowClearUserDataOnFailedRestore(boolean allowClearUserDataOnFailedRestore); - - ParsingPackage setAllowTaskReparenting(boolean allowTaskReparenting); - - ParsingPackage setIsOverlay(boolean isOverlay); - - ParsingPackage setBackupInForeground(boolean backupInForeground); - - ParsingPackage setCantSaveState(boolean cantSaveState); - - ParsingPackage setDebuggable(boolean debuggable); - - ParsingPackage setDefaultToDeviceProtectedStorage(boolean defaultToDeviceProtectedStorage); - - ParsingPackage setDirectBootAware(boolean directBootAware); - - ParsingPackage setExternalStorage(boolean externalStorage); - - ParsingPackage setExtractNativeLibs(boolean extractNativeLibs); - - ParsingPackage setFullBackupOnly(boolean fullBackupOnly); - - ParsingPackage setHasCode(boolean hasCode); - - ParsingPackage setHasFragileUserData(boolean hasFragileUserData); - - ParsingPackage setIsGame(boolean isGame); - - ParsingPackage setIsolatedSplitLoading(boolean isolatedSplitLoading); - - ParsingPackage setKillAfterRestore(boolean killAfterRestore); - - ParsingPackage setLargeHeap(boolean largeHeap); - - ParsingPackage setMultiArch(boolean multiArch); - - ParsingPackage setPartiallyDirectBootAware(boolean partiallyDirectBootAware); - - ParsingPackage setPersistent(boolean persistent); - - ParsingPackage setProfileableByShell(boolean profileableByShell); - - ParsingPackage setRequestLegacyExternalStorage(boolean requestLegacyExternalStorage); - - ParsingPackage setRestoreAnyVersion(boolean restoreAnyVersion); - - ParsingPackage setSplitHasCode(int splitIndex, boolean splitHasCode); - - ParsingPackage setStaticSharedLibrary(boolean staticSharedLibrary); - - ParsingPackage setSupportsRtl(boolean supportsRtl); - - ParsingPackage setTestOnly(boolean testOnly); - - ParsingPackage setUseEmbeddedDex(boolean useEmbeddedDex); - - ParsingPackage setUsesCleartextTraffic(boolean usesCleartextTraffic); - - ParsingPackage setUsesNonSdkApi(boolean usesNonSdkApi); - - ParsingPackage setVisibleToInstantApps(boolean visibleToInstantApps); - - ParsingPackage setVmSafeMode(boolean vmSafeMode); - - ParsingPackage removeUsesOptionalLibrary(String libraryName); - - ParsingPackage setAnyDensity(int anyDensity); - - ParsingPackage setAppComponentFactory(String appComponentFactory); - - ParsingPackage setApplicationVolumeUuid(String applicationVolumeUuid); - - ParsingPackage setBackupAgentName(String backupAgentName); - - ParsingPackage setBanner(int banner); - - ParsingPackage setCategory(int category); - - ParsingPackage setClassLoaderName(String classLoaderName); - - ParsingPackage setClassName(String className); - - ParsingPackage setCodePath(String codePath); - - ParsingPackage setCompatibleWidthLimitDp(int compatibleWidthLimitDp); - - ParsingPackage setDescriptionRes(int descriptionRes); - - ParsingPackage setEnabled(boolean enabled); - - ParsingPackage setFullBackupContent(int fullBackupContent); - - ParsingPackage setHasDomainUrls(boolean hasDomainUrls); - - ParsingPackage setIcon(int icon); - - ParsingPackage setIconRes(int iconRes); - - ParsingPackage setInstallLocation(int installLocation); - - ParsingPackage setLabelRes(int labelRes); - - ParsingPackage setLargestWidthLimitDp(int largestWidthLimitDp); - - ParsingPackage setLogo(int logo); - - ParsingPackage setManageSpaceActivityName(String manageSpaceActivityName); - - ParsingPackage setMinSdkVersion(int minSdkVersion); - - ParsingPackage setNetworkSecurityConfigRes(int networkSecurityConfigRes); - - ParsingPackage setNonLocalizedLabel(CharSequence nonLocalizedLabel); - - ParsingPackage setOverlayCategory(String overlayCategory); - - ParsingPackage setOverlayIsStatic(boolean overlayIsStatic); - - ParsingPackage setOverlayPriority(int overlayPriority); - - ParsingPackage setOverlayTarget(String overlayTarget); - - ParsingPackage setOverlayTargetName(String overlayTargetName); - - ParsingPackage setRealPackage(String realPackage); - - ParsingPackage setRequiredAccountType(String requiredAccountType); - - ParsingPackage setRequiredForAllUsers(boolean requiredForAllUsers); - - ParsingPackage setRequiresSmallestWidthDp(int requiresSmallestWidthDp); - - ParsingPackage setResizeable(int resizeable); - - ParsingPackage setRestrictUpdateHash(byte[] restrictUpdateHash); - - ParsingPackage setRestrictedAccountType(String restrictedAccountType); - - ParsingPackage setRoundIconRes(int roundIconRes); - - ParsingPackage setSharedUserLabel(int sharedUserLabel); - - ParsingPackage setSigningDetails(PackageParser.SigningDetails signingDetails); - - ParsingPackage setSplitClassLoaderName(int splitIndex, String classLoaderName); - - ParsingPackage setStaticSharedLibVersion(long staticSharedLibVersion); - - ParsingPackage setSupportsLargeScreens(int supportsLargeScreens); - - ParsingPackage setSupportsNormalScreens(int supportsNormalScreens); - - ParsingPackage setSupportsSmallScreens(int supportsSmallScreens); - - ParsingPackage setSupportsXLargeScreens(int supportsXLargeScreens); - - ParsingPackage setTargetSandboxVersion(int targetSandboxVersion); - - ParsingPackage setTheme(int theme); - - ParsingPackage setUpgradeKeySets(ArraySet<String> upgradeKeySets); - - ParsingPackage setUse32BitAbi(boolean use32BitAbi); - - ParsingPackage setVolumeUuid(String volumeUuid); - - ParsingPackage setZygotePreloadName(String zygotePreloadName); - - ParsingPackage sortActivities(); - - ParsingPackage sortReceivers(); - - ParsingPackage sortServices(); - - ParsedPackage hideAsParsed(); - - ParsingPackage setBaseRevisionCode(int baseRevisionCode); - - ParsingPackage setPreferredOrder(int preferredOrder); - - ParsingPackage setVersionName(String versionName); - - ParsingPackage setCompileSdkVersion(int compileSdkVersion); - - ParsingPackage setCompileSdkVersionCodename(String compileSdkVersionCodename); - - boolean usesCompatibilityMode(); -} diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 567e26b4c2f6..7d6dc97e82cb 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -60,7 +60,6 @@ import java.util.Map; public final class AssetManager implements AutoCloseable { private static final String TAG = "AssetManager"; private static final boolean DEBUG_REFS = false; - private static final boolean FEATURE_FLAG_IDMAP2 = true; private static final String FRAMEWORK_APK_PATH = "/system/framework/framework-res.apk"; @@ -202,20 +201,14 @@ public final class AssetManager implements AutoCloseable { try { final ArrayList<ApkAssets> apkAssets = new ArrayList<>(); apkAssets.add(ApkAssets.loadFromPath(FRAMEWORK_APK_PATH, true /*system*/)); - if (FEATURE_FLAG_IDMAP2) { - final String[] systemIdmapPaths = - nativeCreateIdmapsForStaticOverlaysTargetingAndroid(); - if (systemIdmapPaths != null) { - for (String idmapPath : systemIdmapPaths) { - apkAssets.add(ApkAssets.loadOverlayFromPath(idmapPath, true /*system*/)); - } - } else { - Log.w(TAG, "'idmap2 --scan' failed: no static=\"true\" overlays targeting " - + "\"android\" will be loaded"); + final String[] systemIdmapPaths = nativeCreateIdmapsForStaticOverlaysTargetingAndroid(); + if (systemIdmapPaths != null) { + for (String idmapPath : systemIdmapPaths) { + apkAssets.add(ApkAssets.loadOverlayFromPath(idmapPath, true /*system*/)); } } else { - nativeVerifySystemIdmaps(); - loadStaticRuntimeOverlays(apkAssets); + Log.w(TAG, "'idmap2 --scan' failed: no static=\"true\" overlays targeting " + + "\"android\" will be loaded"); } sSystemApkAssetsSet = new ArraySet<>(apkAssets); diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl index 0daf30f25d59..638d81b2f635 100644 --- a/core/java/android/hardware/input/IInputManager.aidl +++ b/core/java/android/hardware/input/IInputManager.aidl @@ -76,6 +76,9 @@ interface IInputManager { // Registers a tablet mode change listener void registerTabletModeChangedListener(ITabletModeChangedListener listener); + // Queries whether the device's microphone is muted by switch + int isMicMuted(); + // Input device vibrator control. void vibrate(int deviceId, in long[] pattern, int repeat, IBinder token); void cancelVibrate(int deviceId, IBinder token); diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index 2a59be28a937..0c0f248e3222 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -520,6 +520,22 @@ public final class InputManager { } /** + * Queries whether the device's microphone is muted + * + * @return The mic mute switch state which is one of {@link #SWITCH_STATE_UNKNOWN}, + * {@link #SWITCH_STATE_OFF} or {@link #SWITCH_STATE_ON}. + * @hide + */ + @SwitchState + public int isMicMuted() { + try { + return mIm.isMicMuted(); + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } + } + + /** * Gets information about all supported keyboard layouts. * <p> * The input manager consults the built-in keyboard layouts as well diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 351462f8d68e..2d8af83c7ca7 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -1580,7 +1580,14 @@ public class StorageManager { /** {@hide} */ public static boolean hasAdoptable() { - return SystemProperties.getBoolean(PROP_HAS_ADOPTABLE, false); + switch (SystemProperties.get(PROP_ADOPTABLE)) { + case "force_on": + return true; + case "force_off": + return false; + default: + return SystemProperties.getBoolean(PROP_HAS_ADOPTABLE, false); + } } /** diff --git a/core/java/android/os/telephony/TelephonyRegistryManager.java b/core/java/android/os/telephony/TelephonyRegistryManager.java index 459c414cdf73..5c49cb6f60aa 100644 --- a/core/java/android/os/telephony/TelephonyRegistryManager.java +++ b/core/java/android/os/telephony/TelephonyRegistryManager.java @@ -21,23 +21,25 @@ import android.net.NetworkCapabilities; import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; +import android.telephony.Annotation; +import android.telephony.Annotation.ApnType; +import android.telephony.Annotation.CallState; +import android.telephony.Annotation.DataActivityType; +import android.telephony.Annotation.DataFailureCause; +import android.telephony.Annotation.DataState; +import android.telephony.Annotation.NetworkType; +import android.telephony.Annotation.RadioPowerState; +import android.telephony.Annotation.SimActivationState; +import android.telephony.Annotation.SrvccState; import android.telephony.CallQuality; import android.telephony.CellInfo; -import android.telephony.DataFailCause; import android.telephony.DisconnectCause; import android.telephony.PhoneCapability; import android.telephony.PreciseCallState.State; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.TelephonyManager; -import android.telephony.TelephonyManager.CallState; -import android.telephony.TelephonyManager.DataActivityType; -import android.telephony.TelephonyManager.DataState; -import android.telephony.TelephonyManager.NetworkType; -import android.telephony.TelephonyManager.RadioPowerState; -import android.telephony.TelephonyManager.SimActivationState; import android.telephony.data.ApnSetting; -import android.telephony.data.ApnSetting.ApnType; import android.telephony.ims.ImsReasonInfo; import com.android.internal.telephony.ITelephonyRegistry; import java.util.List; @@ -410,7 +412,7 @@ public class TelephonyRegistryManager { * @hide */ public void notifyPreciseDataConnectionFailed(int subId, int slotIndex, String apnType, - String apn, @DataFailCause.FailCause int failCause) { + String apn, @DataFailureCause int failCause) { try { sRegistry.notifyPreciseDataConnectionFailed(slotIndex, subId, apnType, apn, failCause); } catch (RemoteException ex) { @@ -427,7 +429,7 @@ public class TelephonyRegistryManager { * * @hide */ - public void notifySrvccStateChanged(int subId, @TelephonyManager.SrvccState int state) { + public void notifySrvccStateChanged(int subId, @SrvccState int state) { try { sRegistry.notifySrvccStateChanged(subId, state); } catch (RemoteException ex) { diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java index 2b3a2ab05e82..4dd9baba3e5f 100644 --- a/core/java/android/preference/SeekBarVolumizer.java +++ b/core/java/android/preference/SeekBarVolumizer.java @@ -151,7 +151,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba .PRIORITY_CATEGORY_ALARMS) != 0; mAllowMedia = (mNotificationPolicy.priorityCategories & NotificationManager.Policy .PRIORITY_CATEGORY_MEDIA) != 0; - mAllowRinger = !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted( + mAllowRinger = !ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted( mNotificationPolicy); mStreamType = streamType; mAffectedByRingerMode = mAudioManager.isStreamAffectedByRingerMode(mStreamType); @@ -571,7 +571,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba .PRIORITY_CATEGORY_ALARMS) != 0; mAllowMedia = (mNotificationPolicy.priorityCategories & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) != 0; - mAllowRinger = !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted( + mAllowRinger = !ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted( mNotificationPolicy); updateSlider(); } diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 937990f7e88e..1f2c872a2233 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -1904,10 +1904,10 @@ public class ZenModeConfig implements Parcelable { } /** - * Determines whether dnd behavior should mute all notification/ringer sounds - * (sounds associated with ringer volume discluding system) + * Determines whether dnd behavior should mute all ringer-controlled sounds + * This includes notification, ringer and system sounds */ - public static boolean areAllPriorityOnlyNotificationZenSoundsMuted(NotificationManager.Policy + public static boolean areAllPriorityOnlyRingerSoundsMuted(NotificationManager.Policy policy) { boolean allowReminders = (policy.priorityCategories & NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS) != 0; @@ -1920,20 +1920,19 @@ public class ZenModeConfig implements Parcelable { boolean allowRepeatCallers = (policy.priorityCategories & NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS) != 0; boolean areChannelsBypassingDnd = (policy.state & Policy.STATE_CHANNELS_BYPASSING_DND) != 0; + boolean allowSystem = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_SYSTEM) != 0; return !allowReminders && !allowCalls && !allowMessages && !allowEvents - && !allowRepeatCallers && !areChannelsBypassingDnd; + && !allowRepeatCallers && !areChannelsBypassingDnd && !allowSystem; } /** - * Determines whether dnd behavior should mute all sounds controlled by ringer + * Determines whether dnd behavior should mute all sounds */ public static boolean areAllZenBehaviorSoundsMuted(NotificationManager.Policy policy) { boolean allowAlarms = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_ALARMS) != 0; boolean allowMedia = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_MEDIA) != 0; - boolean allowSystem = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_SYSTEM) != 0; - return !allowAlarms && !allowMedia && !allowSystem - && areAllPriorityOnlyNotificationZenSoundsMuted(policy); + return !allowAlarms && !allowMedia && areAllPriorityOnlyRingerSoundsMuted(policy); } /** @@ -1943,24 +1942,25 @@ public class ZenModeConfig implements Parcelable { return zen == Global.ZEN_MODE_NO_INTERRUPTIONS || zen == Global.ZEN_MODE_ALARMS || (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS - && ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(consolidatedPolicy)); + && ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(consolidatedPolicy)); } /** - * Determines whether dnd behavior should mute all sounds controlled by ringer + * Determines whether dnd behavior should mute all ringer-controlled sounds + * This includes notification, ringer and system sounds */ - public static boolean areAllPriorityOnlyNotificationZenSoundsMuted(ZenModeConfig config) { + public static boolean areAllPriorityOnlyRingerSoundsMuted(ZenModeConfig config) { return !config.allowReminders && !config.allowCalls && !config.allowMessages && !config.allowEvents && !config.allowRepeatCallers - && !config.areChannelsBypassingDnd; + && !config.areChannelsBypassingDnd && !config.allowSystem; } /** - * Determines whether all dnd mutes all sounds + * Determines whether dnd mutes all sounds */ public static boolean areAllZenBehaviorSoundsMuted(ZenModeConfig config) { - return !config.allowAlarms && !config.allowMedia && !config.allowSystem - && areAllPriorityOnlyNotificationZenSoundsMuted(config); + return !config.allowAlarms && !config.allowMedia + && areAllPriorityOnlyRingerSoundsMuted(config); } /** diff --git a/core/java/android/view/DragAndDropPermissions.java b/core/java/android/view/DragAndDropPermissions.java index e72ff38ce3f0..d47604d6ec41 100644 --- a/core/java/android/view/DragAndDropPermissions.java +++ b/core/java/android/view/DragAndDropPermissions.java @@ -37,7 +37,7 @@ import com.android.internal.view.IDragAndDropPermissions; * View.startDragAndDrop} by the app that started the drag operation. * </p> * <p> - * The life cycle of the permissions is bound to the activity used to call {@link + * The lifecycle of the permissions is bound to the activity used to call {@link * android.app.Activity#requestDragAndDropPermissions(DragEvent) requestDragAndDropPermissions}. The * permissions are revoked when this activity is destroyed, or when {@link #release()} is called, * whichever occurs first. @@ -49,6 +49,10 @@ import com.android.internal.view.IDragAndDropPermissions; * {@link Activity#onSaveInstanceState} bundle and later retrieved in order to manually release * the permissions once they are no longer needed. * </p> + * <p> + * Learn more about <a href="/guide/topics/ui/drag-drop#DragPermissionsMultiWindow">drag permissions + * in multi-window mode</a>. + * </p> */ public final class DragAndDropPermissions implements Parcelable { diff --git a/core/java/android/view/InputMonitor.java b/core/java/android/view/InputMonitor.java index bbd27dc45779..1a1d7e682f6e 100644 --- a/core/java/android/view/InputMonitor.java +++ b/core/java/android/view/InputMonitor.java @@ -21,6 +21,8 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; +import com.android.internal.util.DataClass; + /** * An {@code InputMonitor} allows privileged applications and components to monitor streams of * {@link InputEvent}s without having to be the designated recipient for the event. @@ -31,57 +33,19 @@ import android.os.RemoteException; * * @hide */ +@DataClass(genToString = true) public final class InputMonitor implements Parcelable { private static final String TAG = "InputMonitor"; private static final boolean DEBUG = false; - public static final Parcelable.Creator<InputMonitor> CREATOR = - new Parcelable.Creator<InputMonitor>() { - - public InputMonitor createFromParcel(Parcel source) { - return new InputMonitor(source); - } - - public InputMonitor[] newArray(int size) { - return new InputMonitor[size]; - } - }; - @NonNull private final String mName; @NonNull - private final InputChannel mChannel; + private final InputChannel mInputChannel; @NonNull private final IInputMonitorHost mHost; - public InputMonitor(@NonNull String name, @NonNull InputChannel channel, - @NonNull IInputMonitorHost host) { - mName = name; - mChannel = channel; - mHost = host; - } - - public InputMonitor(Parcel in) { - mName = in.readString(); - mChannel = in.readParcelable(null); - mHost = IInputMonitorHost.Stub.asInterface(in.readStrongBinder()); - } - - /** - * Get the {@link InputChannel} corresponding to this InputMonitor - */ - public InputChannel getInputChannel() { - return mChannel; - } - - /** - * Get the name of this channel. - */ - public String getName() { - return mName; - } - /** * Takes all of the current pointer events streams that are currently being sent to this @@ -107,7 +71,7 @@ public final class InputMonitor implements Parcelable { * no longer be used. */ public void dispose() { - mChannel.dispose(); + mInputChannel.dispose(); try { mHost.dispose(); } catch (RemoteException e) { @@ -115,20 +79,108 @@ public final class InputMonitor implements Parcelable { } } - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeString(mName); - out.writeParcelable(mChannel, flags); - out.writeStrongBinder(mHost.asBinder()); + + + // Code below generated by codegen v1.0.1. + // + // DO NOT MODIFY! + // + // To regenerate run: + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/InputMonitor.java + // + // CHECKSTYLE:OFF Generated code + + @DataClass.Generated.Member + public InputMonitor( + @NonNull String name, + @NonNull InputChannel inputChannel, + @NonNull IInputMonitorHost host) { + this.mName = name; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mName); + this.mInputChannel = inputChannel; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mInputChannel); + this.mHost = host; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mHost); + + // onConstructed(); // You can define this method to get a callback } - @Override - public int describeContents() { - return 0; + @DataClass.Generated.Member + public @NonNull String getName() { + return mName; + } + + @DataClass.Generated.Member + public @NonNull InputChannel getInputChannel() { + return mInputChannel; + } + + @DataClass.Generated.Member + public @NonNull IInputMonitorHost getHost() { + return mHost; } @Override + @DataClass.Generated.Member public String toString() { - return "InputMonitor{mName=" + mName + ", mChannel=" + mChannel + ", mHost=" + mHost + "}"; + // You can override field toString logic by defining methods like: + // String fieldNameToString() { ... } + + return "InputMonitor { " + + "name = " + mName + ", " + + "inputChannel = " + mInputChannel + ", " + + "host = " + mHost + + " }"; + } + + @Override + @DataClass.Generated.Member + public void writeToParcel(Parcel dest, int flags) { + // You can override field parcelling by defining methods like: + // void parcelFieldName(Parcel dest, int flags) { ... } + + dest.writeString(mName); + dest.writeTypedObject(mInputChannel, flags); + dest.writeStrongInterface(mHost); } + + @Override + @DataClass.Generated.Member + public int describeContents() { return 0; } + + @DataClass.Generated.Member + public static final @NonNull Parcelable.Creator<InputMonitor> CREATOR + = new Parcelable.Creator<InputMonitor>() { + @Override + public InputMonitor[] newArray(int size) { + return new InputMonitor[size]; + } + + @Override + @SuppressWarnings({"unchecked", "RedundantCast"}) + public InputMonitor createFromParcel(Parcel in) { + // You can override field unparcelling by defining methods like: + // static FieldType unparcelFieldName(Parcel in) { ... } + + String name = in.readString(); + InputChannel inputChannel = (InputChannel) in.readTypedObject(InputChannel.CREATOR); + IInputMonitorHost host = IInputMonitorHost.Stub.asInterface(in.readStrongBinder()); + return new InputMonitor( + name, + inputChannel, + host); + } + }; + + @DataClass.Generated( + time = 1569871940995L, + codegenVersion = "1.0.1", + sourceFile = "frameworks/base/core/java/android/view/InputMonitor.java", + inputSignatures = "private static final java.lang.String TAG\nprivate static final boolean DEBUG\nprivate final @android.annotation.NonNull java.lang.String mName\nprivate final @android.annotation.NonNull android.view.InputChannel mInputChannel\nprivate final @android.annotation.NonNull android.view.IInputMonitorHost mHost\npublic void pilferPointers()\npublic void dispose()\nclass InputMonitor extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true)") + @Deprecated + private void __metadata() {} + } diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 06ff568202d5..a85830009f58 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -167,6 +167,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall boolean mUseAlpha = false; float mSurfaceAlpha = 1f; + boolean mClipSurfaceToBounds; @UnsupportedAppUsage boolean mHaveFrame = false; @@ -555,9 +556,52 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall super.dispatchDraw(canvas); } + /** + * Control whether the surface is clipped to the same bounds as the View. If true, then + * the bounds set by {@link #setClipBounds(Rect)} are applied to the surface as window-crop. + * + * @param enabled whether to enable surface clipping + * @hide + */ + public void setEnableSurfaceClipping(boolean enabled) { + mClipSurfaceToBounds = enabled; + invalidate(); + } + + @Override + public void setClipBounds(Rect clipBounds) { + super.setClipBounds(clipBounds); + + if (!mClipSurfaceToBounds) { + return; + } + + // When cornerRadius is non-zero, a draw() is required to update + // the viewport (rounding the corners of the clipBounds). + if (mCornerRadius > 0f && !isAboveParent()) { + invalidate(); + } + + if (mSurfaceControl != null) { + if (mClipBounds != null) { + mTmpRect.set(mClipBounds); + } else { + mTmpRect.set(0, 0, mSurfaceWidth, mSurfaceHeight); + } + SyncRtSurfaceTransactionApplier applier = new SyncRtSurfaceTransactionApplier(this); + applier.scheduleApply( + new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(mSurfaceControl) + .withWindowCrop(mTmpRect) + .build()); + } + } + private void clearSurfaceViewPort(Canvas canvas) { if (mCornerRadius > 0f) { canvas.getClipBounds(mTmpRect); + if (mClipSurfaceToBounds && mClipBounds != null) { + mTmpRect.intersect(mClipBounds); + } canvas.drawRoundRect(mTmpRect.left, mTmpRect.top, mTmpRect.right, mTmpRect.bottom, mCornerRadius, mCornerRadius, mRoundedViewportPaint); } else { @@ -583,6 +627,16 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } /** + * Returns the corner radius for the SurfaceView. + + * @return the radius of the corners in pixels + * @hide + */ + public float getCornerRadius() { + return mCornerRadius; + } + + /** * Control whether the surface view's surface is placed on top of another * regular surface view in the window (but still behind the window itself). * This is typically used to place overlays on top of an underlying media @@ -840,7 +894,11 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall // crop the buffer to the surface size since the buffer producer may // use SCALING_MODE_SCALE and submit a larger size than the surface // size. - mSurfaceControl.setWindowCrop(mSurfaceWidth, mSurfaceHeight); + if (mClipSurfaceToBounds && mClipBounds != null) { + mSurfaceControl.setWindowCrop(mClipBounds); + } else { + mSurfaceControl.setWindowCrop(mSurfaceWidth, mSurfaceHeight); + } } mSurfaceControl.setCornerRadius(mCornerRadius); if (sizeChanged && !creating) { diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java index 5f3ce33db19d..606e8f99999a 100644 --- a/core/java/android/view/ViewStructure.java +++ b/core/java/android/view/ViewStructure.java @@ -230,6 +230,8 @@ public abstract class ViewStructure { /** * Sets the identifier used to set the hint associated with this view. * + * <p>Used as metadata for fingerprinting view nodes/structures. + * * <p>Should only be set when the node is used for autofill purposes - it will be ignored * when used for Assist. */ diff --git a/core/java/android/view/WindowlessViewRoot.java b/core/java/android/view/WindowlessViewRoot.java index b76e1fad563e..c2500b89073e 100644 --- a/core/java/android/view/WindowlessViewRoot.java +++ b/core/java/android/view/WindowlessViewRoot.java @@ -41,4 +41,12 @@ public class WindowlessViewRoot { public void addView(View view, WindowManager.LayoutParams attrs) { mViewRoot.setView(view, attrs, null); } + + public void relayout(WindowManager.LayoutParams attrs) { + mViewRoot.setLayoutParams(attrs, false); + mViewRoot.setReportNextDraw(); + mWm.setCompletionCallback(mViewRoot.mWindow.asBinder(), (SurfaceControl.Transaction t) -> { + t.apply(); + }); + } } diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index 430fb6dd9770..f4f7d0b33fd1 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -39,11 +39,27 @@ import java.util.HashMap; class WindowlessWindowManager implements IWindowSession { private final static String TAG = "WindowlessWindowManager"; + private class State { + SurfaceControl mSurfaceControl; + WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(); + State(SurfaceControl sc, WindowManager.LayoutParams p) { + mSurfaceControl = sc; + mParams.copyFrom(p); + } + }; /** * Used to store SurfaceControl we've built for clients to * reconfigure them if relayout is called. */ - final HashMap<IBinder, SurfaceControl> mScForWindow = new HashMap<IBinder, SurfaceControl>(); + final HashMap<IBinder, State> mStateForWindow = new HashMap<IBinder, State>(); + + public interface ResizeCompleteCallback { + public void finished(SurfaceControl.Transaction completion); + } + + final HashMap<IBinder, ResizeCompleteCallback> mResizeCompletionForWindow = + new HashMap<IBinder, ResizeCompleteCallback>(); + final SurfaceSession mSurfaceSession = new SurfaceSession(); final SurfaceControl mRootSurface; final Configuration mConfiguration; @@ -58,6 +74,19 @@ class WindowlessWindowManager implements IWindowSession { mRealWm = WindowManagerGlobal.getWindowSession(); } + /** + * Utility API. + */ + void setCompletionCallback(IBinder window, ResizeCompleteCallback callback) { + if (mResizeCompletionForWindow.get(window) != null) { + Log.w(TAG, "Unsupported overlapping resizes"); + } + mResizeCompletionForWindow.put(window, callback); + } + + /** + * IWindowSession implementation. + */ public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, @@ -68,7 +97,7 @@ class WindowlessWindowManager implements IWindowSession { .setName(attrs.getTitle().toString()); final SurfaceControl sc = b.build(); synchronized (this) { - mScForWindow.put(window.asBinder(), sc); + mStateForWindow.put(window.asBinder(), new State(sc, attrs)); } if ((attrs.inputFeatures & @@ -104,34 +133,40 @@ class WindowlessWindowManager implements IWindowSession { } @Override - public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs, + public int relayout(IWindow window, int seq, WindowManager.LayoutParams inAttrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Rect outStableInsets, Rect outsets, Rect outBackdropFrame, DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState) { - SurfaceControl sc = null; + State state = null; synchronized (this) { - sc = mScForWindow.get(window.asBinder()); + state = mStateForWindow.get(window.asBinder()); } - if (sc == null) { + if (state == null) { throw new IllegalArgumentException( "Invalid window token (never added or removed already)"); } + SurfaceControl sc = state.mSurfaceControl; SurfaceControl.Transaction t = new SurfaceControl.Transaction(); + if (inAttrs != null) { + state.mParams.copyFrom(inAttrs); + } + WindowManager.LayoutParams attrs = state.mParams; + final Rect surfaceInsets = attrs.surfaceInsets; int width = surfaceInsets != null ? - requestedWidth + surfaceInsets.left + surfaceInsets.right : requestedWidth; + attrs.width + surfaceInsets.left + surfaceInsets.right : attrs.width; int height = surfaceInsets != null ? - requestedHeight + surfaceInsets.top + surfaceInsets.bottom : requestedHeight; + attrs.height + surfaceInsets.top + surfaceInsets.bottom : attrs.height; t.show(sc) .setBufferSize(sc, width, height) .setOpaque(sc, isOpaque(attrs)) .apply(); outSurfaceControl.copyFrom(sc); - outFrame.set(0, 0, requestedWidth, requestedHeight); + outFrame.set(0, 0, attrs.width, attrs.height); mergedConfiguration.setConfiguration(mConfiguration, mConfiguration); @@ -165,6 +200,17 @@ class WindowlessWindowManager implements IWindowSession { @Override public void finishDrawing(android.view.IWindow window, android.view.SurfaceControl.Transaction postDrawTransaction) { + synchronized (this) { + final ResizeCompleteCallback c = + mResizeCompletionForWindow.get(window.asBinder()); + if (c == null) { + // No one wanted the callback, but it wasn't necessarily unexpected. + postDrawTransaction.apply(); + return; + } + c.finished(postDrawTransaction); + mResizeCompletionForWindow.remove(window.asBinder()); + } } @Override diff --git a/core/java/android/view/contentcapture/ChildContentCaptureSession.java b/core/java/android/view/contentcapture/ChildContentCaptureSession.java index 5e02de451fa3..7487ec4d921c 100644 --- a/core/java/android/view/contentcapture/ChildContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ChildContentCaptureSession.java @@ -89,8 +89,13 @@ final class ChildContentCaptureSession extends ContentCaptureSession { } @Override - public void internalNotifySessionLifecycle(boolean started) { - getMainCaptureSession().notifySessionLifecycle(mId, started); + void internalNotifySessionResumed() { + getMainCaptureSession().notifySessionResumed(); + } + + @Override + void internalNotifySessionPaused() { + getMainCaptureSession().notifySessionPaused(); } @Override diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index d22fac996dbb..6040abd4f5f6 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -404,14 +404,14 @@ public final class ContentCaptureManager { @UiThread public void onActivityResumed() { if (mOptions.lite) return; - getMainContentCaptureSession().notifySessionLifecycle(/* started= */ true); + getMainContentCaptureSession().notifySessionResumed(); } /** @hide */ @UiThread public void onActivityPaused() { if (mOptions.lite) return; - getMainContentCaptureSession().notifySessionLifecycle(/* started= */ false); + getMainContentCaptureSession().notifySessionPaused(); } /** @hide */ diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java index cf08c18b019a..232d96ba7f43 100644 --- a/core/java/android/view/contentcapture/ContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ContentCaptureSession.java @@ -439,17 +439,26 @@ public abstract class ContentCaptureSession implements AutoCloseable { public abstract void internalNotifyViewTreeEvent(boolean started); /** - * Notifies the Content Capture Service that a session has paused/resumed. - * - * @param started whether session has resumed. + * Notifies the Content Capture Service that a session has resumed. + */ + public final void notifySessionResumed() { + if (!isContentCaptureEnabled()) return; + + internalNotifySessionResumed(); + } + + abstract void internalNotifySessionResumed(); + + /** + * Notifies the Content Capture Service that a session has paused. */ - public final void notifySessionLifecycle(boolean started) { + public final void notifySessionPaused() { if (!isContentCaptureEnabled()) return; - internalNotifySessionLifecycle(started); + internalNotifySessionPaused(); } - abstract void internalNotifySessionLifecycle(boolean started); + abstract void internalNotifySessionPaused(); /** * Creates a {@link ViewStructure} for a "standard" view. diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index 349ef09cf059..96f224fef251 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -583,8 +583,13 @@ public final class MainContentCaptureSession extends ContentCaptureSession { } @Override - public void internalNotifySessionLifecycle(boolean started) { - notifySessionLifecycle(mId, started); + public void internalNotifySessionResumed() { + notifySessionResumed(mId); + } + + @Override + public void internalNotifySessionPaused() { + notifySessionPaused(mId); } @Override @@ -642,9 +647,12 @@ public final class MainContentCaptureSession extends ContentCaptureSession { sendEvent(new ContentCaptureEvent(sessionId, type), FORCE_FLUSH); } - void notifySessionLifecycle(int sessionId, boolean started) { - final int type = started ? TYPE_SESSION_RESUMED : TYPE_SESSION_PAUSED; - sendEvent(new ContentCaptureEvent(sessionId, type), FORCE_FLUSH); + void notifySessionResumed(int sessionId) { + sendEvent(new ContentCaptureEvent(sessionId, TYPE_SESSION_RESUMED), FORCE_FLUSH); + } + + void notifySessionPaused(int sessionId) { + sendEvent(new ContentCaptureEvent(sessionId, TYPE_SESSION_PAUSED), FORCE_FLUSH); } void notifyContextUpdated(int sessionId, @Nullable ContentCaptureContext context) { diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 032af1c5c7b5..6420d71216cd 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -525,16 +525,16 @@ public final class InputMethodManager { final InputMethodManager fallbackImm = viewRootImpl.mContext.getSystemService(InputMethodManager.class); if (fallbackImm == null) { - Log.e(TAG, "b/117267690: Failed to get non-null fallback IMM. view=" + view); + Log.v(TAG, "b/117267690: Failed to get non-null fallback IMM. view=" + view); return null; } if (fallbackImm.mDisplayId != viewRootDisplayId) { - Log.e(TAG, "b/117267690: Failed to get fallback IMM with expected displayId=" + Log.v(TAG, "b/117267690: Failed to get fallback IMM with expected displayId=" + viewRootDisplayId + " actual IMM#displayId=" + fallbackImm.mDisplayId + " view=" + view); return null; } - Log.w(TAG, "b/117267690: Display ID mismatch found." + Log.v(TAG, "b/117267690: Display ID mismatch found." + " ViewRootImpl displayId=" + viewRootDisplayId + " InputMethodManager displayId=" + mDisplayId + ". Use the right InputMethodManager instance to avoid performance overhead.", diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java index f04a6715e55f..fee8345d1660 100644 --- a/core/java/com/android/internal/content/NativeLibraryHelper.java +++ b/core/java/com/android/internal/content/NativeLibraryHelper.java @@ -28,11 +28,12 @@ import static android.system.OsConstants.S_IXOTH; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageParser; +import android.content.pm.PackageParser.Package; import android.content.pm.PackageParser.PackageLite; import android.content.pm.PackageParser.PackageParserException; -import android.content.pm.parsing.AndroidPackage; import android.os.Build; import android.os.SELinux; +import android.os.SystemProperties; import android.system.ErrnoException; import android.system.Os; import android.util.Slog; @@ -87,12 +88,11 @@ public class NativeLibraryHelper { } } - public static Handle create(AndroidPackage pkg) throws IOException { - return create( - pkg.makeListAllCodePaths(), - (pkg.getFlags() & ApplicationInfo.FLAG_MULTIARCH) != 0, - (pkg.getFlags() & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) != 0, - (pkg.getFlags() & ApplicationInfo.FLAG_DEBUGGABLE) != 0); + public static Handle create(Package pkg) throws IOException { + return create(pkg.getAllCodePaths(), + (pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0, + (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) != 0, + (pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0); } public static Handle create(PackageLite lite) throws IOException { diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java index c928f3f39f03..d6dcb29e0682 100644 --- a/core/java/com/android/internal/content/PackageMonitor.java +++ b/core/java/com/android/internal/content/PackageMonitor.java @@ -22,11 +22,11 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; -import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; import android.util.Slog; + import com.android.internal.os.BackgroundThread; import com.android.internal.util.Preconditions; @@ -203,10 +203,6 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { public void onPackagesSuspended(String[] packages) { } - public void onPackagesSuspended(String[] packages, Bundle launcherExtras) { - onPackagesSuspended(packages); - } - public void onPackagesUnsuspended(String[] packages) { } @@ -446,9 +442,8 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { } } else if (Intent.ACTION_PACKAGES_SUSPENDED.equals(action)) { String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); - final Bundle launcherExtras = intent.getBundleExtra(Intent.EXTRA_LAUNCHER_EXTRAS); mSomePackagesChanged = true; - onPackagesSuspended(pkgList, launcherExtras); + onPackagesSuspended(pkgList); } else if (Intent.ACTION_PACKAGES_UNSUSPENDED.equals(action)) { String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); mSomePackagesChanged = true; diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java index bc8019796d22..821022f1f917 100644 --- a/core/java/com/android/internal/util/ArrayUtils.java +++ b/core/java/com/android/internal/util/ArrayUtils.java @@ -600,14 +600,6 @@ public class ArrayUtils { return cur; } - public static @NonNull <T> ArrayList<T> add(@Nullable ArrayList<T> cur, int index, T val) { - if (cur == null) { - cur = new ArrayList<>(); - } - cur.add(index, val); - return cur; - } - public static @Nullable <T> ArrayList<T> remove(@Nullable ArrayList<T> cur, T val) { if (cur == null) { return null; diff --git a/core/jni/Android.bp b/core/jni/Android.bp index e3b8560ae749..0505fe30c55c 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -110,7 +110,6 @@ cc_library_shared { "android_view_InputEventReceiver.cpp", "android_view_InputEventSender.cpp", "android_view_InputQueue.cpp", - "android_view_FrameMetricsObserver.cpp", "android_view_KeyCharacterMap.cpp", "android_view_KeyEvent.cpp", "android_view_MotionEvent.cpp", @@ -423,7 +422,9 @@ cc_library_static { android: { srcs: [ // sources that depend on android only libraries "android/graphics/apex/android_canvas.cpp", + "android/graphics/apex/jni_runtime.cpp", + "android_view_FrameMetricsObserver.cpp", "android_view_TextureLayer.cpp", "android_view_ThreadedRenderer.cpp", "android/graphics/BitmapRegionDecoder.cpp", diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index d46fe8d3388a..d476d2d2c35c 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -22,6 +22,7 @@ #include <android-base/macros.h> #include <android-base/properties.h> +#include <android/graphics/jni_runtime.h> #include <binder/IBinder.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> @@ -33,8 +34,6 @@ #include <cutils/properties.h> #include <server_configurable_flags/get_flags.h> -#include <SkGraphics.h> - #include "jni.h" #include <nativehelper/JNIHelp.h> #include <nativehelper/JniInvocation.h> @@ -56,24 +55,7 @@ using android::base::GetProperty; extern int register_android_os_Binder(JNIEnv* env); extern int register_android_os_Process(JNIEnv* env); -extern int register_android_graphics_Bitmap(JNIEnv*); -extern int register_android_graphics_BitmapFactory(JNIEnv*); -extern int register_android_graphics_BitmapRegionDecoder(JNIEnv*); -extern int register_android_graphics_ByteBufferStreamAdaptor(JNIEnv* env); -extern int register_android_graphics_Camera(JNIEnv* env); -extern int register_android_graphics_CreateJavaOutputStreamAdaptor(JNIEnv* env); extern int register_android_graphics_GraphicBuffer(JNIEnv* env); -extern int register_android_graphics_Graphics(JNIEnv* env); -extern int register_android_graphics_ImageDecoder(JNIEnv*); -extern int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv*); -extern int register_android_graphics_Interpolator(JNIEnv* env); -extern int register_android_graphics_MaskFilter(JNIEnv* env); -extern int register_android_graphics_Movie(JNIEnv* env); -extern int register_android_graphics_NinePatch(JNIEnv*); -extern int register_android_graphics_PathEffect(JNIEnv* env); -extern int register_android_graphics_Shader(JNIEnv* env); -extern int register_android_graphics_Typeface(JNIEnv* env); -extern int register_android_graphics_YuvImage(JNIEnv* env); extern int register_com_google_android_gles_jni_EGLImpl(JNIEnv* env); extern int register_com_google_android_gles_jni_GLImpl(JNIEnv* env); @@ -130,46 +112,18 @@ extern int register_android_util_StatsLog(JNIEnv* env); extern int register_android_util_StatsLogInternal(JNIEnv* env); extern int register_android_util_Log(JNIEnv* env); extern int register_android_util_MemoryIntArray(JNIEnv* env); -extern int register_android_util_PathParser(JNIEnv* env); extern int register_android_content_StringBlock(JNIEnv* env); extern int register_android_content_XmlBlock(JNIEnv* env); extern int register_android_content_res_ApkAssets(JNIEnv* env); -extern int register_android_graphics_Canvas(JNIEnv* env); -extern int register_android_graphics_CanvasProperty(JNIEnv* env); -extern int register_android_graphics_ColorFilter(JNIEnv* env); -extern int register_android_graphics_ColorSpace(JNIEnv* env); -extern int register_android_graphics_DrawFilter(JNIEnv* env); -extern int register_android_graphics_FontFamily(JNIEnv* env); -extern int register_android_graphics_Matrix(JNIEnv* env); -extern int register_android_graphics_Paint(JNIEnv* env); -extern int register_android_graphics_Path(JNIEnv* env); -extern int register_android_graphics_PathMeasure(JNIEnv* env); -extern int register_android_graphics_Picture(JNIEnv*); -extern int register_android_graphics_Region(JNIEnv* env); -extern int register_android_graphics_SurfaceTexture(JNIEnv* env); -extern int register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv* env); -extern int register_android_graphics_drawable_VectorDrawable(JNIEnv* env); -extern int register_android_graphics_fonts_Font(JNIEnv* env); -extern int register_android_graphics_fonts_FontFamily(JNIEnv* env); -extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env); -extern int register_android_graphics_pdf_PdfEditor(JNIEnv* env); -extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env); -extern int register_android_graphics_text_MeasuredText(JNIEnv* env); -extern int register_android_graphics_text_LineBreaker(JNIEnv *env); extern int register_android_view_DisplayEventReceiver(JNIEnv* env); -extern int register_android_view_DisplayListCanvas(JNIEnv* env); -extern int register_android_view_FrameMetricsObserver(JNIEnv* env); extern int register_android_view_InputApplicationHandle(JNIEnv* env); extern int register_android_view_InputWindowHandle(JNIEnv* env); -extern int register_android_view_TextureLayer(JNIEnv* env); -extern int register_android_view_RenderNode(JNIEnv* env); extern int register_android_view_RenderNodeAnimator(JNIEnv* env); extern int register_android_view_Surface(JNIEnv* env); extern int register_android_view_SurfaceControl(JNIEnv* env); extern int register_android_view_SurfaceSession(JNIEnv* env); extern int register_android_view_CompositionSamplingListener(JNIEnv* env); extern int register_android_view_TextureView(JNIEnv* env); -extern int register_android_view_ThreadedRenderer(JNIEnv* env); extern int register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper(JNIEnv *env); extern int register_android_database_CursorWindow(JNIEnv* env); extern int register_android_database_SQLiteConnection(JNIEnv* env); @@ -314,7 +268,7 @@ AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) mArgBlockStart(argBlockStart), mArgBlockLength(argBlockLength) { - SkGraphics::Init(); + init_android_graphics(); // Pre-allocate enough space to hold a fair number of options. mOptions.setCapacity(20); @@ -1457,7 +1411,6 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_util_EventLog), REG_JNI(register_android_util_Log), REG_JNI(register_android_util_MemoryIntArray), - REG_JNI(register_android_util_PathParser), REG_JNI(register_android_util_StatsLog), REG_JNI(register_android_util_StatsLogInternal), REG_JNI(register_android_app_admin_SecurityLog), @@ -1481,20 +1434,10 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_os_NativeHandle), REG_JNI(register_android_os_VintfObject), REG_JNI(register_android_os_VintfRuntimeInfo), - REG_JNI(register_android_graphics_Canvas), - // This needs to be before register_android_graphics_Graphics, or the latter - // will not be able to find the jmethodID for ColorSpace.get(). - REG_JNI(register_android_graphics_ColorSpace), - REG_JNI(register_android_graphics_Graphics), REG_JNI(register_android_view_DisplayEventReceiver), - REG_JNI(register_android_view_RenderNode), REG_JNI(register_android_view_RenderNodeAnimator), - REG_JNI(register_android_view_DisplayListCanvas), - REG_JNI(register_android_view_FrameMetricsObserver), REG_JNI(register_android_view_InputApplicationHandle), REG_JNI(register_android_view_InputWindowHandle), - REG_JNI(register_android_view_TextureLayer), - REG_JNI(register_android_view_ThreadedRenderer), REG_JNI(register_android_view_Surface), REG_JNI(register_android_view_SurfaceControl), REG_JNI(register_android_view_SurfaceSession), @@ -1516,43 +1459,8 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_opengl_jni_GLES31Ext), REG_JNI(register_android_opengl_jni_GLES32), - REG_JNI(register_android_graphics_Bitmap), - REG_JNI(register_android_graphics_BitmapFactory), - REG_JNI(register_android_graphics_BitmapRegionDecoder), - REG_JNI(register_android_graphics_ByteBufferStreamAdaptor), - REG_JNI(register_android_graphics_Camera), - REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor), - REG_JNI(register_android_graphics_CanvasProperty), - REG_JNI(register_android_graphics_ColorFilter), - REG_JNI(register_android_graphics_DrawFilter), - REG_JNI(register_android_graphics_FontFamily), + REG_JNI(register_android_graphics_classes), REG_JNI(register_android_graphics_GraphicBuffer), - REG_JNI(register_android_graphics_ImageDecoder), - REG_JNI(register_android_graphics_drawable_AnimatedImageDrawable), - REG_JNI(register_android_graphics_Interpolator), - REG_JNI(register_android_graphics_MaskFilter), - REG_JNI(register_android_graphics_Matrix), - REG_JNI(register_android_graphics_Movie), - REG_JNI(register_android_graphics_NinePatch), - REG_JNI(register_android_graphics_Paint), - REG_JNI(register_android_graphics_Path), - REG_JNI(register_android_graphics_PathMeasure), - REG_JNI(register_android_graphics_PathEffect), - REG_JNI(register_android_graphics_Picture), - REG_JNI(register_android_graphics_Region), - REG_JNI(register_android_graphics_Shader), - REG_JNI(register_android_graphics_SurfaceTexture), - REG_JNI(register_android_graphics_Typeface), - REG_JNI(register_android_graphics_YuvImage), - REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable), - REG_JNI(register_android_graphics_drawable_VectorDrawable), - REG_JNI(register_android_graphics_fonts_Font), - REG_JNI(register_android_graphics_fonts_FontFamily), - REG_JNI(register_android_graphics_pdf_PdfDocument), - REG_JNI(register_android_graphics_pdf_PdfEditor), - REG_JNI(register_android_graphics_pdf_PdfRenderer), - REG_JNI(register_android_graphics_text_MeasuredText), - REG_JNI(register_android_graphics_text_LineBreaker), REG_JNI(register_android_database_CursorWindow), REG_JNI(register_android_database_SQLiteConnection), diff --git a/core/jni/android/graphics/ByteBufferStreamAdaptor.cpp b/core/jni/android/graphics/ByteBufferStreamAdaptor.cpp index 173818b13837..d443fd8cdf14 100644 --- a/core/jni/android/graphics/ByteBufferStreamAdaptor.cpp +++ b/core/jni/android/graphics/ByteBufferStreamAdaptor.cpp @@ -1,6 +1,7 @@ #include "ByteBufferStreamAdaptor.h" #include "core_jni_helpers.h" #include "Utils.h" +#include <jni.h> #include <SkStream.h> @@ -9,6 +10,24 @@ using namespace android; static jmethodID gByteBuffer_getMethodID; static jmethodID gByteBuffer_setPositionMethodID; +/** + * Helper method for accessing the JNI interface pointer. + * + * Image decoding (which this supports) is started on a thread that is already + * attached to the Java VM. But an AnimatedImageDrawable continues decoding on + * the AnimatedImageThread, which is not attached. This will attach if + * necessary. + */ +static JNIEnv* requireEnv(JavaVM* jvm) { + JNIEnv* env; + if (jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { + if (jvm->AttachCurrentThreadAsDaemon(&env, nullptr) != JNI_OK) { + LOG_ALWAYS_FATAL("Failed to AttachCurrentThread!"); + } + } + return env; +} + class ByteBufferStream : public SkStreamAsset { private: ByteBufferStream(JavaVM* jvm, jobject jbyteBuffer, size_t initialPosition, size_t length, @@ -46,7 +65,7 @@ public: } ~ByteBufferStream() override { - auto* env = get_env_or_die(mJvm); + auto* env = requireEnv(mJvm); env->DeleteGlobalRef(mByteBuffer); env->DeleteGlobalRef(mStorage); } @@ -63,7 +82,7 @@ public: return this->setPosition(mPosition + size) ? size : 0; } - auto* env = get_env_or_die(mJvm); + auto* env = requireEnv(mJvm); size_t bytesRead = 0; do { const size_t requested = (size > kStorageSize) ? kStorageSize : size; @@ -146,7 +165,7 @@ private: // Range has already been checked by the caller. bool setPosition(size_t newPosition) { - auto* env = get_env_or_die(mJvm); + auto* env = requireEnv(mJvm); env->CallObjectMethod(mByteBuffer, gByteBuffer_setPositionMethodID, newPosition + mInitialPosition); if (env->ExceptionCheck()) { @@ -185,7 +204,7 @@ public: } ~ByteArrayStream() override { - auto* env = get_env_or_die(mJvm); + auto* env = requireEnv(mJvm); env->DeleteGlobalRef(mByteArray); } @@ -197,7 +216,7 @@ public: return 0; } - auto* env = get_env_or_die(mJvm); + auto* env = requireEnv(mJvm); if (buffer) { env->GetByteArrayRegion(mByteArray, mPosition + mOffset, size, reinterpret_cast<jbyte*>(buffer)); diff --git a/core/jni/android/graphics/apex/include/android/graphics/jni_runtime.h b/core/jni/android/graphics/apex/include/android/graphics/jni_runtime.h new file mode 100644 index 000000000000..872a9497ab90 --- /dev/null +++ b/core/jni/android/graphics/apex/include/android/graphics/jni_runtime.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 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. + */ +#ifndef ANDROID_GRAPHICS_JNI_RUNTIME_H +#define ANDROID_GRAPHICS_JNI_RUNTIME_H + +#include <jni.h> + +__BEGIN_DECLS + +void init_android_graphics(); + +int register_android_graphics_classes(JNIEnv* env); + +void zygote_preload_graphics(); + +__END_DECLS + + +#endif // ANDROID_GRAPHICS_JNI_RUNTIME_H
\ No newline at end of file diff --git a/core/jni/android/graphics/apex/jni_runtime.cpp b/core/jni/android/graphics/apex/jni_runtime.cpp new file mode 100644 index 000000000000..7f9bac0df44a --- /dev/null +++ b/core/jni/android/graphics/apex/jni_runtime.cpp @@ -0,0 +1,169 @@ +/* + * Copyright (C) 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 "android/graphics/jni_runtime.h" + +#include <android/log.h> +#include <nativehelper/JNIHelp.h> +#include <sys/cdefs.h> + +#include <EGL/egl.h> +#include <Properties.h> +#include <SkGraphics.h> + +#define LOG_TAG "AndroidGraphicsJNI" + +extern int register_android_graphics_Bitmap(JNIEnv*); +extern int register_android_graphics_BitmapFactory(JNIEnv*); +extern int register_android_graphics_BitmapRegionDecoder(JNIEnv*); +extern int register_android_graphics_ByteBufferStreamAdaptor(JNIEnv* env); +extern int register_android_graphics_Camera(JNIEnv* env); +extern int register_android_graphics_CreateJavaOutputStreamAdaptor(JNIEnv* env); +extern int register_android_graphics_Graphics(JNIEnv* env); +extern int register_android_graphics_ImageDecoder(JNIEnv*); +extern int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv*); +extern int register_android_graphics_Interpolator(JNIEnv* env); +extern int register_android_graphics_MaskFilter(JNIEnv* env); +extern int register_android_graphics_Movie(JNIEnv* env); +extern int register_android_graphics_NinePatch(JNIEnv*); +extern int register_android_graphics_PathEffect(JNIEnv* env); +extern int register_android_graphics_Shader(JNIEnv* env); +extern int register_android_graphics_Typeface(JNIEnv* env); +extern int register_android_graphics_YuvImage(JNIEnv* env); + +namespace android { + +extern int register_android_graphics_Canvas(JNIEnv* env); +extern int register_android_graphics_CanvasProperty(JNIEnv* env); +extern int register_android_graphics_ColorFilter(JNIEnv* env); +extern int register_android_graphics_ColorSpace(JNIEnv* env); +extern int register_android_graphics_DrawFilter(JNIEnv* env); +extern int register_android_graphics_FontFamily(JNIEnv* env); +extern int register_android_graphics_Matrix(JNIEnv* env); +extern int register_android_graphics_Paint(JNIEnv* env); +extern int register_android_graphics_Path(JNIEnv* env); +extern int register_android_graphics_PathMeasure(JNIEnv* env); +extern int register_android_graphics_Picture(JNIEnv*); +extern int register_android_graphics_Region(JNIEnv* env); +extern int register_android_graphics_SurfaceTexture(JNIEnv* env); +extern int register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv* env); +extern int register_android_graphics_drawable_VectorDrawable(JNIEnv* env); +extern int register_android_graphics_fonts_Font(JNIEnv* env); +extern int register_android_graphics_fonts_FontFamily(JNIEnv* env); +extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env); +extern int register_android_graphics_pdf_PdfEditor(JNIEnv* env); +extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env); +extern int register_android_graphics_text_MeasuredText(JNIEnv* env); +extern int register_android_graphics_text_LineBreaker(JNIEnv *env); + +extern int register_android_util_PathParser(JNIEnv* env); +extern int register_android_view_DisplayListCanvas(JNIEnv* env); +extern int register_android_view_FrameMetricsObserver(JNIEnv* env); +extern int register_android_view_RenderNode(JNIEnv* env); +extern int register_android_view_TextureLayer(JNIEnv* env); +extern int register_android_view_ThreadedRenderer(JNIEnv* env); + +#ifdef NDEBUG + #define REG_JNI(name) { name } + struct RegJNIRec { + int (*mProc)(JNIEnv*); + }; +#else + #define REG_JNI(name) { name, #name } + struct RegJNIRec { + int (*mProc)(JNIEnv*); + const char* mName; + }; +#endif + +static const RegJNIRec gRegJNI[] = { + REG_JNI(register_android_graphics_Canvas), + // This needs to be before register_android_graphics_Graphics, or the latter + // will not be able to find the jmethodID for ColorSpace.get(). + REG_JNI(register_android_graphics_ColorSpace), + REG_JNI(register_android_graphics_Graphics), + REG_JNI(register_android_graphics_Bitmap), + REG_JNI(register_android_graphics_BitmapFactory), + REG_JNI(register_android_graphics_BitmapRegionDecoder), + REG_JNI(register_android_graphics_ByteBufferStreamAdaptor), + REG_JNI(register_android_graphics_Camera), + REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor), + REG_JNI(register_android_graphics_CanvasProperty), + REG_JNI(register_android_graphics_ColorFilter), + REG_JNI(register_android_graphics_DrawFilter), + REG_JNI(register_android_graphics_FontFamily), + REG_JNI(register_android_graphics_ImageDecoder), + REG_JNI(register_android_graphics_drawable_AnimatedImageDrawable), + REG_JNI(register_android_graphics_Interpolator), + REG_JNI(register_android_graphics_MaskFilter), + REG_JNI(register_android_graphics_Matrix), + REG_JNI(register_android_graphics_Movie), + REG_JNI(register_android_graphics_NinePatch), + REG_JNI(register_android_graphics_Paint), + REG_JNI(register_android_graphics_Path), + REG_JNI(register_android_graphics_PathMeasure), + REG_JNI(register_android_graphics_PathEffect), + REG_JNI(register_android_graphics_Picture), + REG_JNI(register_android_graphics_Region), + REG_JNI(register_android_graphics_Shader), + REG_JNI(register_android_graphics_SurfaceTexture), + REG_JNI(register_android_graphics_Typeface), + REG_JNI(register_android_graphics_YuvImage), + REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable), + REG_JNI(register_android_graphics_drawable_VectorDrawable), + REG_JNI(register_android_graphics_fonts_Font), + REG_JNI(register_android_graphics_fonts_FontFamily), + REG_JNI(register_android_graphics_pdf_PdfDocument), + REG_JNI(register_android_graphics_pdf_PdfEditor), + REG_JNI(register_android_graphics_pdf_PdfRenderer), + REG_JNI(register_android_graphics_text_MeasuredText), + REG_JNI(register_android_graphics_text_LineBreaker), + + REG_JNI(register_android_util_PathParser), + REG_JNI(register_android_view_RenderNode), + REG_JNI(register_android_view_DisplayListCanvas), + REG_JNI(register_android_view_FrameMetricsObserver), + REG_JNI(register_android_view_TextureLayer), + REG_JNI(register_android_view_ThreadedRenderer), +}; + +} // namespace android + +void init_android_graphics() { + SkGraphics::Init(); +} + +int register_android_graphics_classes(JNIEnv *env) { + for (size_t i = 0; i < NELEM(android::gRegJNI); i++) { + if (android::gRegJNI[i].mProc(env) < 0) { +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "JNI Error!!! %s failed to load\n", + android::gRegJNI[i].mName); +#endif + return -1; + } + } + return 0; +} + +using android::uirenderer::Properties; +using android::uirenderer::RenderPipelineType; + +void zygote_preload_graphics() { + if (Properties::peekRenderPipelineType() == RenderPipelineType::SkiaGL) { + eglGetDisplay(EGL_DEFAULT_DISPLAY); + } +}
\ No newline at end of file diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp index c380fd5e439f..59dab0c82162 100644 --- a/core/jni/android_view_InputEventReceiver.cpp +++ b/core/jni/android_view_InputEventReceiver.cpp @@ -148,7 +148,7 @@ void NativeInputEventReceiver::setFdEvents(int events) { mFdEvents = events; int fd = mInputConsumer.getChannel()->getFd(); if (events) { - mMessageQueue->getLooper()->addFd(fd, 0, events, this, NULL); + mMessageQueue->getLooper()->addFd(fd, 0, events, this, nullptr); } else { mMessageQueue->getLooper()->removeFd(fd); } @@ -169,7 +169,7 @@ int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) if (events & ALOOPER_EVENT_INPUT) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - status_t status = consumeEvents(env, false /*consumeBatches*/, -1, NULL); + status_t status = consumeEvents(env, false /*consumeBatches*/, -1, nullptr); mMessageQueue->raiseAndClearException(env, "handleReceiveCallback"); return status == OK || status == NO_MEMORY ? 1 : 0; } @@ -230,7 +230,7 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, *outConsumedBatch = false; } - ScopedLocalRef<jobject> receiverObj(env, NULL); + ScopedLocalRef<jobject> receiverObj(env, nullptr); bool skipCallbacks = false; for (;;) { uint32_t seq; @@ -305,7 +305,7 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, default: assert(false); // InputConsumer should prevent this from ever happening - inputEventObj = NULL; + inputEventObj = nullptr; } if (inputEventObj) { @@ -337,13 +337,13 @@ static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject inputChannelObj, jobject messageQueueObj) { sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env, inputChannelObj); - if (inputChannel == NULL) { + if (inputChannel == nullptr) { jniThrowRuntimeException(env, "InputChannel is not initialized."); return 0; } sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); - if (messageQueue == NULL) { + if (messageQueue == nullptr) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); return 0; } diff --git a/core/jni/com_android_internal_os_ZygoteInit.cpp b/core/jni/com_android_internal_os_ZygoteInit.cpp index c2a5ee43dbd5..a5152b6e689c 100644 --- a/core/jni/com_android_internal_os_ZygoteInit.cpp +++ b/core/jni/com_android_internal_os_ZygoteInit.cpp @@ -16,17 +16,13 @@ #define LOG_TAG "Zygote" -#include <EGL/egl.h> -#include <Properties.h> +#include <android/graphics/jni_runtime.h> #include <ui/GraphicBufferMapper.h> #include "core_jni_helpers.h" namespace { -using android::uirenderer::Properties; -using android::uirenderer::RenderPipelineType; - // Shadow call stack (SCS) is a security mitigation that uses a separate stack // (the SCS) for return addresses. In versions of Android newer than P, the // compiler cooperates with the system to ensure that the SCS address is always @@ -64,9 +60,7 @@ void android_internal_os_ZygoteInit_nativePreloadAppProcessHALs(JNIEnv* env, jcl void android_internal_os_ZygoteInit_nativePreloadGraphicsDriver(JNIEnv* env, jclass) { ScopedSCSExit x; - if (Properties::peekRenderPipelineType() == RenderPipelineType::SkiaGL) { - eglGetDisplay(EGL_DEFAULT_DISPLAY); - } + zygote_preload_graphics(); } const JNINativeMethod gMethods[] = { diff --git a/core/proto/android/service/package.proto b/core/proto/android/service/package.proto index 6ffa0c943037..301fa13ce4d8 100644 --- a/core/proto/android/service/package.proto +++ b/core/proto/android/service/package.proto @@ -110,7 +110,7 @@ message PackageProto { optional bool is_launched = 6; optional EnabledState enabled_state = 7; optional string last_disabled_app_caller = 8; - optional string suspending_package = 9; + repeated string suspending_package = 9; optional int32 distraction_flags = 10; } diff --git a/core/proto/android/telecomm/enums.proto b/core/proto/android/telecomm/enums.proto index 7a2ba624c021..5ca4a85f7c6a 100644 --- a/core/proto/android/telecomm/enums.proto +++ b/core/proto/android/telecomm/enums.proto @@ -110,6 +110,24 @@ enum CallStateEnum { * {@link android.telecom.Connection#CAPABILITY_CAN_PULL_CALL}. */ PULLING = 10; + + /** + * Indicates that an incoming call has been answered by the in-call UI, but Telephony hasn't yet + * set the call to active. + */ + ANSWERED = 11; + + /** + * Indicates that the call is undergoing audio processing by a different app in the background. + * @see android.telecom.Call#STATE_AUDIO_PROCESSING + */ + AUDIO_PROCESSING = 12; + + /** + * Indicates that the call is in a fake ringing state. + * @see android.telecom.Call#STATE_SIMULATED_RINGING + */ + SIMULATED_RINGING = 13; } // Disconnect causes for a call. Primarily used by android/telecom/DisconnectCause.java diff --git a/core/res/res/anim/screen_rotate_0_exit.xml b/core/res/res/anim/screen_rotate_0_exit.xml index f1df2de04619..37d5a4115621 100644 --- a/core/res/res/anim/screen_rotate_0_exit.xml +++ b/core/res/res/anim/screen_rotate_0_exit.xml @@ -19,7 +19,4 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> - <alpha android:fromAlpha="1.0" android:toAlpha="0" - android:interpolator="@interpolator/decelerate_quint" - android:duration="@android:integer/config_shortAnimTime" /> </set> diff --git a/core/res/res/anim/screen_rotate_180_exit.xml b/core/res/res/anim/screen_rotate_180_exit.xml index 1eb6361c736f..58a1868bd398 100644 --- a/core/res/res/anim/screen_rotate_180_exit.xml +++ b/core/res/res/anim/screen_rotate_180_exit.xml @@ -25,7 +25,4 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" android:duration="@android:integer/config_mediumAnimTime" /> - <alpha android:fromAlpha="1.0" android:toAlpha="0" - android:interpolator="@interpolator/decelerate_cubic" - android:duration="@android:integer/config_mediumAnimTime"/> </set>
\ No newline at end of file diff --git a/core/res/res/anim/screen_rotate_minus_90_frame.xml b/core/res/res/anim/screen_rotate_alpha.xml index 2d198f3929e6..c49ef9cafd39 100644 --- a/core/res/res/anim/screen_rotate_minus_90_frame.xml +++ b/core/res/res/anim/screen_rotate_alpha.xml @@ -19,10 +19,9 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> - <rotate android:fromDegrees="0" android:toDegrees="90" - android:pivotX="50%" android:pivotY="50%" - android:interpolator="@interpolator/decelerate_quint" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:duration="@android:integer/config_longAnimTime" /> + <alpha android:fromAlpha="1.0" android:toAlpha="0.0" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime" /> </set> diff --git a/core/res/res/anim/screen_rotate_minus_90_exit.xml b/core/res/res/anim/screen_rotate_minus_90_exit.xml index 9b389392c3e4..0927dd30ceb3 100644 --- a/core/res/res/anim/screen_rotate_minus_90_exit.xml +++ b/core/res/res/anim/screen_rotate_minus_90_exit.xml @@ -40,9 +40,4 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" android:duration="@android:integer/config_mediumAnimTime" /> - <alpha android:fromAlpha="1.0" android:toAlpha="0" - android:interpolator="@interpolator/decelerate_quint" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:duration="@android:integer/config_mediumAnimTime" /> </set> diff --git a/core/res/res/anim/screen_rotate_plus_90_exit.xml b/core/res/res/anim/screen_rotate_plus_90_exit.xml index fa345337cbf6..fd786f9afce0 100644 --- a/core/res/res/anim/screen_rotate_plus_90_exit.xml +++ b/core/res/res/anim/screen_rotate_plus_90_exit.xml @@ -40,9 +40,4 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" android:duration="@android:integer/config_mediumAnimTime" /> - <alpha android:fromAlpha="1.0" android:toAlpha="0" - android:interpolator="@interpolator/decelerate_quint" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:duration="@android:integer/config_mediumAnimTime" /> </set> diff --git a/core/res/res/anim/screen_rotate_plus_90_frame.xml b/core/res/res/anim/screen_rotate_plus_90_frame.xml deleted file mode 100644 index cd2005087291..000000000000 --- a/core/res/res/anim/screen_rotate_plus_90_frame.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2012, 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. -*/ ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false"> - <rotate android:fromDegrees="0" android:toDegrees="-90" - android:pivotX="50%" android:pivotY="50%" - android:interpolator="@interpolator/decelerate_quint" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:duration="@android:integer/config_longAnimTime" /> -</set> diff --git a/core/res/res/drawable-hdpi/ic_launcher_android.png b/core/res/res/drawable-hdpi/ic_launcher_android.png Binary files differindex 2e9b196c9625..8fed9534e1c8 100644 --- a/core/res/res/drawable-hdpi/ic_launcher_android.png +++ b/core/res/res/drawable-hdpi/ic_launcher_android.png diff --git a/core/res/res/drawable-mdpi/ic_launcher_android.png b/core/res/res/drawable-mdpi/ic_launcher_android.png Binary files differindex baacd4f23e43..16b66a15d544 100644 --- a/core/res/res/drawable-mdpi/ic_launcher_android.png +++ b/core/res/res/drawable-mdpi/ic_launcher_android.png diff --git a/core/res/res/drawable-xhdpi/ic_launcher_android.png b/core/res/res/drawable-xhdpi/ic_launcher_android.png Binary files differindex 00b69a53a62b..824794a6b76e 100644 --- a/core/res/res/drawable-xhdpi/ic_launcher_android.png +++ b/core/res/res/drawable-xhdpi/ic_launcher_android.png diff --git a/core/res/res/drawable-xxhdpi/ic_launcher_android.png b/core/res/res/drawable-xxhdpi/ic_launcher_android.png Binary files differindex ad05cd5b337b..81268b38ccc8 100644 --- a/core/res/res/drawable-xxhdpi/ic_launcher_android.png +++ b/core/res/res/drawable-xxhdpi/ic_launcher_android.png diff --git a/core/res/res/drawable-xxxhdpi/ic_launcher_android.png b/core/res/res/drawable-xxxhdpi/ic_launcher_android.png Binary files differnew file mode 100644 index 000000000000..eedc9f94fc89 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/ic_launcher_android.png diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index a44b137ab93d..0e0f34a2d6e1 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Laat die program toe om Moenie Steur Nie-opstelling te lees en skryf."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"begin kyk van toestemminggebruik"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Laat die houer toe om die toestemminggebruik vir \'n program te begin. Behoort nooit vir normale programme nodig te wees nie."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"toeganklikheidkortpadteiken"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Laat \'n program toe om die toeganklikheidkortpadteiken te definieer."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Stel wagwoordreëls"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Beheer die lengte en die karakters wat in skermslotwagwoorde en -PIN\'e toegelaat word."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitor pogings om skerm te ontsluit"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Kies om USB-ontfouting te deaktiveer."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Toetsraamwerkmodus is geaktiveer"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Voer \'n fabriekterugstelling uit om Toetsraamwerkmodus te deaktiveer."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Reekskonsole is geaktiveer"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Werkverrigting word beïnvloed. Gaan selflaaiprogram na om te deaktiveer."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vloeistof of vuilgoed in USB-poort"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-poort is outomaties gedeaktiveer. Tik om meer te wete te kom."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK om USB-poort te gebruik"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Ongekategoriseer"</string> <string name="importance_from_user" msgid="7318955817386549931">"Jy stel die belangrikheid van hierdie kennisgewings."</string> <string name="importance_from_person" msgid="9160133597262938296">"Dit is belangrik as gevolg van die mense wat betrokke is."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Laat <xliff:g id="APP">%1$s</xliff:g> toe om \'n nuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> te skep (\'n gebruiker met hierdie rekening bestaan reeds)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Laat <xliff:g id="APP">%1$s</xliff:g> toe om \'n nuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> te skep?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Voeg \'n taal by"</string> <string name="country_selection_title" msgid="2954859441620215513">"Streekvoorkeur"</string> <string name="search_language_hint" msgid="7042102592055108574">"Voer taalnaam in"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index db758e3e45f8..eec1b221eac6 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"መተግበሪያው የአትረብሽ ውቅረትን እንዲያነብብ እና እንዲጸፍ ይፈቅዳል።"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"የእይታ ፈቃድ መጠቀምን መጀመር"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ያዢው ለአንድ መተግበሪያ የፈቃድ አጠቃቀሙን እንዲያስጀምር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"የተደራሽነት አቋራጭ ዒላማ"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"መተግበሪያ የተደራሽነት አቋራጭ ዒላማን ለመግለጽ እንዲችል ይፈቅድለታል።"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"የይለፍ ቃል ደንቦች አዘጋጅ"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"በማያ ገጽ መቆለፊያ የይለፍ ቃሎች እና ፒኖች ውስጥ የሚፈቀዱ ቁምፊዎችን እና ርዝመታቸውን ተቆጣጠር።"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"የማሳያ-ክፈት ሙከራዎችን ክትትል ያድርጉባቸው"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ማረሚያ ላለማንቃት ምረጥ።"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"የሙከራ ጥቅል ሁነታ ነቅቷል"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"የመሞከሪያ ጥቅል ሁነታን ለማሰናከል የፋብሪካ ዳግም ቅንብርን ይሞክሩ።"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"ተከታታይ ኮንሶል ነቅቷል"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"አፈጻጸም ተጽዕኖ አርፎበታል። ለማሰናከል፣ bootloader ን ይፈትሹ።"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"በዩኤስቢ ወደብ ውስጥ ፈሳሽ ወይም ፍርስራሽ"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"የዩኤስቢ ወደብ በራስ-ሰር ተሰናክሏል። የበለጠ ለመረዳት መታ ያድርጉ።"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"የዩኤስቢ ወደቡን መጠቀም ችግር የለውም"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"ያልተመደቡ"</string> <string name="importance_from_user" msgid="7318955817386549931">"የእነዚህን ማሳወቂያዎች አስፈላጊነት አዘጋጅተዋል።"</string> <string name="importance_from_person" msgid="9160133597262938296">"ይሄ በሚሳተፉ ሰዎች ምክንያት አስፈላጊ ነው።"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> በ<xliff:g id="ACCOUNT">%2$s</xliff:g> አዲስ ተጠቃሚ እንዲፈጥር ይፈቀድለት (ይህ መለያ ያለው ተጠቃሚ አስቀድሞ አለ)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> አዲስ ተጠቃሚ ከ <xliff:g id="ACCOUNT">%2$s</xliff:g> ጋር መፍጠር እንዲችል ይፍቀዱ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"ቋንቋ ያክሉ"</string> <string name="country_selection_title" msgid="2954859441620215513">"የክልል ምርጫ"</string> <string name="search_language_hint" msgid="7042102592055108574">"የቋንቋ ስም ይተይቡ"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 113a3426cf5f..d195d7482790 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -536,7 +536,7 @@ <string name="permdesc_imagesWrite" msgid="7073662756617474375">"للسماح للتطبيق بتعديل مجموعة صورك."</string> <string name="permlab_mediaLocation" msgid="8675148183726247864">"قراءة المواقع من مجموعة الوسائط التابعة لك"</string> <string name="permdesc_mediaLocation" msgid="2237023389178865130">"للسماح للتطبيق بقراءة المواقع من مجموعة الوسائط التابعة لك."</string> - <string name="biometric_dialog_default_title" msgid="881952973720613213">"التحقق من هويتك"</string> + <string name="biometric_dialog_default_title" msgid="881952973720613213">"إثبات هويتك"</string> <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"معدّات المقاييس الحيوية غير متاحة."</string> <string name="biometric_error_user_canceled" msgid="2260175018114348727">"تم إلغاء المصادقة."</string> <string name="biometric_not_recognized" msgid="5770511773560736082">"لم يتم التعرف عليها."</string> @@ -667,6 +667,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"للسماح للتطبيق بقراءة تهيئة \"عدم الإزعاج\" وكتابتها."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"بدء استخدام إذن العرض"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"للسماح للمالك ببدء استخدام الإذن لأحد التطبيقات. ولن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"هدف اختصار أدوات تمكين الوصول"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"للسماح للتطبيق بتحديد هدف اختصار أدوات تمكين الوصول."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"تعيين قواعد كلمة المرور"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"للتحكم في الطول والأحرف المسموح بها في كلمات المرور وأرقام التعريف الشخصي في قفل الشاشة."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"مراقبة محاولات إلغاء قفل الشاشة"</string> @@ -1449,6 +1451,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"اختيار إيقاف تصحيح أخطاء USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"تم تفعيل وضع \"مفعّل الاختبار\""</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"يمكنك إجراء إعادة ضبط على إعدادات المصنع لإيقاف وضع \"مفعِّل اختبار\"."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"وحدة التحكّم التسلسلية مفعّلة"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"الأداء متأثر. لإيقاف وحدة التحكّم، تحقّق من برنامج الإقلاع."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"السوائل والشوائب في منفذ USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"تمّ إيقاف منفذ USB تلقائيًا. انقُر لمعرفة المزيد من المعلومات."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"مسموح باستخدام منفذ USB"</string> @@ -2026,10 +2030,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"غير مصنفة"</string> <string name="importance_from_user" msgid="7318955817386549931">"لقد عيَّنت أهمية هذه الإشعارات."</string> <string name="importance_from_person" msgid="9160133597262938296">"هذه الرسالة مهمة نظرًا لأهمية الأشخاص المعنيين."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"هل تسمح لتطبيق <xliff:g id="APP">%1$s</xliff:g> بإنشاء مستخدم جديد باستخدام <xliff:g id="ACCOUNT">%2$s</xliff:g> (يوجد مستخدم بهذا الحساب مسبقًا)؟"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"هل تسمح لتطبيق <xliff:g id="APP">%1$s</xliff:g> بإنشاء مستخدم جديد باستخدام <xliff:g id="ACCOUNT">%2$s</xliff:g> ؟"</string> <string name="language_selection_title" msgid="2680677278159281088">"إضافة لغة"</string> <string name="country_selection_title" msgid="2954859441620215513">"تفضيل المنطقة"</string> <string name="search_language_hint" msgid="7042102592055108574">"اكتب اسم اللغة"</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 00617a548082..aa2fbc570021 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"অসুবিধা নিদিবৰ কনফিগাৰেশ্বনক পঢ়িবলৈ আৰু সালসলনি কৰিবলৈ এপটোক অনুমতি দিয়ে।"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"চোৱাৰ অনুমতিৰ ব্যৱহাৰ আৰম্ভ কৰক"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ধাৰকক কোনো এপৰ বাবে অনুমতিৰ ব্যৱহাৰ আৰম্ভ কৰিবলৈ দিয়ে। সাধাৰণ এপ্সমূহৰ বাবে কেতিয়াও প্ৰয়োজন হ’ব নালাগে।"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"সাধ্য সুবিধাসমূহৰ শ্বৰ্টকাট লক্ষ্য"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"সাধ্য সুবিধাসমূহৰ শ্বৰ্টকাট লক্ষ্য নির্ধাৰণ কৰিবলৈ এটা এপক অনুমতি দিয়ে।"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"পাছৱর্ডৰ নিয়ম ছেট কৰক"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"স্ক্ৰীণ লক পাছৱৰ্ড আৰু পিনৰ দৈর্ঘ্য আৰু কি কি আখৰ ব্যৱহাৰ কৰিব পাৰে তাক নিয়ন্ত্ৰণ কৰক।"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"স্ক্ৰীণ আনলক কৰা প্ৰয়াসবোৰ পৰ্যবেক্ষণ কৰিব পাৰে"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ইউএছবি ডিবাগিং অক্ষম কৰিবলৈ বাছনি কৰক।"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"টেষ্ট হাৰনেছ ম’ড সক্ষম কৰা আছে"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"টেষ্ট হাৰনেছ ম’ড অক্ষম কৰিবলৈ ফেক্টৰী ৰিছেট কৰক।"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"ক্ৰমিক কনছ’ল সক্ষম কৰা আছে"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"কাৰ্যক্ষমতা প্ৰভাৱিত হৈছে। অক্ষম কৰিবলৈ বুটল’ডাৰ পৰীক্ষা কৰক।"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ইউএছবি প’ৰ্টত তৰল বা ধূলি-মাকতি আছে"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"ইউএছবি প’ৰ্ট স্বয়ংক্ৰিয়ভাৱে অক্ষম কৰা হয়। অধিক জানিবৰ বাবে টিপক।"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ইউএছবি প’ৰ্ট ব্যৱহাৰ কৰাত সমস্যা নাই"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"শ্ৰেণীবদ্ধ নকৰা"</string> <string name="importance_from_user" msgid="7318955817386549931">"এই জাননীবোৰৰ গুৰুত্ব আপুনি ছেট কৰব লাগিব।"</string> <string name="importance_from_person" msgid="9160133597262938296">"এই কার্যৰ সৈতে জড়িত থকা লোকসকলক ভিত্তি কৰি এইয়া গুৰুত্বপূর্ণ বুলি বিবেচনা কৰা হৈছ।"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>ক <xliff:g id="ACCOUNT">%2$s</xliff:g>ৰ (এই একাউণ্টটোৰ এজন ব্যৱহাৰকাৰী ইতিমধ্যে আছে) জৰিয়তে এজন নতুন ব্যৱহাৰকাৰী সৃষ্টি কৰিবলৈ অনুমতি দিবনে ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>ক <xliff:g id="ACCOUNT">%2$s</xliff:g>ৰ জৰিয়তে এজন নতুন ব্যৱহাৰকাৰী সৃষ্টি কৰিবলৈ অনুমতি দিবনে?"</string> <string name="language_selection_title" msgid="2680677278159281088">"ভাষা যোগ কৰক"</string> <string name="country_selection_title" msgid="2954859441620215513">"অঞ্চলৰ অগ্ৰাধিকাৰ"</string> <string name="search_language_hint" msgid="7042102592055108574">"ভাষাৰ নাম লিখক"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index f79decd068d3..5709bfdc2126 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Tətbiqə \"Narahat Etməyin\" konfiqurasiyasını oxumağa və yazmağa icazə verin."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"Baxış icazəsinin istifadəsinə başlayın"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Sahibinə tətbiqin icazədən istifadəsinə başlamağa imkan verir. Adi tətbiqlər üçün heç vaxt tələb edilmir."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"əlçatımlılıq qısayolunun hədəfi"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Tətbiqə əlçatımlılıq qısayolunun hədəfini müəyyən etməyə imkan verir."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Parol qaydalarını təyin edin"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Ekran kilidinin parolu və PINlərində icazə verilən uzunluq və simvollara nəzarət edin."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Ekranı kiliddən çıxarmaq üçün edilən cəhdlərə nəzarət edin"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USb debaqı deaktivasiya etməyi seçin."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test Rejimi aktivdir"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Test Rejimini deaktiv etmək üçün fabrika ayarlarına sıfırlayın."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Ardıcıl konsol aktiv edildi"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Performansa təsir edir. Deaktiv etmək üçün yükləyicini yoxlayın."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB portuna maye sızıb və ya qırılıb"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB portu avtomatik deaktiv edildi. Ətraflı məlumat üçün klikləyin."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB portundan istifadə etmək üçün OK"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Kateqoriyasız"</string> <string name="importance_from_user" msgid="7318955817386549931">"Bildirişlərin əhəmiyyətini Siz ayarlaryırsınız."</string> <string name="importance_from_person" msgid="9160133597262938296">"İnsanlar cəlb olunduğu üçün bu vacibdir."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> tətbiqinə <xliff:g id="ACCOUNT">%2$s</xliff:g> (artıq bu hesabı olan İstifadəçi mövcuddur) ilə yeni İstifadəçi yaratmağa icazə verilsin?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> tətbiqinə <xliff:g id="ACCOUNT">%2$s</xliff:g> ilə yeni İstifadəçi yartmağa icazə verilsin?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Dil əlavə edin"</string> <string name="country_selection_title" msgid="2954859441620215513">"Region seçimi"</string> <string name="search_language_hint" msgid="7042102592055108574">"Dil adını daxil edin"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 10dc339ae8ff..0e3332968375 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -27,7 +27,7 @@ <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> - <string name="untitled" msgid="4638956954852782576">"<Bez naslova>"</string> + <string name="untitled" msgid="4638956954852782576">"<Bez imena>"</string> <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nema broja telefona)"</string> <string name="unknownName" msgid="6867811765370350269">"Nepoznato"</string> <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Glasovna pošta"</string> @@ -658,6 +658,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Dozvoljava aplikaciji da čita i upisuje konfiguraciju podešavanja Ne uznemiravaj."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"početak korišćenja dozvole za pregled"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Dozvoljava vlasniku da započne korišćenje dozvole za aplikaciju. Nikada ne bi trebalo da bude potrebna za uobičajene aplikacije."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cilj prečice za pristupačnost"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Dozvoljava aplikaciji da definiše cilj prečice za pristupačnost."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Podešavanje pravila za lozinku"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontroliše dužinu i znakove dozvoljene u lozinkama i PIN-ovima za zaključavanje ekrana."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Nadgledajte pokušaje otključavanja ekrana"</string> @@ -1383,6 +1385,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izaberite da biste onemogućili otklanjanja grešaka sa USB-a."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Omogućen je režim probnog korišćenja"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Obavite resetovanje na fabrička podešavanja da biste onemogućili režim probnog korišćenja."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Serijska konzola je omogućena"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Učinak je smanjen. Da biste onemogući konzolu, proverite pokretački program."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tečnost ili nečistoća u USB portu"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port je automatski isključen. Dodirnite da biste saznali više."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Korišćenje USB porta je dozvoljeno"</string> @@ -1924,10 +1928,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Nekategorizovano"</string> <string name="importance_from_user" msgid="7318955817386549931">"Vi podešavate važnost ovih obaveštenja."</string> <string name="importance_from_person" msgid="9160133597262938296">"Ovo je važno zbog ljudi koji učestvuju."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Želite li da dozvolite da <xliff:g id="APP">%1$s</xliff:g> napravi novog korisnika sa nalogom <xliff:g id="ACCOUNT">%2$s</xliff:g> (korisnik sa tim nalogom već postoji)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Želite li da dozvolite da <xliff:g id="APP">%1$s</xliff:g> napravi novog korisnika sa nalogom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Dodajte jezik"</string> <string name="country_selection_title" msgid="2954859441620215513">"Podešavanje regiona"</string> <string name="search_language_hint" msgid="7042102592055108574">"Unesite naziv jezika"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index ce65bead0fd1..662290d8f7e6 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -661,6 +661,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Дазваляе праграме чытаць і выконваць запіс у канфігурацыю рэжыму «Не турбаваць»."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"запусціць выкарыстанне дазволаў на прагляд"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Дазваляе трымальніку запусціць выкарыстанне дазволаў праграмай. Не патрэбна для звычайных праграм."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"Аб\'екты хуткага доступу да спецыяльных магчымасцей"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Праграма зможа вызначаць аб\'екты хуткага доступу да спецыяльных магчымасцей."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Устанавіць правілы паролю"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Кіраваць даўжынёй і сімваламі, дазволенымі пры ўводзе пароляў і PIN-кодаў блакіроўкі экрана."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Сачыць за спробамі разблакіроўкі экрана"</string> @@ -1405,6 +1407,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Выберыце, каб адключыць адладку USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Тэставы рэжым уключаны"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Каб выключыць тэставы рэжым, скіньце налады да заводскіх значэнняў."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Паслядоўная кансоль уключана"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Змянілася эфектыўнасць. Каб выключыць, праверце загрузчык."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Вадкасць або смецце ў порце USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Порт USB аўтаматычна адключаны. Каб даведацца больш, націсніце тут."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Порт USB можна выкарыстоўваць"</string> @@ -1958,10 +1962,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Некатэгарызаванае"</string> <string name="importance_from_user" msgid="7318955817386549931">"Вы задалі важнасць гэтых апавяшчэнняў."</string> <string name="importance_from_person" msgid="9160133597262938296">"Гэта важна, бо з гэтым звязаны пэўныя людзі."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Дазволіць праграме \"<xliff:g id="APP">%1$s</xliff:g>\" стварыць новага Карыстальніка з уліковым запісам <xliff:g id="ACCOUNT">%2$s</xliff:g> (Карыстальнік з гэтым уліковым запісам ужо існуе)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Дазволіць праграме \"<xliff:g id="APP">%1$s</xliff:g>\" стварыць новага Карыстальніка з уліковым запісам <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Дадаць мову"</string> <string name="country_selection_title" msgid="2954859441620215513">"Параметры рэгіёна"</string> <string name="search_language_hint" msgid="7042102592055108574">"Увядзіце назву мовы"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 87ea6de20162..28949d184d63 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Предоставя на приложението достъп за четене и запис до конфигурацията на „Не безпокойте“."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"стартиране на прегледа на използваните разрешения"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Разрешава на притежателя да стартира прегледа на използваните разрешения за дадено приложение. Нормалните приложения би трябвало никога да не се нуждаят от това."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"цел на прекия път към функцията за достъпност"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Разрешава на приложението да определя целта на прекия път към функцията за достъпност."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Задаване на правила за паролата"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Контролира дължината и разрешените знаци за паролите и ПИН кодовете за заключване на екрана."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Наблюдаване на опитите за отключване на екрана"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете, за да деактивирате отстраняването на грешки през USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Режимът за тестова среда е активиран"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Възстановете фабричните настройки, за да деактивирате режима за тестова среда."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Серийната конзола е активирана"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Ефективността е засегната. За да деактивирате, проверете програмата за първоначално зареждане."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или замърсяване в USB порта"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB портът е деактивиран автоматично. Докоснете, за да научите повече."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Можете да използвате USB порта"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Некатегоризирани"</string> <string name="importance_from_user" msgid="7318955817386549931">"Зададохте важността на тези известия."</string> <string name="importance_from_person" msgid="9160133597262938296">"Това е важно заради участващите хора."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Да се разреши ли на <xliff:g id="APP">%1$s</xliff:g> да създаде нов потребител с профила <xliff:g id="ACCOUNT">%2$s</xliff:g> (вече съществува потребител с този профил)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Да се разреши ли на <xliff:g id="APP">%1$s</xliff:g> да създаде нов потребител с профила <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Добавяне на език"</string> <string name="country_selection_title" msgid="2954859441620215513">"Предпочитание за региона"</string> <string name="search_language_hint" msgid="7042102592055108574">"Въведете име на език"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index c0843eaeba7d..f88e778273be 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"অ্যাপটিকে \'বিরক্ত করবে না\' কনফিগারেশন পড়া এবং লেখার অনুমতি দেয়।"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"দেখার অনুমতি কাজে লাগানো শুরু করুন"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"কোনও অ্যাপের কোনও নির্দিষ্ট অনুমতির ব্যবহার শুরু করার ক্ষেত্রে হোল্ডারকে সাহায্য করে। সাধারণ অ্যাপের জন্য এটির পরিবর্তন হওয়ার কথা নয়।"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"অ্যাক্সেসিবিলিটির শর্টকাটের টার্গেট"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"এটি একটি অ্যাপকে অ্যাক্সেসিবিলিটির শর্টকাটের টার্গেটকে ব্যাখ্যা করতে অনুমতি দেয়।"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"পাসওয়ার্ড নিয়মগুলি সেট করে"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"স্ক্রিন লক করার পাসওয়ার্ডগুলিতে অনুমতিপ্রাপ্ত অক্ষর এবং দৈর্ঘ্য নিয়ন্ত্রণ করে৷"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"স্ক্রিন আনলক করার প্রচেষ্টাগুলির উপরে নজর রাখুন"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ডিবাগিং অক্ষম করতে বেছে নিন।"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"টেস্ট হারনেস মোড চালু আছে"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"টেস্ট হারনেস মোড বন্ধ করতে ফ্যাক্টরি রিসেট করুন।"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"সিরিয়াল কনসোল চালু করা হয়েছে"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"পারফর্ম্যান্সে এর প্রভাব পড়বে। চালানো বন্ধ করতে \'বুটলোডার\' প্রোগ্রামে এটিকে চেক করে দেখুন।"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ইউএসবি পোর্টে তরল পদার্থ অথবা ধুলো কণা"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"ইউএসবি পোর্ট নিজে থেকে বন্ধ করা হবে। আরও জানতে ট্যাপ করুন।"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ইউএসবি পোর্ট ব্যবহার করা যেতে পারে"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"বিভাগ নির্ধারিত নয়"</string> <string name="importance_from_user" msgid="7318955817386549931">"আপনি এই বিজ্ঞপ্তিগুলির গুরুত্ব সেট করেছেন।"</string> <string name="importance_from_person" msgid="9160133597262938296">"লোকজন জড়িত থাকার কারণে এটি গুরুত্বপূর্ণ।"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g>-এ (একজন ব্যবহারকারী এই অ্যাকাউন্টে আগে থেকেই রয়েছেন) একজন নতুন ব্যবহারকারী তৈরি করার অনুমতি <xliff:g id="APP">%1$s</xliff:g>-কে দেবেন?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g>-এ একজন নতুন ব্যবহারকারী তৈরি করার অনুমতি <xliff:g id="APP">%1$s</xliff:g>-কে দেবেন?"</string> <string name="language_selection_title" msgid="2680677278159281088">"একটি ভাষা যোগ করুন"</string> <string name="country_selection_title" msgid="2954859441620215513">"পছন্দের অঞ্চল"</string> <string name="search_language_hint" msgid="7042102592055108574">"ভাষার নাম লিখুন"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 0d4b12c30332..ae075cc8de6f 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -658,6 +658,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Omogućava aplikaciji da čita i upisuje konfiguraciju načina rada Ne ometaj."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"pokrenuti korištenje odobrenja za pregled"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Dozvoljava vlasniku da pokrene korištenje odobrenja za aplikaciju. Ne bi trebalo biti potrebno za obične aplikacije."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cilj prečice pristupačnosti"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Omogućava aplikaciji da definira cilj prečice pristupačnosti."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Postavljanje pravila za lozinke"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolira dužinu i znakove koji su dozvoljeni u lozinkama za zaključavanje ekrana i PIN-ovima."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Prati pokušaje otključavanja ekrana"</string> @@ -1385,6 +1387,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Odaberite da onemogućite ispravljanje grešaka koristeći USB"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Omogućen način rada okvira za testiranje"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Izvršite vraćanje na fabričke postavke da onemogućite način rada okvira za testiranje."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Serijska konzola omogućena"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Izvedba je otežana. Da onemogućite, provjerite program za učitavanje operativnog sistema."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tečnost ili nečistoće u USB priključku"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB priključak je automatski onemogućen. Dodirnite da saznate više."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB priključak je sada sigurno koristiti"</string> @@ -1926,10 +1930,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Nije kategorizirano"</string> <string name="importance_from_user" msgid="7318955817386549931">"Vi određujete značaj ovih obavještenja."</string> <string name="importance_from_person" msgid="9160133597262938296">"Ovo je značajno zbog osoba koje su uključene."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Dozvoliti aplikaciji <xliff:g id="APP">%1$s</xliff:g> da kreira novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g> (korisnik s ovim računom već postoji)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Dozvoliti aplikaciji <xliff:g id="APP">%1$s</xliff:g> da kreira novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Dodajte jezik"</string> <string name="country_selection_title" msgid="2954859441620215513">"Izbor regije"</string> <string name="search_language_hint" msgid="7042102592055108574">"Upišite ime jezika"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index d82884434305..0427569a6056 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permet que l\'aplicació llegeixi la configuració No molestis i hi escrigui."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"comença a utilitzar el permís de visualització"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permet que un propietari comenci a utilitzar el permís amb una aplicació. No s\'hauria de necessitar mai per a les aplicacions normals."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"objectiu de la drecera d\'accessibilitat"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permet a una aplicació definir l\'objectiu de la drecera d\'accessibilitat."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir les normes de contrasenya"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Permet controlar la longitud i el nombre de caràcters permesos a les contrasenyes i als PIN del bloqueig de pantalla."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Supervisar els intents de desbloqueig de la pantalla"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecciona per desactivar la depuració per USB"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"S\'ha activat el mode Agent de prova"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Si vols desactivar el mode Agent de prova, restableix les dades de fàbrica."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"S\'ha activat la consola de sèrie"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"El rendiment s\'ha vist afectat. Per desactivar-la, comprova el bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Hi ha líquid o pols al port USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"El port USB es desactiva automàticament. Toca per obtenir més informació."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Ja pots utilitzar el port USB"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Sense classificar"</string> <string name="importance_from_user" msgid="7318955817386549931">"Has definit la importància d\'aquestes notificacions."</string> <string name="importance_from_person" msgid="9160133597262938296">"Aquest missatge és important per les persones implicades."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Concedeixes permís a <xliff:g id="APP">%1$s</xliff:g> per crear un usuari amb el compte <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Ja hi ha un usuari amb aquest compte.)"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Concedeixes permís a <xliff:g id="APP">%1$s</xliff:g> per crear un usuari amb el compte <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Afegeix un idioma"</string> <string name="country_selection_title" msgid="2954859441620215513">"Preferència de regió"</string> <string name="search_language_hint" msgid="7042102592055108574">"Nom de l\'idioma"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 2b524ae64aba..32dac4d34727 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -661,6 +661,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Umožňuje aplikaci číst a zapisovat konfiguraci režimu Nerušit."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"zahájení zobrazení využití oprávnění"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Umožňuje přístup zahájit využití oprávnění jiné aplikace. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cíl zkratky přístupnosti"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Umožňuje aplikaci definovat cíl zkratky přístupnosti."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavit pravidla pro heslo"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Ovládání délky a znaků povolených v heslech a kódech PIN zámku obrazovky."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Sledovat pokusy o odemknutí obrazovky"</string> @@ -1405,6 +1407,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vyberte, chcete-li zakázat ladění přes USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Režim správce testů je aktivní"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Chcete-li deaktivovat režim správce testů, restartujte zařízení do továrního nastavení."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Je zapnutá sériová konzole"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Toto má dopad na výkon. Chcete-li ji vypnout, zkontrolujte bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Kapalina nebo nečistota v portu USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB byl automaticky deaktivován. Klepnutím zobrazíte další informace."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Port USB lze bezpečně použít"</string> @@ -1958,10 +1962,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Neklasifikováno"</string> <string name="importance_from_user" msgid="7318955817386549931">"Důležitost oznámení určujete vy."</string> <string name="importance_from_person" msgid="9160133597262938296">"Tato zpráva je důležitá kvůli lidem zapojeným do konverzace."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Povolit aplikaci <xliff:g id="APP">%1$s</xliff:g> vytvořit nového uživatele s účtem <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Uživatel s tímto účtem již existuje.)"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Povolit aplikaci <xliff:g id="APP">%1$s</xliff:g> vytvořit nového uživatele s účtem <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Přidat jazyk"</string> <string name="country_selection_title" msgid="2954859441620215513">"Preferovaná oblast"</string> <string name="search_language_hint" msgid="7042102592055108574">"Zadejte název jazyka"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 4d57a90fa068..3d7958817b27 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -226,7 +226,7 @@ <string name="global_actions" product="default" msgid="2406416831541615258">"Indstillinger for telefon"</string> <string name="global_action_lock" msgid="2844945191792119712">"Skærmlås"</string> <string name="global_action_power_off" msgid="4471879440839879722">"Sluk"</string> - <string name="global_action_emergency" msgid="7112311161137421166">"Nødopkald"</string> + <string name="global_action_emergency" msgid="7112311161137421166">"Nødsituation"</string> <string name="global_action_bug_report" msgid="7934010578922304799">"Fejlrapport"</string> <string name="global_action_logout" msgid="935179188218826050">"Afslut sessionen"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string> @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Giver appen tilladelse til at læse og redigere konfigurationen af Forstyr ikke."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"start brugen at tilladelsesvisning"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Tillader, at brugeren kan bruge en tilladelse for en app. Dette bør aldrig være nødvendigt for almindelige apps."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"mål for hjælpefunktionsgenvej"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Tillader, at en app definerer målet for en hjælpefunktionsgenvej."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Angiv regler for adgangskoder"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Tjek længden samt tilladte tegn i adgangskoder og pinkoder til skærmlåsen."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Overvåg forsøg på oplåsning af skærm"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vælg for at deaktivere USB-fejlretning."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Tilstanden Testsele er aktiveret"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Gendan fabriksindstillingerne for at deaktivere tilstanden Testsele."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Seriekonsollen er aktiveret"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Effektiviteten er påvirket. Deaktiver via bootloaderen."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Væske eller snavs i USB-porten"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-porten deaktiveres automatisk. Tryk for at få flere oplysninger."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-porten kan bruges"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Uden kategori"</string> <string name="importance_from_user" msgid="7318955817386549931">"Du angiver, hvor vigtige disse notifikationer er."</string> <string name="importance_from_person" msgid="9160133597262938296">"Dette er vigtigt på grund af de personer, det handler om."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Vil du give <xliff:g id="APP">%1$s</xliff:g> tilladelse til at oprette en ny bruger med <xliff:g id="ACCOUNT">%2$s</xliff:g> (der findes allerede en bruger med denne konto)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Vil du give <xliff:g id="APP">%1$s</xliff:g> tilladelse til at oprette en nye bruger med <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Tilføj et sprog"</string> <string name="country_selection_title" msgid="2954859441620215513">"Områdeindstilling"</string> <string name="search_language_hint" msgid="7042102592055108574">"Angiv sprog"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 2ec70d36a412..cbba324f3a78 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Ermöglicht der App Lese- und Schreibzugriff auf die \"Bitte nicht stören\"-Konfiguration"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"Mit der Verwendung der Anzeigeberechtigung beginnen"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Ermöglicht dem Inhaber, die Berechtigungsnutzung für eine App zu beginnen. Sollte für normale Apps nie benötigt werden."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"Ziel der Verknüpfung für Bedienungshilfen"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Ermöglicht einer App, das Ziel der Verknüpfung für Bedienungshilfen zu definieren."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Passwortregeln festlegen"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Zulässige Länge und Zeichen für Passwörter für die Displaysperre festlegen"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Versuche zum Entsperren des Displays überwachen"</string> @@ -1361,7 +1363,9 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB-Debugging deaktivieren: auswählen"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test-Harnischmodus aktiviert"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Setz das Gerät auf die Werkseinstellungen zurück, um den Test-Harnischmodus zu deaktivieren."</string> - <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Flüssigkeiten oder Fremdkörper im USB-Port"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Serielle Konsole aktiviert"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Leistung wird beeinflusst. Überprüfe Bootloader zum Deaktivieren."</string> + <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Flüssigkeit oder Fremdkörper im USB-Port"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Der USB-Port wird automatisch deaktiviert. Für weitere Informationen tippen."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-Port kann wieder verwendet werden"</string> <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Das Smartphone erkennt keine Flüssigkeiten oder Fremdkörper mehr."</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Unkategorisiert"</string> <string name="importance_from_user" msgid="7318955817386549931">"Du hast die Wichtigkeit dieser Benachrichtigungen festgelegt."</string> <string name="importance_from_person" msgid="9160133597262938296">"Diese Benachrichtigung ist aufgrund der beteiligten Personen wichtig."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Es gibt bereits einen Nutzer mit <xliff:g id="ACCOUNT">%2$s</xliff:g>. Möchtest du zulassen, dass <xliff:g id="APP">%1$s</xliff:g> einen neuen Nutzer mit diesem Konto erstellt?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Möchtest du zulassen, dass <xliff:g id="APP">%1$s</xliff:g> einen neuen Nutzer mit <xliff:g id="ACCOUNT">%2$s</xliff:g> erstellt?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Sprache hinzufügen"</string> <string name="country_selection_title" msgid="2954859441620215513">"Region auswählen"</string> <string name="search_language_hint" msgid="7042102592055108574">"Sprache eingeben"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 6998c0c16811..e162d6b9d5de 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Επιτρέπει στην εφαρμογή την εγγραφή και τη σύνταξη διαμόρφωσης για τη λειτουργία \"Μην ενοχλείτε\"."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"έναρξη χρήσης άδειας προβολής"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Επιτρέπει στον κάτοχο να ξεκινήσει τη χρήση της άδειας για μια εφαρμογή. Δεν απαιτείται ποτέ για κανονικές εφαρμογές."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"στόχος συντόμευσης προσβασιμότητας"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Επιτρέπει σε μια εφαρμογή να καθορίσει τον στόχο της συντόμευσης προσβασιμότητας."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Ορισμός κανόνων κωδικού πρόσβασης"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Ελέγξτε την έκταση και τους επιτρεπόμενους χαρακτήρες σε κωδικούς πρόσβασης κλειδώματος οθόνης και PIN."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Παρακολούθηση προσπαθειών ξεκλειδώματος οθόνης"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Επιλογή για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Η λειτουργία περιβάλλοντος δοκιμών ενεργοποιήθηκε"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Εκτελέστε επαναφορά εργοστασιακών ρυθμίσεων για να απενεργοποιήσετε τη λειτουργία περιβάλλοντος δοκιμών."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Η σειριακή κονσόλα ενεργοποιήθηκε"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Η απόδοση επηρεάζεται. Για απενεργοποίηση, επιλέξτε το πρόγραμμα φόρτωσης εκκίνησης."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Υγρασία ή ακαθαρσίες στη θύρα USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Η θύρα USB απενεργοποιείται αυτόματα. Πατήστε για να μάθετε περισσότερα."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Αποδεκτή η χρήση της θύρας USB"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Μη κατηγοριοποιημένο"</string> <string name="importance_from_user" msgid="7318955817386549931">"Μπορείτε να ρυθμίσετε τη βαρύτητα αυτών των ειδοποιήσεων."</string> <string name="importance_from_person" msgid="9160133597262938296">"Αυτό είναι σημαντικό λόγω των ατόμων που συμμετέχουν."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Επιτρέπετε στην εφαρμογή <xliff:g id="APP">%1$s</xliff:g> να δημιουργήσει έναν νέο χρήστη με τον λογαριασμό <xliff:g id="ACCOUNT">%2$s</xliff:g> (υπάρχει ήδη χρήστης με αυτόν τον λογαριασμό);"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Επιτρέπετε στην εφαρμογή <xliff:g id="APP">%1$s</xliff:g> να δημιουργήσει έναν νέο χρήστη με τον λογαριασμό <xliff:g id="ACCOUNT">%2$s</xliff:g>;"</string> <string name="language_selection_title" msgid="2680677278159281088">"Προσθήκη γλώσσας"</string> <string name="country_selection_title" msgid="2954859441620215513">"Προτίμηση περιοχής"</string> <string name="search_language_hint" msgid="7042102592055108574">"Εισαγ. όνομα γλώσσας"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 7c2b32989c5d..56d09f3d7b59 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Allows the app to read and write Do Not Disturb configuration."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"start view permission usage"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"accessibility shortcut target"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Allows an app to define the accessibility shortcut target."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Control the length and the characters allowed in screen lock passwords and PINs."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitor screen unlock attempts"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test Harness Mode enabled"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Perform a factory reset to disable Test Harness Mode."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Serial console enabled"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Performance is impacted. To disable, check bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid or debris in USB port"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port is automatically disabled. Tap to learn more."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK to use USB port"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorised"</string> <string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string> <string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string> <string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string> <string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 6da3a5fbdcf9..2aafb7a40793 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Allows the app to read and write Do Not Disturb configuration."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"start view permission usage"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"accessibility shortcut target"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Allows an app to define the accessibility shortcut target."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Control the length and the characters allowed in screen lock passwords and PINs."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitor screen unlock attempts"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test Harness Mode enabled"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Perform a factory reset to disable Test Harness Mode."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Serial console enabled"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Performance is impacted. To disable, check bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid or debris in USB port"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port is automatically disabled. Tap to learn more."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK to use USB port"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorised"</string> <string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string> <string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string> <string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string> <string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 7c2b32989c5d..56d09f3d7b59 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Allows the app to read and write Do Not Disturb configuration."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"start view permission usage"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"accessibility shortcut target"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Allows an app to define the accessibility shortcut target."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Control the length and the characters allowed in screen lock passwords and PINs."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitor screen unlock attempts"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test Harness Mode enabled"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Perform a factory reset to disable Test Harness Mode."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Serial console enabled"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Performance is impacted. To disable, check bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid or debris in USB port"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port is automatically disabled. Tap to learn more."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK to use USB port"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorised"</string> <string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string> <string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string> <string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string> <string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 7c2b32989c5d..56d09f3d7b59 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Allows the app to read and write Do Not Disturb configuration."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"start view permission usage"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"accessibility shortcut target"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Allows an app to define the accessibility shortcut target."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Control the length and the characters allowed in screen lock passwords and PINs."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitor screen unlock attempts"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test Harness Mode enabled"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Perform a factory reset to disable Test Harness Mode."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Serial console enabled"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Performance is impacted. To disable, check bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid or debris in USB port"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port is automatically disabled. Tap to learn more."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK to use USB port"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorised"</string> <string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string> <string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string> <string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string> <string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index 62f294e66438..9844b6704d8f 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Allows the app to read and write Do Not Disturb configuration."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"start view permission usage"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"accessibility shortcut target"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Allows an app to define the accessibility shortcut target."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Control the length and the characters allowed in screen lock passwords and PINs."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitor screen unlock attempts"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test Harness Mode enabled"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Perform a factory reset to disable Test Harness Mode."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Serial console enabled"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Performance is impacted. To disable, check bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid or debris in USB port"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port is automatically disabled. Tap to learn more."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK to use USB port"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorized"</string> <string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string> <string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists) ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string> <string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string> <string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 7346bd0b3ace..7289f4b5cdf6 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permite que la aplicación lea y modifique la configuración de la función No interrumpir."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"iniciar uso de permiso de vista"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permite que el propietario inicie el uso de permisos para una app. No debería requerirse para apps normales."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"orientación del acceso directo de accesibilidad"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permite que una app defina la orientación del acceso directo de accesibilidad."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecer reglas de contraseña"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Controlar la longitud y los caracteres permitidos en las contraseñas y los PIN para el bloqueo de pantalla."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Supervisa los intentos para desbloquear la pantalla"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para desactivar la depuración por USB"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Se habilitó el modo de agente de prueba"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Restablece la configuración de fábrica para inhabilitar el modo de agente de prueba."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Se habilitó la consola en serie"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Afecta el rendimiento. Para inhabilitarla, verifica bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Hay líquido o suciedad en el puerto USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"El puerto USB se inhabilitó automáticamente. Presiona para obtener más información."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Se puede usar el puerto USB"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Sin categoría"</string> <string name="importance_from_user" msgid="7318955817386549931">"Estableciste la importancia de estas notificaciones."</string> <string name="importance_from_person" msgid="9160133597262938296">"Es importante debido a las personas involucradas."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"¿Quieres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario nuevo con <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Ya existe un usuario con esta cuenta)"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"¿Deseas permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario nuevo con <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Agregar un idioma"</string> <string name="country_selection_title" msgid="2954859441620215513">"Preferencia de región"</string> <string name="search_language_hint" msgid="7042102592055108574">"Nombre del idioma"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 6c1c99230adb..c513b3970f49 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permite que la aplicación lea y modifique la configuración de No molestar."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"iniciar uso de permiso de visualización"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permite que el titular inicie el uso de permisos de una aplicación. Las aplicaciones normales no deberían necesitar nunca este permiso."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"objetivo de atajo de accesibilidad"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permite que una aplicación defina el objetivo de un atajo de accesibilidad."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecimiento de reglas de contraseña"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Controla la longitud y los caracteres permitidos en los PIN y en las contraseñas de bloqueo de pantalla."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Supervisar los intentos de desbloqueo de pantalla"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para inhabilitar la depuración USB"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modo de agente de prueba habilitado"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Restablece los ajustes de fábrica para inhabilitar el modo de agente de prueba."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Se ha habilitado la consola en serie"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Afecta al rendimiento. Para inhabilitarlo, comprueba el bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Se ha detectado líquido o suciedad en el puerto USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"El puerto USB se ha inhabilitado automáticamente. Toca para obtener más información."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Se puede utilizar el puerto USB"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Sin clasificar"</string> <string name="importance_from_user" msgid="7318955817386549931">"Tú determinas la importancia de estas notificaciones."</string> <string name="importance_from_person" msgid="9160133597262938296">"Esto es importante por los usuarios implicados."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"¿Permitir que <xliff:g id="APP">%1$s</xliff:g> cree otro usuario con la cuenta <xliff:g id="ACCOUNT">%2$s</xliff:g>, que ya tiene uno?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"¿Permitir que <xliff:g id="APP">%1$s</xliff:g> cree otro usuario con la cuenta <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Añadir un idioma"</string> <string name="country_selection_title" msgid="2954859441620215513">"Preferencia de región"</string> <string name="search_language_hint" msgid="7042102592055108574">"Nombre de idioma"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 28d12036a9b6..d70a5804c37a 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Võimaldab rakendusel lugeda ja kirjutada funktsiooni Mitte segada seadistusi."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"vaatamisloa kasutamise alustamine"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Võimaldab omanikul rakenduse puhul alustada loa kasutamist. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"juurdepääsetavuse otsetee sihtmärk"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Lubab rakendusel määrata juurdepääsetavuse otsetee sihtmärgi."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Parooli reeglite määramine"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Juhitakse ekraaniluku paroolide ja PIN-koodide pikkusi ning lubatud tähemärkide seadeid."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Ekraani avamiskatsete jälgimine"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Valige USB silumise keelamiseks"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Testrakendirežiim on lubatud"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Testrakendirežiimi keelamiseks taastage tehaseseaded."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Seeriakonsool on lubatud"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"See mõjutab toimivust. Keelamiseks kontrollige käivituslaadurit."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB-pordis on vedelik või mustus"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-port on automaatselt keelatud. Puudutage lisateabe saamiseks."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-porti tohib kasutada"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Kategoriseerimata"</string> <string name="importance_from_user" msgid="7318955817386549931">"Teie määrasite nende märguannete tähtsuse."</string> <string name="importance_from_person" msgid="9160133597262938296">"See on tähtis osalevate inimeste tõttu."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Kas lubada rakendusel <xliff:g id="APP">%1$s</xliff:g> luua uus kasutaja kontoga <xliff:g id="ACCOUNT">%2$s</xliff:g> (selle kontoga kasutaja on juba olemas)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Kas lubada rakendusel <xliff:g id="APP">%1$s</xliff:g> luua uus kasutaja kontoga <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Keele lisamine"</string> <string name="country_selection_title" msgid="2954859441620215513">"Piirkonnaeelistus"</string> <string name="search_language_hint" msgid="7042102592055108574">"Sisestage keele nimi"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 9460ee702856..3a9cb13cd37b 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"\"Ez molestatu\" konfigurazioa irakurtzeko eta bertan idazteko baimena ematen die aplikazioei."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"hasi ikusteko baimena erabiltzen"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Aplikazioaren baimena erabiltzen hasteko baimena ematen die titularrei. Aplikazio normalek ez lukete beharko."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"erabilerraztasun-lasterbidearen helburua"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Erabilerraztasun-lasterbidearen helburua zehazteko baimena ematen dio aplikazioari."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Ezarri pasahitzen arauak"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolatu pantaila blokeoaren pasahitzen eta PINen luzera eta onartutako karaktereak."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Gainbegiratu pantaila desblokeatzeko saiakerak"</string> @@ -1260,7 +1262,7 @@ <string name="wifi_suggestion_title" msgid="6396033039578436801">"Iradokitako wifi-sareak baimendu nahi dituzu?"</string> <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> aplikazioak sare batzuk iradoki ditu. Baliteke gailua automatikoki konektatzea."</string> <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Baimendu"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ez. Eskerrik asko."</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ez, eskerrik asko"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi konexioa automatikoki aktibatuko da"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Gordeta daukazun kalitate handiko sare batetik gertu zaudenean"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ez aktibatu berriro"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Hautatu USB arazketa desgaitzeko."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Proba-materialeko modua gaitu da"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Proba-materialaren modua desgaitzeko, berrezarri jatorrizko datuak."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Serie-kontsola gaituta dago"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Funtzionamenduari eragiten dio. Desgaitzeko, joan abiarazlera."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Likidoa edo zikinkeriak daude USB atakan"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ataka automatikoki desgaitu da. Informazio gehiago lortzeko, sakatu hau."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Erabiltzeko moduan dago USB ataka"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Kategoriarik gabea"</string> <string name="importance_from_user" msgid="7318955817386549931">"Zuk ezarri duzu jakinarazpen hauen garrantzia."</string> <string name="importance_from_person" msgid="9160133597262938296">"Garrantzitsua da eragiten dien pertsonengatik."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> aplikazioari <xliff:g id="ACCOUNT">%2$s</xliff:g> kontua duen erabiltzailea sortzeko baimena eman nahi diozu? (Badago kontu hori duen erabiltzaile bat)"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> aplikazioari <xliff:g id="ACCOUNT">%2$s</xliff:g> kontua duen erabiltzailea sortzeko baimena eman nahi diozu?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Gehitu hizkuntza"</string> <string name="country_selection_title" msgid="2954859441620215513">"Lurralde-hobespena"</string> <string name="search_language_hint" msgid="7042102592055108574">"Adierazi hizkuntza"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index ec5dbcb20151..f0ea22d14d3f 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"به برنامه امکان میدهد پیکربندی «مزاحم نشوید» را بخواند و بنویسد."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"شروع مشاهده استفاده از مجوز"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"به دارنده اجازه شروع استفاده از مجوز را برای برنامه میدهد. هرگز برای برنامههای معمول نیاز نیست."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"مقصد میانبر دسترسپذیری"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"به برنامه اجازه میدهد مقصد میانبر دسترسپذیری را تعریف کند."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"تنظیم قوانین گذرواژه"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"کنترل طول و نوع نویسههایی که در گذرواژه و پین قفل صفحه مجاز است."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"پایش تلاشهای باز کردن قفل صفحه"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"انتخاب کنید تا رفع عیب USB غیرفعال شود."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"«حالت مجموعه دادههای تست» فعال شد"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"برای غیرفعال کردن «حالت مجموعه دادههای تست»، بازنشانی کارخانهای کنید."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"کنسول سریال فعال است"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"عملکرد تحتتأثیر قرار گرفته است. برای غیرفعال کردن، bootloader را بررسی کنید."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"مایعات یا خاکروبه در درگاه USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"درگاه USB بهطور خودکار غیرفعال شده است. برای اطلاعات بیشتر، ضربه بزنید."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"میتوان از درگاه USB استفاده کرد"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"دستهبندینشده"</string> <string name="importance_from_user" msgid="7318955817386549931">"شما اهمیت این اعلانها را تنظیم میکنید."</string> <string name="importance_from_person" msgid="9160133597262938296">"به دلیل افراد درگیر مهم است."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"به<xliff:g id="APP">%1$s</xliff:g> اجازه میدهید با <xliff:g id="ACCOUNT">%2$s</xliff:g> (کاربری با این حساب درحالحاضر وجود دارد) کاربری جدید ایجاد کند؟"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"به <xliff:g id="APP">%1$s</xliff:g> اجازه میدهید با <xliff:g id="ACCOUNT">%2$s</xliff:g> کاربری جدید ایجاد کند؟"</string> <string name="language_selection_title" msgid="2680677278159281088">"افزودن زبان"</string> <string name="country_selection_title" msgid="2954859441620215513">"اولویتهای منطقه"</string> <string name="search_language_hint" msgid="7042102592055108574">"نام زبان را تایپ کنید"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index a94253b9e68f..b1648f5af1df 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Sallii sovelluksen lukea ja muokata Älä häiritse -tilan asetuksia."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"aloita katseluoikeuksien käyttö"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Antaa luvanhaltijan käynnistää sovelluksen käyttöoikeuksien käytön. Ei tavallisten sovelluksien käyttöön."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"esteettömyystilan pikakuvakkeen kohde"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Sallii sovelluksen määrittää kohteen esteettömystilan pikakuvakkeelle."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Asentaa salasanasäännöt"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Hallinnoida ruudun lukituksen salasanoissa ja PIN-koodeissa sallittuja merkkejä ja niiden pituutta."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Tarkkailla näytön avaamisyrityksiä"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Poista USB-vianetsintä käytöstä valitsemalla tämä."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Testikehystila käytössä"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Palauta tehdasasetukset, niin voit poistaa testikehystilan käytöstä."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Sarjakonsoli käytössä"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Tämä vaikuttaa suorituskykyyn. Jos haluat poistaa toiminnon käytöstä, tarkista käynnistysohjelma."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Nestettä tai likaa USB-portissa"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-portti poistetaan käytöstä automaattisesti. Napauta nähdäksesi lisätietoja."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-portin käyttö on sallittu"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Luokittelematon"</string> <string name="importance_from_user" msgid="7318955817386549931">"Voit valita näiden ilmoitusten tärkeyden."</string> <string name="importance_from_person" msgid="9160133597262938296">"Tämä on tärkeää siihen liittyvien ihmisten perusteella."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Saako <xliff:g id="APP">%1$s</xliff:g> luoda uuden käyttäjän (<xliff:g id="ACCOUNT">%2$s</xliff:g>) – tällä käyttäjällä on jo tili?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Saako <xliff:g id="APP">%1$s</xliff:g> luoda uuden käyttäjän (<xliff:g id="ACCOUNT">%2$s</xliff:g>)?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Lisää kieli"</string> <string name="country_selection_title" msgid="2954859441620215513">"Alueasetus"</string> <string name="search_language_hint" msgid="7042102592055108574">"Anna kielen nimi"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 94f6acbdd080..384f5fa1026b 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permet à l\'application de consulter et de modifier la configuration du mode Ne pas déranger."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"démarrer l\'affichage de l\'usage des autorisations"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permet au détenteur de démarrer l\'usage des autorisations pour une application. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cible du raccourci d\'accessibilité"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permet à une application de définir la cible du raccourci d\'accessibilité."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Gérer le nombre et le type de caractères autorisés dans les mots de passe et les NIP de verrouillage de l\'écran."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Gérer les tentatives de déverrouillage de l\'écran"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Mode Logiciel de test activé"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Effectuez une réinitialisation pour désactiver le mode Logiciel de test."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"La console série est activée"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"La performance est réduite. Pour désactiver cette fonction, vérifier le programme d\'amorçage."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquide ou débris dans le port USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Le port USB est désactivé automatiquement. Touchez ici pour en savoir plus."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Autorisation d\'utiliser le port USB"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Sans catégorie"</string> <string name="importance_from_user" msgid="7318955817386549931">"Vous définissez l\'importance de ces notifications."</string> <string name="importance_from_person" msgid="9160133597262938296">"Ces notifications sont importantes en raison des participants."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un utilisateur <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Un utilisateur est déjà associé à ce compte)"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil d\'utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Ajouter une langue"</string> <string name="country_selection_title" msgid="2954859441620215513">"Préférences régionales"</string> <string name="search_language_hint" msgid="7042102592055108574">"Entrez la langue"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 11ba7dc7911b..d204ac1a5188 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permet à l\'application de consulter et de modifier la configuration du mode Ne pas déranger."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"activer l\'utilisation de l\'autorisation d\'affichage"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permet à l\'application autorisée d\'activer l\'utilisation de l\'autorisation pour une application. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cible du raccourci d\'accessibilité"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Autorise une application à définir la cible du raccourci d\'accessibilité."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Gérer le nombre et le type de caractères autorisés dans les mots de passe et les codes d\'accès de verrouillage de l\'écran"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Gérer les tentatives de déverrouillage de l\'écran"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Mode Atelier de test activé"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Rétablissez la configuration d\'usine pour désactiver le mode Atelier de test."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Console série activée"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Les performances sont affectées. Pour désactiver la console série, vérifiez le bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Présence de liquide ou de saletés dans le port USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Le port USB est désactivé automatiquement. Appuyez sur cette notification pour en savoir plus."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Le port USB peut être utilisé"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Sans catégorie"</string> <string name="importance_from_user" msgid="7318955817386549931">"Vous définissez l\'importance de ces notifications."</string> <string name="importance_from_person" msgid="9160133597262938296">"Ces notifications sont importantes en raison des participants."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g> (un utilisateur associé à ce compte existe déjà) ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Ajouter une langue"</string> <string name="country_selection_title" msgid="2954859441620215513">"Préférences régionales"</string> <string name="search_language_hint" msgid="7042102592055108574">"Saisissez la langue"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 1becada75cac..b798bc540daa 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permite á aplicación ler e escribir a configuración do modo Non molestar."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"iniciar uso de permiso de vista"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permite ao propietario iniciar o uso de permisos dunha aplicación. As aplicacións normais non deberían precisalo nunca."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"obxectivo do atallo de accesibilidade"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permite que unha aplicación defina o obxectivo do atallo de accesibilidade."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecer as normas de contrasinal"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Controla a lonxitude e os caracteres permitidos nos contrasinais e nos PIN de bloqueo da pantalla."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Controlar os intentos de desbloqueo da pantalla"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecciona a opción para desactivar a depuración por USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Activouse o modo de axente de proba"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Restablece a configuración de fábrica para desactivar o modo de axente de proba."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"A consola de serie está activada"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"O rendemento vese afectado. Para desactivar a consola, comproba o cargador de arranque."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Hai líquido ou residuos no porto USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"O porto USB desactivouse automaticamente. Toca para obter máis información."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Pódese utilizar o porto USB"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Sen clasificar"</string> <string name="importance_from_user" msgid="7318955817386549931">"Ti defines a importancia destas notificacións."</string> <string name="importance_from_person" msgid="9160133597262938296">"É importante polas persoas involucradas."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Queres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario novo con <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Xa existe un usuario con esta conta)"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Queres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario novo con <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Engadir un idioma"</string> <string name="country_selection_title" msgid="2954859441620215513">"Preferencia de rexión"</string> <string name="search_language_hint" msgid="7042102592055108574">"Nome do idioma"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 09661c15afe8..5a415037d553 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"એપ્લિકેશનને ખલેલ પાડશો નહીં ગોઠવણી વાંચવા અને લખવાની મંજૂરી આપે છે."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"પરવાનગી વપરાશ જુઓને શરૂ કરો"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"કોઈ ઍપ માટે પરવાનગી વપરાશ શરૂ કરવાની ધારકને મંજૂરી આપે છે. સામાન્ય ઍપ માટે ક્યારેય જરૂર પડી ન શકે."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ઍક્સેસિબિલિટી શૉર્ટકટ ટાર્ગેટ"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ઍપને ઍક્સેસિબિલિટી શૉર્ટકટ ટાર્ગેટ વ્યાખ્યાતિત કરવાની મંજૂરી આપે છે."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"પાસવર્ડ નિયમો સેટ કરો"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"સ્ક્રીન લૉક પાસવર્ડ અને પિનમાં મંજૂર લંબાઈ અને અક્ષરોને નિયંત્રિત કરો."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"સ્ક્રીનને અનલૉક કરવાના પ્રયત્નોનું નિયમન કરો"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ડિબગીંગને અક્ષમ કરવા માટે પસંદ કરો."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"ટેસ્ટ હાર્નેસ મોડ ચાલુ કર્યો"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ટેસ્ટ હાર્નેસ મોડ બંધ કરવા માટે ફૅક્ટરી રીસેટ કરો."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"સિરીયલ કન્સોલ ચાલુ થયો"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"કાર્યપ્રદર્શનને અસર થાય છે. બંધ કરવા માટે, બૂટલોડર ચેક કરો."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB પોર્ટમાં પ્રવાહી કે ધૂળ"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB પોર્ટ ઑટોમૅટિક રીતે બંધ કરવામાં આવ્યો છે. વધુ જાણવા માટે ટૅપ કરો."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB પોર્ટનો ઉપયોગ કરવો યોગ્ય છે"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"અવર્ગીકૃત"</string> <string name="importance_from_user" msgid="7318955817386549931">"તમે આ સૂચનાઓનું મહત્વ સેટ કર્યું છે."</string> <string name="importance_from_person" msgid="9160133597262938296">"શામેલ થયેલ લોકોને કારણે આ મહત્વપૂર્ણ છે."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>ને <xliff:g id="ACCOUNT">%2$s</xliff:g> માટે એક નવા વપરાશકર્તા બનાવવાની મંજૂરી આપીએ (આ એકાઉન્ટ માટે એક વપરાશકર્તા પહેલાંથી અસ્તિત્વમાં છે) ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>ને <xliff:g id="ACCOUNT">%2$s</xliff:g> માટે એક નવા વપરાશકર્તા બનાવવાની મંજૂરી આપીએ ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"ભાષા ઉમેરો"</string> <string name="country_selection_title" msgid="2954859441620215513">"પ્રદેશ પસંદગી"</string> <string name="search_language_hint" msgid="7042102592055108574">"ભાષાનું નામ ટાઇપ કરો"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index f21d138f14f0..5b902345f5e4 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"ऐप को परेशान न करें कॉन्फ़िगरेशन पढ़ने और लिखने देती है."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"देखने की अनुमतियां चालू करें"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"इस्तेमाल करने वाले को किसी ऐप्लिकेशन के लिए अनुमतियों का इस्तेमाल शुरू करने देता है. सामान्य ऐप्लिकेशन के लिए इसकी ज़रूरत कभी नहीं पड़ती."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"सुलभता शॉर्टकट टारगेट"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"सुलभता शॉर्टकट टारगेट के बारे में बताने के लिए ऐप्लिकेशन को मंज़ूरी दें."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करना"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"स्क्रीन लॉक पासवर्ड और पिन की लंबाई और उनमें स्वीकृत वर्णों को नियंत्रित करना."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"स्क्रीन अनलॉक करने के की कोशिशों पर नज़र रखना"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डीबग करना अक्षम करने के लिए चुनें."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"टेस्ट हार्नेस मोड चालू किया गया"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"टेस्ट हार्नेस मोड बंद करने के लिए फ़ैक्ट्री रीसेट करें."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"सीरियल कंसोल को चालू करें"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"परफ़ॉर्मेंस पर असर पड़ा है. बंद करने के लिए बूटलोडर चुनें."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"यूएसबी पोर्ट में तरल चीज़ या कचरा है"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"यूएसबी पोर्ट अपने आप बंद हो गया है. ज़्यादा जानने के लिए टैप करें."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"यूएसबी पोर्ट का इस्तेमाल करना सुरक्षित है"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"बिना किसी श्रेणी के"</string> <string name="importance_from_user" msgid="7318955817386549931">"आपने इन सूचनाओं की अहमियत सेट की है."</string> <string name="importance_from_person" msgid="9160133597262938296">"यह मौजूद व्यक्तियों के कारण महत्वपूर्ण है."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के नाम से एक नया उपयोगकर्ता बनाने की अनुमति दें (इस नाम से एक खाता पहले से मौजूद है)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"भाषा जोड़ें"</string> <string name="country_selection_title" msgid="2954859441620215513">"क्षेत्र प्राथमिकता"</string> <string name="search_language_hint" msgid="7042102592055108574">"भाषा का नाम लिखें"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 25007d514064..291b116ef44c 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -658,6 +658,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Omogućuje aplikaciji čitanje i pisanje konfiguracije opcije Ne ometaj."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"pokrenuti upotrebu dopuštenja za pregled"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Dopušta nositelju pokretanje upotrebe dopuštenja za aplikaciju. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cilj prečaca pristupačnosti"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Aplikaciji omogućuje da definira cilj prečaca pristupačnosti."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Postavi pravila zaporke"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Upravlja duljinom i znakovima koji su dopušteni u zaporkama i PIN-ovima zaključavanja zaslona."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Nadziri pokušaje otključavanja zaslona"</string> @@ -1383,6 +1385,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Odaberite da biste onemogućili rješavanje programske pogreške na USB-u."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Omogućen je način testnog okvira"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Vratite na tvorničke postavke da biste onemogućili način testnog okvira."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Serijska konzola omogućena"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Izvedba je otežana. Provjerite početni program za pokretanje da biste onemogućili konzolu."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tekućina ili prljavština u USB priključku"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB priključak automatski je onemogućen. Dodirnite da biste saznali više."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Možete koristiti USB priključak"</string> @@ -1924,10 +1928,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Nema kategorije"</string> <string name="importance_from_user" msgid="7318955817386549931">"Postavili ste važnost tih obavijesti."</string> <string name="importance_from_person" msgid="9160133597262938296">"Važno je zbog uključenih osoba."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Dopustiti aplikaciji <xliff:g id="APP">%1$s</xliff:g> da izradi novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g> (korisnik s ovim računom već postoji)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Dopustiti aplikaciji <xliff:g id="APP">%1$s</xliff:g> da izradi novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Dodavanje jezika"</string> <string name="country_selection_title" msgid="2954859441620215513">"Postavke regije"</string> <string name="search_language_hint" msgid="7042102592055108574">"Unesite naziv jezika"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 0487601ac29b..f83ac69de35c 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Az alkalmazás olvashatja és szerkesztheti a „Ne zavarjanak” funkció beállításait."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"engedélyhasználat megtekintésének elindítása"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Lehetővé teszi a felhasználó számára, hogy elindítsa az alkalmazás engedélyhasználatát. A normál alkalmazásoknak erre soha nincs szükségük."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"A kisegítő lehetőségek gyorsparancs célja"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Engedélyezi az alkalmazásoknak a kisegítő lehetőségek gyorsparancs céljának meghatározását."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Jelszavakkal kapcsolatos szabályok beállítása"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"A képernyőzár jelszavaiban és PIN kódjaiban engedélyezett karakterek és hosszúság vezérlése."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Képernyőzár-feloldási kísérletek figyelése"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Válassza ezt az USB hibakeresés kikapcsolásához."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Tesztelési alapkörnyezet mód engedélyezve"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"A Tesztelési alapkörnyezet mód kikapcsolásához állítsa vissza a gyári beállításokat."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Soros konzol engedélyezve"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Ez hatással van a teljesítményre. A letiltáshoz ellenőrizze a rendszerindítót."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Folyadék vagy szennyeződés az USB-portban"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-port automatikusan letiltva. Koppintson, ha további információra van szüksége."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Az USB-port rendben használható"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Nincs kategóriába sorolva"</string> <string name="importance_from_user" msgid="7318955817386549931">"Ön állította be ezen értesítések fontossági szintjét."</string> <string name="importance_from_person" msgid="9160133597262938296">"Ez az üzenet a résztvevők miatt fontos."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Engedélyezi a(z) <xliff:g id="APP">%1$s</xliff:g> számára, hogy új felhasználót hozzon létre a(z) <xliff:g id="ACCOUNT">%2$s</xliff:g> fiókkal? (Már létezik felhasználó ezzel a fiókkal.)"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Engedélyezi a(z) <xliff:g id="APP">%1$s</xliff:g> számára, hogy új felhasználót hozzon létre a(z) <xliff:g id="ACCOUNT">%2$s</xliff:g> fiókkal?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Nyelv hozzáadása"</string> <string name="country_selection_title" msgid="2954859441620215513">"Régió beállítása"</string> <string name="search_language_hint" msgid="7042102592055108574">"Adja meg a nyelvet"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index e6223f0ce438..2c40a5a9732a 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Թույլ է տալիս հավելվածին փոփոխել «Չանհանգստացնել» գործառույթի կազմաձևումը:"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"թույլտվությունների մասին տվյալների հասանելիություն"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Հավելվածին հասանելի կդառնան թույլտվությունների մասին տվյալները։ Այս թույլտվությունն անհրաժեշտ չէ սովորական հավելվածներին։"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"հատուկ գործառույթների դյուրանցումն օգտագործելու նպատակը"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Հավելվածին թույլ է տալիս որոշել հատուկ գործառույթների դյուրանցումն օգտագործելու նպատակը։"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Սահմանել գաղտնաբառի կանոնները"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Կառավարել էկրանի ապակողպման գաղտնաբառերի և PIN կոդերի թույլատրելի երկարությունն ու գրանշանները:"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Վերահսկել էկրանի ապակողպման փորձերը"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Սեղմեք՝ USB-ով վրիպազերծումն անջատելու համար:"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Թեստային ռեժիմը միացված է"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Թեստային ռեժիմն անջատելու համար զրոյացրեք կարգավորումները։"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Սերիական վահանակը միացված է"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Աշխատանքի արդյունավետությունը նվազում է։ Վահանակն անջատելու համար ստուգեք օպերացիոն համակարգի բեռնիչը։"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB միացքում ջուր կամ աղտ է հայտնաբերվել"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB միացքն ավտոմատ անջատվել է: Հպեք՝ ավելին իմանալու համար:"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB միացքը կարող է օգտագործվել"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Չդասակարգված"</string> <string name="importance_from_user" msgid="7318955817386549931">"Դուք սահմանել եք այս ծանուցումների կարևորությունը:"</string> <string name="importance_from_person" msgid="9160133597262938296">"Կարևոր է, քանի որ որոշակի մարդիկ են ներգրավված:"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Թույլատրե՞լ <xliff:g id="APP">%1$s</xliff:g> հավելվածին <xliff:g id="ACCOUNT">%2$s</xliff:g> հաշվով նոր Օգտատեր ստեղծել (նման հաշվով Օգտատեր արդեն գոյություն ունի):"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Թույլատրե՞լ <xliff:g id="APP">%1$s</xliff:g> հավելվածին <xliff:g id="ACCOUNT">%2$s</xliff:g> հաշվով նոր Օգտատեր ստեղծել:"</string> <string name="language_selection_title" msgid="2680677278159281088">"Ավելացնել լեզու"</string> <string name="country_selection_title" msgid="2954859441620215513">"Նախընտրելի տարածաշրջան"</string> <string name="search_language_hint" msgid="7042102592055108574">"Մուտքագրեք լեզուն"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 3c6ee839dbab..4d0eea065dc4 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Mengizinkan aplikasi membaca dan menulis konfigurasi status Jangan Ganggu."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"mulai melihat penggunaan izin"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Memungkinkan pemegang memulai penggunaan izin untuk aplikasi. Tidak diperlukan untuk aplikasi normal."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"target pintasan aksesibilitas"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Mengizinkan aplikasi menentukan target pintasan aksesibilitas."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Setel aturan sandi"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Mengontrol panjang dan karakter yang diizinkan dalam sandi dan PIN kunci layar."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Pantau upaya pembukaan kunci layar"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk menonaktifkan debugging USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Mode Tes Otomatis diaktifkan"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Lakukan reset ke setelan pabrik untuk menonaktifkan Mode Tes Otomatis."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Konsol serial diaktifkan"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Performa terpengaruh. Untuk menonaktifkan, periksa bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Cairan atau kotoran di port USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB otomatis dinonaktifkan. Ketuk untuk mempelajari lebih lanjut."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Boleh menggunakan port USB"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Belum dikategorikan"</string> <string name="importance_from_user" msgid="7318955817386549931">"Anda menyetel nilai penting notifikasi ini."</string> <string name="importance_from_person" msgid="9160133597262938296">"Ini penting karena orang-orang yang terlibat."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Izinkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baru dengan <xliff:g id="ACCOUNT">%2$s</xliff:g> (Pengguna dengan akun ini sudah ada) ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Izinkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baru dengan <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Tambahkan bahasa"</string> <string name="country_selection_title" msgid="2954859441620215513">"Preferensi wilayah"</string> <string name="search_language_hint" msgid="7042102592055108574">"Ketik nama bahasa"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 59cd4c165a50..558f4afa22c8 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Leyfir forriti að lesa og skrifa í grunnstillingu „Ónáðið ekki“."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"heimildanotkun upphafsyfirlits"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Leyfir handhafa að byrja heimildanotkun fyrir forrit. Ætti aldrei að þurfa fyrir venjuleg forrit."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"áfangastaður aðgengisflýtileiðar"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Leyfir forriti að skilgreina áfangastað aðgengisflýtileiðar."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Setja reglur um aðgangsorð"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Stjórna lengd og fjölda stafa í aðgangsorðum og PIN-númerum skjáláss."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Fylgjast með tilraunum til að taka skjáinn úr lás"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Veldu til að gera USB-villuleit óvirka."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Kveikt á stillingu prófunarvangs"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Núllstilltu til að slökkva á stillingu prófunarvangs."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Raðstjórnborð virkjað"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Þetta hefur áhrif á afköst. Athugaðu ræsiforritið ef þú vilt gera þetta óvirkt."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vökvi eða óhreinindi í USB-tengi"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-tengi er gert óvirkt sjálfkrafa. Ýttu til að fá frekari upplýsingar."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Óhætt að nota USB-tengi"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Óflokkað"</string> <string name="importance_from_user" msgid="7318955817386549931">"Þú stilltir mikilvægi þessara tilkynninga."</string> <string name="importance_from_person" msgid="9160133597262938296">"Þetta er mikilvægt vegna fólksins sem tekur þátt í þessu."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Viltu leyfa <xliff:g id="APP">%1$s</xliff:g> að stofna nýjan notanda með <xliff:g id="ACCOUNT">%2$s</xliff:g> (notandi með þennan reikning er þegar fyrir hendi)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Leyfa <xliff:g id="APP">%1$s</xliff:g> að stofna nýjan notanda með <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Bæta við tungumáli"</string> <string name="country_selection_title" msgid="2954859441620215513">"Svæðisval"</string> <string name="search_language_hint" msgid="7042102592055108574">"Sláðu inn heiti tungumáls"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index cbc99896202c..d0cded8fa33d 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Consente all\'app di leggere e modificare la configurazione della funzione Non disturbare."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"avvio dell\'uso dell\'autorizzazione di visualizzazione"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Consente al titolare di avviare l\'uso delle autorizzazioni per un\'app. Non dovrebbe essere mai necessaria per le normali applicazioni."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"target della scorciatoia Accessibilità"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Consente a un\'app di definire il target della scorciatoia Accessibilità"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Impostare regole per le password"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Controlla la lunghezza e i caratteri ammessi nelle password e nei PIN del blocco schermo."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitorare tentativi di sblocco dello schermo"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleziona per disattivare il debug USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modalità test harness attivata"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Ripristina le impostazioni di fabbrica per disattivare la modalità test harness."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Console seriale attivata"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Ci sono conseguenze sulle prestazioni. Per disattivare, seleziona il bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquidi o detriti nella porta USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"La porta USB viene disattivata automaticamente. Tocca per avere ulteriori informazioni."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Utilizzo porta USB consentito"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Senza categoria"</string> <string name="importance_from_user" msgid="7318955817386549931">"Stabilisci tu l\'importanza di queste notifiche."</string> <string name="importance_from_person" msgid="9160133597262938296">"Importante a causa delle persone coinvolte."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Consentire a <xliff:g id="APP">%1$s</xliff:g> di creare un nuovo utente con l\'account <xliff:g id="ACCOUNT">%2$s</xliff:g> (esiste già un utente con questo account)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Consentire a <xliff:g id="APP">%1$s</xliff:g> di creare un nuovo utente con l\'account <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Aggiungi una lingua"</string> <string name="country_selection_title" msgid="2954859441620215513">"Area geografica preferita"</string> <string name="search_language_hint" msgid="7042102592055108574">"Digita nome lingua"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 0a721a82ee2e..8b2b6257e19b 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -661,6 +661,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"מאפשר לאפליקציה לקרוא ולכתוב את התצורה של \'נא לא להפריע\'."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"התחלת צפייה בהרשאות השימוש"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"מאפשרת לבעלים להפעיל את השימוש בהרשאות עבור אפליקציה מסוימת. הרשאה זו אף פעם לא נדרשת עבור אפליקציות רגילות."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"קיצור דרך ליעד של פעולת נגישות"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"מאפשרת לאפליקציה להגדיר את קיצור הדרך ליעד של פעולת נגישות."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"הגדר כללי סיסמה"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"קביעת האורך הנדרש והתווים המותרים בסיסמאות ובקודי הגישה של מסך הנעילה."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"מעקב אחר ניסיונות לביטול של נעילת המסך"</string> @@ -1405,6 +1407,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"בחר להשבית ניפוי באגים ב-USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"מצב מסגרת בדיקה הופעל"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"כדי להשבית את מצב מסגרת בדיקה צריך לאפס להגדרות היצרן."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"קונסולה סדרתית מופעלת"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"קיימת השפעה על הביצועים. כדי להשבית, יש לבדוק את תוכנת האתחול."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"יש נוזלים או חלקיקים ביציאת ה-USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"יציאת ה-USB הושבתה באופן אוטומטי. יש להקיש לקבלת מידע נוסף."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ניתן להשתמש ביציאת ה-USB"</string> @@ -1958,10 +1962,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"ללא שיוך לקטגוריה"</string> <string name="importance_from_user" msgid="7318955817386549931">"עליך להגדיר את החשיבות של ההתראות האלה."</string> <string name="importance_from_person" msgid="9160133597262938296">"ההודעה חשובה בשל האנשים המעורבים."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"האם לאפשר לאפליקציה <xliff:g id="APP">%1$s</xliff:g> ליצור משתמש חדש באמצעות <xliff:g id="ACCOUNT">%2$s</xliff:g> (כבר קיים משתמש לחשבון הזה) ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"האם לאפשר לאפליקציה <xliff:g id="APP">%1$s</xliff:g> ליצור משתמש חדש באמצעות <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"הוספת שפה"</string> <string name="country_selection_title" msgid="2954859441620215513">"העדפת אזור"</string> <string name="search_language_hint" msgid="7042102592055108574">"הקלד שם שפה"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index fe45c1fa9486..39f05db96bcc 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"サイレント モード設定の読み取りと書き込みをアプリに許可します。"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"表示権限の使用の開始"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"アプリの権限使用の開始を所有者に許可します。通常のアプリでは不要です。"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ユーザー補助ショートカットのターゲット"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ユーザー補助ショートカットのターゲットの定義付けをアプリに許可します。"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"パスワードルールの設定"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"画面ロックのパスワードとPINの長さと使用できる文字を制御します。"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"画面ロック解除試行の監視"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USBデバッグを無効にする場合に選択します。"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"テストハーネス モード有効"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"出荷時設定にリセットしてテストハーネス モードを無効にしてください。"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"シリアル コンソールは有効です"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"シリアル コンソールを有効にすると、パフォーマンスに影響します。無効にするには、ブートローダーをチェックしてください。"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ポート内の液体やゴミ"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ポートが自動的に無効になりました。タップして詳細をご確認ください。"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ポートを安全に使用できます"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"カテゴリなし"</string> <string name="importance_from_user" msgid="7318955817386549931">"このような通知の重要度を設定します。"</string> <string name="importance_from_person" msgid="9160133597262938296">"関係するユーザーのため、この設定は重要です。"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> が <xliff:g id="ACCOUNT">%2$s</xliff:g> で新しいユーザーを作成できるようにしますか?(このアカウントのユーザーはすでに存在します)"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> が <xliff:g id="ACCOUNT">%2$s</xliff:g> で新しいユーザーを作成できるようにしますか?"</string> <string name="language_selection_title" msgid="2680677278159281088">"言語を追加"</string> <string name="country_selection_title" msgid="2954859441620215513">"地域設定"</string> <string name="search_language_hint" msgid="7042102592055108574">"言語名を入力"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 00afe0263bf5..2f216f9e64f0 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"საშუალებას აძლევს აპს, წაიკითხოს და დაწეროს კონფიგურაცია „არ შემაწუხოთ“."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"ნახვის ნებართვის გამოყენების დაწყება"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"მფლობელს საშუალებას აძლევს, დაიწყოს აპის ნებართვის გამოყენება. ჩვეულებრივი აპებისთვის არასოდეს უნდა იყოს საჭირო."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"მარტივი წვდომის მალსახმობის სამიზნე"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"აპს აძლევს მარტივი წვდომის მალსახმობის სამიზნის განსაზღვრის საშუალებას."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"პაროლის წესების დაყენება"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"აკონტროლეთ ეკრანის ბლოკირების პაროლებისა და PIN-ების სიმბოლოების სიგრძე."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"ეკრანის განბლოკვის მცდელობების მონიტორინგი"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"მონიშნეთ რათა შეწყვიტოთ USB-ის გამართვა"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"რეჟიმი „გარემო ტესტირებისთვის“ ჩართულია"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"დააბრუნეთ ქარხნული პარამეტრები „გარემო ტესტირებისთვის“ რეჟიმის გასათიშად."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"სერიული კონსოლი ჩართულია"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"მუშაობა შეფერხებულია. გასათიშად მონიშნეთ ჩამტვირთავი."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB პორტში აღმოჩენილია სითხე ან ჭუჭყი"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB პორტი ავტომატურად გათიშულია. შეეხეთ დამატებითი ინფორმაციისთვის."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"თანხმობა USB პორტის გამოყენებაზე"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"კატეგორიის გარეშე"</string> <string name="importance_from_user" msgid="7318955817386549931">"ამ შეტყობინებების მნიშვნელობის დონე განისაზღვრა თქვენ მიერ."</string> <string name="importance_from_person" msgid="9160133597262938296">"მნიშვნელოვანია ჩართული მომხმარებლების გამო."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"მიეცეს უფლება <xliff:g id="APP">%1$s</xliff:g>-ს <xliff:g id="ACCOUNT">%2$s</xliff:g>-ის მეშვეობით ახალი მომხმარებელი შექმნას (ამ ანგარიშის მქონე მომხმარებელი უკვე არსებობს)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"მიეცეს უფლება <xliff:g id="APP">%1$s</xliff:g>-ს <xliff:g id="ACCOUNT">%2$s</xliff:g>-ის მეშვეობით ახალი მომხმარებელი შექმნას?"</string> <string name="language_selection_title" msgid="2680677278159281088">"ენის დამატება"</string> <string name="country_selection_title" msgid="2954859441620215513">"რეგიონის პარამეტრები"</string> <string name="search_language_hint" msgid="7042102592055108574">"აკრიფეთ ენის სახელი"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 81f512b6a011..8fb6eb7bf6f4 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Қолданбаға «Мазаламау» конфигурациясын оқу және жазу мүмкіндігін береді."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"рұқсаттарды пайдалану туралы деректерді көру"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Пайдаланушы қолданбаға берілетін рұқсаттарды басқара алады. Ондай рұқсаттар әдеттегі қолданбаларға керек емес."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"арнайы мүмкіндіктер таңбашасының мақсаты"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Қолданбаға арнайы мүмкіндіктер таңбашасының мақсатын анықтауға мүмкіндік береді."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Құпия сөз ережелерін тағайындау"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Экран бекітпесінің құпия сөздерінің және PIN кодтарының ұзындығын және оларда рұқсат етілген таңбаларды басқару."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Экран құлпын ашу әркеттерін бақылау"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB түзетуін өшіру үшін таңдаңыз."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Сынақ бағдарламасы режимі қосылды"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Сынақ бағдарламасы режимін өшіру үшін зауыттық күйіне қайтарыңыз."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Сериялық консоль қосылды"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Өнімділікке әсер етеді. Өшіру үшін жүктегішті тексеріңіз."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB портына сұйықтық немесе қоқыс кірді"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порты автоматты түрде өшірілді. Толығырақ ақпарат алу үшін түртіңіз."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB портын пайдалана беруге болады"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Санатқа жатқызылмаған"</string> <string name="importance_from_user" msgid="7318955817386549931">"Сіз осы хабарландырулардың маңыздылығын орнатасыз."</string> <string name="importance_from_person" msgid="9160133597262938296">"Қатысты адамдарға байланысты бұл маңызды."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> қолданбасына <xliff:g id="ACCOUNT">%2$s</xliff:g> есептік жазбасы бар жаңа пайдаланушы (мұндай есептік жазбаға ие пайдаланушы бұрыннан бар) жасауға рұқсат етілсін бе?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> қолданбасына <xliff:g id="ACCOUNT">%2$s</xliff:g> есептік жазбасы бар жаңа пайдаланушы жасауға рұқсат етілсін бе?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Тілді қосу"</string> <string name="country_selection_title" msgid="2954859441620215513">"Аймақ параметрі"</string> <string name="search_language_hint" msgid="7042102592055108574">"Тіл атауын теріңіз"</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 539747b9652b..6355289eead2 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"អនុញ្ញាតឲ្យកម្មវិធីអាន និងសរសេរការកំណត់រចនាសម្ព័ន្ធមុខងារ កុំរំខាន។"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"ចាប់ផ្ដើមមើលការប្រើប្រាស់ការអនុញ្ញាត"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"អនុញ្ញាតឱ្យម្ចាស់ចាប់ផ្ដើមការប្រើប្រាស់ការអនុញ្ញាតសម្រាប់កម្មវិធី។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"គោលដៅផ្លូវកាត់ភាពងាយស្រួល"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"អនុញ្ញាតឱ្យកម្មវិធីកំណត់គោលដៅផ្លូវកាត់ភាពងាយស្រួល។"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"កំណត់ក្បួនពាក្យសម្ងាត់"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"គ្រប់គ្រងប្រវែង និងតួអក្សរដែលអនុញ្ញាតឲ្យប្រើក្នុងពាក្យសម្ងាត់ និងលេខសម្ងាត់ចាក់សោអេក្រង់។"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"តាមដានការព្យាយាមដោះសោអេក្រង់"</string> @@ -1363,6 +1365,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ជ្រើសរើស ដើម្បីបិទការកែកំហុសតាម USB ។"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"បានបើកមុខងារប្រមូលធ្វើតេស្ត"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ធ្វើការកំណត់ដូចដើមឡើងវិញ ដើម្បីបិទមុខងារប្រមូលធ្វើតេស្ត។"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"កុងសូលស៊េរីត្រូវបានបើក"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"ប្រតិបត្តិការទទួលរងការប៉ះពាល់។ សូមពិនិត្យមើលកម្មវិធីដំណើរការប្រព័ន្ធ ដើម្បីបិទ។"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"មានទឹក ឬកម្ទេចផ្សេងៗនៅក្នុងរន្ធ USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"រន្ធ USB ត្រូវបានបិទដោយស្វ័យប្រវត្តិ។ សូមចុចដើម្បីស្វែងយល់បន្ថែម។"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"អាចប្រើរន្ធ USB បាន"</string> @@ -1892,10 +1896,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"មិនបែងចែកប្រភេទ"</string> <string name="importance_from_user" msgid="7318955817386549931">"អ្នកបានកំណត់សារៈសំខាន់នៃការជូនដំណឹងទាំងនេះ"</string> <string name="importance_from_person" msgid="9160133597262938296">"វាមានសារៈសំខាន់ដោយសារតែមនុស្សដែលពាក់ព័ន្ធ"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"អនុញ្ញាតឱ្យ <xliff:g id="APP">%1$s</xliff:g> បង្កើតអ្នកប្រើប្រាស់ថ្មីដោយប្រើ <xliff:g id="ACCOUNT">%2$s</xliff:g> (អ្នកប្រើប្រាស់ដែលមានគណនីនេះមានរួចហើយ) ដែរឬទេ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"អនុញ្ញាតឱ្យ <xliff:g id="APP">%1$s</xliff:g> បង្កើតអ្នកប្រើប្រាស់ថ្មីដោយប្រើ <xliff:g id="ACCOUNT">%2$s</xliff:g> ដែរឬទេ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"បន្ថែមភាសា"</string> <string name="country_selection_title" msgid="2954859441620215513">"ចំណូលចិត្តតំបន់"</string> <string name="search_language_hint" msgid="7042102592055108574">"វាយបញ្ចូលឈ្មោះភាសា"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index c7d0feae9b34..7802129b580c 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಓದಲು ಮತ್ತು ಬರೆಯಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"ವೀಕ್ಷಣಾ ಅನುಮತಿಯ ಬಳಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಿ"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ಆ್ಯಪ್ಗಾಗಿ ಅನುಮತಿ ಬಳಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಸಾಮಾನ್ಯ ಆ್ಯಪ್ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್ಕಟ್ ಟಾರ್ಗೆಟ್"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್ಕಟ್ ಟಾರ್ಗೆಟ್ ಅನ್ನು ವಿವರಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"ಪಾಸ್ವರ್ಡ್ ನಿಮಯಗಳನ್ನು ಹೊಂದಿಸಿ"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"ಪರದೆ ಲಾಕ್ನಲ್ಲಿನ ಪಾಸ್ವರ್ಡ್ಗಳು ಮತ್ತು ಪಿನ್ಗಳ ಅನುಮತಿಸಲಾದ ಅಕ್ಷರಗಳ ಪ್ರಮಾಣವನ್ನು ನಿಯಂತ್ರಿಸಿ."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"ಪರದೆಯ ಅನ್ಲಾಕ್ ಪ್ರಯತ್ನಗಳನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"ಸ್ವಯಂ ಪರೀಕ್ಷೆಯಾಗುವಿಕೆ ಮೋಡ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ಸ್ವಯಂ ಪರೀಕ್ಷೆಯಾಗುವಿಕೆ ಮೋಡ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಫ್ಯಾಕ್ಟರಿ ರಿಸೆಟ್ ಮಾಡಬೇಕು."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"ಸರಣಿ ಕನ್ಸೋಲ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"ಕಾರ್ಯಕ್ಷಮತೆಯ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರುತ್ತದೆ. ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು, ಬೂಟ್ಲೋಡರ್ ಅನ್ನು ಪರಿಶೀಲಿಸಿ."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ಪೋರ್ಟ್ನಲ್ಲಿ ದ್ರವ ಅಥವಾ ಧೂಳಿನ ಕಣಗಳಿವೆ"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ಪೋರ್ಟ್ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ಪೋರ್ಟ್ ಬಳಸಲು ಸರಿ ಅನ್ನು ಆಯ್ಕೆ ಮಾಡಿ"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"ವರ್ಗೀಕರಿಸದಿರುವುದು"</string> <string name="importance_from_user" msgid="7318955817386549931">"ನೀವು ಈ ಅಧಿಸೂಚನೆಗಳ ಪ್ರಾಮುಖ್ಯತೆಯನ್ನು ಹೊಂದಿಸಿರುವಿರಿ."</string> <string name="importance_from_person" msgid="9160133597262938296">"ಜನರು ತೊಡಗಿಕೊಂಡಿರುವ ಕಾರಣ ಇದು ಅತ್ಯಂತ ಪ್ರಮುಖವಾಗಿದೆ."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> (ಈ ಖಾತೆಯ ಬಳಕೆದಾರರು ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿದ್ದಾರೆ) ಮೂಲಕ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲು <xliff:g id="APP">%1$s</xliff:g> ಗೆ ಅನುಮತಿಸಬೇಕೆ ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> ಮೂಲಕ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲು <xliff:g id="APP">%1$s</xliff:g> ಗೆ ಅನುಮತಿಸುವುದೇ ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"ಭಾಷೆ ಸೇರಿಸಿ"</string> <string name="country_selection_title" msgid="2954859441620215513">"ಪ್ರದೇಶ ಪ್ರಾಶಸ್ತ್ಯ"</string> <string name="search_language_hint" msgid="7042102592055108574">"ಭಾಷೆ ಹೆಸರನ್ನು ಟೈಪ್ ಮಾಡಿ"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index c0dd8b127514..72302c3cdf11 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"앱에서 방해 금지 모드 설정을 읽고 작성하도록 허용합니다."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"권한 사용 보기 시작"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"앱의 권한 사용을 시작하려면 보유자를 허용하세요. 일반 앱에는 필요하지 않습니다."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"접근성 단축키 대상"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"앱이 접근성 단축키 대상을 정의할 수 있도록 허용합니다."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"비밀번호 규칙 설정"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"화면 잠금 비밀번호와 PIN에 허용되는 길이와 문자 수를 제어합니다."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"화면 잠금 해제 시도 모니터링"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB 디버깅을 사용하지 않으려면 선택합니다."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"테스트 하네스 모드 사용 설정됨"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"테스트 하네스 모드를 사용 중지하려면 초기화하세요."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"시리얼 콘솔 사용 설정됨"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"성능에 영향을 미쳤습니다. 사용 중지하려면 부트로더를 확인하세요."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 포트에서 액체 또는 이물질 감지됨"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 포트가 자동으로 사용 중지되었습니다. 자세한 내용을 보려면 탭하세요."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB 포트를 사용해도 좋음"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"지정된 카테고리 없음"</string> <string name="importance_from_user" msgid="7318955817386549931">"이러한 알림의 중요도를 설정했습니다."</string> <string name="importance_from_person" msgid="9160133597262938296">"관련된 사용자가 있으므로 중요합니다."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>에서 <xliff:g id="ACCOUNT">%2$s</xliff:g> 계정으로 신규 사용자를 만들도록 허용하시겠습니까? 이 계정으로 등록된 사용자가 이미 존재합니다."</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>에서 <xliff:g id="ACCOUNT">%2$s</xliff:g> 계정으로 신규 사용자를 만들도록 허용하시겠습니까?"</string> <string name="language_selection_title" msgid="2680677278159281088">"언어 추가"</string> <string name="country_selection_title" msgid="2954859441620215513">"지역 환경설정"</string> <string name="search_language_hint" msgid="7042102592055108574">"언어 이름 입력"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 91825630f34e..09ee99c1eb4f 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Колдонмого \"Тынчымды алба\" режиминин конфигурациясын окуу жана жазуу мүмкүнчүлүгүн берет."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"уруксаттын колдонулушун көрүп баштоо"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Колдонмонун пайдаланылышына уруксат берүүгө мүмкүнчүлүк берет. Кадимки колдонмолорго эч качан талап кылынбашы керек."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"максаттуу атайын мүмкүнчүлүк аракетине кыска жол"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Колдонмого максаттуу атайын мүмкүнчүлүк аракетине кыска жолду аныктоого уруксат берет."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Сырсөз эрежелерин коюу"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Экран кулпусунун сырсөздөрү менен PIN\'дерине уруксат берилген узундук менен белгилерди көзөмөлдөө."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Экран кулпусун ачуу аракеттерин көзөмөлдөө"</string> @@ -1363,6 +1365,8 @@ <skip /> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Сыноо программасынын режими иштетилди"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Сыноо программасынын режимин өчүрүү үчүн, баштапкы жөндөөлөргө кайтарыңыз."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Сериялык консоль иштетилди"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Майнаптуулугуна таасири тиет. Аны өчүрүү үчүн операциялык тутумду жүктөгүчтү текшериңиз."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB портунда суюктук же урандылар бар"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порт автоматтык түрдө өчүрүлдү. Кененирээк маалымат алуу үчүн таптап коюңуз."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB портун колдонууга болот"</string> @@ -1892,10 +1896,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Категорияларга бөлүнгөн эмес"</string> <string name="importance_from_user" msgid="7318955817386549931">"Бул эскертмелердин маанилүүлүгүн белгиледиңиз."</string> <string name="importance_from_person" msgid="9160133597262938296">"Булар сиз үчүн маанилүү адамдар."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> колдонмосуна <xliff:g id="ACCOUNT">%2$s</xliff:g> аккаунту менен жаңы колдонуучу түзүүгө уруксат бересизби (мындай аккаунту бар колдонуучу мурунтан эле бар)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> колдонмосуна <xliff:g id="ACCOUNT">%2$s</xliff:g> аккаунту менен жаңы колдонуучу түзүүгө уруксат бересизби?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Тил кошуу"</string> <string name="country_selection_title" msgid="2954859441620215513">"Чөлкөмдүк жөндөөлөр"</string> <string name="search_language_hint" msgid="7042102592055108574">"Тилди киргизиңиз"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 0189c081b2b8..00bfc0ea9226 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"ອະນຸຍາດໃຫ້ແອັບອ່ານ ແລະຂຽນການກນຳດຄ່າ ບໍ່ລົບກວນ."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"ເລີ່ມການໃຊ້ສິດອະນຸຍາດການເບິ່ງ"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ອະນຸຍາດໃຫ້ຜູ້ຖືເລີ່ມການໃຊ້ສິດອະນຸຍາດສຳລັບແອັບໃດໜຶ່ງໄດ້. ແອັບປົກກະຕິບໍ່ຄວນຕ້ອງໃຊ້."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ເປົ້າໝາຍທາງລັດການຊ່ວຍເຂົ້າເຖິງ"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ອະນຸຍາດໃຫ້ແອັບລະບຸເປົ້າໝາຍທາງລັດການຊ່ວຍເຂົ້າເຖິງ."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"ຕັ້ງຄ່າກົດຂອງລະຫັດຜ່ານ"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"ຄວບຄຸມຄວາມຍາວ ແລະຕົວອັກສອນທີ່ອະນຸຍາດໃຫ້ຢູ່ໃນລະຫັດລັອກໜ້າຈໍ ແລະ PIN."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"ຕິດຕາມການພະຍາຍາມປົດລັອກໜ້າຈໍ"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ເລືອກເພື່ອປິດການດີບັ໊ກຜ່ານ USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"ເປີດໃຊ້ໂໝດ Test Harness ແລ້ວ"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ດຳເນີນການຣີເຊັດເປັນຄ່າຈາກໂຮງງານເພື່ອປິດການນຳໃຊ້ໂໝດ Test Harness."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"ເປີດນຳໃຊ້ຊີຣຽວຄອນໂຊແລ້ວ"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"ມີຜົນກະທົບກັບປະສິດທິພາບ. ເພື່ອປິດການນຳໃຊ້, ໃຫ້ກວດສອບ bootloader ເບິ່ງ."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ມີຂອງແຫລວ ຫຼື ເສດດິນໃນຜອດ USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"ປິດຜອດ USB ໂດຍອັດຕະໂນມັດແລ້ວ. ແຕະເພື່ອສຶກສາເພີ່ມເຕີມ."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ສາມາດໃຊ້ຜອດ USB ໄດ້"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"ບໍ່ມີໝວດໝູ່"</string> <string name="importance_from_user" msgid="7318955817386549931">"ທ່ານຕັ້ງຄວາມສຳຄັນຂອງການແຈ້ງເຕືອນເຫຼົ່ານີ້."</string> <string name="importance_from_person" msgid="9160133597262938296">"ຂໍ້ຄວາມນີ້ສຳຄັນເນື່ອງຈາກບຸກຄົນທີ່ກ່ຽວຂ້ອງ."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"ອະນຸຍາດໃຫ້ <xliff:g id="APP">%1$s</xliff:g> ສ້າງຜູ້ໃຊ້ໃໝ່ກັບ <xliff:g id="ACCOUNT">%2$s</xliff:g> ໄດ້ບໍ່ (ມີຜູ້ໃຊ້ທີ່ໃຊ້ບັນຊີນີ້ຢູ່ກ່ອນແລ້ວ) ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"ອະນຸຍາດໃຫ້ <xliff:g id="APP">%1$s</xliff:g> ສ້າງຜູ້ໃຊ້ໃໝ່ກັບ <xliff:g id="ACCOUNT">%2$s</xliff:g> ໄດ້ບໍ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"ເພີ່ມພາສາ"</string> <string name="country_selection_title" msgid="2954859441620215513">"ການຕັ້ງຄ່າພາກພື້ນ"</string> <string name="search_language_hint" msgid="7042102592055108574">"ພິມຊື່ພາສາ"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 0d29c84f6560..b615b247b7c9 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -661,6 +661,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Leidžiama programai skaityti ir rašyti „Do Not Disturb“ konfigūraciją."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"pradėti peržiūrėti leidimo naudojimą"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Leidžia savininkui pradėti naudoti programos leidimą. Įprastoms programoms to neturėtų prireikti."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"pritaikomumo sparčiojo klavišo tikslas"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Programai leidžiama apibrėžti pritaikomumo sparčiojo klavišo tikslą."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Nustatyti slaptažodžio taisykles"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Valdykite, kokio ilgio ekrano užrakto slaptažodžius ir PIN kodus galima naudoti."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Stebėti bandymus atrakinti ekraną"</string> @@ -1405,6 +1407,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pasirinkite, kas išjungtumėte USB derinimą."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Testavimo sistemos režimas įgalintas"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Atkurkite gamyklinius duomenis, kad išjungtumėte testavimo sistemos režimą."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Serijos pultas įgalintas"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Našumas paveiktas. Norėdami išjungti, patikrinkite paleidyklę."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB prievade yra skysčių ar smulkių dalelių"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB prievadas automatiškai išjungtas. Palieskite, kad sužinotumėte daugiau."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Saugu naudoti USB prievadą"</string> @@ -1958,10 +1962,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Be kategorijos"</string> <string name="importance_from_user" msgid="7318955817386549931">"Galite nustatyti šių pranešimų svarbą."</string> <string name="importance_from_person" msgid="9160133597262938296">"Tai svarbu dėl susijusių žmonių."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Leisti „<xliff:g id="APP">%1$s</xliff:g>“ kurti naują <xliff:g id="ACCOUNT">%2$s</xliff:g> naudotoją (šią paskyrą naudojantis naudotojas jau yra)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Leisti „<xliff:g id="APP">%1$s</xliff:g>“ kurti naują <xliff:g id="ACCOUNT">%2$s</xliff:g> naudotoją?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Pridėkite kalbą"</string> <string name="country_selection_title" msgid="2954859441620215513">"Regiono nuostata"</string> <string name="search_language_hint" msgid="7042102592055108574">"Įveskite kalbos pav."</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 2547ba92f9c5..acc14304e487 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -658,6 +658,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Ļauj lietotnei lasīt un rakstīt režīma “Netraucēt” konfigurāciju."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"Datu skatīšana par izmantojamajām atļaujām"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Ļauj atļaujas īpašniekam sākt lietotnes atļauju izmantošanu. Parastām lietotnēm tas nekad nav nepieciešams."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"pieejamības īsinājumtaustiņa mērķis"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Ļauj lietotnei definēt pieejamības īsinājumtaustiņa mērķi."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Paroles kārtulu iestatīšana"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolēt ekrāna bloķēšanas paroļu un PIN garumu un tajos atļautās rakstzīmes."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Ekrāna atbloķēšanas mēģinājumu pārraudzīšana"</string> @@ -1383,6 +1385,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Atlasiet, lai atspējotu USB atkļūdošanu."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Drošības pārbaudes režīms ir iespējots"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Lai atspējotu drošības pārbaudes režīmu, veiciet rūpnīcas datu atiestatīšanu."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Seriālā konsole ir iespējota"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Tiek ietekmēta veiktspēja. Lai atspējotu, pārbaudiet operētājsistēmu ielādes rīku."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB pieslēgvietā ir šķidrums vai daļiņas"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB pieslēgvieta ir automātiski atspējota. Pieskarieties, lai uzzinātu vairāk."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB pieslēgvietu drīkst izmantot"</string> @@ -1924,10 +1928,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Nav kategorijas"</string> <string name="importance_from_user" msgid="7318955817386549931">"Jūs iestatījāt šo paziņojumu svarīguma līmeni."</string> <string name="importance_from_person" msgid="9160133597262938296">"Tas ir svarīgi iesaistīto personu dēļ."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Vai atļaut lietotnei <xliff:g id="APP">%1$s</xliff:g> izveidot jaunu lietotāju, izmantojot e-pasta adresi <xliff:g id="ACCOUNT">%2$s</xliff:g> (lietotājs ar šādu kontu jau pastāv)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Vai atļaut lietotnei <xliff:g id="APP">%1$s</xliff:g> izveidot jaunu lietotāju, izmantojot e-pasta adresi <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Pievienot valodu"</string> <string name="country_selection_title" msgid="2954859441620215513">"Reģiona preference"</string> <string name="search_language_hint" msgid="7042102592055108574">"Ierakstiet valodas nosaukumu"</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 9949eaa7ce7b..761d965d3cf2 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Дозволува апликацијата да чита и пишува конфигурација Не вознемирувај."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"започнете со користење на дозволата за приказ"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Дозволува сопственикот да почне со користење на дозволата за апликација. Не треба да се користи за стандардни апликации."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"цел на кратенката за пристапност"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Дозволува апликација да ја дефинира целта на кратенката за пристап."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Постави правила за лозинката"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Контролирај ги должината и знаците што се дозволени за лозинки и PIN-броеви за отклучување екран."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Следи ги обидите за отклучување на екранот"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете за да се оневозможи отстранување грешки на USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Овозможен е режимот на рамка за тестирање"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Извршете фабричко ресетирање за да го оневозможите режимот на рамка за тестирање."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Сериската конзола е овозможена"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Перформансите се засегнати. За да оневозможите, проверете го подигнувачот."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или нечистотија во USB-портата"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-портата е автоматски оневозможена. Допрете за да дознаете повеќе."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Во ред е да се користи USB-порта"</string> @@ -1893,10 +1897,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Некатегоризирано"</string> <string name="importance_from_user" msgid="7318955817386549931">"Ја поставивте важноста на известувањава."</string> <string name="importance_from_person" msgid="9160133597262938296">"Ова е важно заради луѓето кои се вклучени."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Дозволувате <xliff:g id="APP">%1$s</xliff:g> да создаде нов корисник со <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Веќе постои корисник со оваа сметка.)"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Дозволувате <xliff:g id="APP">%1$s</xliff:g> да создаде нов корисник со <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Додај јазик"</string> <string name="country_selection_title" msgid="2954859441620215513">"Претпочитувања за регион"</string> <string name="search_language_hint" msgid="7042102592055108574">"Внеси име на јазик"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index f71115806013..7876c2972e95 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"\'ശല്യപ്പെടുത്തരുത്\' കോൺഫിഗറേഷൻ വായിക്കുന്നതിനും എഴുതുന്നതിനും ആപ്പിനെ അനുവദിക്കുന്നു."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"അനുമതി ഉപയോഗം കാണാൻ ആരംഭിക്കുക"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ഒരു ആപ്പിനുള്ള അനുമതി ഉപയോഗം ആരംഭിക്കാൻ ഹോൾഡറിനെ അനുവദിക്കുന്നു. സാധാരണ ആപ്പുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ഉപയോഗസഹായി കുറുക്കുവഴിയുടെ ടാർഗറ്റ്"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ഉപയോഗസഹായി കുറുക്കുവഴിയുടെ ടാർഗറ്റ് നിർവ്വചിക്കാൻ ആപ്പിനെ അനുവദിക്കുക."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"പാസ്വേഡ് നിയമങ്ങൾ സജ്ജീകരിക്കുക"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"സ്ക്രീൻ ലോക്ക് പാസ്വേഡുകളിലും PIN-കളിലും അനുവദിച്ചിരിക്കുന്ന ദൈർഘ്യവും പ്രതീകങ്ങളും നിയന്ത്രിക്കുക."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"സ്ക്രീൻ അൺലോക്ക് ശ്രമങ്ങൾ നിരീക്ഷിക്കുക"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ഡീബഗ്ഗുചെയ്യൽ പ്രവർത്തനരഹിതമാക്കാൻ തിരഞ്ഞെടുക്കുക."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"പരിശോധനാ സംവിധാനങ്ങൾ മോഡ് പ്രവർത്തനക്ഷമമാക്കി"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"പരിശോധനാ സംവിധാന മോഡ് പ്രവർത്തനരഹിതമാക്കാൻ ഫാക്ടറി പുനഃക്രമീകരണം നിർവഹിക്കുക."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"സീരിയൽ കൺസോൾ പ്രവർത്തനക്ഷമമാക്കി"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"പ്രകടനത്തെ ബാധിച്ചു. പ്രവർത്തനരഹിതമാക്കാൻ, ബൂട്ട് ലോഡർ പരിശോധിക്കുക."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB പോർട്ടിൽ ദ്രാവകമോ പൊടിയോ കണ്ടെത്തി"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB പോർട്ടർ സ്വയമേവ പ്രവർത്തനരഹിതമായി. കൂടുതലറിയാൻ ടാപ്പ് ചെയ്യുക."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ഇനി USB പോർട്ട് ഉപയോഗിക്കാം"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"വർഗ്ഗീകരിച്ചിട്ടില്ലാത്ത"</string> <string name="importance_from_user" msgid="7318955817386549931">"ഈ അറിയിപ്പുകളുടെ പ്രാധാന്യം നിങ്ങൾ സജ്ജീകരിച്ചു."</string> <string name="importance_from_person" msgid="9160133597262938296">"ഉൾപ്പെട്ടിട്ടുള്ള ആളുകളെ കണക്കിലെടുക്കുമ്പോള് ഇത് പ്രധാനപ്പെട്ടതാണ്."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> എന്ന അക്കൗണ്ട് (ഈ അക്കൗണ്ട് ഉപയോഗിക്കുന്ന ഒരു ഉപയോക്താവ് നിലവിലുണ്ട്) ഉപയോഗിച്ച് പുതിയ ഉപയോക്താവിനെ സൃഷ്ടിക്കാൻ <xliff:g id="APP">%1$s</xliff:g> എന്നതിനെ അനുവദിക്കണോ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> എന്ന അക്കൗണ്ട് ഉപയോഗിച്ച് പുതിയ ഉപയോക്താവിനെ സൃഷ്ടിക്കാൻ <xliff:g id="APP">%1$s</xliff:g> എന്നതിനെ അനുവദിക്കണോ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"ഒരു ഭാഷ ചേർക്കുക"</string> <string name="country_selection_title" msgid="2954859441620215513">"മേഖലാ മുൻഗണന"</string> <string name="search_language_hint" msgid="7042102592055108574">"ഭാഷയുടെ പേര് ടൈപ്പുചെയ്യുക"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 75700287a2fa..1a474038d7ca 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Апп-д Бүү саад бол тохируулгыг уншиж, бичихийг зөвшөөрөх"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"зөвшөөрлийн ашиглалтыг харж эхлэх"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Эзэмшигчид аппын зөвшөөрлөө ашиглаж эхлэхийг зөвшөөрдөг. Энгийн аппуудад шаардлагагүй."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"хандалтын товчлолын зорилт"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Аппад хандалтын товчлолын зорилтыг тодорхойлохыг зөвшөөрдөг."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Нууц үгний дүрмийг тохируулах"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Дэлгэц түгжих нууц үг болон ПИН кодны урт болон нийт тэмдэгтийн уртыг хянах."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Дэлгэцийн түгжээг тайлах оролдлогыг хянах"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB дебаг хийхийг идэвхгүй болгох бол сонгоно уу."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Туршилтын цогц горимыг идэвхжүүлсэн"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Туршилтын цогц горимыг идэвхгүй болгохын тулд үйлдвэрийн төлөвт шинэчилнэ үү."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Цуваа консолыг идэвхжүүлсэн"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Гүйцэтгэлд нөлөөлнө. Идэвхгүй болгохын тулд эхэлж ачаалагчийг шалгана уу."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB порт дээрх шингэн зүйл эсвэл бохирдол"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB портыг автоматаар идэвхгүй болгосон байна. Дэлгэрэнгүй мэдээлэл авахын тулд товшино уу."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB портыг ашиглахад зүгээр"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Ангилаагүй"</string> <string name="importance_from_user" msgid="7318955817386549931">"Та эдгээр мэдэгдлийн ач холбогдлыг тогтоосон."</string> <string name="importance_from_person" msgid="9160133597262938296">"Оролцсон хүмүүсээс шалтгаалан энэ нь өндөр ач холбогдолтой."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>-д <xliff:g id="ACCOUNT">%2$s</xliff:g>-тай (ийм бүртгэлтэй хэрэглэгч аль хэдийн байна) шинэ хэрэглэгч үүсгэхийг зөвшөөрөх үү ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>-д <xliff:g id="ACCOUNT">%2$s</xliff:g>-тай шинэ хэрэглэгч үүсгэхийг зөвшөөрөх үү?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Хэл нэмэх"</string> <string name="country_selection_title" msgid="2954859441620215513">"Бүс нутгийн тохиргоо"</string> <string name="search_language_hint" msgid="7042102592055108574">"Улсын хэлийг бичнэ үү"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index e22bca049ece..05638dfb4c61 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"व्यत्यय आणू नका कॉन्फिगरेशन वाचण्यासाठी आणि लिहिण्यासाठी अॅपला अनुमती देते."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"व्ह्यू परवानगी वापर सुरू करा"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"धारकास अॅपसाठी परवानगी वापरणे सुरू करण्याची अनुमती देते. सामान्य अॅप्ससाठी कधीही आवश्यकता नसते."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"अॅक्सेसिबिलिटी शॉर्टकट लक्ष्य"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"अॅपला अॅक्सेसिबिलिटी शॉर्टकट लक्ष्याबद्दल सांगण्यासाठी अनुमती द्या."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करा"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"स्क्रीन लॉक पासवर्ड आणि पिन मध्ये अनुमती दिलेले लांबी आणि वर्ण नियंत्रित करा."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"स्क्रीन अनलॉक प्रयत्नांचे परीक्षण करा"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डीबगिंग बंद करण्यासाठी निवडा."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"टेस्ट हार्नेस मोड सुरू केला आहे"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"टेस्ट हार्नेस मोड बंद करण्यासाठी फॅक्टरी रीसेट करा."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"सिरीअल कन्सोल सुरू केला आहे"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"परफॉर्मन्सवर परिणाम होतो. बंद करण्यासाठी, बूटलोडर तपासा."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB पोर्ट मध्ये ओलावा किंवा धूळ आहे"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB पोर्ट आपोआप बंद होईल. अधिक जाणून घेण्यासाठी टॅप करा."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB पोर्ट वापरण्यासाठी ठीक आहे"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"वर्गीकरण न केलेले"</string> <string name="importance_from_user" msgid="7318955817386549931">"तुम्ही या सूचनांचे महत्त्व सेट केले."</string> <string name="importance_from_person" msgid="9160133597262938296">"सामील असलेल्या लोकांमुळे हे महत्वाचे आहे."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> सह नवीन वापरकर्ता तयार करण्याची (हे खाते असलेला वापरकर्ता आधीपासून अस्तित्वात आहे) <xliff:g id="APP">%1$s</xliff:g> ला अनुमती द्यायची आहे का?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> सह नवीन वापरकर्ता तयार करण्याची <xliff:g id="APP">%1$s</xliff:g> ला अनुमती द्यायची आहे का?"</string> <string name="language_selection_title" msgid="2680677278159281088">"एक भाषा जोडा"</string> <string name="country_selection_title" msgid="2954859441620215513">"प्रदेश प्राधान्य"</string> <string name="search_language_hint" msgid="7042102592055108574">"भाषा नाव टाइप करा"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 35e36587ad9c..d5c5475c879a 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Membenarkan apl membaca dan menulis konfigurasi Jangan Ganggu."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"mulakan lihat penggunaan kebenaran"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Membenarkan pemegang memulakan penggunaan kebenaran untuk apl. Tidak sekali-kali diperlukan untuk apl biasa."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"sasaran pintasan kebolehaksesan"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Membenarkan apl mentakrifkan sasaran pintasan kebolehaksesan."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Tetapkan peraturan kata laluan"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Mengawal panjang dan aksara yang dibenarkan dalam kata laluan dan PIN kunci skrin."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Pantau percubaan buka kunci skrin"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk melumpuhkan penyahpepijatan USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Mod Abah-abah Ujian didayakan"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Laksanakan tetapan semula kilang untuk melumpuhkan Mod Abah-abah Ujian."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Konsol bersiri didayakan"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Prestasi terjejas. Untuk melumpuhkan, semak pemuat but."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Cecair atau serpihan dalam port USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB dilumpuhkan secara automatik. Ketik untuk mengetahui lebih lanjut."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK untuk menggunakan port USB"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Tidak dikategorikan"</string> <string name="importance_from_user" msgid="7318955817386549931">"Anda menetapkan kepentingan pemberitahuan ini."</string> <string name="importance_from_person" msgid="9160133597262938296">"Mesej ini penting disebabkan orang yang terlibat."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Benarkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baharu dengan <xliff:g id="ACCOUNT">%2$s</xliff:g> (Pengguna dengan akaun ini sudah wujud) ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Benarkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baharu dengan <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Tambahkan bahasa"</string> <string name="country_selection_title" msgid="2954859441620215513">"Pilihan wilayah"</string> <string name="search_language_hint" msgid="7042102592055108574">"Taipkan nama bahasa"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index d69b7d1fcbbb..55061661c330 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"မနှောင့်ယှက်ရန် ချိန်ညှိမှုကို အပ်ဖ်များ ဖတ်ခြင်း ပြင်ခြင်းပြုလုပ်နိုင်ရန် ခွင့်ပြုမည်။"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"အစမြင်ကွင်း ခွင့်ပြုချက် အသုံးပြုမှု"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"အက်ပ်တစ်ခုအတွက် ခွင့်ပြုချက်စတင်အသုံးပြုမှုကို ကိုင်ဆောင်သူအား ခွင့်ပြုသည်။ ပုံမှန်အက်ပ်များအတွက် ဘယ်သောအခါမျှ မလိုအပ်ပါ။"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"အများသုံးစွဲနိုင်မှု ဖြတ်လမ်းလင့်ခ် ပစ်မှတ်"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"အများသုံးစွဲနိုင်မှု ဖြတ်လမ်းလင့်ခ် ပစ်မှတ်ကို အက်ပ်အား သတ်မှတ်ခွင့်ပြုသည်။"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"စကားဝှက်စည်းမျဥ်းကိုသတ်မှတ်ရန်"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"မျက်နှာပြင်သော့ခတ်သည့် စကားဝှက်များနှင့် PINများရှိ ခွင့်ပြုထားသည့် စာလုံးအရေအတွက်နှင့် အက္ခရာများအား ထိန်းချုပ်ရန်။"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"မျက်နှာပြင်လော့ခ်ဖွင့်ရန် ကြိုးပမ်းမှုများကို စောင့်ကြည့်ပါ"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ဖြင့် အမှားရှာပြင်ခြင်းကို ပိတ်ရန် ရွေးပါ။"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"\'စမ်းသပ်ခြင်းစနစ်မုဒ်\' ဖွင့်ထားသည်"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"\'စမ်းသပ်ခြင်းစနစ် မုဒ်\' ကိုပိတ်ရန် စက်ရုံထုတ်အတိုင်း ပြင်ဆင်သတ်မှတ်ပါ။"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"အမှတ်စဉ် ကွန်ဆိုးလ်ကို ဖွင့်ထားသည်"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"စွမ်းဆောင်ရည်အပေါ် သက်ရောက်မှုရှိနိုင်ပါသည်။ ပိတ်ရန် bootloader ကို စစ်ဆေးပါ။"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ပို့တ်တွင် အရည် သို့မဟုတ် အမှိုက်စ ရှိနေသည်"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ပို့တ်ကို အလိုအလျောက် ပိတ်ထားသည်။ ပိုမိုလေ့လာရန် တို့ပါ။"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ပို့တ်ကို အသုံးပြုနိုင်သည်"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"အမျိုးအစားမခွဲရသေးပါ"</string> <string name="importance_from_user" msgid="7318955817386549931">"ဤသတိပေးချက်များ၏ အရေးပါမှုကိုသတ်မှတ်ပြီးပါပြီ။"</string> <string name="importance_from_person" msgid="9160133597262938296">"ပါဝင်သည့်လူများကြောင့် အရေးပါပါသည်။"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> ဖြင့်အသုံးပြုသူအသစ်ကို <xliff:g id="APP">%1$s</xliff:g> အား ဖန်တီးခွင့်ပြုလိုပါသလား (ဤအကောင့်ဖြင့် အသုံးပြုသူ ရှိနှင့်ပြီးဖြစ်သည်) ။"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> ဖြင့်အသုံးပြုသူအသစ်ကို <xliff:g id="APP">%1$s</xliff:g> အား ဖန်တီးခွင့်ပြုလိုပါသလား ။"</string> <string name="language_selection_title" msgid="2680677278159281088">"ဘာသာစကားတစ်ခု ထည့်ပါ"</string> <string name="country_selection_title" msgid="2954859441620215513">"ဒေသရွေးချယ်မှု"</string> <string name="search_language_hint" msgid="7042102592055108574">"ဘာသာစကားအမည် ထည့်ပါ"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index a59717047add..f6bbaaad96d7 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -226,7 +226,7 @@ <string name="global_actions" product="default" msgid="2406416831541615258">"Telefoninnstillinger"</string> <string name="global_action_lock" msgid="2844945191792119712">"Lås skjermen"</string> <string name="global_action_power_off" msgid="4471879440839879722">"Slå av"</string> - <string name="global_action_emergency" msgid="7112311161137421166">"Nødsituasjon"</string> + <string name="global_action_emergency" msgid="7112311161137421166">"Nødssituasjon"</string> <string name="global_action_bug_report" msgid="7934010578922304799">"Feilrapport"</string> <string name="global_action_logout" msgid="935179188218826050">"Avslutt økten"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"Skjermdump"</string> @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Lar appen lese og skrive konfigurasjon av Ikke forstyrr."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"start visning av bruk av tillatelser"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Lar innehaveren starte bruk av tillatelser for en app. Dette skal aldri være nødvendig for vanlige apper."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"mål for tilgjengelighetssnarvei"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Tillat at en app definerer målet for tilgjengelighetssnarveien."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Angi passordregler"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrollerer tillatt lengde og tillatte tegn i passord og PIN-koder for opplåsing av skjermen."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Overvåk forsøk på å låse opp skjermen"</string> @@ -815,7 +817,7 @@ <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Trykk på menyknappen for å låse opp eller ringe et nødnummer."</string> <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Trykk på menyknappen for å låse opp."</string> <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Tegn mønster for å låse opp"</string> - <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Nødsituasjon"</string> + <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Nødssituasjon"</string> <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Tilbake til samtale"</string> <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Riktig!"</string> <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Prøv på nytt"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Velg for å deaktivere USB-debugging."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Testrammeverk-modus er slått på"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Tilbakestill enheten til fabrikkstandard for å slå av Testrammeverk-modus."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Seriekonsollen er aktivert"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Ytelsen er påvirket. Sjekk oppstartsinnlasteren for å deaktivere."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Væske eller rusk i USB-porten"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-porten deaktiveres automatisk. Trykk for å finne ut mer."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Trygt å bruke USB-porten"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Uten kategori"</string> <string name="importance_from_user" msgid="7318955817386549931">"Du angir viktigheten for disse varslene."</string> <string name="importance_from_person" msgid="9160133597262938296">"Dette er viktig på grunn av folkene som er involvert."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Vil du la <xliff:g id="APP">%1$s</xliff:g> opprette en ny bruker med <xliff:g id="ACCOUNT">%2$s</xliff:g> (en bruker med denne kontoen eksisterer allerede)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Vil du la <xliff:g id="APP">%1$s</xliff:g> opprette en ny bruker med <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Legg til et språk"</string> <string name="country_selection_title" msgid="2954859441620215513">"Regionsinnstilling"</string> <string name="search_language_hint" msgid="7042102592055108574">"Skriv inn språknavn"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 0cbaaa023c94..c5608225df3e 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"बाधा नपुर्याउँनुहोस् कन्फिगरेसन पढ्न र लेख्नको लागि अनुप्रयोगलाई अनुमति दिनुहोस्।"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"हेर्ने अनुमतिको प्रयोग सुरु गर्नुहोस्"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"वाहकलाई कुनै अनुप्रयोगसम्बन्धी अनुमतिको प्रयोग सुरु गर्न दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक नपर्नु पर्ने हो।"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"पहुँचसम्बन्धी सर्टकटको लक्ष्य"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"कुनै अनुप्रयोगलाई पहुँचसम्बन्धी सर्टकटको लक्ष्य परिभाषित गर्न दिन्छ।"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियमहरू मिलाउनुहोस्"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"स्क्रिन लक पासवर्ड र PIN हरूमा अनुमति दिइएको लम्बाइ र वर्णहरूको नियन्त्रण गर्नुहोस्।"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"मनिटरको स्क्रिन अनलक गर्ने प्रयासहरू"</string> @@ -1367,6 +1369,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डिबगिङलाई असक्षम पार्न ट्याप गर्नुहोस्।"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"परीक्षण प्याकेज मोड सक्षम पारियो"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"परीक्षण प्याकेज मोड असक्षम पार्न फ्याक्ट्री रिसेट गर्नुहोस्।"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"क्रमसम्बन्धी कन्सोल सक्षम पारियो"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"कार्यसम्पादनमा प्रभाव परेको छ। यसलाई असक्षम पार्न बुटलोडरको जाँच गर्नुहोस्।"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB पोर्टमा तरल पदार्थ वा धुलो भएको कुरा पत्ता लाग्यो"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB पोर्ट स्वतः असक्षम पारियो। थप जान्न ट्याप गर्नुहोस्।"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB पोर्ट प्रयोग गर्दा हुन्छ"</string> @@ -1896,10 +1900,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"वर्गीकरण नगरिएको"</string> <string name="importance_from_user" msgid="7318955817386549931">"तपाईंले यी सूचनाहरूको महत्त्व सेट गर्नुहोस् ।"</string> <string name="importance_from_person" msgid="9160133597262938296">"यसमा सङ्लग्न भएका मानिसहरूको कारणले गर्दा यो महत्वपूर्ण छ।"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> (यस खाताको प्रयोगकर्ता पहिले नै अवस्थित छ) मा नयाँ प्रयोगकर्ता सिर्जना गर्न <xliff:g id="APP">%1$s</xliff:g> लाई अनुमति दिने हो?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> मा नयाँ प्रयोगकर्ता सिर्जना गर्न <xliff:g id="APP">%1$s</xliff:g> लाई अनुमति दिने हो?"</string> <string name="language_selection_title" msgid="2680677278159281088">"भाषा थप्नुहोस्"</string> <string name="country_selection_title" msgid="2954859441620215513">"क्षेत्रको प्राथमिकता"</string> <string name="search_language_hint" msgid="7042102592055108574">"भाषाको नाम टाइप गर्नुहोस्"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index e898389ed6e7..6dc5a644cdd0 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Hiermee kan de app configuratie voor Niet storen lezen en schrijven."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"rechtengebruik starten"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Hiermee kan de houder het rechtengebruik voor een app starten. Nooit vereist voor normale apps."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"doel van snelkoppeling voor toegankelijkheid"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Hiermee kan een app het doel van de snelkoppeling voor toegankelijkheid definiëren."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Wachtwoordregels instellen"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"De lengte en het aantal tekens beheren die zijn toegestaan in wachtwoorden en pincodes voor schermvergrendeling."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Pogingen voor schermontgrendeling bijhouden"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecteer deze optie om USB-foutopsporing uit te schakelen."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test harness-modus is ingeschakeld"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Reset de fabrieksinstellingen om de test harness-modus uit te schakelen."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Seriële console ingeschakeld"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Dit is van invloed op de prestaties. Controleer de bootloader om dit uit te schakelen."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vloeistof of vuil in USB-poort"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-poort is automatisch uitgeschakeld. Tik voor meer informatie."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-poort kan worden gebruikt"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Geen categorie"</string> <string name="importance_from_user" msgid="7318955817386549931">"Je stelt het belang van deze meldingen in."</string> <string name="importance_from_person" msgid="9160133597262938296">"Dit is belangrijk vanwege de betrokken mensen."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Toestaan dat <xliff:g id="APP">%1$s</xliff:g> een nieuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> maakt (er is al een gebruiker met dit account)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Toestaan dat <xliff:g id="APP">%1$s</xliff:g> een nieuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> maakt?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Een taal toevoegen"</string> <string name="country_selection_title" msgid="2954859441620215513">"Regiovoorkeur"</string> <string name="search_language_hint" msgid="7042102592055108574">"Typ een taalnaam"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index bd6d2cc8f635..bc3c400a3d2a 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" କନଫିଗରେଶନ୍ ପଢ଼ିବା ତଥା ଲେଖିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦେଇଥାଏ।"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"ଅନୁମତି ବ୍ୟବହାର ଦେଖିବା ଆରମ୍ଭ କରନ୍ତୁ"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ଏକ ଆପ୍ ପାଇଁ ଅନୁମତିର ବ୍ୟବହାର ଆରମ୍ଭ କରିବାକୁ ଧାରକକୁ ଅନୁମତି ଦେଇଥାଏ। ସାଧାରଣ ଆପ୍ଗୁଡ଼ିକ ପାଇଁ ଏହା ଆବଶ୍ୟକ ନୁହେଁ।"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ଆକ୍ସେସିବିଲିଟୀ ସର୍ଟକଟ୍ ଟାର୍ଗେଟ୍"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ଆକ୍ସେସିବିଲିଟୀ ସର୍ଟକଟ୍ ଟାର୍ଗେଟ୍ ବ୍ୟାଖ୍ୟା କରିବା ପାଇଁ ଯେ କୌଣସି ଆପ୍କୁ ଅନୁମତି ଦିଏ।"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"ପାସ୍ୱର୍ଡ ନିୟମାବଳୀ ସେଟ୍ କରନ୍ତୁ"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"ଲକ୍ ସ୍କ୍ରୀନ୍ ପାସ୍ୱର୍ଡ ଓ PINରେ ଅନୁମୋଦିତ ଦୀର୍ଘତା ଓ ବର୍ଣ୍ଣ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ।"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"ସ୍କ୍ରୀନ୍-ଅନଲକ୍ କରିବା ଉଦ୍ୟମ ନୀରିକ୍ଷଣ କରନ୍ତୁ"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ଡିବଗିଙ୍ଗକୁ ଅକ୍ଷମ କରିବା ପାଇଁ ଚୟନ କରନ୍ତୁ।"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"ଟେଷ୍ଟ ହାର୍ନେସ୍ ମୋଡ୍ ସକ୍ଷମ ଅଛି"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ଟେଷ୍ଟ ହାର୍ନେସ୍ ମୋଡ୍ ଅକ୍ଷମ କରିବାକୁ ଏକ ଫ୍ୟାକ୍ଟରୀ ରିସେଟ୍ କରନ୍ତୁ।"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"କ୍ରମିକ କନ୍ସୋଲ୍କୁ ସକ୍ଷମ କରାଯାଇଛି"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"କାର୍ଯ୍ୟଦକ୍ଷତା ପ୍ରଭାବିତ ହୋଇଛି। ଅକ୍ଷମ କରିବା ପାଇଁ, ବୁଟ୍ଲୋଡର୍ର ଯାଞ୍ଚ କରନ୍ତୁ।"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ପୋର୍ଟରେ ତରଳ ପଦାର୍ଥ ବା ଧୂଳି"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ପୋର୍ଟ ସ୍ୱଚାଳିତ ଭାବେ ଅକ୍ଷମ ହୋଇଛି। ଅଧିକ ଜାଣିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ପୋର୍ଟ ବ୍ୟବହାର କରିବା ପାଇଁ ଠିକ୍ ଅଟେ"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"ଅବର୍ଗୀକୃତ"</string> <string name="importance_from_user" msgid="7318955817386549931">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ପ୍ରମୁଖତା ଆପଣ ସେଟ୍ କରନ୍ତି।"</string> <string name="importance_from_person" msgid="9160133597262938296">"ସମ୍ପୃକ୍ତ ଲୋକଙ୍କ କାରଣରୁ ଏହା ଗୁରୁତ୍ୱପୂର୍ଣ୍ଣ ଅଟେ।"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ (ପୂର୍ବରୁ ଏହି ଆକାଉଣ୍ଟ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ନାମରେ ଅଛି) ଅନୁମତି ଦେବେ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"ଏକ ଭାଷା ଯୋଡ଼ନ୍ତୁ"</string> <string name="country_selection_title" msgid="2954859441620215513">"ପସନ୍ଦର ଅଞ୍ଚଳ"</string> <string name="search_language_hint" msgid="7042102592055108574">"ଭାଷାର ନାମ ଟାଇପ୍ କରନ୍ତୁ"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index a9e93d485bfc..74deed1933d2 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"ਐਪ ਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਕੌਂਫਿਗਰੇਸ਼ਨ ਨੂੰ ਪੜ੍ਹਨ ਅਤੇ ਲਿਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"ਇਜਾਜ਼ਤ ਵਰਤੋਂ ਦੇਖਣਾ ਸ਼ੁਰੂ ਕਰੋ"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ਧਾਰਕ ਨੂੰ ਕਿਸੇ ਹੋਰ ਐਪ ਲਈ ਇਜਾਜ਼ਤ ਵਰਤੋਂ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਾਂ ਲਈ ਕਦੇ ਵੀ ਲੋੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਟੀਚਾ"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ਕਿਸੇ ਐਪ ਨੂੰ ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਟੀਚੇ ਨੂੰ ਪਰਿਭਾਸ਼ਿਤ ਕਰਨ ਦਿਓ।"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"ਪਾਸਵਰਡ ਨਿਯਮ ਸੈੱਟ ਕਰੋ"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"ਸਕ੍ਰੀਨ ਲਾਕ ਪਾਸਵਰਡਾਂ ਅਤੇ ਪਿੰਨ ਵਿੱਚ ਆਗਿਆ ਦਿੱਤੀ ਲੰਮਾਈ ਅਤੇ ਅੱਖਰਾਂ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ।"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"ਸਕ੍ਰੀਨ ਅਣਲਾਕ ਕਰਨ ਦੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ \'ਤੇ ਨਿਗਰਾਨੀ ਰੱਖੋ"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ਡੀਬੱਗਿੰਗ ਅਯੋਗ ਬਣਾਉਣ ਲਈ ਚੁਣੋ।"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"ਟੈਸਟ ਹਾਰਨੈੱਸ ਮੋਡ ਚਾਲੂ ਹੈ"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ਟੈਸਟ ਹਾਰਨੈੱਸ ਮੋਡ ਬੰਦ ਕਰਨ ਲਈ ਫੈਕਟਰੀ ਰੀਸੈੱਟ ਕਰੋ।"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"ਸੀਰੀਅਲ ਕੰਸੋਲ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"ਕਾਰਗੁਜ਼ਾਰੀ ਪ੍ਰਭਾਵਿਤ ਹੋਈ ਹੈ। ਬੰਦ ਕਰਨ ਲਈ, ਬੂਟਲੋਡਰ ਦੇਖੋ।"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ਪੋਰਟ ਵਿੱਚ ਪਾਣੀ ਜਾਂ ਧੂੜ-ਮਿੱਟੀ"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ਪੋਰਟ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ। ਹੋਰ ਜਾਣਨ ਲਈ ਟੈਪ ਕਰੋ।"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ਪੋਰਟ ਵਰਤਣ ਲਈ ਠੀਕ ਹੈ"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"ਗੈਰ-ਸ਼੍ਰੇਣੀਕਿਰਤ"</string> <string name="importance_from_user" msgid="7318955817386549931">"ਤੁਸੀਂ ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਦੀ ਮਹੱਤਤਾ ਸੈੱਟ ਕੀਤੀ।"</string> <string name="importance_from_person" msgid="9160133597262938296">"ਇਹ ਸ਼ਾਮਲ ਲੋਕਾਂ ਦੇ ਕਾਰਨ ਮਹੱਤਵਪੂਰਨ ਹੈ।"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"ਕੀ <xliff:g id="APP">%1$s</xliff:g> ਨੂੰ <xliff:g id="ACCOUNT">%2$s</xliff:g> ਨਾਲ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ (ਇਸ ਖਾਤੇ ਨਾਲ ਇੱਕ ਵਰਤੋਂਕਾਰ ਪਹਿਲਾਂ ਤੋਂ ਹੀ ਮੌਜੂਦ ਹੈ)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"ਕੀ <xliff:g id="APP">%1$s</xliff:g> ਨੂੰ <xliff:g id="ACCOUNT">%2$s</xliff:g> ਨਾਲ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"ਇੱਕ ਭਾਸ਼ਾ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="country_selection_title" msgid="2954859441620215513">"ਖੇਤਰ ਤਰਜੀਹ"</string> <string name="search_language_hint" msgid="7042102592055108574">"ਭਾਸ਼ਾ ਨਾਮ ਟਾਈਪ ਕਰੋ"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 537089ce640f..b1369c7cde8d 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -661,6 +661,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Pozwala aplikacji na odczyt i zmianę konfiguracji trybu Nie przeszkadzać."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"rozpocząć wyświetlanie użycia uprawnień"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Umożliwia rozpoczęcie korzystania z uprawnienia dotyczącego danej aplikacji jego posiadaczowi. Zwykłe aplikacje nie powinny potrzebować tego uprawnienia."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cel skrótu do ułatwień dostępu"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Pozwala aplikacji definiować cel skrótu do ułatwień dostępu."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Określ reguły hasła"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolowanie długości haseł blokady ekranu i kodów PIN oraz dozwolonych w nich znaków."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitorowanie prób odblokowania ekranu"</string> @@ -1405,6 +1407,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Wybierz, aby wyłączyć debugowanie USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Tryb jarzma testowego został włączony"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Przywróć ustawienia fabryczne, by wyłączyć tryb jarzma testowego."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Konsola szeregowa włączona"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Wpływa na wydajność. Aby wyłączyć, sprawdź program rozruchowy."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Wilgoć lub brud w porcie USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB został automatycznie wyłączony. Kliknij, by dowiedzieć się więcej."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Możesz używać portu USB"</string> @@ -1958,10 +1962,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Bez kategorii"</string> <string name="importance_from_user" msgid="7318955817386549931">"Ustawiłeś ważność tych powiadomień."</string> <string name="importance_from_person" msgid="9160133597262938296">"Ta wiadomość jest ważna ze względu na osoby uczestniczące w wątku."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Zezwolić aplikacji <xliff:g id="APP">%1$s</xliff:g> na utworzenie nowego użytkownika dla konta <xliff:g id="ACCOUNT">%2$s</xliff:g> (użytkownik dla tego konta już istnieje)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Zezwolić aplikacji <xliff:g id="APP">%1$s</xliff:g> na utworzenie nowego użytkownika dla konta <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Dodaj język"</string> <string name="country_selection_title" msgid="2954859441620215513">"Ustawienie regionu"</string> <string name="search_language_hint" msgid="7042102592055108574">"Wpisz nazwę języka"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index ba8285fa79d9..4dc270094b63 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permitir que o app leia e grave a configuração \"Não perturbe\"."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"iniciar uso da permissão para visualização"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permite que o sistema inicie o uso de permissão para um app. Não deve ser necessário para apps comuns."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"objetivo do atalho de acessibilidade"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permite que um app defina o objetivo do atalho de acessibilidade."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras para senha"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Controla o tamanho e os caracteres permitidos nos PINs e nas senhas do bloqueio de tela."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitorar tentativas de desbloqueio de tela"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modo Arcabouço de testes ativado"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Console serial ativado"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"O desempenho foi impactado. Para desativar, verifique o carregador de inicialização."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Líquido ou detrito na porta USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"A porta USB é desativada automaticamente. Toque para saber mais."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"É seguro usar a porta USB"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Sem classificação"</string> <string name="importance_from_user" msgid="7318955817386549931">"Você definiu a importância dessas notificações."</string> <string name="importance_from_person" msgid="9160133597262938296">"Isso é importante por causa das pessoas envolvidas."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Permitir que o app <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g> (já existe um usuário com essa conta)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Permitir que o app <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Adicionar um idioma"</string> <string name="country_selection_title" msgid="2954859441620215513">"Preferência de região"</string> <string name="search_language_hint" msgid="7042102592055108574">"Digitar nome do idioma"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index c7df3a7d848c..141dca320ad9 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -229,7 +229,7 @@ <string name="global_action_emergency" msgid="7112311161137421166">"Emergência"</string> <string name="global_action_bug_report" msgid="7934010578922304799">"Relatório de erros"</string> <string name="global_action_logout" msgid="935179188218826050">"Terminar sessão"</string> - <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de ecrã"</string> + <string name="global_action_screenshot" msgid="8329831278085426283">"Capt. ecrã"</string> <string name="bugreport_title" msgid="5981047024855257269">"Relatório de erro"</string> <string name="bugreport_message" msgid="398447048750350456">"Será recolhida informação sobre o estado atual do seu dispositivo a enviar através de uma mensagem de email. Demorará algum tempo até que o relatório de erro esteja pronto para ser enviado. Aguarde um pouco."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Relatório interativo"</string> @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permite à aplicação ler e alterar a configuração de Não incomodar"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"iniciar utilização da autorização de visualização"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permite que o titular inicie a utilização de autorizações para uma aplicação. Nunca deverá ser necessário para aplicações normais."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"alvo do atalho de acessibilidade"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permite a uma aplicação definir o alvo do atalho de acessibilidade."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras de palavra-passe"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Controlar o comprimento e os carateres permitidos nos PINs e nas palavras-passe do bloqueio de ecrã."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitorizar tentativas de desbloqueio do ecrã"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração por USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modo de estrutura de teste ativado"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Efetue uma reposição de dados de fábrica para desativar o Modo de estrutura de teste."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Consola de série ativada"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"O desempenho é afetado. Para desativar, selecione o carregador de arranque."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Líquido ou resíduos na porta USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"A porta USB é automaticamente desativada. Toque para saber mais."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"É seguro utilizar a porta USB"</string> @@ -1508,7 +1512,7 @@ <string name="sync_really_delete" msgid="2572600103122596243">"Eliminar os itens"</string> <string name="sync_undo_deletes" msgid="2941317360600338602">"Anular as eliminações"</string> <string name="sync_do_nothing" msgid="3743764740430821845">"Não fazer nada por agora"</string> - <string name="choose_account_label" msgid="5655203089746423927">"Selecionar uma conta"</string> + <string name="choose_account_label" msgid="5655203089746423927">"Selecione uma conta"</string> <string name="add_account_label" msgid="2935267344849993553">"Adicionar uma conta"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Adicionar conta"</string> <string name="number_picker_increment_button" msgid="2412072272832284313">"Aumentar"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Sem categoria"</string> <string name="importance_from_user" msgid="7318955817386549931">"Definiu a importância destas notificações."</string> <string name="importance_from_person" msgid="9160133597262938296">"É importante devido às pessoas envolvidas."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Pretende permitir que a aplicação <xliff:g id="APP">%1$s</xliff:g> crie um novo utilizador com a conta <xliff:g id="ACCOUNT">%2$s</xliff:g> (já existe um utilizador com esta conta)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Pretende permitir que a aplicação <xliff:g id="APP">%1$s</xliff:g> crie um novo utilizador com a conta <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Adicionar um idioma"</string> <string name="country_selection_title" msgid="2954859441620215513">"Preferência de região"</string> <string name="search_language_hint" msgid="7042102592055108574">"Intr. nome do idioma"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index ba8285fa79d9..4dc270094b63 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permitir que o app leia e grave a configuração \"Não perturbe\"."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"iniciar uso da permissão para visualização"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permite que o sistema inicie o uso de permissão para um app. Não deve ser necessário para apps comuns."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"objetivo do atalho de acessibilidade"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permite que um app defina o objetivo do atalho de acessibilidade."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras para senha"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Controla o tamanho e os caracteres permitidos nos PINs e nas senhas do bloqueio de tela."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitorar tentativas de desbloqueio de tela"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modo Arcabouço de testes ativado"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Console serial ativado"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"O desempenho foi impactado. Para desativar, verifique o carregador de inicialização."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Líquido ou detrito na porta USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"A porta USB é desativada automaticamente. Toque para saber mais."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"É seguro usar a porta USB"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Sem classificação"</string> <string name="importance_from_user" msgid="7318955817386549931">"Você definiu a importância dessas notificações."</string> <string name="importance_from_person" msgid="9160133597262938296">"Isso é importante por causa das pessoas envolvidas."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Permitir que o app <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g> (já existe um usuário com essa conta)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Permitir que o app <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Adicionar um idioma"</string> <string name="country_selection_title" msgid="2954859441620215513">"Preferência de região"</string> <string name="search_language_hint" msgid="7042102592055108574">"Digitar nome do idioma"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 72772288d947..73f31c4b85bc 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -658,6 +658,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permite aplicației să citească și să scrie configurația Nu deranja."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"porniți folosirea permisiunii de vizualizare"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permite proprietarului să pornească folosirea permisiunii pentru o aplicație. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ținta comenzii rapide de accesibilitate"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permite unei aplicații să definească ținta comenzii rapide de accesibilitate."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Să seteze reguli pentru parolă"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Stabiliți lungimea și tipul de caractere permise pentru parolele și codurile PIN de blocare a ecranului."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Să monitorizeze încercările de deblocare a ecranului"</string> @@ -1383,6 +1385,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selectați pentru a dezactiva remedierea erorilor prin USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modul Set de testare este activat"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Reveniți la setările din fabrică pentru a dezactiva modul Set de testare."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Consola din serie este activată"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Performanța este afectată. Pentru a dezactiva, verificați programul bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Lichide sau reziduuri în portul USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Portul USB este dezactivat automat. Atingeți ca să aflați mai multe."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Portul USB poate fi folosit"</string> @@ -1924,10 +1928,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Neclasificate"</string> <string name="importance_from_user" msgid="7318955817386549931">"Dvs. setați importanța acestor notificări."</string> <string name="importance_from_person" msgid="9160133597262938296">"Notificarea este importantă având în vedere persoanele implicate."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Permiteți ca <xliff:g id="APP">%1$s</xliff:g> să creeze un nou utilizator folosind <xliff:g id="ACCOUNT">%2$s</xliff:g>? (există deja un utilizator cu acest cont)"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Permiteți ca <xliff:g id="APP">%1$s</xliff:g> să creeze un nou utilizator folosind <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Adăugați o limbă"</string> <string name="country_selection_title" msgid="2954859441620215513">"Regiunea preferată"</string> <string name="search_language_hint" msgid="7042102592055108574">"Numele limbii"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index e458e4644ab2..9e43592d29e9 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -661,6 +661,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Открывает приложению доступ к настройкам режима \"Не беспокоить\" и позволяет изменять их."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"Просмотр данных об используемых разрешениях"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Приложение получит доступ к данным об используемых разрешениях. Это разрешение не требуется обычным приложениям."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"Цель быстрого включения"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Приложение сможет определять цель быстрого включения."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Настройка правил для паролей"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Контролировать длину и символы при вводе пароля и PIN-кода."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Отслеживание попыток разблокировать экран"</string> @@ -1405,6 +1407,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Нажмите, чтобы отключить отладку по USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Тестовый режим включен"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Чтобы отключить тестовый режим, сбросьте настройки до заводских."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Консоль последовательного порта включена"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Производительность устройства снижена. Чтобы отключить консоль, перейдите в загрузчик операционной системы."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"В USB-порт попала вода или грязь"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-порт был автоматически отключен. Нажмите, чтобы узнать подробности."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-порт можно использовать"</string> @@ -1958,10 +1962,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Без категории"</string> <string name="importance_from_user" msgid="7318955817386549931">"Вы определяете важность этих уведомлений."</string> <string name="importance_from_person" msgid="9160133597262938296">"Важное (люди)"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Разрешить приложению \"<xliff:g id="APP">%1$s</xliff:g>\" создать нового пользователя с аккаунтом <xliff:g id="ACCOUNT">%2$s</xliff:g> (пользователь с этим аккаунтом уже существует)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Разрешить приложению \"<xliff:g id="APP">%1$s</xliff:g>\" создать нового пользователя с аккаунтом <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Добавьте язык"</string> <string name="country_selection_title" msgid="2954859441620215513">"Региональные настройки"</string> <string name="search_language_hint" msgid="7042102592055108574">"Введите язык"</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 3e0f582ba87e..cc2a2a89018d 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"බාධා නොකරන්න වින්යාස කිරීම කියවීමට සහ ලිවීමට යෙදුමට ඉඩ දෙයි."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"අවසර භාවිතය බැලීමට ආරම්භ කරන්න"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"තබා සිටින්නාට යෙදුමක් සඳහා අවසර භාවිතය ආරම්භ කිරීමට ඉඩ දෙයි. සාමාන්ය යෙදුම් සඳහා කිසි විටෙක අවශ්ය නොවිය යුතු ය."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ප්රවේශ්යතා කෙටිමං ඉලක්කය"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ප්රවේශ්යතා කෙටිමං ඉලක්කය නිර්වචනය කිරීමට යෙදුමකට ඉඩ දෙන්න."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"මුරපද නීති සකස් කිරීම"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"තිර අගුලු මුරපද සහ PIN තුළ ඉඩ දෙන දිග සහ අනුලකුණු පාලනය කිරීම."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"තිරය අගුළු ඇරීමේ උත්සාහයන් නිරීක්ෂණය කරන්න"</string> @@ -1363,6 +1365,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB නිදොස්කරණය අබල කිරීමට තෝරන්න."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"පුරක පරීක්ෂා ප්රකාරය සබලයි"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"පුරක පරීක්ෂා ප්රකාරය අබල කිරීමට කර්මාන්තශාලා යළි සැකසීමක් ඉටු කරන්න."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"අනුක්රමික කොන්සෝලය සබලයි"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"කාර්ය සාධනය බලපෑමට ලක් වී ඇත. අබල කිරීමට, ආරම්භකය පරීක්ෂා කරන්න."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB තොට තුළ ද්රව හෝ කුණු"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB තොට ස්වයංක්රීයව අබල කෙරේ. තවත් දැන ගැනීමට තට්ටු කරන්න."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB තොට භාවිත කළාට කමක් නැත"</string> @@ -1892,10 +1896,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"වර්ගීකරණය නොකළ"</string> <string name="importance_from_user" msgid="7318955817386549931">"ඔබ මෙම දැනුම්දීම්වල වැදගත්කම සකසා ඇත."</string> <string name="importance_from_person" msgid="9160133597262938296">"සම්බන්ධ වූ පුද්ගලයන් නිසා මෙය වැදගත් වේ."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> හට <xliff:g id="ACCOUNT">%2$s</xliff:g> සමගින් නව පරිශීලකයෙකු සෑදීමට ඉඩ දෙන්නද (මෙම ගිණුම සහිත පරිශීලකයෙකු දැනටමත් සිටී) ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> හට <xliff:g id="ACCOUNT">%2$s</xliff:g> සමගින් නව පරිශීලකයෙකු සෑදීමට ඉඩ දෙන්නද ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"භාෂාවක් එක් කරන්න"</string> <string name="country_selection_title" msgid="2954859441620215513">"ප්රදේශ මනාපය"</string> <string name="search_language_hint" msgid="7042102592055108574">"භාෂා නම ටයිප් කරන්න"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 015cd91d60c9..0e49c86c49c5 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -661,6 +661,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Umožňuje aplikácii čítať a zapisovať konfiguráciu režimu bez vyrušení."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"spustenie používania povolenia na zobrazenie"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Umožňuje držiteľovi spustiť používanie povolenia aplikáciou. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cieľ skratky dostupnosti"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Umožňuje aplikácii definovať cieľ skratky dostupnosti."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastaviť pravidlá pre heslo"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Nastavte dĺžku hesiel na odomknutie obrazovky aj kódov PIN a v nich používané znaky."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Sledovanie pokusov o odomknutie obrazovky"</string> @@ -1405,6 +1407,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vyberte, ak chcete zakázať ladenie cez USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Režim správcu testov je aktivovaný"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Ak chcete zakázať režim správcu testov, obnovte výrobné nastavenia."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Sériová konzola je povolená"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Ovplyvňuje výkon. Ak ju chcete zakázať, skontrolujte zavádzací program systému."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tekutina alebo nečistoty v porte USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB je automaticky deaktivovaný. Ďalšie informácie zobrazíte klepnutím."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Port USB môžete použiť"</string> @@ -1958,10 +1962,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Nekategorizované"</string> <string name="importance_from_user" msgid="7318955817386549931">"Nastavili ste dôležitosť týchto upozornení."</string> <string name="importance_from_person" msgid="9160133597262938296">"Táto správa je dôležitá vzhľadom na osoby, ktorých sa to týka."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Chcete povoliť aplikácii <xliff:g id="APP">%1$s</xliff:g> vytvoriť nového používateľa pomocou účtu <xliff:g id="ACCOUNT">%2$s</xliff:g> (používateľ s týmto účtom už existuje)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Chcete povoliť aplikácii <xliff:g id="APP">%1$s</xliff:g> vytvoriť nového používateľa pomocou účtu <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Pridať jazyk"</string> <string name="country_selection_title" msgid="2954859441620215513">"Preferovaný región"</string> <string name="search_language_hint" msgid="7042102592055108574">"Zadajte názov jazyka"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 54da1dc2d7c8..83400469d86f 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -661,6 +661,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Aplikaciji omogoča branje in pisanje konfiguracije načina »ne moti«."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"začetek uporabe dovoljenja za ogledovanje"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Imetniku omogoča začetek uporabe dovoljenj za aplikacijo. Nikoli ni potrebno za navadne aplikacije."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cilj bližnjice funkcije za ljudi s posebnimi potrebami"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Aplikaciji dovoljuje, da določi cilj bližnjice funkcije za ljudi s posebnimi potrebami."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavitev pravil za geslo"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Nadzor nad dolžino in znaki, ki so dovoljeni v geslih in kodah PIN za odklepanje zaslona."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Nadzor nad poskusi odklepanja zaslona"</string> @@ -1405,6 +1407,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izberite, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Način preizkusnega ogrodja je omogočen"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Če želite onemogočiti način preizkusnega ogrodja, ponastavite napravo na tovarniške nastavitve."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Serijska konzola je omogočena"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Učinkovitost delovanja je slabša. Uporabo konzole lahko onemogočite v zagonskem nalagalniku."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"V vratih USB je tekočina ali umazanija"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Vrata USB so samodejno onemogočena. Dotaknite se, če želite izvedeti več."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Vrata USB so varna za uporabo"</string> @@ -1958,10 +1962,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Nekategorizirano"</string> <string name="importance_from_user" msgid="7318955817386549931">"Vi določite raven pomembnosti teh obvestil."</string> <string name="importance_from_person" msgid="9160133597262938296">"Pomembno zaradi udeleženih ljudi."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Ali aplikaciji <xliff:g id="APP">%1$s</xliff:g> dovolite, da ustvari novega uporabnika za račun <xliff:g id="ACCOUNT">%2$s</xliff:g> (uporabnik s tem računom že obstaja)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Ali aplikaciji <xliff:g id="APP">%1$s</xliff:g> dovolite, da ustvari novega uporabnika za račun <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Dodajanje jezika"</string> <string name="country_selection_title" msgid="2954859441620215513">"Nastavitev območja"</string> <string name="search_language_hint" msgid="7042102592055108574">"Vnesite ime jezika"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 48ae4d79554e..411d4586ad08 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Lejon aplikacionin të lexojë dhe shkruajë konfigurimin e \"Mos shqetëso\"."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"nis përdorimin e lejes për shikimin"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Lejon që mbajtësi të nisë përdorimin e lejeve për një aplikacion. Nuk duhet të nevojitet asnjëherë për aplikacionet normale."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"objektivi i shkurtores së qasshmërisë"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Lejon që një aplikacion të përcaktojë objektivin e shkurtores së qasshmërisë."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Cakto rregullat e fjalëkalimit"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrollo gjatësinë dhe karakteret e lejuara në fjalëkalimet dhe kodet PIN të kyçjes së ekranit."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitoro tentativat e shkyçjes së ekranit"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Përzgjidhe për të çaktivizuar korrigjimin e gabimeve të USB-së"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modaliteti i lidhjes së testimit është aktivizuar"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Kryej një rivendosje në cilësimet e fabrikës për të çaktivizuar \"Modalitetin e lidhjes së testimit\"."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Paneli komandues i serisë është aktivizuar"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Ndikohet cilësia e funksionimit. Për ta çaktivizuar, kontrollo ngarkuesin e sistemit."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Lëngje ose papastërti në portën e USB-së"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Porta e USB-së është çaktivizuar automatikisht. Trokit për të mësuar më shumë."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Në rregulloj për përdorimin e portës USB"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"E pakategorizuara"</string> <string name="importance_from_user" msgid="7318955817386549931">"Ke caktuar rëndësinë e këtyre njoftimeve."</string> <string name="importance_from_person" msgid="9160133597262938296">"Është i rëndësishëm për shkak të personave të përfshirë."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Të lejohet <xliff:g id="APP">%1$s</xliff:g> që të krijojë një përdorues të ri me <xliff:g id="ACCOUNT">%2$s</xliff:g> (një përdorues me këtë llogari ekziston tashmë) ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Të lejohet <xliff:g id="APP">%1$s</xliff:g> që të krijojë një përdorues të ri me <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Shto një gjuhë"</string> <string name="country_selection_title" msgid="2954859441620215513">"Preferenca e rajonit"</string> <string name="search_language_hint" msgid="7042102592055108574">"Shkruaj emrin e gjuhës"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 75fc1ce6732b..c2d636d0323e 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -27,7 +27,7 @@ <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> - <string name="untitled" msgid="4638956954852782576">"<Без наслова>"</string> + <string name="untitled" msgid="4638956954852782576">"<Без имена>"</string> <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Нема броја телефона)"</string> <string name="unknownName" msgid="6867811765370350269">"Непознато"</string> <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Гласовна пошта"</string> @@ -658,6 +658,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Дозвољава апликацији да чита и уписује конфигурацију подешавања Не узнемиравај."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"почетак коришћења дозволе за преглед"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Дозвољава власнику да започне коришћење дозволе за апликацију. Никада не би требало да буде потребна за уобичајене апликације."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"циљ пречице за приступачност"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Дозвољава апликацији да дефинише циљ пречице за приступачност."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Подешавање правила за лозинку"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Контролише дужину и знакове дозвољене у лозинкама и PIN-овима за закључавање екрана."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Надгледајте покушаје откључавања екрана"</string> @@ -1383,6 +1385,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изаберите да бисте онемогућили отклањања грешака са USB-а."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Омогућен је режим пробног коришћења"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Обавите ресетовање на фабричка подешавања да бисте онемогућили режим пробног коришћења."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Серијска конзола је омогућена"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Учинак је смањен. Да бисте онемогући конзолу, проверите покретачки програм."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или нечистоћа у USB порту"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порт је аутоматски искључен. Додирните да бисте сазнали више."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Коришћење USB порта је дозвољено"</string> @@ -1924,10 +1928,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Некатегоризовано"</string> <string name="importance_from_user" msgid="7318955817386549931">"Ви подешавате важност ових обавештења."</string> <string name="importance_from_person" msgid="9160133597262938296">"Ово је важно због људи који учествују."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Желите ли да дозволите да <xliff:g id="APP">%1$s</xliff:g> направи новог корисника са налогом <xliff:g id="ACCOUNT">%2$s</xliff:g> (корисник са тим налогом већ постоји)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Желите ли да дозволите да <xliff:g id="APP">%1$s</xliff:g> направи новог корисника са налогом <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Додајте језик"</string> <string name="country_selection_title" msgid="2954859441620215513">"Подешавање региона"</string> <string name="search_language_hint" msgid="7042102592055108574">"Унесите назив језика"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index fdd0b7b7267a..854e44f852fa 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Ger appen läs- och skrivbehörighet till konfigurationen för Stör ej."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"börja visa behörighetsanvändningen"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Gör att innehavaren kan öppna behörighetsanvändning för en app. Ska inte behövas för vanliga appar."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"mål för Aktivera tillgänglighet snabbt"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Tillåter att en app kan definiera målet för Aktivera tillgänglighet snabbt."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Ange lösenordsregler"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Styr tillåten längd och tillåtna tecken i lösenord och pinkoder för skärmlåset."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Övervaka försök att låsa upp skärmen"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Välj för att inaktivera USB-felsökning."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Läget för testverktyg har aktiverats"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Inaktivera testverktygsläget genom att göra en återställning till standardinställningarna."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Seriekonsolen är aktiverad"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Prestandan påverkas. Inaktivera via starthanteraren."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vätska eller smuts i USB-porten"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-porten har inaktiverats automatiskt. Tryck för att läsa mer."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Nu kan du använda USB-porten"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Okategoriserad"</string> <string name="importance_from_user" msgid="7318955817386549931">"Du anger hur viktiga aviseringarna är."</string> <string name="importance_from_person" msgid="9160133597262938296">"Detta är viktigt på grund av personerna som deltar."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Tillåter du att <xliff:g id="APP">%1$s</xliff:g> skapar en ny användare för <xliff:g id="ACCOUNT">%2$s</xliff:g> (det finns redan en användare med det här kontot)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Tillåter du att <xliff:g id="APP">%1$s</xliff:g> skapar en ny användare för <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Lägg till ett språk"</string> <string name="country_selection_title" msgid="2954859441620215513">"Regionsinställningar"</string> <string name="search_language_hint" msgid="7042102592055108574">"Ange språket"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index c8c582f334a9..565cdf94080d 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Inaruhusu programu kusoma na kuandika usanidi wa kipengee cha Usinisumbue."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"anzisha kipengele cha kuona matumizi ya ruhusa"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Huruhusu kishikiliaji kuanzisha matumizi ya ruhusa ya programu. Haipaswi kuhitajika kwa ajili ya programu za kawaida."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"kulenga njia ya mkato ya ufikivu"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Huruhusu programu kubainisha ulengaji wa njia ya mkato ya ufikivu."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Kuweka kanuni za nenosiri"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Dhibiti urefu na maandishi yanayokubalika katika nenosiri la kufunga skrini na PIN."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Kuhesabu mara ambazo skrini inajaribu kufunguliwa"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chagua ili kulemaza utatuaji USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Hali ya Muunganisho wa Majaribio imewashwa"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Rejesha mipangilio iliyotoka nayo kiwandani ili uzime hali ya Muunganisho wa Majaribio."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Muunganisho kupitia mlango umewashwa"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Utendaji unaathirika. lli uzime, teua programu ya kuwasha mfumo wa uendeshaji."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Unyevu au uchafu katika mlango wa USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Mlango wa USB umezimwa kiotomatiki. Gusa ili upate maelezo zaidi."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Ni sawa kutumia mlango wa USB"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Ambazo aina haijabainishwa"</string> <string name="importance_from_user" msgid="7318955817386549931">"Uliweka mipangilio ya umuhimu wa arifa hizi."</string> <string name="importance_from_person" msgid="9160133597262938296">"Hii ni muhimu kwa sababu ya watu waliohusika."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Ruhusu <xliff:g id="APP">%1$s</xliff:g> iweke Mtumiaji mpya ikitumia <xliff:g id="ACCOUNT">%2$s</xliff:g> (Je, tayari kuna mtumiaji anayetumia akaunti hii)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Ungependa kuruhusu <xliff:g id="APP">%1$s</xliff:g> iweke Mtumiaji mpya ikitumia <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Ongeza lugha"</string> <string name="country_selection_title" msgid="2954859441620215513">"Mapendeleo ya eneo"</string> <string name="search_language_hint" msgid="7042102592055108574">"Weka jina la lugha"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 0956aad3003f..9d6d4e14a0fb 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -220,7 +220,7 @@ <string name="reboot_safemode_title" msgid="7054509914500140361">"பாதுகாப்பான பயன்முறைக்கு மீண்டும் தொடங்கவும்"</string> <string name="reboot_safemode_confirm" msgid="55293944502784668">"பாதுகாப்பான பயன்முறைக்குச் செல்ல மீண்டும் துவக்க விரும்புகிறீர்களா? நீங்கள் நிறுவிய எல்லா மூன்றாம் தரப்பு பயன்பாடுகளையும் இது முடக்கும். நீங்கள் மீண்டும் மறுதொடக்கம் செய்யும்போது அவை மீட்டமைக்கப்படும்."</string> <string name="recent_tasks_title" msgid="3691764623638127888">"சமீபத்தியவை"</string> - <string name="no_recent_tasks" msgid="8794906658732193473">"சமீபத்திய பயன்பாடுகள் எதுவுமில்லை."</string> + <string name="no_recent_tasks" msgid="8794906658732193473">"சமீபத்திய ஆப்ஸ் எதுவுமில்லை."</string> <string name="global_actions" product="tablet" msgid="408477140088053665">"டேப்லெட் விருப்பங்கள்"</string> <string name="global_actions" product="tv" msgid="9091480417912345975">"Android TV விருப்பத்தேர்வுகள்"</string> <string name="global_actions" product="default" msgid="2406416831541615258">"தொலைபேசி விருப்பங்கள்"</string> @@ -271,7 +271,7 @@ <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"ஆப்ஸ் இயங்குகிறது"</string> <string name="notification_channel_foreground_service" msgid="3931987440602669158">"பேட்டரியைப் பயன்படுத்தும் ஆப்ஸ்"</string> <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் பேட்டரியைப் பயன்படுத்துகிறது"</string> - <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> பயன்பாடுகள் பேட்டரியைப் பயன்படுத்துகின்றன"</string> + <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ஆப்ஸ் பேட்டரியைப் பயன்படுத்துகின்றன"</string> <string name="foreground_service_tap_for_details" msgid="372046743534354644">"பேட்டரி மற்றும் டேட்டா உபயோக விவரங்களைக் காண, தட்டவும்"</string> <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string> <string name="safeMode" msgid="2788228061547930246">"பாதுகாப்பு பயன்முறை"</string> @@ -345,11 +345,11 @@ <string name="permlab_receiveMms" msgid="1821317344668257098">"உரைச் செய்திகளை (MMS) பெறுதல்"</string> <string name="permdesc_receiveMms" msgid="533019437263212260">"MMS செய்திகளைப் பெற, செயற்படுத்தப் ஆப்ஸை அனுமதிக்கிறது. இதற்கு அர்த்தம் உங்கள் சாதனத்திற்கு அனுப்பப்படும் செய்திகளை உங்களுக்குக் காட்டாமல் கண்காணிக்கவோ, நீக்கவோ ஆப்ஸால் முடியும் என்பதாகும்."</string> <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"செல் அலைபரப்புச் செய்திகளைப் படித்தல்"</string> - <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"உங்கள் சாதனத்தில் பெறப்படும் செல் அலைபரப்புச் செய்திகளைப் படிப்பதற்குப் ஆப்ஸை அனுமதிக்கிறது. அவசரநிலை சூழ்நிலைகளை உங்களுக்கு எச்சரிக்கைச் செய்வதற்கு சில இடங்களில் செல் அலைபரப்பு விழிப்பூட்டல்கள் வழங்கப்படும். அவசரநிலை மொபைல் அலைபரப்புப் பெறப்படும்போது உங்கள் சாதனத்தின் செயல்திறன் அல்லது செயல்பாட்டுடன் தீங்கிழைக்கும் பயன்பாடுகள் அதைத் தடுக்கலாம்."</string> + <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"உங்கள் சாதனத்தில் பெறப்படும் செல் அலைபரப்புச் செய்திகளைப் படிப்பதற்குப் ஆப்ஸை அனுமதிக்கிறது. அவசரநிலை சூழ்நிலைகளை உங்களுக்கு எச்சரிக்கைச் செய்வதற்கு சில இடங்களில் செல் அலைபரப்பு விழிப்பூட்டல்கள் வழங்கப்படும். அவசரநிலை மொபைல் அலைபரப்புப் பெறப்படும்போது உங்கள் சாதனத்தின் செயல்திறன் அல்லது செயல்பாட்டுடன் தீங்கிழைக்கும் ஆப்ஸ் அதைத் தடுக்கலாம்."</string> <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"குழுசேர்ந்த ஊட்டங்களைப் படித்தல்"</string> <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"தற்போது ஒத்திசைந்த ஊட்டங்களைப் பற்றிய விவரங்களைப் பெற ஆப்ஸை அனுமதிக்கிறது."</string> <string name="permlab_sendSms" msgid="7544599214260982981">"SMS செய்திகளை அனுப்புதல் மற்றும் பார்த்தல்"</string> - <string name="permdesc_sendSms" msgid="7094729298204937667">"SMS செய்திகளை அனுப்ப ஆப்ஸை அனுமதிக்கிறது. இதற்கு எதிர்பாராத பேமெண்ட்கள் விதிக்கப்படலாம். தீங்கு விளைவிக்கும் பயன்பாடுகள் உங்களின் உறுதிப்படுத்தல் எதுவுமின்றி செய்திகளை அனுப்பி உங்களுக்குக் கட்டணம் விதிக்கலாம்."</string> + <string name="permdesc_sendSms" msgid="7094729298204937667">"SMS செய்திகளை அனுப்ப ஆப்ஸை அனுமதிக்கிறது. இதற்கு எதிர்பாராத பேமெண்ட்கள் விதிக்கப்படலாம். தீங்கு விளைவிக்கும் ஆப்ஸ் உங்களின் உறுதிப்படுத்தல் எதுவுமின்றி செய்திகளை அனுப்பி உங்களுக்குக் கட்டணம் விதிக்கலாம்."</string> <string name="permlab_readSms" msgid="8745086572213270480">"உங்கள் உரைச் செய்திகளை (SMS அல்லது MMS) படித்தல்"</string> <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"இந்த ஆப்ஸ் உங்கள் டேப்லெட்டில் சேமிக்கப்பட்டுள்ள எல்லா SMS (உரை) செய்திகளையும் படிக்கலாம்."</string> <string name="permdesc_readSms" product="tv" msgid="9106832390302749856">"உங்கள் Android TVயில் சேமித்துள்ள அனைத்து மெசேஜ்களையும் இந்த ஆப்ஸால் தெரிந்துகொள்ள முடியும்."</string> @@ -357,7 +357,7 @@ <string name="permlab_receiveWapPush" msgid="5991398711936590410">"உரைச் செய்திகளைப் (WAP) பெறுதல்"</string> <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP செய்திகளைப் பெற, செயற்படுத்தப் ஆப்ஸை அனுமதிக்கிறது. உங்களுக்கு அனுப்பப்படும் செய்திகளை உங்களுக்குக் காட்டாமல் கண்காணிக்க அல்லது நீக்குவதற்கான திறன் இந்த அனுமதியில் உள்ளடங்கும்."</string> <string name="permlab_getTasks" msgid="6466095396623933906">"இயங்கும் ஆப்ஸை மீட்டெடுத்தல்"</string> - <string name="permdesc_getTasks" msgid="7454215995847658102">"நடப்பில் மற்றும் சமீபத்தில் இயங்கும் காரியங்களின் தகவலைப் பெற ஆப்ஸை அனுமதிக்கிறது. சாதனத்தில் எந்தப் பயன்பாடுகள் பயன்படுத்தப்படுகின்றன என்பது குறித்த தகவலைக் கண்டறிய ஆப்ஸை இது அனுமதிக்கலாம்."</string> + <string name="permdesc_getTasks" msgid="7454215995847658102">"நடப்பில் மற்றும் சமீபத்தில் இயங்கும் காரியங்களின் தகவலைப் பெற ஆப்ஸை அனுமதிக்கிறது. சாதனத்தில் எந்த ஆப்ஸ் பயன்படுத்தப்படுகின்றன என்பது குறித்த தகவலைக் கண்டறிய ஆப்ஸை இது அனுமதிக்கலாம்."</string> <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"சுயவிவரத்தையும் சாதன உரிமையாளர்களையும் நிர்வகித்தல்"</string> <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"சுயவிவர உரிமையாளர்களையும் சாதன உரிமையாளரையும் அமைக்க, ஆப்ஸை அனுமதிக்கிறது."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"இயங்கும் ஆப்ஸை மறுவரிசைப்படுத்தல்"</string> @@ -365,9 +365,9 @@ <string name="permlab_enableCarMode" msgid="5684504058192921098">"கார் பயன்முறையை இயக்குதல்"</string> <string name="permdesc_enableCarMode" msgid="4853187425751419467">"கார் முறையை இயக்க, ஆப்ஸை அனுமதிக்கிறது."</string> <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"பிற ஆப்ஸை மூடுதல்"</string> - <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"பிற ஆப்ஸின் பின்புலச் செயல்முறைகளை நிறுத்த ஆப்ஸை அனுமதிக்கிறது. இதனால் பிற பயன்பாடுகள் இயங்குவதை நிறுத்தலாம்."</string> + <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"பிற ஆப்ஸின் பின்புலச் செயல்முறைகளை நிறுத்த ஆப்ஸை அனுமதிக்கிறது. இதனால் பிற ஆப்ஸ் இயங்குவதை நிறுத்தலாம்."</string> <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"இந்த ஆப்ஸ் பிற ஆப்ஸின் மேலே தோன்றலாம்"</string> - <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"இந்த ஆப்ஸ் பிற ஆப்ஸின் மேலே அல்லது திரையின் பிற பகுதிகளில் தோன்றலாம். இது வழக்கமான ஆப்ஸ் உபயோகத்தில் குறுக்கிட்டு, பிற பயன்பாடுகள் தோன்றும் விதத்தை மாற்றக்கூடும்."</string> + <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"இந்த ஆப்ஸ் பிற ஆப்ஸின் மேலே அல்லது திரையின் பிற பகுதிகளில் தோன்றலாம். இது வழக்கமான ஆப்ஸ் உபயோகத்தில் குறுக்கிட்டு, பிற ஆப்ஸ் தோன்றும் விதத்தை மாற்றக்கூடும்."</string> <string name="permlab_runInBackground" msgid="7365290743781858803">"பின்னணியில் இயக்கு"</string> <string name="permdesc_runInBackground" msgid="7370142232209999824">"இந்த ஆப்ஸ், பின்னணியில் இயங்கலாம். இதனால் பேட்டரி விரைவாகத் தீர்ந்துவிடக்கூடும்."</string> <string name="permlab_useDataInBackground" msgid="8694951340794341809">"பின்னணியில் தரவைப் பயன்படுத்து"</string> @@ -381,7 +381,7 @@ <string name="permlab_getPackageSize" msgid="7472921768357981986">"பயன்பாட்டுச் சேமிப்பு இடத்தை அளவிடல்"</string> <string name="permdesc_getPackageSize" msgid="3921068154420738296">"ஆப்ஸ், அதன் குறியீடு, தரவு, மற்றும் தற்காலிகச் சேமிப்பு அளவுகளை மீட்டெடுக்க அனுமதிக்கிறது"</string> <string name="permlab_writeSettings" msgid="2226195290955224730">"சாதன அமைப்புகளை மாற்றுதல்"</string> - <string name="permdesc_writeSettings" msgid="7775723441558907181">"முறைமையின் அமைப்பு தரவைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. தீங்குவிளைவிக்கும் பயன்பாடுகள், முறைமையின் உள்ளமைவைச் சிதைக்கலாம்."</string> + <string name="permdesc_writeSettings" msgid="7775723441558907181">"முறைமையின் அமைப்பு தரவைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. தீங்குவிளைவிக்கும் ஆப்ஸ், முறைமையின் உள்ளமைவைச் சிதைக்கலாம்."</string> <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"தொடக்கத்தில் இயக்குதல்"</string> <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"மறுஇயக்கம் முடிந்தது, விரைவில் தானாகவே தொடங்க, ஆப்ஸை அனுமதிக்கிறது. இதனால் டேப்லெட் நீண்ட நேரம் கழித்து தொடங்கும் மற்றும் எப்போதும் இயங்குகின்ற டேப்லெட்டின் ஒட்டுமொத்தச் செயல்பாட்டையும் தாமதமாகும்."</string> <string name="permdesc_receiveBootCompleted" product="tv" msgid="6725487837446317527">"சாதனம் தொடங்கியவுடன் ஆப்ஸைத் தானாகவே தொடங்க அனுமதிக்கும். இது Android TV தொடங்குவதற்கான நேரத்தைத் தாமதமாக்குவதோடு எப்போதும் இயங்கிக்கொண்டிருப்பதன் மூலம் ஒட்டுமொத்த சாதனத்தின் வேகத்தைக் குறைக்கும்."</string> @@ -391,9 +391,9 @@ <string name="permdesc_broadcastSticky" product="tv" msgid="5029460344724532288">"வலைபரப்பு முடிந்த பின்னரும் தங்கிவிடும் ஸ்டிக்கி வலைபரப்புகளை அனுப்ப ஆப்ஸை அனுமதிக்கும். அளவுக்கதிகமான உபயோகம் Android TVயின் வேகத்தைக் குறைக்கவோ நிலையற்றதாகவோ ஆக்கக்கூடும். இதனால் அதிகமான நினைவகம் பயன்படுத்தப்படும்."</string> <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"அலைபரப்பு முடிந்த பின்னும் இருக்கும், தொடர்ந்து அணுகத்தக்க அலைபரப்பை அனுப்பப் ஆப்ஸை அனுமதிக்கிறது. அதிகமாகப் பயன்படுத்தினால், மொபைலானது நினைவகத்தை மிக அதிகமாகப் பயன்படுத்துவதால் வேகம் குறைந்ததாகவும், நிலையற்றதாகவும் ஆகலாம்."</string> <string name="permlab_readContacts" msgid="8348481131899886131">"உங்கள் தொடர்புகளைப் படித்தல்"</string> - <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"குறிப்பிட்டவர்களுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உட்பட, உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைப் படிக்க ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதி, உங்கள் தொடர்பு தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் பயன்பாடுகள் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரலாம்."</string> + <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"குறிப்பிட்டவர்களுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உட்பட, உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைப் படிக்க ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதி, உங்கள் தொடர்பு தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் ஆப்ஸ் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரலாம்."</string> <string name="permdesc_readContacts" product="tv" msgid="3890061004911027912">"உங்கள் Android TVயில் சேமித்துள்ள தொடர்புகள் பற்றிய தரவைத் தெரிந்துகொள்ள ஆப்ஸை அனுமதிக்கும். குறிப்பிட்ட தனிநபரை எத்தனை முறை அழைத்தீர்கள், பிறவழிகளில் தொடர்புகொண்டீர்கள் அல்லது அவருக்கு எத்தனை முறை மின்னஞ்சல் அனுப்பினீர்கள் என்பதும் இதில் அடங்கும். இது உங்கள் தொடர்புத் தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கும், அத்துடன் தீங்குவிளைவிக்கும் ஆப்ஸ் உங்களுக்குத் தெரியாமல் தொடர்புத் தரவைப் பகிரக்கூடும்."</string> - <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"குறிப்பிட்டவர்களுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்ட எண்ணிக்கை உட்பட, உங்கள் மொபைலில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைப் படிக்க ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதி, உங்கள் தொடர்பு தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் பயன்பாடுகள் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரலாம்."</string> + <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"குறிப்பிட்டவர்களுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்ட எண்ணிக்கை உட்பட, உங்கள் மொபைலில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைப் படிக்க ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதி, உங்கள் தொடர்பு தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் ஆப்ஸ் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரலாம்."</string> <string name="permlab_writeContacts" msgid="5107492086416793544">"உங்கள் தொடர்புகளை மாற்றுதல்"</string> <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"குறிப்பிட்ட தொடர்புகளுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உள்பட, உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதியானது தொடர்புத் தரவை நீக்க ஆப்ஸை அனுமதிக்கிறது."</string> <string name="permdesc_writeContacts" product="tv" msgid="307929337692573341">"உங்கள் Android TVயில் சேமித்துள்ள தொடர்புகள் பற்றிய தரவை மாற்ற ஆப்ஸை அனுமதிக்கும். குறிப்பிட்ட தொடர்பை எத்தனை முறை அழைத்தீர்கள், பிறவழிகளில் தொடர்புகொண்டீர்கள் அல்லது அவருக்கு எத்தனை முறை மின்னஞ்சல் அனுப்பினீர்கள் என்பதும் இதில் அடங்கும். தொடர்புத் தரவை நீக்க ஆப்ஸை இது அனுமதிக்கும்."</string> @@ -401,9 +401,9 @@ <string name="permlab_readCallLog" msgid="3478133184624102739">"அழைப்புப் பதிவைப் படித்தல்"</string> <string name="permdesc_readCallLog" msgid="3204122446463552146">"இந்த ஆப்ஸ் உங்கள் அழைப்பு வரலாற்றைப் படிக்கலாம்."</string> <string name="permlab_writeCallLog" msgid="8552045664743499354">"அழைப்புப் பதிவை எழுதுதல்"</string> - <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் டேப்லெட்டின் அழைப்புப் பதிவைத் திருத்துவதற்குப் ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் பயன்பாடுகள் இதைப் பயன்படுத்தலாம்."</string> + <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் டேப்லெட்டின் அழைப்புப் பதிவைத் திருத்துவதற்குப் ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தலாம்."</string> <string name="permdesc_writeCallLog" product="tv" msgid="7939219462637746280">"உள்வரும், வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உட்பட உங்கள் Android TVயின் அழைப்புப் பதிவைத் திருத்த ஆப்ஸை அனுமதிக்கும். உங்கள் அழைப்புப் பதிவை அழிக்கவோ திருத்தவோ தீங்கு விளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தக்கூடும்."</string> - <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் மொபைல் அழைப்புப் பதிவைத் திருத்துவதற்குப் ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் பயன்பாடுகள் இதைப் பயன்படுத்தலாம்."</string> + <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் மொபைல் அழைப்புப் பதிவைத் திருத்துவதற்குப் ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தலாம்."</string> <string name="permlab_bodySensors" msgid="4683341291818520277">"உடல் உணர்விகளை (இதயத் துடிப்பு மானிட்டர்கள் போன்றவை) அணுகுதல்"</string> <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"உங்கள் இதயத்துடிப்பு விகிதம் போன்ற உங்கள் உடல்நிலையைக் கண்காணிக்கும் உணர்விகளில் இருந்து தரவை அணுக ஆப்ஸை அனுமதிக்கும்."</string> <string name="permlab_readCalendar" msgid="6716116972752441641">"கேலெண்டர் நிகழ்வுகளையும் விவரங்களையும் படிக்கலாம்"</string> @@ -439,7 +439,7 @@ <string name="permlab_vibrate" msgid="7696427026057705834">"அதிர்வைக் கட்டுப்படுத்துதல்"</string> <string name="permdesc_vibrate" msgid="6284989245902300945">"அதிர்வைக் கட்டுப்படுத்தப் ஆப்ஸை அனுமதிக்கிறது."</string> <string name="permlab_callPhone" msgid="3925836347681847954">"தொலைபேசி எண்களை நேரடியாக அழைத்தல்"</string> - <string name="permdesc_callPhone" msgid="3740797576113760827">"உங்கள் தலையீட்டின்றி மொபைல் எண்களை அழைக்கப் ஆப்ஸை அனுமதிக்கிறது. இதன் விளைவாக எதிர்பாராத கட்டணங்களோ அழைப்புகளோ ஏற்படலாம். அவசரகால எண்களை அழைக்க இது ஆப்ஸை அனுமதிக்காது என்பதை நினைவில்கொள்ளவும். தீங்கிழைக்கும் பயன்பாடுகள், உங்கள் உறுதிப்படுத்தல் இன்றி அழைப்புகளைச் செய்வதால் உங்களுக்குச் செலவு ஏற்படக்கூடும்."</string> + <string name="permdesc_callPhone" msgid="3740797576113760827">"உங்கள் தலையீட்டின்றி மொபைல் எண்களை அழைக்கப் ஆப்ஸை அனுமதிக்கிறது. இதன் விளைவாக எதிர்பாராத கட்டணங்களோ அழைப்புகளோ ஏற்படலாம். அவசரகால எண்களை அழைக்க இது ஆப்ஸை அனுமதிக்காது என்பதை நினைவில்கொள்ளவும். தீங்கிழைக்கும் ஆப்ஸ், உங்கள் உறுதிப்படுத்தல் இன்றி அழைப்புகளைச் செய்வதால் உங்களுக்குச் செலவு ஏற்படக்கூடும்."</string> <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS அழைப்புச் சேவையை அணுகுதல்"</string> <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"உங்கள் குறுக்கீடின்றி IMS சேவையைப் பயன்படுத்தி அழைப்பதற்கு, ஆப்ஸை அனுமதிக்கும்."</string> <string name="permlab_readPhoneState" msgid="9178228524507610486">"மொபைல் நிலை மற்றும் அடையாளத்தைப் படித்தல்"</string> @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"தொந்தரவு செய்ய வேண்டாம் உள்ளமைவைப் படிக்கவும் எழுதவும், ஆப்ஸை அனுமதிக்கிறது."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"அனுமதி உபயோகத்தை அணுகுதல்"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ஆப்ஸிற்கான அனுமதி உபயோகத்தை ஹோல்டருக்கு வழங்கும். இயல்பான ஆப்ஸிற்கு இது எப்போதுமே தேவைப்படாது."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"அணுகலம்ச ஷார்ட்கட் இலக்கு"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"அணுகலம்ச ஷார்ட்கட் இலக்கை விளக்க ஆப்ஸை அனுமதிக்கும்."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"கடவுச்சொல் விதிகளை அமைக்கவும்"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"திரைப் பூட்டின் கடவுச்சொற்கள் மற்றும் பின்களில் அனுமதிக்கப்படும் நீளத்தையும் எழுத்துக்குறிகளையும் கட்டுப்படுத்தும்."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"திரையைத் திறப்பதற்கான முயற்சிகளைக் கண்காணி"</string> @@ -939,15 +941,15 @@ <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"உங்கள் இணையப் புத்தக்கக்குறிகள் மற்றும் வரலாற்றைப் படித்தல்"</string> <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"உலாவி மூலம் பார்வையிட்ட எல்லா URLகளின் வரலாற்றையும், உலாவியில் குறிக்கப்பட்ட எல்லா புத்தகக்குறிகளையும் படிக்கப் ஆப்ஸை அனுமதிக்கிறது. குறிப்பு: மூன்றாம் தரப்பு உலாவிகள் அல்லது இணைய உலாவல் திறன்களுடன் கூடிய பிற பயன்பாடுகளால் இந்த அனுமதி செயற்படுத்தப்படாமல் போகலாம்."</string> <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"இணையப் புத்தகக்குறிகளையும், வரலாற்றையும் எழுதுதல்"</string> - <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்கவோ, திருத்தவோ ஆப்ஸை அனுமதிக்கலாம். குறிப்பு: இணைய உலாவல் செயல்திறன்கள் மூலம் மூன்றாம் தரப்பு உலாவிகள் அல்லது பிற பயன்பாடுகள் இந்த அனுமதியைச் செயற்படுத்த முடியாது."</string> + <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்கவோ, திருத்தவோ ஆப்ஸை அனுமதிக்கலாம். குறிப்பு: இணைய உலாவல் செயல்திறன்கள் மூலம் மூன்றாம் தரப்பு உலாவிகள் அல்லது பிற ஆப்ஸ் இந்த அனுமதியைச் செயற்படுத்த முடியாது."</string> <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="6340829212433680418">"Android TVயில் சேமித்துள்ள உலாவியின் மூலம் பார்க்கப்பட்ட தளங்களையோ புக்மார்க்குகளையோ திருத்த ஆப்ஸை அனுமதிக்கும். இது உலாவியின் தரவை அழிக்கவோ திருத்தவோ ஆப்ஸை அனுமதிக்கக்கூடும். கவனத்திற்கு: மூன்றாம் தரப்பு உலாவிகளோ இணைய உலாவல் திறன்களுடன் கூடிய பிற ஆப்ஸோ இந்த அனுமதியைச் செயல்படுத்த முடியாது."</string> - <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"உங்கள் மொபைலில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்கவோ, திருத்தவோ ஆப்ஸை அனுமதிக்கலாம். குறிப்பு: இணைய உலாவல் செயல்திறன்கள் மூலம் மூன்றாம் தரப்பு உலாவிகள் அல்லது பிற பயன்பாடுகள் இந்த அனுமதியைச் செயற்படுத்த முடியாது."</string> + <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"உங்கள் மொபைலில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்கவோ, திருத்தவோ ஆப்ஸை அனுமதிக்கலாம். குறிப்பு: இணைய உலாவல் செயல்திறன்கள் மூலம் மூன்றாம் தரப்பு உலாவிகள் அல்லது பிற ஆப்ஸ் இந்த அனுமதியைச் செயற்படுத்த முடியாது."</string> <string name="permlab_setAlarm" msgid="1379294556362091814">"அலாரத்தை அமைத்தல்"</string> <string name="permdesc_setAlarm" msgid="316392039157473848">"நிறுவிய அலார கடிகாரப் பயன்பாட்டில் அலாரத்தை அமைக்க, ஆப்ஸை அனுமதிக்கிறது. சில அலார கடிகார பயன்பாடுகளில் இந்த அம்சம் இல்லாமல் இருக்கலாம்."</string> <string name="permlab_addVoicemail" msgid="5525660026090959044">"குரலஞ்சலைச் சேர்த்தல்"</string> <string name="permdesc_addVoicemail" msgid="6604508651428252437">"குரலஞ்சல் இன்பாக்ஸில் செய்திகளைச் சேர்க்க, ஆப்ஸை அனுமதிக்கிறது."</string> <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"உலாவியின் புவியியல் இருப்பிடம் சார்ந்த அனுமதிகளைத் திருத்துதல்"</string> - <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"உலாவியின் புவியியல் இருப்பிடம் சார்ந்த அனுமதிகளைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. இடத் தகவலை தன்னிச்சையான இணையதளங்களுக்கு அனுப்புவதை அனுமதிக்க, தீங்குவிளைவிக்கும் பயன்பாடுகள் இதைப் பயன்படுத்தலாம்."</string> + <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"உலாவியின் புவியியல் இருப்பிடம் சார்ந்த அனுமதிகளைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. இடத் தகவலை தன்னிச்சையான இணையதளங்களுக்கு அனுப்புவதை அனுமதிக்க, தீங்குவிளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தலாம்."</string> <string name="save_password_message" msgid="767344687139195790">"இந்தக் கடவுச்சொல்லை உலாவி நினைவில்கொள்ள விரும்புகிறீர்களா?"</string> <string name="save_password_notnow" msgid="6389675316706699758">"இப்போது இல்லை"</string> <string name="save_password_remember" msgid="6491879678996749466">"நினைவில்கொள்"</string> @@ -1156,10 +1158,10 @@ <string name="whichImageCaptureApplicationLabel" msgid="6390303445371527066">"படமெடு"</string> <string name="alwaysUse" msgid="4583018368000610438">"இந்தச் செயலுக்கு இயல்பாகப் பயன்படுத்து."</string> <string name="use_a_different_app" msgid="8134926230585710243">"வேறு ஆப்ஸைப் பயன்படுத்தவும்"</string> - <string name="clearDefaultHintMsg" msgid="3252584689512077257">"முறைமை அமைப்பு > பயன்பாடுகள் > பதிவிறக்கியவை என்பதில் உள்ள இயல்பை அழிக்கவும்."</string> + <string name="clearDefaultHintMsg" msgid="3252584689512077257">"முறைமை அமைப்பு > ஆப்ஸ் > பதிவிறக்கியவை என்பதில் உள்ள இயல்பை அழிக்கவும்."</string> <string name="chooseActivity" msgid="7486876147751803333">"செயலைத் தேர்ந்தெடுக்கவும்"</string> <string name="chooseUsbActivity" msgid="6894748416073583509">"USB சாதனத்திற்கான பயன்பாட்டைத் தேர்வுசெய்க"</string> - <string name="noApplications" msgid="2991814273936504689">"இந்தச் செயலைச் செய்ய பயன்பாடுகள் எதுவுமில்லை."</string> + <string name="noApplications" msgid="2991814273936504689">"இந்தச் செயலைச் செய்ய ஆப்ஸ் எதுவுமில்லை."</string> <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> செயலிழந்தது"</string> <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> செயலிழந்தது"</string> <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> தொடர்ந்து செயலிழக்கிறது"</string> @@ -1184,7 +1186,7 @@ <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> உண்மையாக வெளியிடப்பட்டது."</string> <string name="screen_compat_mode_scale" msgid="3202955667675944499">"அளவு"</string> <string name="screen_compat_mode_show" msgid="4013878876486655892">"எப்போதும் காட்டு"</string> - <string name="screen_compat_mode_hint" msgid="1064524084543304459">"சிஸ்டம் அமைப்பு > பயன்பாடுகள் > பதிவிறக்கம் என்பதில் இதை மீண்டும் இயக்கவும்."</string> + <string name="screen_compat_mode_hint" msgid="1064524084543304459">"சிஸ்டம் அமைப்பு > ஆப்ஸ் > பதிவிறக்கம் என்பதில் இதை மீண்டும் இயக்கவும்."</string> <string name="unsupported_display_size_message" msgid="6545327290756295232">"தற்போதைய திரை அளவு அமைப்பை <xliff:g id="APP_NAME">%1$s</xliff:g> ஆதரிக்காததால், அது வழக்கத்திற்கு மாறாகச் செயல்படக்கூடும்."</string> <string name="unsupported_display_size_show" msgid="7969129195360353041">"எப்போதும் காட்டு"</string> <string name="unsupported_compile_sdk_message" msgid="4253168368781441759">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாடானது, இந்தச் சாதனத்தின் Android OSக்கு இணக்கமற்ற பதிப்பிற்காக உருவாக்கப்பட்டதால், இதில் சரியாகச் செயல்படாது. இந்த ஆப்ஸின் புதுப்பிக்கப்பட்ட பதிப்பானது தற்போது கிடைக்கக்கூடும்."</string> @@ -1204,7 +1206,7 @@ <string name="app_upgrading_toast" msgid="3008139776215597053">"<xliff:g id="APPLICATION">%1$s</xliff:g>ஐ மேம்படுத்துகிறது…"</string> <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g> ஆப்ஸை ஒருங்கிணைக்கிறது."</string> <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g>ஐத் தயார்செய்கிறது."</string> - <string name="android_upgrading_starting_apps" msgid="451464516346926713">"பயன்பாடுகள் தொடங்கப்படுகின்றன."</string> + <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ஆப்ஸ் தொடங்கப்படுகின்றன."</string> <string name="android_upgrading_complete" msgid="1405954754112999229">"துவக்குதலை முடிக்கிறது."</string> <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> இயங்குகிறது"</string> <string name="heavy_weight_notification_detail" msgid="2304833848484424985">"கேமிற்குச் செல்ல, தட்டவும்"</string> @@ -1322,7 +1324,7 @@ <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"அனுப்பு"</string> <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"ரத்துசெய்"</string> <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"எனது விருப்பத்தேர்வை நினைவில்கொள்"</string> - <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"அமைப்பு > பயன்பாடுகள் என்பதில் பிறகு நீங்கள் மாற்றலாம்"</string> + <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"அமைப்பு > ஆப்ஸ் என்பதில் பிறகு நீங்கள் மாற்றலாம்"</string> <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"எப்போதும் அனுமதி"</string> <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"ஒருபோதும் அனுமதிக்காதே"</string> <string name="sim_removed_title" msgid="6227712319223226185">"சிம் கார்டு அகற்றப்பட்டது"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB பிழைதிருத்தத்தை முடக்க, தேர்ந்தெடுக்கவும்."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"\'தன்னியக்க சோதனைப்\' பயன்முறை இயக்கப்பட்டது"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"’தன்னியக்க சோதனைப்\' பயன்முறையை முடக்க ஆரம்பநிலைக்கு மீட்டமைக்கவும்."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"சீரியல் கன்சோல் இயக்கப்பட்டது"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"செயல்திறன் பாதிக்கப்பட்டுள்ளது. முடக்குவதற்கு பூட்லோடரைத் தேர்வுசெய்யவும்."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB போர்ட்டில் சேதம் உள்ளது"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB போர்ட் தானாகவே முடக்கப்பட்டது மேலும் அறிய, தட்டவும்."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB போர்ட்டைப் பயன்படுத்தலாம்"</string> @@ -1446,7 +1450,7 @@ <string name="ime_action_default" msgid="2840921885558045721">"செயலாக்கு"</string> <string name="dial_number_using" msgid="5789176425167573586">"<xliff:g id="NUMBER">%s</xliff:g> ஐப் பயன்படுத்தி\nஅழை"</string> <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g> ஐப்\nபயன்படுத்தி தொடர்பை உருவாக்கு"</string> - <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"பின்வரும் ஒன்று அல்லது அதற்கு மேற்பட்ட பயன்பாடுகள், இப்போதும் எதிர்காலத்திலும் உங்கள் கணக்கை அணுகுவதற்கான அனுமதியைக் கோருகின்றன."</string> + <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"பின்வரும் ஒன்று அல்லது அதற்கு மேற்பட்ட ஆப்ஸ், இப்போதும் எதிர்காலத்திலும் உங்கள் கணக்கை அணுகுவதற்கான அனுமதியைக் கோருகின்றன."</string> <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"இந்தக் கோரிக்கையை அனுமதிக்க விரும்புகிறீர்களா?"</string> <string name="grant_permissions_header_text" msgid="6874497408201826708">"அணுகல் கோரிக்கை"</string> <string name="allow" msgid="7225948811296386551">"அனுமதி"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"வகைப்படுத்தப்படாதவை"</string> <string name="importance_from_user" msgid="7318955817386549931">"இந்த அறிவிப்புகளின் முக்கியத்துவத்தை அமைத்துள்ளீர்கள்."</string> <string name="importance_from_person" msgid="9160133597262938296">"ஈடுபட்டுள்ளவர்களின் காரணமாக, இது முக்கியமானது."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> மூலம் புதிய பயனரை உருவாக்க <xliff:g id="APP">%1$s</xliff:g> ஆப்ஸை அனுமதிக்கவா (இந்தக் கணக்கில் ஏற்கெனவே ஒரு பயனர் உள்ளார்) ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> மூலம் புதிய பயனரை உருவாக்க <xliff:g id="APP">%1$s</xliff:g> ஆப்ஸை அனுமதிக்கவா?"</string> <string name="language_selection_title" msgid="2680677278159281088">"மொழியைச் சேர்"</string> <string name="country_selection_title" msgid="2954859441620215513">"மண்டல விருப்பம்"</string> <string name="search_language_hint" msgid="7042102592055108574">"மொழி பெயரை உள்ளிடுக"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index a8550f860cc9..a14bcb99d08a 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"అంతరాయం కలిగించవద్దు ఎంపిక కాన్ఫిగరేషన్ చదవడానికి మరియు వ్రాయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"వీక్షణ అనుమతి వినియోగాన్ని ప్రారంభించండి"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"యాప్నకు అనుమతి వినియోగాన్ని ప్రారంభించడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ యాప్లకు ఎప్పటికీ ఇటువంటి అనుమతి అవసరం ఉండదు."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"యాక్సెసిబిలిటీ షార్ట్కట్ లక్ష్యం"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"యాక్సెసిబిలిటీ షార్ట్కట్ లక్ష్యాన్ని నిర్వచించడానికి యాప్ను అనుమతించండి."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"పాస్వర్డ్ నియమాలను సెట్ చేయండి"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"స్క్రీన్ లాక్ పాస్వర్డ్లు మరియు PINల్లో అనుమతించబడిన పొడవు మరియు అక్షరాలను నియంత్రిస్తుంది."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"స్క్రీన్ అన్లాక్ ప్రయత్నాలను పర్యవేక్షించండి"</string> @@ -1330,7 +1332,7 @@ <string name="sim_done_button" msgid="827949989369963775">"పూర్తయింది"</string> <string name="sim_added_title" msgid="3719670512889674693">"సిమ్ కార్డు జోడించబడింది"</string> <string name="sim_added_message" msgid="6599945301141050216">"మొబైల్ నెట్వర్క్ను యాక్సెస్ చేయడానికి మీ పరికరాన్ని పునఃప్రారంభించండి."</string> - <string name="sim_restart_button" msgid="4722407842815232347">"పునఃప్రారంభించు"</string> + <string name="sim_restart_button" msgid="4722407842815232347">"రీస్టార్ట్ చేయి"</string> <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"మొబైల్ సేవను సక్రియం చేయండి"</string> <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"మీ కొత్త SIMని సక్రియం చేయడానికి క్యారియర్ యాప్ను డౌన్లోడ్ చేయండి"</string> <string name="install_carrier_app_notification_text_app_name" msgid="1196505084835248137">"మీ కొత్త SIMని సక్రియం చేయడం కోసం <xliff:g id="APP_NAME">%1$s</xliff:g> యాప్ని డౌన్లోడ్ చేయండి"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"డీబగ్గింగ్ని నిలిపివేయడానికి ఎంచుకోండి."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"పరీక్ష నియంత్రణ మోడ్ ప్రారంభించబడింది"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"పరీక్ష నియంత్రణ మోడ్ను నిలిపివేయడానికి ఫ్యాక్టరీ రీసెట్ను అమలు చేయండి."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"సీరియల్ కన్సోల్ ప్రారంభించబడింది"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"పని తీరు ప్రభావితమైంది. నిలిపివేయడానికి, బూట్లోడర్ను తనిఖీ చేయండి."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB పోర్ట్లో ద్రవ లేదా వ్యర్థ పదార్థాలు ఉన్నాయి"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB పోర్ట్ ఆటోమేటిక్గా నిలిపివేయబడింది. మరింత తెలుసుకోవడానికి నొక్కండి."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB పోర్ట్ను ఉపయోగించడం సురక్షితం"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"వర్గీకరించబడలేదు"</string> <string name="importance_from_user" msgid="7318955817386549931">"మీరు ఈ నోటిఫికేషన్ల ప్రాముఖ్యతను సెట్ చేసారు."</string> <string name="importance_from_person" msgid="9160133597262938296">"ఇందులో పేర్కొనబడిన వ్యక్తులను బట్టి ఇది చాలా ముఖ్యమైనది."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g>తో కొత్త వినియోగదారుని సృష్టించడానికి <xliff:g id="APP">%1$s</xliff:g>ను అనుమతించాలా (ఈ ఖాతాతో ఇప్పటికే ఒక వినియోగదారు ఉన్నారు) ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g>తో కొత్త వినియోగదారుని సృష్టించడానికి <xliff:g id="APP">%1$s</xliff:g>ను అనుమతించాలా?"</string> <string name="language_selection_title" msgid="2680677278159281088">"భాషను జోడించండి"</string> <string name="country_selection_title" msgid="2954859441620215513">"ప్రాంతం ప్రాధాన్యత"</string> <string name="search_language_hint" msgid="7042102592055108574">"భాష పేరును టైప్ చేయండి"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index f2376d7959d2..4210354f5da6 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"อนุญาตให้แอปอ่านและเขียนการกำหนดค่าโหมดห้ามรบกวน"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"เริ่มการใช้สิทธิ์การดู"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"อนุญาตให้เจ้าของเริ่มการใช้สิทธิ์ของแอป ไม่จำเป็นสำหรับแอปทั่วไป"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"เป้าหมายทางลัดการช่วยเหลือพิเศษ"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"อนุญาตให้แอปกำหนดเป้าหมายทางลัดการช่วยเหลือพิเศษ"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"ตั้งค่ากฎรหัสผ่าน"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"ควบคุมความยาวและอักขระที่สามารถใช้ในรหัสผ่านของการล็อกหน้าจอและ PIN"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"ตรวจสอบความพยายามในการปลดล็อกหน้าจอ"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"เลือกเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"โหมดโปรแกรมทดสอบอัตโนมัติเปิดใช้อยู่"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"รีเซ็ตเป็นค่าเริ่มต้นเพื่อปิดใช้โหมดโปรแกรมทดสอบอัตโนมัติ"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"เปิดใช้คอนโซลการเรียงอันดับแล้ว"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"ประสิทธิภาพได้รับผลกระทบ ตรวจสอบ Bootloader เพื่อปิดใช้งาน"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"มีของเหลวหรือฝุ่นละอองในพอร์ต USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"พอร์ต USB ปิดใช้โดยอัตโนมัติ แตะเพื่อดูข้อมูลเพิ่มเติม"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ใช้พอร์ต USB ได้แล้ว"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"ไม่จัดอยู่ในหมวดหมู่ใดๆ"</string> <string name="importance_from_user" msgid="7318955817386549931">"คุณตั้งค่าความสำคัญของการแจ้งเตือนเหล่านี้"</string> <string name="importance_from_person" msgid="9160133597262938296">"ข้อความนี้สำคัญเนื่องจากบุคคลที่เกี่ยวข้อง"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"อนุญาตให้ <xliff:g id="APP">%1$s</xliff:g> สร้างผู้ใช้ใหม่ด้วย <xliff:g id="ACCOUNT">%2$s</xliff:g> ไหม (มีผู้ใช้ที่มีบัญชีนี้อยู่แล้ว)"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"อนุญาตให้ <xliff:g id="APP">%1$s</xliff:g> สร้างผู้ใช้ใหม่ด้วย <xliff:g id="ACCOUNT">%2$s</xliff:g> ไหม"</string> <string name="language_selection_title" msgid="2680677278159281088">"เพิ่มภาษา"</string> <string name="country_selection_title" msgid="2954859441620215513">"ค่ากำหนดภูมิภาค"</string> <string name="search_language_hint" msgid="7042102592055108574">"พิมพ์ชื่อภาษา"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 9acd72aaeaf0..70d2a2f62497 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Nagbibigay-daan sa app na basahin at isulat ang configuration ng Huwag Istorbohin."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"simulan ang paggamit sa pahintulot sa pagtingin"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Binibigyang-daan ang may hawak na simulan ang paggamit ng pahintulot para sa isang app. Hindi dapat kailanganin kailanman para sa mga normal na app."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"Target ng shortcut sa pagiging accessible"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Nagbibigay-daan sa isang app na tukuyin ang target ng shortcut sa pagiging accessible."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Magtakda ng mga panuntunan sa password"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolin ang haba at ang mga character na pinapayagan sa mga password at PIN sa screen lock."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Subaybayan ang mga pagsubok sa pag-unlock ng screen"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Piliin upang i-disable ang debugging ng USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Naka-enable ang Test Harness Mode"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Mag-factory reset para i-disable ang Test Harness Mode."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Naka-enable ang serial console"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Naaapektuhan ang performance. Para i-disable, lagyan ng check ang bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid o debris sa USB port"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Awtomatikong na-disable ang USB port. Mag-tap para matuto pa."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Ayos na gamitin ang USB port"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Di-nakategorya"</string> <string name="importance_from_user" msgid="7318955817386549931">"Ikaw ang magtatakda sa kahalagahan ng mga notification na ito."</string> <string name="importance_from_person" msgid="9160133597262938296">"Mahalaga ito dahil sa mga taong kasangkot."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Payagan ang <xliff:g id="APP">%1$s</xliff:g> na gumawa ng bagong User sa <xliff:g id="ACCOUNT">%2$s</xliff:g> (mayroon nang User sa account na ito) ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Payagan ang <xliff:g id="APP">%1$s</xliff:g> na gumawa ng bagong User sa <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Magdagdag ng wika"</string> <string name="country_selection_title" msgid="2954859441620215513">"Kagustuhan sa rehiyon"</string> <string name="search_language_hint" msgid="7042102592055108574">"I-type ang wika"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index e2bda9fc602e..94e21dcd8cac 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Uygulamaya, Rahatsız Etmeyin yapılandırmasını okuma ve yazma izni verir."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"izin kullanımı görüntülemeye başlama"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"İzin sahibinin bir uygulama için izin kullanımı başlatmasına olanak tanır. Normal uygulamalar için hiçbir zaman kullanılmamalıdır."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"erişilebilirlik kısayolu hedefi"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Uygulamaların erişilebilirlik kısayolu hedefi tanımlamasına izin verir."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Şifre kuralları ayarla"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Ekran kilidini açma şifrelerinde ve PIN\'lerde izin verilen uzunluğu ve karakterleri denetleyin."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Ekran kilidini açma denemelerini izle"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB hata ayıklamasını devre dışı bırakmak için seçin."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test Bandı Modu etkin"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Test Bandı Modu\'nu devre dışı bırakmak için cihazı fabrika ayarlarına sıfırlayın."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Seri konsol etkinleştirildi"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Performans etkilendi. Devre dışı bırakmak için bootloader\'ı kontrol edin."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB bağlantı noktasında sıvı veya toz var"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB bağlantı noktası otomatik olarak devre dışı bırakıldı. Daha fazla bilgi için dokunun."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB bağlantı noktasını kullanabilirsiniz"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Kategorize edilmemiş"</string> <string name="importance_from_user" msgid="7318955817386549931">"Bu bildirimlerin önem derecesini ayarladınız."</string> <string name="importance_from_person" msgid="9160133597262938296">"Bu, dahil olan kişiler nedeniyle önemlidir."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> uygulamasının <xliff:g id="ACCOUNT">%2$s</xliff:g> hesabına sahip yeni bir Kullanıcı eklemesine izin verilsin mi (bu hesaba sahip bir kullanıcı zaten var)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> uygulamasının <xliff:g id="ACCOUNT">%2$s</xliff:g> hesabına sahip yeni bir Kullanıcı eklemesine izin verilsin mi?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Dil ekleyin"</string> <string name="country_selection_title" msgid="2954859441620215513">"Bölge tercihi"</string> <string name="search_language_hint" msgid="7042102592055108574">"Dil adını yazın"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index ee5257554ac9..3c306093e8bf 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -661,6 +661,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Додаток зможе переглядати та змінювати конфігурацію режиму \"Не турбувати\"."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"перегляньте дані про використання дозволів"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Власник зможе використовувати дозволи для цього додатка. Цей дозвіл не потрібен для звичайних додатків."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"потрібні засоби спеціальних можливостей"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Дає додатку змогу визначати потрібні засоби спеціальних можливостей."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Устан. правила пароля"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Укажіть максимальну довжину та кількість символів для паролів розблокування екрана та PIN-кодів."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Відстежувати спроби розблокування екрана"</string> @@ -1405,6 +1407,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Виберіть, щоб вимкнути налагодження за USB"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Увімкнено режим автоматизованого тестування"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Щоб вимкнути режим автоматизованого тестування, відновіть заводські налаштування."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Послідовну консоль увімкнено"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Продуктивність зазнала впливу. Щоб вимкнути, перевірте завантажувач операційної системи."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Рідина або сміття в USB-порту"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-порт автоматично вимкнено. Торкніться, щоб дізнатися більше."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Можна використовувати USB-порт"</string> @@ -1958,10 +1962,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Без категорії"</string> <string name="importance_from_user" msgid="7318955817386549931">"Ви вказуєте пріоритет цих сповіщень."</string> <string name="importance_from_person" msgid="9160133597262938296">"Важливе з огляду на учасників."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Дозволити додатку <xliff:g id="APP">%1$s</xliff:g> створити нового користувача з обліковим записом <xliff:g id="ACCOUNT">%2$s</xliff:g> (користувач із таким обліковим записом уже існує)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Дозволити додатку <xliff:g id="APP">%1$s</xliff:g> створити нового користувача з обліковим записом <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Додати мову"</string> <string name="country_selection_title" msgid="2954859441620215513">"Вибір регіону"</string> <string name="search_language_hint" msgid="7042102592055108574">"Введіть назву мови"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 5cc8db70decc..59b30f09e845 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"ایپ کو ڈسٹرب نہ کریں کنفیگریشن لکھنے اور پڑھنے کے قابل کرتا ہے۔"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"اجازت کی استعمال کا ملاحظہ شروع کریں"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"حامل کو ایپ کی اجازت کے استعمال کو شروع کرنے کی اجازت دیتا ہے۔ عام ایپس کے لیے کبھی بھی درکار نہیں ہونا چاہیے۔"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ایکسیسبیلٹی شارٹ کٹ ہدف"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ایپ کو ایکسیسبیلٹی شارٹ کٹ ہدف کی وضاحت کرنے کے ليے اجازتیں۔"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"پاس ورڈ کے اصول سیٹ کریں"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"اسکرین لاک پاس ورڈز اور PINs میں اجازت یافتہ لمبائی اور حروف کو کنٹرول کریں۔"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"اسکرین غیر مقفل کرنے کی کوششیں مانیٹر کریں"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ڈیبگ کرنے کو غیر فعال کرنے کیلئے منتخب کریں۔"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"ٹیسٹ ہارنیس موڈ فعال ہے"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ٹیسٹ ہارنیس موڈ غیر فعال کرنے کے لیے فیکٹری ری سیٹ کریں۔"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"شمار کونسول فعال ہے"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"کارکردگی پر اثر پڑا ہے۔ غیر فعال کرنے کے ليے، بوٹ لوڈر چیک کریں۔"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB پورٹ میں سیال یا دھول ہے"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB پورٹ خودکار طور پر غیر فعال کر دیا گیا۔ مزید جاننے کیلئے تھپتھپائیں۔"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB پورٹ کا استعمال ٹھیک ہے"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"غیر زمرہ بند"</string> <string name="importance_from_user" msgid="7318955817386549931">"ان اطلاعات کی اہمیت آپ مقرر کرتے ہیں۔"</string> <string name="importance_from_person" msgid="9160133597262938296">"اس میں موجود لوگوں کی وجہ سے یہ اہم ہے۔"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> کو <xliff:g id="ACCOUNT">%2$s</xliff:g> کے ساتھ ایک نیا صارف بنانے کی اجازت دیں (اس اکاؤنٹ کے ساتھ ایک صارف پہلے سے موجود ہے) ؟"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> کے ساتھ نئے صارف کو تخلیق کرنے کے لیے <xliff:g id="APP">%1$s</xliff:g> کو اجازت دیں ؟"</string> <string name="language_selection_title" msgid="2680677278159281088">"ایک زبان شامل کریں"</string> <string name="country_selection_title" msgid="2954859441620215513">"علاقہ کی ترجیح"</string> <string name="search_language_hint" msgid="7042102592055108574">"زبان کا نام ٹائپ کریں"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index cb5191dd82c9..22655d00b785 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"“Bezovta qilinmasin” rejimi sozlamalarini ko‘rish va o‘zgartirish."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"foydalaniladigan ruxsatlar axborotini ochish"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Ilova foydalanadigan ruxsatlar axborotini ishga tushirishga ruxsat beradi. Oddiy ilovalar uchun talab qilinmaydi."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"tezkor yoqish maqsadi"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Ilova tezkor yoqish maqsadini aniqlay oladi."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Parol qoidalarini o‘rnatish"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Ekran qulfi paroli va PIN kodlari uchun qo‘yiladigan talablarni (belgilar soni va uzunligi) nazorat qiladi."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Ekranni qulfdan chiqarishga urinishlarni nazorat qilish"</string> @@ -1362,6 +1364,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB orqali nosozliklarni tuzatishni o‘chirib qo‘yish uchun bosing."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Xavfsizlik sinovi rejimi yoqildi"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Xavfsizlik sinovi rejimini faolsizlantirish uchun zavod sozlamalariga qaytaring."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Davomiy port terminali yoqildi"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Samaradorlik pasaydi. Terminalni faolsizlantirish uchun operatsion tizim yuklagichini oching."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB portda suyuqlik yoki parcha bor"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port avtomatik tarzda faolsizlashtirildi. Batafsil axborot olish uchun bosing."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB portdan foydalanish mumkin"</string> @@ -1891,10 +1895,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Turkumlanmagan"</string> <string name="importance_from_user" msgid="7318955817386549931">"Siz ushbu bildirishnomalarning muhimligini belgilagansiz."</string> <string name="importance_from_person" msgid="9160133597262938296">"Bu odamlar siz uchun muhim."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> ilovasiga <xliff:g id="ACCOUNT">%2$s</xliff:g> hisobi bilan yangi foydalanuvchi yaratishiga ruxsat berilsinmi (bunday hisobdagi foydalanuvchi allaqachon mavjud) ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> ilovasiga <xliff:g id="ACCOUNT">%2$s</xliff:g> hisobi bilan yangi foydalanuvchi yaratishiga ruxsat berilsinmi ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Til qoʻshish"</string> <string name="country_selection_title" msgid="2954859441620215513">"Hudud sozlamalari"</string> <string name="search_language_hint" msgid="7042102592055108574">"Til nomini kiriting"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index e41dc4374714..f36d993cfbdb 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Cho phép ứng dụng đọc và ghi cấu hình Không làm phiền."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"cấp quyền xem"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Cho phép chủ sở hữu cấp quyền cho một ứng dụng. Các ứng dụng thông thường sẽ không bao giờ cần quyền này."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"đích đến của phím tắt hỗ trợ tiếp cận"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Cho phép ứng dụng xác định đích đến của phím tắt hỗ trợ tiếp cận."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Đặt quy tắc mật khẩu"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kiểm soát độ dài và ký tự được phép trong mật khẩu khóa màn hình và mã PIN."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Giám sát những lần thử mở khóa màn hình"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chọn để tắt chế độ gỡ lỗi qua USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Đã bật Chế độ khai thác kiểm thử"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Khôi phục cài đặt gốc để tắt Chế độ khai thác kiểm thử."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"Đã bật bảng điều khiển cổng nối tiếp"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Hiệu suất sẽ bị ảnh hưởng. Để tắt, hãy chọn trình tải khởi động."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Có chất lỏng hoặc mảnh vỡ trong cổng USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Cổng USB đã tự động tắt. Nhấn để tìm hiểu thêm."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Có thể sử dụng cổng USB"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Chưa được phân loại"</string> <string name="importance_from_user" msgid="7318955817386549931">"Bạn đặt tầm quan trọng của các thông báo này."</string> <string name="importance_from_person" msgid="9160133597262938296">"Thông báo này quan trọng vì những người có liên quan."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Cho phép <xliff:g id="APP">%1$s</xliff:g> tạo người dùng mới bằng <xliff:g id="ACCOUNT">%2$s</xliff:g> (đã tồn tại người dùng có tài khoản này)?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Cho phép <xliff:g id="APP">%1$s</xliff:g> tạo người dùng mới bằng <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Thêm ngôn ngữ"</string> <string name="country_selection_title" msgid="2954859441620215513">"Tùy chọn khu vực"</string> <string name="search_language_hint" msgid="7042102592055108574">"Nhập tên ngôn ngữ"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index ba39f1e22e2c..461bbb0531e2 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"允许此应用读取和写入“勿扰”模式配置。"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"授权使用“查看权限”"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"允许该应用开始查看应用的权限使用情况(普通应用绝不需要此权限)。"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"无障碍功能快捷方式目标"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"允许应用定义无障碍功能快捷方式目标。"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"设置密码规则"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"控制锁屏密码和 PIN 码所允许的长度和字符。"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"监控屏幕解锁尝试次数"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"选择即可停用 USB 调试功能。"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"自动化测试框架模式已启用"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"恢复出厂设置以停用自动化测试框架模式。"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"已启用序列控制台"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"性能受到影响。要停用,请查看引导加载程序。"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 端口中有液体或碎屑"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 端口已自动停用。点按即可了解详情。"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"允许使用 USB 端口"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"未分类"</string> <string name="importance_from_user" msgid="7318955817386549931">"这些通知的重要程度由您来设置。"</string> <string name="importance_from_person" msgid="9160133597262938296">"这条通知涉及特定的人,因此被归为重要通知。"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"允许<xliff:g id="APP">%1$s</xliff:g>使用 <xliff:g id="ACCOUNT">%2$s</xliff:g>(目前已有用户使用此帐号)创建新用户吗?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"允许<xliff:g id="APP">%1$s</xliff:g>使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 创建新用户吗?"</string> <string name="language_selection_title" msgid="2680677278159281088">"添加语言"</string> <string name="country_selection_title" msgid="2954859441620215513">"区域偏好设置"</string> <string name="search_language_hint" msgid="7042102592055108574">"输入语言名称"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index f0fce71e9d8c..a57b4ebd9315 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -201,7 +201,7 @@ <string name="turn_on_radio" msgid="3912793092339962371">"開啟無線網絡"</string> <string name="turn_off_radio" msgid="8198784949987062346">"關閉無線網絡"</string> <string name="screen_lock" msgid="799094655496098153">"螢幕鎖定"</string> - <string name="power_off" msgid="4266614107412865048">"關閉"</string> + <string name="power_off" msgid="4266614107412865048">"關機"</string> <string name="silent_mode_silent" msgid="319298163018473078">"鈴聲關閉"</string> <string name="silent_mode_vibrate" msgid="7072043388581551395">"鈴聲震動"</string> <string name="silent_mode_ring" msgid="8592241816194074353">"鈴聲開啟"</string> @@ -225,7 +225,7 @@ <string name="global_actions" product="tv" msgid="9091480417912345975">"Android TV 選項"</string> <string name="global_actions" product="default" msgid="2406416831541615258">"手機選項"</string> <string name="global_action_lock" msgid="2844945191792119712">"螢幕鎖定"</string> - <string name="global_action_power_off" msgid="4471879440839879722">"關閉"</string> + <string name="global_action_power_off" msgid="4471879440839879722">"關機"</string> <string name="global_action_emergency" msgid="7112311161137421166">"緊急"</string> <string name="global_action_bug_report" msgid="7934010578922304799">"錯誤報告"</string> <string name="global_action_logout" msgid="935179188218826050">"結束工作階段"</string> @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"允許應用程式讀取和寫入「請勿騷擾」設定。"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"開始查看權限使用情況"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"允許應用程式開始查看應用程式的權限使用情況 (一般應用程式並不需要)。"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"無障礙功能捷徑目標位置"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"允許應用程式定義無障礙功能捷徑目標位置。"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"控制螢幕鎖定密碼和 PIN 所允許的長度和字元。"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"監控螢幕解鎖嘗試次數"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取即可停用 USB 偵錯。"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"已啟用測試工具模式"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"請將裝置回復原廠設定,以停用測試工具模式。"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"已啟用序列控制器"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"效能受到影響,勾選啟動程式即可停用。"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 連接埠中有液體或碎片"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 連接埠已自動停用。輕按即可瞭解詳情。"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB 連接埠可安全使用"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"未分類"</string> <string name="importance_from_user" msgid="7318955817386549931">"您可以設定這些通知的重要性。"</string> <string name="importance_from_person" msgid="9160133597262938296">"列為重要的原因:涉及的人。"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"要允許 <xliff:g id="APP">%1$s</xliff:g> 使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 建立新使用者 (此帳戶目前已有此使用者) 嗎?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"要允許 <xliff:g id="APP">%1$s</xliff:g> 使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 建立新使用者嗎?"</string> <string name="language_selection_title" msgid="2680677278159281088">"新增語言"</string> <string name="country_selection_title" msgid="2954859441620215513">"地區偏好設定"</string> <string name="search_language_hint" msgid="7042102592055108574">"輸入語言名稱"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 1f132087ede3..34fee2bbc4a8 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"允許應用程式讀取及寫入「零打擾」設定。"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"啟動檢視權限用途"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"允許應用程式開始使用其他應用程式 (一般應用程式並不需要)。"</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"指定無障礙捷徑目標"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"允許應用程式定義指定的無障礙捷徑目標。"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"管理螢幕鎖定密碼和 PIN 碼支援的字元和長度上限。"</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"監控螢幕解鎖嘗試次數"</string> @@ -1361,10 +1363,12 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取這個選項以停用 USB 偵錯功能。"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"測試控管工具模式已啟用"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"恢復原廠設定以停用測試控管工具模式。"</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"已啟用序列主控台"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"效能已受到影響。如要停用,請檢查系統啟動載入程式。"</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 連接埠中有液體或灰塵"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"系統已自動停用 USB 連接埠。輕觸即可瞭解詳情。"</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"現在可以使用 USB 連接埠"</string> - <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"手機目前無法偵測液體或灰塵。"</string> + <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"手機目前沒有偵測到液體或灰塵。"</string> <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在接收錯誤報告…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享錯誤報告嗎?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"正在分享錯誤報告…"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"未分類"</string> <string name="importance_from_user" msgid="7318955817386549931">"這些通知的重要性由你決定。"</string> <string name="importance_from_person" msgid="9160133597262938296">"這則通知涉及特定人士,因此被歸為重要通知。"</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"要允許「<xliff:g id="APP">%1$s</xliff:g>」替 <xliff:g id="ACCOUNT">%2$s</xliff:g> (這個帳戶目前已有使用者) 建立新使用者嗎?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"要允許「<xliff:g id="APP">%1$s</xliff:g>」替 <xliff:g id="ACCOUNT">%2$s</xliff:g> 建立新使用者嗎?"</string> <string name="language_selection_title" msgid="2680677278159281088">"新增語言"</string> <string name="country_selection_title" msgid="2954859441620215513">"地區偏好設定"</string> <string name="search_language_hint" msgid="7042102592055108574">"請輸入語言名稱"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index f707fccef3d9..a5e0fed3b8e2 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -655,6 +655,8 @@ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Ivumela izinhlelo zokusebenza ukufunda nokubhala ukulungiswa kokuthi Ungaphazamisi."</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"qala ukusetshenziswa kokubuka imvume"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Ivumela umphathi ukuthi aqale ukusetshenziswa kwemvume kohlelo lokusebenza. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string> + <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"impokophelo yesinqamuleli sokufinyeleleka"</string> + <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Ivumela uhlelo lokusebenza ukuthi luchaze impokophelo yesinqamuleli sokufinyeleleka."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Misa imithetho yephasiwedi"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Lawula ubude nezinhlamvu ezivunyelwe kumaphasiwedi wokukhiya isikrini nama-PIN."</string> <string name="policylab_watchLogin" msgid="5091404125971980158">"Qapha imizamo yokuvula isikrini sakho"</string> @@ -1361,6 +1363,8 @@ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Khetha ukuvimbela ukulungisa iphutha le-USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Imodi yokuhlola i-harness inikwe amandla"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Yenza ukusetha kabusha kwasekuqaleni ukuze ukhubaze imodi yokuqina yokuhlola."</string> + <string name="console_running_notification_title" msgid="4955436518220103382">"I-serial console inikwe amandla"</string> + <string name="console_running_notification_message" msgid="1331995933976263865">"Ukusebenza kuyathinteka. Ukuze ukhubaze, hlola i-bootloader."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Uketshezi noma ama-debris kumbobo ye-USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Imbobo ye-USB inqanyulwa ngokuzenzakalela. Thepha ukuze ufunde kabanzi."</string> <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"KULUNGILE ukusebenzisa imbobo ye-USB"</string> @@ -1890,10 +1894,8 @@ <string name="default_notification_channel_label" msgid="5929663562028088222">"Akufakwanga esigabeni"</string> <string name="importance_from_user" msgid="7318955817386549931">"Usethe ukubaluleka kwalezi zaziso."</string> <string name="importance_from_person" msgid="9160133597262938296">"Lokhu kubalulekile ngenxa yabantu ababandakanyekayo."</string> - <!-- no translation found for user_creation_account_exists (6559477114648176531) --> - <skip /> - <!-- no translation found for user_creation_adding (9089159170398841763) --> - <skip /> + <string name="user_creation_account_exists" msgid="6559477114648176531">"Vumela i-<xliff:g id="APP">%1$s</xliff:g> ukuthi idale umsebenzisi omusha nge-<xliff:g id="ACCOUNT">%2$s</xliff:g> (Umsebenzisi onale akhawunti usevele ukhona) ?"</string> + <string name="user_creation_adding" msgid="9089159170398841763">"Vumela i-<xliff:g id="APP">%1$s</xliff:g> ukuthi idale umsebenzisi omusha nge-<xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string> <string name="language_selection_title" msgid="2680677278159281088">"Engeza ulwimi"</string> <string name="country_selection_title" msgid="2954859441620215513">"Okuncamelayo kwesifunda"</string> <string name="search_language_hint" msgid="7042102592055108574">"Thayipha igama lolimi"</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 3d0a3b309720..e2f2b2c64b77 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1881,15 +1881,14 @@ <java-symbol type="anim" name="screen_rotate_180_enter" /> <java-symbol type="anim" name="screen_rotate_180_exit" /> <java-symbol type="anim" name="screen_rotate_180_frame" /> + <java-symbol type="anim" name="screen_rotate_alpha"/> <java-symbol type="anim" name="screen_rotate_finish_enter" /> <java-symbol type="anim" name="screen_rotate_finish_exit" /> <java-symbol type="anim" name="screen_rotate_finish_frame" /> <java-symbol type="anim" name="screen_rotate_minus_90_enter" /> <java-symbol type="anim" name="screen_rotate_minus_90_exit" /> - <java-symbol type="anim" name="screen_rotate_minus_90_frame" /> <java-symbol type="anim" name="screen_rotate_plus_90_enter" /> <java-symbol type="anim" name="screen_rotate_plus_90_exit" /> - <java-symbol type="anim" name="screen_rotate_plus_90_frame" /> <java-symbol type="anim" name="screen_rotate_start_enter" /> <java-symbol type="anim" name="screen_rotate_start_exit" /> <java-symbol type="anim" name="screen_rotate_start_frame" /> diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index c009f588f8a9..a4c504b9cbdf 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -74,6 +74,7 @@ java_genrule { ":FrameworksCoreTests_install_loc_internal", ":FrameworksCoreTests_install_loc_sdcard", ":FrameworksCoreTests_install_loc_unspecified", + ":FrameworksCoreTests_install_multi_package", ":FrameworksCoreTests_install_split_base", ":FrameworksCoreTests_install_split_feature_a", ":FrameworksCoreTests_install_use_perm_good", diff --git a/core/tests/coretests/apks/install_multi_package/Android.bp b/core/tests/coretests/apks/install_multi_package/Android.bp new file mode 100644 index 000000000000..249242e239e4 --- /dev/null +++ b/core/tests/coretests/apks/install_multi_package/Android.bp @@ -0,0 +1,6 @@ +android_test_helper_app { + name: "FrameworksCoreTests_install_multi_package", + defaults: ["FrameworksCoreTests_apks_defaults"], + + srcs: ["**/*.java"], +} diff --git a/core/tests/coretests/apks/install_multi_package/AndroidManifest.xml b/core/tests/coretests/apks/install_multi_package/AndroidManifest.xml new file mode 100644 index 000000000000..5164cae9e5c0 --- /dev/null +++ b/core/tests/coretests/apks/install_multi_package/AndroidManifest.xml @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 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. +--> +<manifest + xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.coretests.install_multi_package"> + +<!-- + This manifest is has child packages with components. +--> + + <uses-feature + android:name="com.android.frameworks.coretests.nonexistent" /> + <uses-configuration + android:reqFiveWayNav="false" /> + + <instrumentation + android:name="android.test.InstrumentationTestRunner" + android:targetPackage="com.android.frameworks.coretests" + android:label="Frameworks Core Tests" /> + + <permission + android:label="test permission" + android:name="test_permission" + android:protectionLevel="normal" /> + <uses-permission android:name="android.permission.INTERNET" /> + +<!-- + NOTE: This declares a child package, application, then another child + package, to test potential bugs that are order-dependent. Also, each + one varies the order. +--> + + <package package="com.android.frameworks.coretests.install_multi_package.first_child"> + <uses-permission android:name="android.permission.NFC" /> + <!-- NOTE: A declared permission is ignored since the tag is not whitelisted. --> + <permission + android:label="test permission" + android:name="first_child_permission" + android:protectionLevel="signature" /> + <application + android:hasCode="true"> + <activity + android:name="com.android.frameworks.coretests.FirstChildTestActivity"> + </activity> + <provider + android:name="com.android.frameworks.coretests.FirstChildTestProvider" + android:authorities="com.android.frameworks.coretests.testprovider" /> + <receiver + android:name="com.android.frameworks.coretests.FirstChildTestReceiver" /> + <service + android:name="com.android.frameworks.coretests.FirstChildTestService" /> + </application> + </package> + + <application + android:hasCode="true"> + <service + android:name="com.android.frameworks.coretests.TestService" /> + <activity + android:name="com.android.frameworks.coretests.TestActivity"> + </activity> + <provider + android:name="com.android.frameworks.coretests.TestProvider" + android:authorities="com.android.frameworks.coretests.testprovider" /> + <receiver + android:name="com.android.frameworks.coretests.TestReceiver" /> + </application> + + <package package="com.android.frameworks.coretests.blah.second_child"> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission-sdk-23 android:name="android.permission.READ_CONTACTS" /> + <!-- NOTE: A declared permission is ignored since the tag is not whitelisted. --> + <permission + android:label="test permission" + android:name="second_child_permission" + android:protectionLevel="dangerous" /> + <application + android:hasCode="true"> + <receiver + android:name="com.android.frameworks.coretests.SecondChildTestReceiver" /> + <service + android:name="com.android.frameworks.coretests.SecondChildTestService" /> + <activity + android:name="com.android.frameworks.coretests.SecondChildTestActivity"> + </activity> + <provider + android:name="com.android.frameworks.coretests.SecondChildTestProvider" + android:authorities="com.android.frameworks.coretests.testprovider" /> + </application> + </package> +</manifest> diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestActivity.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestActivity.java new file mode 100644 index 000000000000..57afcb0e1a0d --- /dev/null +++ b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestActivity.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2011 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.frameworks.coretests; + +import android.app.Activity; + +public class FirstChildTestActivity extends Activity { + +} diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestProvider.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestProvider.java new file mode 100644 index 000000000000..2816865b2f1f --- /dev/null +++ b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestProvider.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 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.frameworks.coretests; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.database.Cursor; +import android.net.Uri; + +public class FirstChildTestProvider extends ContentProvider { + + @Override + public boolean onCreate() { + return false; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + return null; + } + + @Override + public String getType(Uri uri) { + return null; + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + return null; + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + return 0; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + return 0; + } +} diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestReceiver.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestReceiver.java new file mode 100644 index 000000000000..ffe84b73dd37 --- /dev/null +++ b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestReceiver.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 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.frameworks.coretests; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.database.Cursor; +import android.net.Uri; + +public class FirstChildTestReceiver extends ContentProvider { + + @Override + public boolean onCreate() { + return false; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + return null; + } + + @Override + public String getType(Uri uri) { + return null; + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + return null; + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + return 0; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + return 0; + } +} diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestService.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestService.java new file mode 100644 index 000000000000..faa6e9cff2b2 --- /dev/null +++ b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestService.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011 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.frameworks.coretests; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; + +public class FirstChildTestService extends Service { + + @Override + public IBinder onBind(Intent intent) { + return null; + } +} diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestActivity.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestActivity.java new file mode 100644 index 000000000000..e89f26489959 --- /dev/null +++ b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestActivity.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2011 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.frameworks.coretests; + +import android.app.Activity; + +public class SecondChildTestActivity extends Activity { + +} diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestProvider.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestProvider.java new file mode 100644 index 000000000000..2bd40a5df94d --- /dev/null +++ b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestProvider.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 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.frameworks.coretests; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.database.Cursor; +import android.net.Uri; + +public class SecondChildTestProvider extends ContentProvider { + + @Override + public boolean onCreate() { + return false; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + return null; + } + + @Override + public String getType(Uri uri) { + return null; + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + return null; + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + return 0; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + return 0; + } +} diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestReceiver.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestReceiver.java new file mode 100644 index 000000000000..a6c4ddc90c6a --- /dev/null +++ b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestReceiver.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 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.frameworks.coretests; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.database.Cursor; +import android.net.Uri; + +public class SecondChildTestReceiver extends ContentProvider { + + @Override + public boolean onCreate() { + return false; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + return null; + } + + @Override + public String getType(Uri uri) { + return null; + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + return null; + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + return 0; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + return 0; + } +} diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestService.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestService.java new file mode 100644 index 000000000000..1e721aa8ae5b --- /dev/null +++ b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestService.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011 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.frameworks.coretests; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; + +public class SecondChildTestService extends Service { + + @Override + public IBinder onBind(Intent intent) { + return null; + } +} diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestActivity.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestActivity.java new file mode 100644 index 000000000000..10d0551a3a6f --- /dev/null +++ b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestActivity.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2011 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.frameworks.coretests; + +import android.app.Activity; + +public class TestActivity extends Activity { + +} diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestProvider.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestProvider.java new file mode 100644 index 000000000000..59f9f10c6efe --- /dev/null +++ b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestProvider.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 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.frameworks.coretests; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.database.Cursor; +import android.net.Uri; + +public class TestProvider extends ContentProvider { + + @Override + public boolean onCreate() { + return false; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + return null; + } + + @Override + public String getType(Uri uri) { + return null; + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + return null; + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + return 0; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + return 0; + } +} diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestReceiver.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestReceiver.java new file mode 100644 index 000000000000..21f6263a38bc --- /dev/null +++ b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestReceiver.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 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.frameworks.coretests; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.database.Cursor; +import android.net.Uri; + +public class TestReceiver extends ContentProvider { + + @Override + public boolean onCreate() { + return false; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + return null; + } + + @Override + public String getType(Uri uri) { + return null; + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + return null; + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + return 0; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + return 0; + } +} diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestService.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestService.java new file mode 100644 index 000000000000..b330e75308f9 --- /dev/null +++ b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestService.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011 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.frameworks.coretests; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; + +public class TestService extends Service { + + @Override + public IBinder onBind(Intent intent) { + return null; + } +} diff --git a/core/tests/coretests/src/android/content/pm/AndroidHidlUpdaterTest.java b/core/tests/coretests/src/android/content/pm/AndroidHidlUpdaterTest.java new file mode 100644 index 000000000000..cc48239c4526 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/AndroidHidlUpdaterTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2018 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 android.content.pm; + +import static android.content.pm.PackageBuilder.builder; +import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_BASE; +import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_MANAGER; + +import android.os.Build; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Test for {@link AndroidHidlUpdater} + */ +@SmallTest +@RunWith(JUnit4.class) +public class AndroidHidlUpdaterTest extends PackageSharedLibraryUpdaterTest { + + private static final String OTHER_LIBRARY = "other.library"; + + @Test + public void targeted_at_P() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.P); + + // no change, not system + checkBackwardsCompatibility(before, before); + } + + @Test + public void targeted_at_P_system() { + PackageBuilder before = builder().asSystemApp() + .targetSdkVersion(Build.VERSION_CODES.P); + + // Should add both HIDL libraries + PackageBuilder after = builder().asSystemApp() + .targetSdkVersion(Build.VERSION_CODES.P) + .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void targeted_at_P_not_empty_usesLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.P) + .requiredLibraries(OTHER_LIBRARY); + + // no change, not system + checkBackwardsCompatibility(before, before); + } + + @Test + public void targeted_at_P_not_empty_usesLibraries_system() { + PackageBuilder before = builder().asSystemApp() + .targetSdkVersion(Build.VERSION_CODES.P) + .requiredLibraries(OTHER_LIBRARY); + + // The hidl jars should be added at the start of the list because it + // is not on the bootclasspath and the package targets pre-P. + PackageBuilder after = builder().asSystemApp() + .targetSdkVersion(Build.VERSION_CODES.P) + .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE, OTHER_LIBRARY); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void targeted_at_P_in_usesLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.P) + .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE); + + PackageBuilder after = builder() + .targetSdkVersion(Build.VERSION_CODES.P); + + // Libraries are removed because they are not available for non-system apps + checkBackwardsCompatibility(before, after); + } + + @Test + public void targeted_at_P_in_usesLibraries_system() { + PackageBuilder before = builder().asSystemApp() + .targetSdkVersion(Build.VERSION_CODES.P) + .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE); + + // No change is required because the package explicitly requests the HIDL libraries + // and is targeted at the current version so does not need backwards compatibility. + checkBackwardsCompatibility(before, before); + } + + @Test + public void in_usesLibraries() { + PackageBuilder before = builder().requiredLibraries(ANDROID_HIDL_BASE); + + // Dependency is removed, it is not available. + PackageBuilder after = builder(); + + // Libraries are removed because they are not available for apps targetting Q+ + checkBackwardsCompatibility(before, after); + } + + @Test + public void in_usesOptionalLibraries() { + PackageBuilder before = builder().optionalLibraries(ANDROID_HIDL_BASE); + + // Dependency is removed, it is not available. + PackageBuilder after = builder(); + + // Libraries are removed because they are not available for apps targetting Q+ + checkBackwardsCompatibility(before, after); + } + + private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) { + checkBackwardsCompatibility(before, after, AndroidHidlUpdater::new); + } +} diff --git a/core/tests/coretests/src/android/content/pm/AndroidTestBaseUpdaterTest.java b/core/tests/coretests/src/android/content/pm/AndroidTestBaseUpdaterTest.java new file mode 100644 index 000000000000..03108ced4816 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/AndroidTestBaseUpdaterTest.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2018 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 android.content.pm; + +import static android.content.pm.PackageBuilder.builder; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE; + +import android.os.Build; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Test for {@link AndroidTestBaseUpdater} + */ +@SmallTest +@RunWith(OptionalClassRunner.class) +@OptionalClassRunner.OptionalClass("android.content.pm.AndroidTestBaseUpdater") +public class AndroidTestBaseUpdaterTest extends PackageSharedLibraryUpdaterTest { + + private static final String OTHER_LIBRARY = "other.library"; + + @Test + public void targeted_at_Q() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.Q); + + // Should add org.apache.http.legacy. + PackageBuilder after = builder() + .targetSdkVersion(Build.VERSION_CODES.Q) + .requiredLibraries(ANDROID_TEST_BASE); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void targeted_at_Q_not_empty_usesLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.Q) + .requiredLibraries(OTHER_LIBRARY); + + // The org.apache.http.legacy jar should be added at the start of the list because it + // is not on the bootclasspath and the package targets pre-Q. + PackageBuilder after = builder() + .targetSdkVersion(Build.VERSION_CODES.Q) + .requiredLibraries(ANDROID_TEST_BASE, OTHER_LIBRARY); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void targeted_at_Q_in_usesLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.Q) + .requiredLibraries(ANDROID_TEST_BASE); + + // No change is required because although org.apache.http.legacy has been removed from + // the bootclasspath the package explicitly requests it. + checkBackwardsCompatibility(before, before); + } + + @Test + public void targeted_at_Q_in_usesOptionalLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.Q) + .optionalLibraries(ANDROID_TEST_BASE); + + // No change is required because although org.apache.http.legacy has been removed from + // the bootclasspath the package explicitly requests it. + checkBackwardsCompatibility(before, before); + } + + @Test + public void in_usesLibraries() { + PackageBuilder before = builder().requiredLibraries(ANDROID_TEST_BASE); + + // No change is required because the package explicitly requests org.apache.http.legacy + // and is targeted at the current version so does not need backwards compatibility. + checkBackwardsCompatibility(before, before); + } + + @Test + public void in_usesOptionalLibraries() { + PackageBuilder before = builder().optionalLibraries(ANDROID_TEST_BASE); + + // No change is required because the package explicitly requests org.apache.http.legacy + // and is targeted at the current version so does not need backwards compatibility. + checkBackwardsCompatibility(before, before); + } + + private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) { + checkBackwardsCompatibility(before, after, AndroidTestBaseUpdater::new); + } +} diff --git a/core/tests/coretests/src/android/content/pm/AndroidTestRunnerSplitUpdaterTest.java b/core/tests/coretests/src/android/content/pm/AndroidTestRunnerSplitUpdaterTest.java new file mode 100644 index 000000000000..7f817d66caf7 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/AndroidTestRunnerSplitUpdaterTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2018 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 android.content.pm; + +import static android.content.pm.PackageBuilder.builder; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_MOCK; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER; + +import android.content.pm.PackageBackwardCompatibility.AndroidTestRunnerSplitUpdater; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Test for {@link AndroidTestRunnerSplitUpdater} + */ +@SmallTest +@RunWith(JUnit4.class) +public class AndroidTestRunnerSplitUpdaterTest extends PackageSharedLibraryUpdaterTest { + + @Test + public void android_test_runner_in_usesOptionalLibraries() { + PackageBuilder before = builder().optionalLibraries(ANDROID_TEST_RUNNER); + + PackageBuilder after = builder() + .optionalLibraries(ANDROID_TEST_MOCK, ANDROID_TEST_RUNNER); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void android_test_runner_in_usesLibraries_android_test_mock_in_usesOptionalLibraries() { + PackageBuilder before = builder() + .requiredLibraries(ANDROID_TEST_RUNNER) + .optionalLibraries(ANDROID_TEST_MOCK); + + PackageBuilder after = builder() + .requiredLibraries(ANDROID_TEST_RUNNER) + .optionalLibraries(ANDROID_TEST_MOCK); + + checkBackwardsCompatibility(before, after); + } + + private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) { + checkBackwardsCompatibility(before, after, AndroidTestRunnerSplitUpdater::new); + } +} diff --git a/core/tests/coretests/src/android/content/pm/OrgApacheHttpLegacyUpdaterTest.java b/core/tests/coretests/src/android/content/pm/OrgApacheHttpLegacyUpdaterTest.java new file mode 100644 index 000000000000..834a0bbeab89 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/OrgApacheHttpLegacyUpdaterTest.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2018 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 android.content.pm; + +import static android.content.pm.PackageBuilder.builder; +import static android.content.pm.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; + +import android.os.Build; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Test for {@link OrgApacheHttpLegacyUpdater} + */ +@SmallTest +@RunWith(OptionalClassRunner.class) +@OptionalClassRunner.OptionalClass("android.content.pm.OrgApacheHttpLegacyUpdater") +public class OrgApacheHttpLegacyUpdaterTest extends PackageSharedLibraryUpdaterTest { + + private static final String OTHER_LIBRARY = "other.library"; + + @Test + public void targeted_at_O() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O); + + // Should add org.apache.http.legacy. + PackageBuilder after = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(ORG_APACHE_HTTP_LEGACY); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void targeted_at_O_not_empty_usesLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(OTHER_LIBRARY); + + // The org.apache.http.legacy jar should be added at the start of the list because it + // is not on the bootclasspath and the package targets pre-P. + PackageBuilder after = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(ORG_APACHE_HTTP_LEGACY, OTHER_LIBRARY); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void targeted_at_O_in_usesLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(ORG_APACHE_HTTP_LEGACY); + + // No change is required because although org.apache.http.legacy has been removed from + // the bootclasspath the package explicitly requests it. + checkBackwardsCompatibility(before, before); + } + + @Test + public void targeted_at_O_in_usesOptionalLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .optionalLibraries(ORG_APACHE_HTTP_LEGACY); + + // No change is required because although org.apache.http.legacy has been removed from + // the bootclasspath the package explicitly requests it. + checkBackwardsCompatibility(before, before); + } + + @Test + public void in_usesLibraries() { + PackageBuilder before = builder().requiredLibraries(ORG_APACHE_HTTP_LEGACY); + + // No change is required because the package explicitly requests org.apache.http.legacy + // and is targeted at the current version so does not need backwards compatibility. + checkBackwardsCompatibility(before, before); + } + + @Test + public void in_usesOptionalLibraries() { + PackageBuilder before = builder().optionalLibraries(ORG_APACHE_HTTP_LEGACY); + + // No change is required because the package explicitly requests org.apache.http.legacy + // and is targeted at the current version so does not need backwards compatibility. + checkBackwardsCompatibility(before, before); + } + + private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) { + checkBackwardsCompatibility(before, after, OrgApacheHttpLegacyUpdater::new); + } +} diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/PackageBackwardCompatibilityTest.java b/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java index 00d468de4ee4..ad9814bd01b1 100644 --- a/core/tests/coretests/src/android/content/pm/parsing/library/PackageBackwardCompatibilityTest.java +++ b/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2017 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. @@ -14,18 +14,15 @@ * limitations under the License. */ -package android.content.pm.parsing.library; +package android.content.pm; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_BASE; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_MOCK; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_RUNNER; -import static android.content.pm.parsing.library.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; +import static android.content.pm.PackageBuilder.builder; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_MOCK; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER; +import static android.content.pm.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.PackageImpl; -import android.content.pm.parsing.ParsedPackage; -import android.content.pm.parsing.ParsingPackage; -import android.content.pm.parsing.library.PackageBackwardCompatibility.RemoveUnnecessaryAndroidTestBaseLibrary; +import android.content.pm.PackageBackwardCompatibility.RemoveUnnecessaryAndroidTestBaseLibrary; import android.os.Build; import androidx.test.filters.SmallTest; @@ -35,20 +32,17 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import java.util.ArrayList; +import java.util.List; + @SmallTest @RunWith(JUnit4.class) public class PackageBackwardCompatibilityTest extends PackageSharedLibraryUpdaterTest { @Test public void null_usesLibraries_and_usesOptionalLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .hideAsParsed() - .hideAsFinal(); + PackageBuilder before = builder(); + PackageBuilder after = builder(); checkBackwardsCompatibility(before, after); } @@ -74,21 +68,20 @@ public class PackageBackwardCompatibilityTest extends PackageSharedLibraryUpdate */ @Test public void targeted_at_O() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .hideAsParsed(); - - ParsingPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .setTargetSdkVersion(Build.VERSION_CODES.O); + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O); + List<String> expected = new ArrayList<>(); if (!PackageBackwardCompatibility.bootClassPathContainsATB()) { - after.addUsesLibrary(ANDROID_TEST_BASE); + expected.add(ANDROID_TEST_BASE); } - after.addUsesLibrary(ORG_APACHE_HTTP_LEGACY); + expected.add(ORG_APACHE_HTTP_LEGACY); + + PackageBuilder after = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(expected); - checkBackwardsCompatibility(before, after.hideAsParsed().hideAsFinal()); + checkBackwardsCompatibility(before, after); } /** @@ -105,17 +98,12 @@ public class PackageBackwardCompatibilityTest extends PackageSharedLibraryUpdate + ANDROID_TEST_BASE + " is on the bootclasspath", PackageBackwardCompatibility.bootClassPathContainsATB()); - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesLibrary(ANDROID_TEST_BASE) - .hideAsParsed(); + PackageBuilder before = builder() + .requiredLibraries(ANDROID_TEST_BASE); // android.test.base should be removed from the libraries because it is provided // on the bootclasspath and providing both increases start up cost unnecessarily. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .hideAsParsed() - .hideAsFinal(); + PackageBuilder after = builder(); checkBackwardsCompatibility(before, after); } @@ -129,23 +117,22 @@ public class PackageBackwardCompatibilityTest extends PackageSharedLibraryUpdate */ @Test public void android_test_runner_in_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesLibrary(ANDROID_TEST_RUNNER) - .hideAsParsed(); + PackageBuilder before = builder().requiredLibraries(ANDROID_TEST_RUNNER); - ParsingPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT); + List<String> expected = new ArrayList<>(); if (!PackageBackwardCompatibility.bootClassPathContainsATB()) { - after.addUsesLibrary(ANDROID_TEST_BASE); + expected.add(ANDROID_TEST_BASE); } - after.addUsesLibrary(ANDROID_TEST_MOCK); - after.addUsesLibrary(ANDROID_TEST_RUNNER); + expected.add(ANDROID_TEST_MOCK); + expected.add(ANDROID_TEST_RUNNER); + + PackageBuilder after = builder() + .requiredLibraries(expected); - checkBackwardsCompatibility(before, after.hideAsParsed().hideAsFinal()); + checkBackwardsCompatibility(before, after); } - private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) { + private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) { checkBackwardsCompatibility(before, after, PackageBackwardCompatibility::getInstance); } } diff --git a/core/tests/coretests/src/android/content/pm/PackageBuilder.java b/core/tests/coretests/src/android/content/pm/PackageBuilder.java new file mode 100644 index 000000000000..f7544af43461 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/PackageBuilder.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2018 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 android.content.pm; + +import static org.junit.Assert.assertEquals; + +import android.os.Build; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Test support for building {@link PackageParser.Package} instances. + */ +class PackageBuilder { + + private int mTargetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; + + private int mFlags = 0; + + private ArrayList<String> mRequiredLibraries; + + private ArrayList<String> mOptionalLibraries; + + public static PackageBuilder builder() { + return new PackageBuilder(); + } + + public PackageParser.Package build() { + PackageParser.Package pkg = new PackageParser.Package("org.package.name"); + pkg.applicationInfo.targetSdkVersion = mTargetSdkVersion; + pkg.applicationInfo.flags = mFlags; + pkg.usesLibraries = mRequiredLibraries; + pkg.usesOptionalLibraries = mOptionalLibraries; + return pkg; + } + + PackageBuilder targetSdkVersion(int version) { + this.mTargetSdkVersion = version; + return this; + } + + PackageBuilder asSystemApp() { + this.mFlags |= ApplicationInfo.FLAG_SYSTEM; + return this; + } + + PackageBuilder requiredLibraries(String... names) { + this.mRequiredLibraries = arrayListOrNull(names); + return this; + } + + PackageBuilder requiredLibraries(List<String> names) { + this.mRequiredLibraries = arrayListOrNull(names.toArray(new String[names.size()])); + return this; + } + + PackageBuilder optionalLibraries(String... names) { + this.mOptionalLibraries = arrayListOrNull(names); + return this; + } + + /** + * Check that this matches the supplied {@link PackageParser.Package}. + * + * @param pkg the instance to compare with this. + */ + public void check(PackageParser.Package pkg) { + assertEquals("targetSdkVersion should not be changed", + mTargetSdkVersion, + pkg.applicationInfo.targetSdkVersion); + assertEquals("usesLibraries not updated correctly", + mRequiredLibraries, + pkg.usesLibraries); + assertEquals("usesOptionalLibraries not updated correctly", + mOptionalLibraries, + pkg.usesOptionalLibraries); + } + + private static ArrayList<String> arrayListOrNull(String... strings) { + if (strings == null || strings.length == 0) { + return null; + } + ArrayList<String> list = new ArrayList<>(); + Collections.addAll(list, strings); + return list; + } + +} diff --git a/core/tests/coretests/src/android/content/pm/PackageParserTest.java b/core/tests/coretests/src/android/content/pm/PackageParserTest.java index cb23850798c3..5c7f2af782b9 100644 --- a/core/tests/coretests/src/android/content/pm/PackageParserTest.java +++ b/core/tests/coretests/src/android/content/pm/PackageParserTest.java @@ -23,26 +23,26 @@ import static org.junit.Assert.assertTrue; import android.apex.ApexInfo; import android.content.Context; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ComponentParseUtils.ParsedComponent; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermission; -import android.content.pm.parsing.ParsedPackage; +import android.content.pm.PackageParser.Component; +import android.content.pm.PackageParser.Package; +import android.content.pm.PackageParser.Permission; import android.os.Build; import android.os.Bundle; import android.os.FileUtils; +import android.os.SystemProperties; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.frameworks.coretests.R; -import com.android.internal.util.ArrayUtils; import org.junit.Test; import org.junit.runner.RunWith; import java.io.File; import java.io.InputStream; +import java.util.Arrays; import java.util.function.Function; @SmallTest @@ -59,8 +59,8 @@ public class PackageParserTest { private static final String PRE_RELEASE_WITH_FINGERPRINT = "B.fingerprint"; private static final String NEWER_PRE_RELEASE_WITH_FINGERPRINT = "C.fingerprint"; - private static final String[] CODENAMES_RELEASED = { /* empty */}; - private static final String[] CODENAMES_PRE_RELEASE = {PRE_RELEASE}; + private static final String[] CODENAMES_RELEASED = { /* empty */ }; + private static final String[] CODENAMES_PRE_RELEASE = { PRE_RELEASE }; private static final int OLDER_VERSION = 10; private static final int PLATFORM_VERSION = 20; @@ -300,6 +300,10 @@ public class PackageParserTest { assertEquals(0x0083, finalConfigChanges); // Should be 10000011. } + Package parsePackage(String apkFileName, int apkResourceId) throws Exception { + return parsePackage(apkFileName, apkResourceId, p -> p); + } + /** * Copies a specified {@code resourceId} to a file. Returns a non-null file if the copy * succeeded, or {@code null} otherwise. @@ -327,17 +331,16 @@ public class PackageParserTest { * * APKs are put into coretests/apks/packageparser_*. * - * @param apkFileName temporary file name to store apk extracted from resources + * @param apkFileName temporary file name to store apk extracted from resources * @param apkResourceId identifier of the apk as a resource */ - ParsedPackage parsePackage(String apkFileName, int apkResourceId, - Function<ParsedPackage, ParsedPackage> converter) throws Exception { + Package parsePackage(String apkFileName, int apkResourceId, + Function<Package, Package> converter) throws Exception { // Copy the resource to a file. File outFile = null; try { outFile = copyRawResourceToFile(apkFileName, apkResourceId); - return converter.apply( - new PackageParser().parseParsedPackage(outFile, 0 /* flags */, false)); + return converter.apply(new PackageParser().parsePackage(outFile, 0 /* flags */)); } finally { if (outFile != null) { outFile.delete(); @@ -348,40 +351,40 @@ public class PackageParserTest { /** * Asserts basic properties about a component. */ - private void assertComponent(String className, int numIntents, ParsedComponent<?> component) { + private void assertComponent(String className, String packageName, int numIntents, + Component<?> component) { assertEquals(className, component.className); + assertEquals(packageName, component.owner.packageName); assertEquals(numIntents, component.intents.size()); } /** * Asserts four regularly-named components of each type: one Activity, one Service, one * Provider, and one Receiver. - * * @param template templated string with %s subbed with Activity, Service, Provider, Receiver */ - private void assertOneComponentOfEachType(String template, AndroidPackage p) { - assertEquals(2, p.getActivities().size()); - - // For normal apps, a Activity that forwards to the App Details page is added. - assertEquals("android.app.AppDetailsActivity", p.getActivities().get(1) - .className); + private void assertOneComponentOfEachType(String template, Package p) { + String packageName = p.packageName; + assertEquals(1, p.activities.size()); assertComponent(String.format(template, "Activity"), - 0 /* intents */, p.getActivities().get(0)); - assertEquals(1, p.getServices().size()); + packageName, 0 /* intents */, p.activities.get(0)); + assertEquals(1, p.services.size()); assertComponent(String.format(template, "Service"), - 0 /* intents */, p.getServices().get(0)); - assertEquals(1, p.getProviders().size()); + packageName, 0 /* intents */, p.services.get(0)); + assertEquals(1, p.providers.size()); assertComponent(String.format(template, "Provider"), - 0 /* intents */, p.getProviders().get(0)); - assertEquals(1, p.getReceivers().size()); + packageName, 0 /* intents */, p.providers.get(0)); + assertEquals(1, p.receivers.size()); assertComponent(String.format(template, "Receiver"), - 0 /* intents */, p.getReceivers().get(0)); + packageName, 0 /* intents */, p.receivers.get(0)); } - private void assertPermission(String name, int protectionLevel, ParsedPermission permission) { - assertEquals(name, permission.getName()); - assertEquals(protectionLevel, permission.getProtection()); + private void assertPermission(String name, String packageName, int protectionLevel, + Permission permission) { + assertEquals(packageName, permission.owner.packageName); + assertEquals(name, permission.info.name); + assertEquals(protectionLevel, permission.info.protectionLevel); } private void assertMetadata(Bundle b, String... keysAndValues) { @@ -413,25 +416,25 @@ public class PackageParserTest { } private void checkPackageWithComponents( - Function<ParsedPackage, ParsedPackage> converter) throws Exception { - ParsedPackage p = parsePackage( + Function<Package, Package> converter) throws Exception { + Package p = parsePackage( "install_complete_package_info.apk", R.raw.install_complete_package_info, converter); String packageName = "com.android.frameworks.coretests.install_complete_package_info"; - assertEquals(packageName, p.getPackageName()); - assertEquals(1, p.getPermissions().size()); + assertEquals(packageName, p.packageName); + assertEquals(1, p.permissions.size()); assertPermission( "com.android.frameworks.coretests.install_complete_package_info.test_permission", - PermissionInfo.PROTECTION_NORMAL, p.getPermissions().get(0)); + packageName, PermissionInfo.PROTECTION_NORMAL, p.permissions.get(0)); // Hidden "app details" activity is added to every package. boolean foundAppDetailsActivity = false; - for (int i = 0; i < ArrayUtils.size(p.getActivities()); i++) { - if (p.getActivities().get(i).className.equals( + for (int i = 0; i < p.activities.size(); i++) { + if (p.activities.get(i).className.equals( PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME)) { foundAppDetailsActivity = true; - p.getActivities().remove(i); + p.activities.remove(i); break; } } @@ -439,23 +442,72 @@ public class PackageParserTest { assertOneComponentOfEachType("com.android.frameworks.coretests.Test%s", p); - assertMetadata(p.getAppMetaData(), + assertMetadata(p.mAppMetaData, "key1", "value1", "key2", "this_is_app"); - assertMetadata(p.getActivities().get(0).getMetaData(), + assertMetadata(p.activities.get(0).metaData, "key1", "value1", "key2", "this_is_activity"); - assertMetadata(p.getServices().get(0).getMetaData(), + assertMetadata(p.services.get(0).metaData, "key1", "value1", "key2", "this_is_service"); - assertMetadata(p.getReceivers().get(0).getMetaData(), + assertMetadata(p.receivers.get(0).metaData, "key1", "value1", "key2", "this_is_receiver"); - assertMetadata(p.getProviders().get(0).getMetaData(), + assertMetadata(p.providers.get(0).metaData, "key1", "value1", "key2", "this_is_provider"); } + /** + * Determines if the current device supports multi-package APKs. + */ + private boolean supportsMultiPackageApk() { + return SystemProperties.getBoolean("persist.sys.child_packages_enabled", false); + } + + @Test + public void testMultiPackageComponents() throws Exception { + // TODO(gboyer): Remove once we decide to launch multi-package APKs. + if (!supportsMultiPackageApk()) { + return; + } + String parentName = "com.android.frameworks.coretests.install_multi_package"; + String firstChildName = + "com.android.frameworks.coretests.install_multi_package.first_child"; + String secondChildName = // NOTE: intentionally inconsistent! + "com.android.frameworks.coretests.blah.second_child"; + + Package parent = parsePackage("install_multi_package.apk", R.raw.install_multi_package); + assertEquals(parentName, parent.packageName); + assertEquals(2, parent.childPackages.size()); + assertOneComponentOfEachType("com.android.frameworks.coretests.Test%s", parent); + assertEquals(1, parent.permissions.size()); + assertPermission(parentName + ".test_permission", parentName, + PermissionInfo.PROTECTION_NORMAL, parent.permissions.get(0)); + assertEquals(Arrays.asList("android.permission.INTERNET"), + parent.requestedPermissions); + + Package firstChild = parent.childPackages.get(0); + assertEquals(firstChildName, firstChild.packageName); + assertOneComponentOfEachType( + "com.android.frameworks.coretests.FirstChildTest%s", firstChild); + assertEquals(0, firstChild.permissions.size()); // Child APKs cannot declare permissions. + assertEquals(Arrays.asList("android.permission.NFC"), + firstChild.requestedPermissions); + + Package secondChild = parent.childPackages.get(1); + assertEquals(secondChildName, secondChild.packageName); + assertOneComponentOfEachType( + "com.android.frameworks.coretests.SecondChildTest%s", secondChild); + assertEquals(0, secondChild.permissions.size()); // Child APKs cannot declare permissions. + assertEquals( + Arrays.asList( + "android.permission.ACCESS_NETWORK_STATE", + "android.permission.READ_CONTACTS"), + secondChild.requestedPermissions); + } + @Test public void testApexPackageInfoGeneration() throws Exception { String apexModuleName = "com.android.tzdata.apex"; @@ -470,7 +522,7 @@ public class PackageParserTest { int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES; PackageParser pp = new PackageParser(); - PackageParser.Package p = pp.parsePackage(apexFile, flags, false); + Package p = pp.parsePackage(apexFile, flags, false); PackageParser.collectCertificates(p, false); PackageInfo pi = PackageParser.generatePackageInfo(p, apexInfo, flags); diff --git a/core/tests/coretests/src/android/content/pm/PackageSharedLibraryUpdaterTest.java b/core/tests/coretests/src/android/content/pm/PackageSharedLibraryUpdaterTest.java new file mode 100644 index 000000000000..71a0e5e51b71 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/PackageSharedLibraryUpdaterTest.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2018 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 android.content.pm; + +import java.util.function.Supplier; + +/** + * Helper for classes that test {@link PackageSharedLibraryUpdater}. + */ +abstract class PackageSharedLibraryUpdaterTest { + + static void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after, + Supplier<PackageSharedLibraryUpdater> updaterSupplier) { + PackageParser.Package pkg = before.build(); + updaterSupplier.get().updatePackage(pkg); + after.check(pkg); + } +} diff --git a/core/tests/coretests/src/android/content/pm/RemoveUnnecessaryAndroidTestBaseLibraryTest.java b/core/tests/coretests/src/android/content/pm/RemoveUnnecessaryAndroidTestBaseLibraryTest.java new file mode 100644 index 000000000000..216b0c8950b7 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/RemoveUnnecessaryAndroidTestBaseLibraryTest.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2018 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 android.content.pm; + +import static android.content.pm.PackageBuilder.builder; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE; + +import android.content.pm.PackageBackwardCompatibility.RemoveUnnecessaryAndroidTestBaseLibrary; +import android.os.Build; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Test for {@link RemoveUnnecessaryAndroidTestBaseLibrary} + */ +@SmallTest +@RunWith(JUnit4.class) +public class RemoveUnnecessaryAndroidTestBaseLibraryTest + extends PackageSharedLibraryUpdaterTest { + + private static final String OTHER_LIBRARY = "other.library"; + + @Test + public void targeted_at_O() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O); + + // No change required. + checkBackwardsCompatibility(before, before); + } + + @Test + public void targeted_at_O_not_empty_usesLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(OTHER_LIBRARY); + + // No change required. + checkBackwardsCompatibility(before, before); + } + + @Test + public void targeted_at_O_in_usesLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(ANDROID_TEST_BASE); + + // android.test.base should be removed from the libraries because it is provided + // on the bootclasspath and providing both increases start up cost unnecessarily. + PackageBuilder after = builder() + .targetSdkVersion(Build.VERSION_CODES.O); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void targeted_at_O_in_usesOptionalLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .optionalLibraries(ANDROID_TEST_BASE); + + // android.test.base should be removed from the libraries because it is provided + // on the bootclasspath and providing both increases start up cost unnecessarily. + PackageBuilder after = builder() + .targetSdkVersion(Build.VERSION_CODES.O); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void in_usesLibraries() { + PackageBuilder before = builder().requiredLibraries(ANDROID_TEST_BASE); + + // android.test.base should be removed from the libraries because it is provided + // on the bootclasspath and providing both increases start up cost unnecessarily. + PackageBuilder after = builder(); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void in_usesOptionalLibraries() { + PackageBuilder before = builder().optionalLibraries(ANDROID_TEST_BASE); + + // android.test.base should be removed from the libraries because it is provided + // on the bootclasspath and providing both increases start up cost unnecessarily. + PackageBuilder after = builder(); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void in_bothLibraries() { + PackageBuilder before = builder() + .requiredLibraries(ANDROID_TEST_BASE) + .optionalLibraries(ANDROID_TEST_BASE); + + // android.test.base should be removed from the libraries because it is provided + // on the bootclasspath and providing both increases start up cost unnecessarily. + PackageBuilder after = builder(); + + checkBackwardsCompatibility(before, after); + } + + private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) { + // TODO(b/72538146) - Cannot use constructor reference here because it is also used in + // PackageBackwardCompatibility and that seems to create a package-private lambda in + // android.content.pm which this then tries to reuse but fails because it cannot access + // package-private classes/members because the test is loaded by a different ClassLoader + // than the lambda. + checkBackwardsCompatibility(before, after, + () -> new RemoveUnnecessaryAndroidTestBaseLibrary()); + } + +} diff --git a/core/tests/coretests/src/android/content/pm/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java b/core/tests/coretests/src/android/content/pm/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java new file mode 100644 index 000000000000..fc60980bb796 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2018 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 android.content.pm; + +import static android.content.pm.PackageBuilder.builder; +import static android.content.pm.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; + +import android.content.pm.PackageBackwardCompatibility.RemoveUnnecessaryOrgApacheHttpLegacyLibrary; +import android.os.Build; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Test for {@link RemoveUnnecessaryOrgApacheHttpLegacyLibrary} + */ +@SmallTest +@RunWith(JUnit4.class) +public class RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest + extends PackageSharedLibraryUpdaterTest { + + private static final String OTHER_LIBRARY = "other.library"; + + @Test + public void targeted_at_O() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O); + + // No change required. + checkBackwardsCompatibility(before, before); + } + + @Test + public void targeted_at_O_not_empty_usesLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(OTHER_LIBRARY); + + // No change required. + checkBackwardsCompatibility(before, before); + } + + @Test + public void targeted_at_O_in_usesLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(ORG_APACHE_HTTP_LEGACY); + + // org.apache.http.legacy should be removed from the libraries because it is provided + // on the bootclasspath and providing both increases start up cost unnecessarily. + PackageBuilder after = builder() + .targetSdkVersion(Build.VERSION_CODES.O); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void targeted_at_O_in_usesOptionalLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .optionalLibraries(ORG_APACHE_HTTP_LEGACY); + + // org.apache.http.legacy should be removed from the libraries because it is provided + // on the bootclasspath and providing both increases start up cost unnecessarily. + PackageBuilder after = builder() + .targetSdkVersion(Build.VERSION_CODES.O); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void in_usesLibraries() { + PackageBuilder before = builder().requiredLibraries(ORG_APACHE_HTTP_LEGACY); + + // org.apache.http.legacy should be removed from the libraries because it is provided + // on the bootclasspath and providing both increases start up cost unnecessarily. + PackageBuilder after = builder(); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void in_usesOptionalLibraries() { + PackageBuilder before = builder().optionalLibraries(ORG_APACHE_HTTP_LEGACY); + + // org.apache.http.legacy should be removed from the libraries because it is provided + // on the bootclasspath and providing both increases start up cost unnecessarily. + PackageBuilder after = builder(); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void in_bothLibraries() { + PackageBuilder before = builder() + .requiredLibraries(ORG_APACHE_HTTP_LEGACY) + .optionalLibraries(ORG_APACHE_HTTP_LEGACY); + + // org.apache.http.legacy should be removed from the libraries because it is provided + // on the bootclasspath and providing both increases start up cost unnecessarily. + PackageBuilder after = builder(); + + checkBackwardsCompatibility(before, after); + } + + private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) { + // TODO(b/72538146) - Cannot use constructor reference here because it is also used in + // PackageBackwardCompatibility and that seems to create a package-private lambda in + // android.content.pm which this then tries to reuse but fails because it cannot access + // package-private classes/members because the test is loaded by a different ClassLoader + // than the lambda. + checkBackwardsCompatibility(before, after, + () -> new RemoveUnnecessaryOrgApacheHttpLegacyLibrary()); + } +} diff --git a/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java b/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java index 1e0bfb08693f..49849ee72a18 100644 --- a/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java +++ b/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java @@ -25,9 +25,9 @@ import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageParser; import android.content.pm.PackageParser.ApkLite; +import android.content.pm.PackageParser.Package; import android.content.pm.PackageParser.PackageLite; import android.content.pm.PackageParser.PackageParserException; -import android.content.pm.parsing.ParsedPackage; import android.os.FileUtils; import androidx.test.InstrumentationRegistry; @@ -36,6 +36,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.frameworks.coretests.R; +import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -94,13 +95,13 @@ public class DexMetadataHelperTest { public void testParsePackageWithDmFileValid() throws IOException, PackageParserException { copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base); createDexMetadataFile("install_split_base.apk"); - ParsedPackage pkg = new PackageParser().parseParsedPackage(mTmpDir, 0 /* flags */, false); + Package pkg = new PackageParser().parsePackage(mTmpDir, 0 /* flags */); Map<String, String> packageDexMetadata = DexMetadataHelper.getPackageDexMetadata(pkg); assertEquals(1, packageDexMetadata.size()); - String baseDexMetadata = packageDexMetadata.get(pkg.getBaseCodePath()); + String baseDexMetadata = packageDexMetadata.get(pkg.baseCodePath); assertNotNull(baseDexMetadata); - assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.getBaseCodePath())); + assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.baseCodePath)); } @Test @@ -110,17 +111,17 @@ public class DexMetadataHelperTest { copyApkToToTmpDir("install_split_feature_a.apk", R.raw.install_split_feature_a); createDexMetadataFile("install_split_base.apk"); createDexMetadataFile("install_split_feature_a.apk"); - ParsedPackage pkg = new PackageParser().parseParsedPackage(mTmpDir, 0 /* flags */, false); + Package pkg = new PackageParser().parsePackage(mTmpDir, 0 /* flags */); Map<String, String> packageDexMetadata = DexMetadataHelper.getPackageDexMetadata(pkg); assertEquals(2, packageDexMetadata.size()); - String baseDexMetadata = packageDexMetadata.get(pkg.getBaseCodePath()); + String baseDexMetadata = packageDexMetadata.get(pkg.baseCodePath); assertNotNull(baseDexMetadata); - assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.getBaseCodePath())); + assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.baseCodePath)); - String splitDexMetadata = packageDexMetadata.get(pkg.getSplitCodePaths()[0]); + String splitDexMetadata = packageDexMetadata.get(pkg.splitCodePaths[0]); assertNotNull(splitDexMetadata); - assertTrue(isDexMetadataForApk(splitDexMetadata, pkg.getSplitCodePaths()[0])); + assertTrue(isDexMetadataForApk(splitDexMetadata, pkg.splitCodePaths[0])); } @Test @@ -129,14 +130,14 @@ public class DexMetadataHelperTest { copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base); copyApkToToTmpDir("install_split_feature_a.apk", R.raw.install_split_feature_a); createDexMetadataFile("install_split_feature_a.apk"); - ParsedPackage pkg = new PackageParser().parseParsedPackage(mTmpDir, 0 /* flags */, false); + Package pkg = new PackageParser().parsePackage(mTmpDir, 0 /* flags */); Map<String, String> packageDexMetadata = DexMetadataHelper.getPackageDexMetadata(pkg); assertEquals(1, packageDexMetadata.size()); - String splitDexMetadata = packageDexMetadata.get(pkg.getSplitCodePaths()[0]); + String splitDexMetadata = packageDexMetadata.get(pkg.splitCodePaths[0]); assertNotNull(splitDexMetadata); - assertTrue(isDexMetadataForApk(splitDexMetadata, pkg.getSplitCodePaths()[0])); + assertTrue(isDexMetadataForApk(splitDexMetadata, pkg.splitCodePaths[0])); } @Test @@ -145,8 +146,7 @@ public class DexMetadataHelperTest { File invalidDmFile = new File(mTmpDir, "install_split_base.dm"); Files.createFile(invalidDmFile.toPath()); try { - ParsedPackage pkg = new PackageParser() - .parseParsedPackage(mTmpDir, 0 /* flags */, false); + PackageParser.Package pkg = new PackageParser().parsePackage(mTmpDir, 0 /* flags */); DexMetadataHelper.validatePackageDexMetadata(pkg); } catch (PackageParserException e) { assertEquals(e.error, PackageManager.INSTALL_FAILED_BAD_DEX_METADATA); @@ -163,8 +163,7 @@ public class DexMetadataHelperTest { Files.createFile(invalidDmFile.toPath()); try { - ParsedPackage pkg = new PackageParser() - .parseParsedPackage(mTmpDir, 0 /* flags */, false); + PackageParser.Package pkg = new PackageParser().parsePackage(mTmpDir, 0 /* flags */); DexMetadataHelper.validatePackageDexMetadata(pkg); } catch (PackageParserException e) { assertEquals(e.error, PackageManager.INSTALL_FAILED_BAD_DEX_METADATA); diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/AndroidHidlUpdaterTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/AndroidHidlUpdaterTest.java deleted file mode 100644 index 21479c096752..000000000000 --- a/core/tests/coretests/src/android/content/pm/parsing/library/AndroidHidlUpdaterTest.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package android.content.pm.parsing.library; - -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_HIDL_BASE; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_HIDL_MANAGER; - -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.PackageImpl; -import android.content.pm.parsing.ParsedPackage; -import android.os.Build; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Test for {@link AndroidHidlUpdater} - */ -@SmallTest -@RunWith(JUnit4.class) -public class AndroidHidlUpdaterTest extends PackageSharedLibraryUpdaterTest { - - private static final String OTHER_LIBRARY = "other.library"; - - @Test - public void targeted_at_P() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.P) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.P) - .hideAsParsed() - .hideAsFinal(); - - // no change, not system - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_P_system() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.P) - .hideAsParsed() - .setSystem(true); - - // Should add both HIDL libraries - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.P) - .addUsesLibrary(ANDROID_HIDL_MANAGER) - .addUsesLibrary(ANDROID_HIDL_BASE) - .hideAsParsed() - .setSystem(true) - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_P_not_empty_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.P) - .addUsesLibrary(OTHER_LIBRARY) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.P) - .addUsesLibrary(OTHER_LIBRARY) - .hideAsParsed() - .hideAsFinal(); - - // no change, not system - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_P_not_empty_usesLibraries_system() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.P) - .addUsesLibrary(OTHER_LIBRARY) - .hideAsParsed() - .setSystem(true); - - // The hidl jars should be added at the start of the list because it - // is not on the bootclasspath and the package targets pre-P. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.P) - .addUsesLibrary(ANDROID_HIDL_MANAGER) - .addUsesLibrary(ANDROID_HIDL_BASE) - .addUsesLibrary(OTHER_LIBRARY) - .hideAsParsed() - .setSystem(true) - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_P_in_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.P) - .addUsesLibrary(ANDROID_HIDL_MANAGER) - .addUsesLibrary(ANDROID_HIDL_BASE) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.P) - .hideAsParsed() - .hideAsFinal(); - - // Libraries are removed because they are not available for non-system apps - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_P_in_usesLibraries_system() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.P) - .addUsesLibrary(ANDROID_HIDL_MANAGER) - .addUsesLibrary(ANDROID_HIDL_BASE) - .hideAsParsed() - .setSystem(true); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.P) - .addUsesLibrary(ANDROID_HIDL_MANAGER) - .addUsesLibrary(ANDROID_HIDL_BASE) - .hideAsParsed() - .setSystem(true) - .hideAsFinal(); - - // No change is required because the package explicitly requests the HIDL libraries - // and is targeted at the current version so does not need backwards compatibility. - checkBackwardsCompatibility(before, after); - } - - @Test - public void in_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesLibrary(ANDROID_HIDL_BASE) - .hideAsParsed(); - - // Dependency is removed, it is not available. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .hideAsParsed() - .hideAsFinal(); - - // Libraries are removed because they are not available for apps targeting Q+ - checkBackwardsCompatibility(before, after); - } - - @Test - public void in_usesOptionalLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesOptionalLibrary(ANDROID_HIDL_BASE) - .hideAsParsed(); - - // Dependency is removed, it is not available. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .hideAsParsed() - .hideAsFinal(); - - // Libraries are removed because they are not available for apps targeting Q+ - checkBackwardsCompatibility(before, after); - } - - private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) { - checkBackwardsCompatibility(before, after, AndroidHidlUpdater::new); - } -} diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/AndroidTestBaseUpdaterTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/AndroidTestBaseUpdaterTest.java deleted file mode 100644 index 65ae219058f4..000000000000 --- a/core/tests/coretests/src/android/content/pm/parsing/library/AndroidTestBaseUpdaterTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package android.content.pm.parsing.library; - -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_BASE; - -import android.content.pm.OptionalClassRunner; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.PackageImpl; -import android.content.pm.parsing.ParsedPackage; -import android.os.Build; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Test for {@link AndroidTestBaseUpdater} - */ -@SmallTest -@RunWith(OptionalClassRunner.class) -@OptionalClassRunner.OptionalClass("android.content.pm.parsing.library.AndroidTestBaseUpdater") -public class AndroidTestBaseUpdaterTest extends PackageSharedLibraryUpdaterTest { - - private static final String OTHER_LIBRARY = "other.library"; - - @Test - public void targeted_at_Q() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.Q) - .hideAsParsed(); - - // Should add org.apache.http.legacy. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.Q) - .addUsesLibrary(ANDROID_TEST_BASE) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_Q_not_empty_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.Q) - .addUsesLibrary(OTHER_LIBRARY) - .hideAsParsed(); - - // The org.apache.http.legacy jar should be added at the start of the list because it - // is not on the bootclasspath and the package targets pre-Q. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.Q) - .addUsesLibrary(ANDROID_TEST_BASE) - .addUsesLibrary(OTHER_LIBRARY) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_Q_in_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.Q) - .addUsesLibrary(ANDROID_TEST_BASE) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.Q) - .addUsesLibrary(ANDROID_TEST_BASE) - .hideAsParsed() - .hideAsFinal(); - - // No change is required because although org.apache.http.legacy has been removed from - // the bootclasspath the package explicitly requests it. - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_Q_in_usesOptionalLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.Q) - .addUsesOptionalLibrary(ANDROID_TEST_BASE) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.Q) - .addUsesOptionalLibrary(ANDROID_TEST_BASE) - .hideAsParsed() - .hideAsFinal(); - - // No change is required because although org.apache.http.legacy has been removed from - // the bootclasspath the package explicitly requests it. - checkBackwardsCompatibility(before, after); - } - - @Test - public void in_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesLibrary(ANDROID_TEST_BASE) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesLibrary(ANDROID_TEST_BASE) - .hideAsParsed() - .hideAsFinal(); - - // No change is required because the package explicitly requests org.apache.http.legacy - // and is targeted at the current version so does not need backwards compatibility. - checkBackwardsCompatibility(before, after); - } - - @Test - public void in_usesOptionalLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesOptionalLibrary(ANDROID_TEST_BASE) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesOptionalLibrary(ANDROID_TEST_BASE) - .hideAsParsed() - .hideAsFinal(); - - // No change is required because the package explicitly requests org.apache.http.legacy - // and is targeted at the current version so does not need backwards compatibility. - checkBackwardsCompatibility(before, after); - } - - private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) { - checkBackwardsCompatibility(before, after, AndroidTestBaseUpdater::new); - } -} diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/AndroidTestRunnerSplitUpdaterTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/AndroidTestRunnerSplitUpdaterTest.java deleted file mode 100644 index 38755b9aa965..000000000000 --- a/core/tests/coretests/src/android/content/pm/parsing/library/AndroidTestRunnerSplitUpdaterTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package android.content.pm.parsing.library; - -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_MOCK; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_RUNNER; - -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.PackageImpl; -import android.content.pm.parsing.ParsedPackage; -import android.content.pm.parsing.library.PackageBackwardCompatibility.AndroidTestRunnerSplitUpdater; -import android.os.Build; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Test for {@link AndroidTestRunnerSplitUpdater} - */ -@SmallTest -@RunWith(JUnit4.class) -public class AndroidTestRunnerSplitUpdaterTest extends PackageSharedLibraryUpdaterTest { - - @Test - public void android_test_runner_in_usesOptionalLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesOptionalLibrary(ANDROID_TEST_RUNNER) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesOptionalLibrary(ANDROID_TEST_MOCK) - .addUsesOptionalLibrary(ANDROID_TEST_RUNNER) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void android_test_runner_in_usesLibraries_android_test_mock_in_usesOptionalLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesLibrary(ANDROID_TEST_RUNNER) - .addUsesOptionalLibrary(ANDROID_TEST_MOCK) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesLibrary(ANDROID_TEST_RUNNER) - .addUsesOptionalLibrary(ANDROID_TEST_MOCK) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) { - checkBackwardsCompatibility(before, after, AndroidTestRunnerSplitUpdater::new); - } -} diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdaterTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdaterTest.java deleted file mode 100644 index 4c7899b47164..000000000000 --- a/core/tests/coretests/src/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdaterTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package android.content.pm.parsing.library; - -import static android.content.pm.parsing.library.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; - -import android.content.pm.OptionalClassRunner; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.PackageImpl; -import android.content.pm.parsing.ParsedPackage; -import android.os.Build; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Test for {@link OrgApacheHttpLegacyUpdater} - */ -@SmallTest -@RunWith(OptionalClassRunner.class) -@OptionalClassRunner.OptionalClass("android.content.pm.parsing.library.OrgApacheHttpLegacyUpdater") -public class OrgApacheHttpLegacyUpdaterTest extends PackageSharedLibraryUpdaterTest { - - private static final String OTHER_LIBRARY = "other.library"; - - @Test - public void targeted_at_O() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .hideAsParsed(); - - // Should add org.apache.http.legacy. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesLibrary(ORG_APACHE_HTTP_LEGACY) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_O_not_empty_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesLibrary(OTHER_LIBRARY) - .hideAsParsed(); - - // The org.apache.http.legacy jar should be added at the start of the list because it - // is not on the bootclasspath and the package targets pre-P. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesLibrary(ORG_APACHE_HTTP_LEGACY) - .addUsesLibrary(OTHER_LIBRARY) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_O_in_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesLibrary(ORG_APACHE_HTTP_LEGACY) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesLibrary(ORG_APACHE_HTTP_LEGACY) - .hideAsParsed() - .hideAsFinal(); - - // No change is required because although org.apache.http.legacy has been removed from - // the bootclasspath the package explicitly requests it. - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_O_in_usesOptionalLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesOptionalLibrary(ORG_APACHE_HTTP_LEGACY) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesOptionalLibrary(ORG_APACHE_HTTP_LEGACY) - .hideAsParsed() - .hideAsFinal(); - - // No change is required because although org.apache.http.legacy has been removed from - // the bootclasspath the package explicitly requests it. - checkBackwardsCompatibility(before, after); - } - - @Test - public void in_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesLibrary(ORG_APACHE_HTTP_LEGACY) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesLibrary(ORG_APACHE_HTTP_LEGACY) - .hideAsParsed() - .hideAsFinal(); - - // No change is required because the package explicitly requests org.apache.http.legacy - // and is targeted at the current version so does not need backwards compatibility. - checkBackwardsCompatibility(before, after); - } - - @Test - public void in_usesOptionalLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesOptionalLibrary(ORG_APACHE_HTTP_LEGACY) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesOptionalLibrary(ORG_APACHE_HTTP_LEGACY) - .hideAsParsed() - .hideAsFinal(); - - // No change is required because the package explicitly requests org.apache.http.legacy - // and is targeted at the current version so does not need backwards compatibility. - checkBackwardsCompatibility(before, after); - } - - private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) { - checkBackwardsCompatibility(before, after, OrgApacheHttpLegacyUpdater::new); - } -} diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/PackageSharedLibraryUpdaterTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/PackageSharedLibraryUpdaterTest.java deleted file mode 100644 index e7a80e1a7618..000000000000 --- a/core/tests/coretests/src/android/content/pm/parsing/library/PackageSharedLibraryUpdaterTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package android.content.pm.parsing.library; - -import static org.junit.Assert.assertEquals; - -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ParsedPackage; - -import java.util.function.Supplier; - -/** - * Helper for classes that test {@link PackageSharedLibraryUpdater}. - */ -abstract class PackageSharedLibraryUpdaterTest { - - protected static final String PACKAGE_NAME = "org.package.name"; - - static void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after, - Supplier<PackageSharedLibraryUpdater> updaterSupplier) { - updaterSupplier.get().updatePackage(before); - check(before.hideAsFinal(), after); - } - - private static void check(AndroidPackage before, AndroidPackage after) { - assertEquals("targetSdkVersion should not be changed", - after.getTargetSdkVersion(), - before.getTargetSdkVersion()); - assertEquals("usesLibraries not updated correctly", - after.getUsesLibraries(), - before.getUsesLibraries()); - assertEquals("usesOptionalLibraries not updated correctly", - after.getUsesOptionalLibraries(), - before.getUsesOptionalLibraries()); - } -} diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/RemoveUnnecessaryAndroidTestBaseLibraryTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/RemoveUnnecessaryAndroidTestBaseLibraryTest.java deleted file mode 100644 index fd3ba2bd0c68..000000000000 --- a/core/tests/coretests/src/android/content/pm/parsing/library/RemoveUnnecessaryAndroidTestBaseLibraryTest.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package android.content.pm.parsing.library; - -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_BASE; - -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.PackageImpl; -import android.content.pm.parsing.ParsedPackage; -import android.content.pm.parsing.library.PackageBackwardCompatibility.RemoveUnnecessaryAndroidTestBaseLibrary; -import android.os.Build; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Test for {@link RemoveUnnecessaryAndroidTestBaseLibrary} - */ -@SmallTest -@RunWith(JUnit4.class) -public class RemoveUnnecessaryAndroidTestBaseLibraryTest - extends PackageSharedLibraryUpdaterTest { - - private static final String OTHER_LIBRARY = "other.library"; - - @Test - public void targeted_at_O() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .hideAsParsed() - .hideAsFinal(); - - // No change required. - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_O_not_empty_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesLibrary(OTHER_LIBRARY) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesLibrary(OTHER_LIBRARY) - .hideAsParsed() - .hideAsFinal(); - - // No change required. - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_O_in_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesLibrary(ANDROID_TEST_BASE) - .hideAsParsed(); - - // android.test.base should be removed from the libraries because it is provided - // on the bootclasspath and providing both increases start up cost unnecessarily. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_O_in_usesOptionalLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesOptionalLibrary(ANDROID_TEST_BASE) - .hideAsParsed(); - - // android.test.base should be removed from the libraries because it is provided - // on the bootclasspath and providing both increases start up cost unnecessarily. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void in_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .addUsesLibrary(ANDROID_TEST_BASE) - .hideAsParsed(); - - // android.test.base should be removed from the libraries because it is provided - // on the bootclasspath and providing both increases start up cost unnecessarily. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void in_usesOptionalLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesOptionalLibrary(ANDROID_TEST_BASE) - .hideAsParsed(); - - // android.test.base should be removed from the libraries because it is provided - // on the bootclasspath and providing both increases start up cost unnecessarily. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void in_bothLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesLibrary(ANDROID_TEST_BASE) - .addUsesOptionalLibrary(ANDROID_TEST_BASE) - .hideAsParsed(); - - // android.test.base should be removed from the libraries because it is provided - // on the bootclasspath and providing both increases start up cost unnecessarily. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) { - // TODO(b/72538146) - Cannot use constructor reference here because it is also used in - // PackageBackwardCompatibility and that seems to create a package-private lambda in - // android.content.pm which this then tries to reuse but fails because it cannot access - // package-private classes/members because the test is loaded by a different ClassLoader - // than the lambda. - checkBackwardsCompatibility(before, after, - () -> new RemoveUnnecessaryAndroidTestBaseLibrary()); - } - -} diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java deleted file mode 100644 index d3494d93ae52..000000000000 --- a/core/tests/coretests/src/android/content/pm/parsing/library/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package android.content.pm.parsing.library; - -import static android.content.pm.parsing.library.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; - -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.PackageImpl; -import android.content.pm.parsing.ParsedPackage; -import android.content.pm.parsing.library.PackageBackwardCompatibility.RemoveUnnecessaryOrgApacheHttpLegacyLibrary; -import android.os.Build; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Test for {@link RemoveUnnecessaryOrgApacheHttpLegacyLibrary} - */ -@SmallTest -@RunWith(JUnit4.class) -public class RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest - extends PackageSharedLibraryUpdaterTest { - - private static final String OTHER_LIBRARY = "other.library"; - - @Test - public void targeted_at_O() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .hideAsParsed() - .hideAsFinal(); - - // No change required. - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_O_not_empty_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesLibrary(OTHER_LIBRARY) - .hideAsParsed(); - - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesLibrary(OTHER_LIBRARY) - .hideAsParsed() - .hideAsFinal(); - - // No change required. - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_O_in_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesLibrary(ORG_APACHE_HTTP_LEGACY) - .hideAsParsed(); - - // org.apache.http.legacy should be removed from the libraries because it is provided - // on the bootclasspath and providing both increases start up cost unnecessarily. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void targeted_at_O_in_usesOptionalLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .addUsesOptionalLibrary(ORG_APACHE_HTTP_LEGACY) - .hideAsParsed(); - - // org.apache.http.legacy should be removed from the libraries because it is provided - // on the bootclasspath and providing both increases start up cost unnecessarily. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.O) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void in_usesLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesLibrary(ORG_APACHE_HTTP_LEGACY) - .hideAsParsed(); - - // org.apache.http.legacy should be removed from the libraries because it is provided - // on the bootclasspath and providing both increases start up cost unnecessarily. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void in_usesOptionalLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesOptionalLibrary(ORG_APACHE_HTTP_LEGACY) - .hideAsParsed(); - - // org.apache.http.legacy should be removed from the libraries because it is provided - // on the bootclasspath and providing both increases start up cost unnecessarily. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - @Test - public void in_bothLibraries() { - ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .addUsesLibrary(ORG_APACHE_HTTP_LEGACY) - .addUsesOptionalLibrary(ORG_APACHE_HTTP_LEGACY) - .hideAsParsed(); - - // org.apache.http.legacy should be removed from the libraries because it is provided - // on the bootclasspath and providing both increases start up cost unnecessarily. - AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME) - .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT) - .hideAsParsed() - .hideAsFinal(); - - checkBackwardsCompatibility(before, after); - } - - private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) { - // TODO(b/72538146) - Cannot use constructor reference here because it is also used in - // PackageBackwardCompatibility and that seems to create a package-private lambda in - // android.content.pm which this then tries to reuse but fails because it cannot access - // package-private classes/members because the test is loaded by a different ClassLoader - // than the lambda. - checkBackwardsCompatibility(before, after, - () -> new RemoveUnnecessaryOrgApacheHttpLegacyLibrary()); - } -} diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java index c5da54936653..02a88fc8aecb 100644 --- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java +++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java @@ -162,8 +162,13 @@ public class ContentCaptureSessionTest { } @Override - public void internalNotifySessionLifecycle(boolean started) { - throw new UnsupportedOperationException("Should not have been called"); + void internalNotifySessionResumed() { + throw new UnsupportedOperationException("should not have been called"); + } + + @Override + void internalNotifySessionPaused() { + throw new UnsupportedOperationException("should not have been called"); } @Override diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index 2dfb777592fd..a2402e25c556 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -1,16 +1,2170 @@ { "version": "1.0.0", "messages": { + "-2146181682": { + "message": "Releasing screen wakelock, obscured by %s", + "level": "DEBUG", + "group": "WM_DEBUG_KEEP_SCREEN_ON", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-2138637148": { + "message": "Clearing focused app, displayId=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/ActivityDisplay.java" + }, + "-2109864870": { + "message": "app-release(): mOuter=%s", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "-2086729999": { + "message": "Removing app token: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-2072089308": { + "message": "Attempted to add window with token that is a sub-window: %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-2039580386": { + "message": "Attempted to add input method window with unknown token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-2024464438": { + "message": "app-onAnimationFinished(): mOuter=%s", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "-2012562539": { + "message": "startAnimation(): Notify animation start:", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "-2002500255": { + "message": "Defer removing snapshot surface in %dms", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/TaskSnapshotSurface.java" + }, + "-1991255017": { + "message": "Drawing snapshot surface sizeMismatch=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/TaskSnapshotSurface.java" + }, + "-1976930686": { + "message": "Attempted to add Accessibility overlay window with bad token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1963461591": { + "message": "Removing %s from %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1958209312": { + "message": "Clear freezing of %s: hidden=%b freezing=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, + "-1953668890": { + "message": "Can't start recents animation, nextAppTransition=%s", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimation.java" + }, + "-1949279037": { + "message": "Attempted to add input method window with bad token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1939358269": { + "message": "mRecentScreenshotAnimator finish", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimationController.java" + }, + "-1938839202": { + "message": "SURFACE LEAK DESTROY: %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "-1915280162": { + "message": "Attempted to add wallpaper window with bad token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1886298021": { + "message": "setAppStartingWindow: token=%s pkg=%s transferFrom=%s newTask=%b taskSwitch=%b processRunning=%b allowTaskSnapshot=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, + "-1884933373": { + "message": "enableScreenAfterBoot: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s", + "level": "INFO", + "group": "WM_DEBUG_BOOT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1872288685": { + "message": "applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", + "at": "com\/android\/server\/wm\/AppTransition.java" + }, + "-1868124841": { + "message": "screenOnEarly=%b, awake=%b, currentAppOrientation=%d, orientationSensorEnabled=%b, keyguardDrawComplete=%b, windowManagerDrawComplete=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayRotation.java" + }, + "-1862269827": { + "message": "applyAnimation: anim=%s transit=%s isEntrance=%b Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", + "at": "com\/android\/server\/wm\/AppTransition.java" + }, + "-1838803135": { + "message": "Attempted to set windowing mode to a display that does not exist: %d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1836092044": { + "message": "Creating SnapshotStartingData", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-1824578273": { + "message": "Reporting new frame to %s: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_RESIZE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "-1822611824": { + "message": "\tRemove token=%s", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "-1797409732": { + "message": "Skipping %s because %s", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "-1770075711": { + "message": "Adding window client %s that is dead, aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1768557332": { + "message": "removeWallpaperAnimation()", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimationController.java" + }, + "-1750206390": { + "message": "Exception thrown when creating surface for client %s (%s). %s", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1747461042": { + "message": "set mOrientationChanging of %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "-1741065110": { + "message": "No app is requesting an orientation, return %d for display id=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "-1736245181": { + "message": "Tried to remove starting window but startingWindow was null: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-1730156332": { + "message": "Display id=%d rotation changed to %d from %d, lastOrientation=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayRotation.java" + }, + "-1710206702": { + "message": "Display id=%d is frozen while keyguard locked, return %d", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "-1661704580": { + "message": "Attempted to set replacing window on non-existing app token %s", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1661404819": { + "message": "applyAnimation: atoken=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-1632122349": { + "message": "Changing surface while display frozen: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1597650595": { + "message": "removeAppToken: %s delayed=%b Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-1596995693": { + "message": "startAnimation", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "-1587841219": { + "message": "Focus moving from %s to %s displayId=%d", + "level": "INFO", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1568331821": { + "message": "Enabling listeners", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayRotation.java" + }, + "-1561845439": { + "message": "reParentWindowToken: removing window token=%s from task=%s", + "level": "INFO", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-1545962566": { + "message": "View server did not start", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1526645239": { + "message": "Timeout waiting for drawn: undrawn=%s", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1524305318": { + "message": "Nulling last startingData", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-1519226370": { + "message": "startingData was nulled out before handling mAddStartingWindow: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-1515151503": { + "message": ">>> OPEN TRANSACTION removeReplacedWindows", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, + "-1497837552": { + "message": "onAnimationFinished(): mPendingAnimations=%d", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "-1483752006": { + "message": " THUMBNAIL %s: CREATE", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/AppWindowThumbnail.java" + }, + "-1470632028": { + "message": "Marking app token %s with replacing windows.", + "level": "DEBUG", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-1455600136": { + "message": "Attempted to add Dream window with unknown token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1448427933": { + "message": "startingWindow was set but startingSurface==null, couldn't remove", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-1443029505": { + "message": "SAFE MODE ENABLED (menu=%d s=%d dpad=%d trackball=%d)", + "level": "INFO", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1434147454": { + "message": "cleanupAnimation(): Notify animation finished mPendingAnimations=%d reorderMode=%d", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimationController.java" + }, + "-1427184084": { + "message": "addWindow: New client %s: window=%s Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1413901262": { + "message": "startRecentsActivity(): intent=%s", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimation.java" + }, + "-1391944764": { + "message": "SURFACE DESTROY: %s. %s", + "level": "INFO", + "group": "WM_SHOW_SURFACE_ALLOC", + "at": "com\/android\/server\/wm\/WindowStateAnimator.java" + }, + "-1389772804": { + "message": "Attempted to add voice interaction window with bad token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1350198040": { + "message": "hideBootMessagesLocked: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s", + "level": "INFO", + "group": "WM_DEBUG_BOOT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1318134223": { + "message": "No longer Stopped: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-1270731689": { + "message": "Attempted to set replacing window on app token with no content %s", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1270148832": { + "message": "Resize start waiting for draw, mDrawState=DRAW_PENDING in %s, surfaceController %s", + "level": "VERBOSE", + "group": "WM_DEBUG_RESIZE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "-1263554915": { + "message": "Attempted to add Dream window with bad token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1259022216": { + "message": "SURFACE HIDE ( %s ): %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowSurfaceController.java" + }, + "-1257821162": { + "message": "OUT SURFACE %s: copied", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1219773477": { + "message": "setInputConsumerEnabled(%s): mCanceled=%b", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimationController.java" + }, + "-1207757583": { + "message": "startAnimation(): Notify animation start: %s", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimationController.java" + }, + "-1176488860": { + "message": "SURFACE isSecure=%b: %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowSurfaceController.java" + }, + "-1156118957": { + "message": "Updated config=%s", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimation.java" + }, + "-1144293044": { + "message": "SURFACE SET FREEZE LAYER: %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowStateAnimator.java" + }, + "-1130891072": { + "message": "Orientation continue waiting for draw in %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/WindowStateAnimator.java" + }, + "-1130868271": { + "message": "Resizing %s WITH DRAW PENDING", + "level": "INFO", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "-1117599386": { + "message": "Deferring rotation, display is not enabled.", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayRotation.java" + }, + "-1113134997": { + "message": "Attempted to add application window with unknown token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1103716954": { + "message": "Not removing %s due to exit animation", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "-1103115659": { + "message": "Performing post-rotate rotation", + "level": "DEBUG", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, + "-1099052739": { + "message": "\tAdd token=%s", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "-1097148233": { + "message": "commitVisibility: %s: hidden=%b hiddenRequested=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-1089874824": { + "message": "SURFACE SHOW (performLayout): %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowSurfaceController.java" + }, + "-1077196445": { + "message": "Add starting %s: startingData=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-1076978367": { + "message": "thawRotation: mRotation=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1060365734": { + "message": "Attempted to add QS dialog window with bad token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1047945589": { + "message": "Remove client=%x, surfaceController=%s Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "-1044506655": { + "message": "New transit away from wallpaper: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "-1042574499": { + "message": "Attempted to add Accessibility overlay window with unknown token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-1009117329": { + "message": "isFetchingAppTransitionSpecs=true", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "-1001633850": { + "message": "Removing focused app token:%s displayId=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-993378225": { + "message": "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s", + "level": "VERBOSE", + "group": "WM_DEBUG_DRAW", + "at": "com\/android\/server\/wm\/WindowStateAnimator.java" + }, + "-986746907": { + "message": "Starting window removed %s", + "level": "DEBUG", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "-979259577": { + "message": "setAppVisibility(%s, visible=%b): %s hidden=%b hiddenRequested=%b Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-955458843": { + "message": "Set freezing of %s: hidden=%b freezing=%b hiddenRequested=%b. %s", + "level": "INFO", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-953872371": { + "message": "setClientHidden: %s clientHidden=%b Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-928291778": { + "message": "applyAnimation: anim=%s nextAppTransition=%d transit=%s Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", + "at": "com\/android\/server\/wm\/AppTransition.java" + }, + "-916108501": { + "message": "Adding %s to %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "-914253865": { + "message": "Attempted to add voice interaction window with unknown token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-883738232": { + "message": "Adding more than one toast window for UID at a time.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-874446906": { + "message": "showBootMessage: msg=%s always=%b mAllowBootMessages=%b mShowingBootMessages=%b mSystemBooted=%b. %s", + "level": "INFO", + "group": "WM_DEBUG_BOOT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-861859917": { + "message": "Attempted to add window to a display that does not exist: %d. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-861707633": { + "message": "Destroying surface %s called by %s", + "level": "INFO", + "group": "WM_SHOW_SURFACE_ALLOC", + "at": "com\/android\/server\/wm\/WindowSurfaceController.java" + }, + "-856025122": { + "message": "SURFACE transparentRegionHint=%s: %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-853404763": { + "message": "\twallpaper=%s", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "-853226675": { + "message": "Attempted to add window with exiting application token .%s Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-809771899": { + "message": "findFocusedWindow: Reached focused app=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "-807062773": { + "message": "Aborted starting %s: removed=%b startingData=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-793346159": { + "message": "New transit into wallpaper: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "-784959154": { + "message": "Attempted to add private presentation window to a non-private display. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-783405930": { + "message": "Performing post-rotate rotation", + "level": "DEBUG", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-771282525": { + "message": "Losing focus: %s", + "level": "INFO", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-760801764": { + "message": "onAnimationCancelled", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java" + }, + "-754503024": { + "message": "Relayout %s: oldVis=%d newVis=%d. %s", + "level": "INFO", + "group": "WM_DEBUG_SCREEN_ON", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-747671114": { + "message": "Failed looking up window callers=%s", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-714291355": { + "message": "Losing delayed focus: %s", + "level": "INFO", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-694710814": { + "message": "Pausing rotation during drag", + "level": "DEBUG", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DragState.java" + }, + "-687185281": { + "message": "New topFocusedDisplayId=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, + "-666510420": { + "message": "With display frozen, orientationChangeComplete=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, + "-666419717": { + "message": "Creating animation bounds layer", + "level": "INFO", + "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-653156702": { + "message": "createAppAnimations()", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "-650040763": { + "message": "rotationForOrientation(orient=%d, last=%d); user=%d %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayRotation.java" + }, + "-635082269": { + "message": "******** booted=%b msg=%b haveBoot=%b haveApp=%b haveWall=%b wallEnabled=%b haveKeyguard=%b", + "level": "INFO", + "group": "WM_DEBUG_SCREEN_ON", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "-622997754": { + "message": "postWindowRemoveCleanupLocked: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-618015844": { + "message": "performEnableScreen: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b mOnlyCore=%b. %s", + "level": "INFO", + "group": "WM_DEBUG_BOOT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-583031528": { + "message": "%s", + "level": "INFO", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-576070986": { + "message": "Performing post-rotate rotation after seamless rotation", + "level": "INFO", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayRotation.java" + }, + "-573268667": { + "message": "applyAnimation: transition animation is disabled or skipped. atoken=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-554834595": { + "message": "Display id=%d is frozen, return %d", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "-549028919": { + "message": "enableScreenIfNeededLocked: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s", + "level": "INFO", + "group": "WM_DEBUG_BOOT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-545190927": { + "message": "<<< CLOSE TRANSACTION animate", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowAnimator.java" + }, + "-519504830": { + "message": "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s isEntrance=%b Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", + "at": "com\/android\/server\/wm\/AppTransition.java" + }, + "-507657818": { + "message": "Window %s is already added", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-496681057": { + "message": "Attempted to get remove mode of a display that does not exist: %d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-481924678": { + "message": "handleNotObscuredLocked w: %s, w.mHasSurface: %b, w.isOnScreen(): %b, w.isDisplayedLw(): %b, w.mAttrs.userActivityTimeout: %d", + "level": "DEBUG", + "group": "WM_DEBUG_KEEP_SCREEN_ON", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, + "-477481651": { + "message": "SURFACE DESTROY PENDING: %s. %s", + "level": "INFO", + "group": "WM_SHOW_SURFACE_ALLOC", + "at": "com\/android\/server\/wm\/WindowStateAnimator.java" + }, + "-445944810": { + "message": "finish(%b): mCanceled=%b", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimationController.java" + }, + "-444624452": { + "message": "REPARENT from: %s to: %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowSurfaceController.java" + }, + "-439951996": { + "message": "Disabling listeners", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayRotation.java" + }, + "-415865166": { + "message": "findFocusedWindow: Found new focus @ %s", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "-405536909": { + "message": "Removing snapshot surface", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/TaskSnapshotSurface.java" + }, + "-393505149": { + "message": "unable to update pointer icon", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-386552155": { + "message": "Attempted to set system decors flag to a display that does not exist: %d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-379068494": { + "message": "unknownApps is not empty: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "-371630969": { + "message": "New wallpaper target=%s, oldWallpaper=%s, openingApps=%s, closingApps=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "-367797467": { + "message": "Creating SplashScreenStartingData", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-344488673": { + "message": "Finishing drawing window %s: mDrawState=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/WindowStateAnimator.java" + }, + "-336658140": { + "message": "Checking theme of starting window: 0x%x", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-324085783": { + "message": "SURFACE CROP %s: %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowSurfaceController.java" + }, + "-322035974": { + "message": "App freeze timeout expired.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-320419645": { + "message": "Removing replaced window: %s", + "level": "DEBUG", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "-198463978": { + "message": "updateRotationUnchecked: alwaysSendConfiguration=%b forceRelayout=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-193782861": { + "message": "Final remove of window: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_WINDOW_MOVEMENT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-167822951": { + "message": "Attempted to add starting window to token with already existing starting window", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-129722369": { + "message": "New transit: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "-121104356": { + "message": "Remove %s: mSurfaceController=%s mAnimatingExit=%b mRemoveOnExit=%b mHasSurface=%b surfaceShowing=%b animating=%b app-animation=%b mWillReplaceWindow=%b inPendingTransaction=%b mDisplayFrozen=%b callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "-117925665": { + "message": "addAppToken: %s task=%s at %d", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, + "-116086365": { + "message": "******************** ENABLING SCREEN!", + "level": "INFO", + "group": "WM_DEBUG_SCREEN_ON", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-106400104": { + "message": "Preload recents with %s", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimation.java" + }, + "-104758113": { + "message": "Removing app %s delayed=%b animation=%s animating=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-96848838": { + "message": "Gaining focus: %s", + "level": "INFO", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-87705714": { + "message": "findFocusedWindow: focusedApp=null using new focus @ %s", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "-87703044": { + "message": "Boot completed: SurfaceFlinger is dead!", + "level": "ERROR", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "-86763148": { + "message": " KILL SURFACE SESSION %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/Session.java" + }, + "-34965929": { + "message": "Moving pending starting from %s to %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "-29233992": { + "message": "SURFACE CLEAR CROP: %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowSurfaceController.java" + }, + "-7343917": { + "message": "onAnimationFinished(): targetStack=%s targetActivity=%s mRestoreTargetBehindStack=%s", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimation.java" + }, + "9803449": { + "message": "startFreezingDisplayLocked: exitAnim=%d enterAnim=%d called by %s", + "level": "DEBUG", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "10608884": { + "message": " FREEZE %s: CREATE", + "level": "INFO", + "group": "WM_SHOW_SURFACE_ALLOC", + "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java" + }, + "11060725": { + "message": "Attempted to get system decors flag of a display that does not exist: %d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "17696244": { + "message": "startAnimation(): mPendingStart=%b mCanceled=%b", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimationController.java" + }, + "38267433": { + "message": "Attempted to reset replacing window on non-existing app token %s", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "44171776": { + "message": "Resetting app token %s of replacing window marks.", + "level": "DEBUG", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "51200510": { + "message": " BLACK %s: DESTROY", + "level": "INFO", + "group": "WM_SHOW_SURFACE_ALLOC", + "at": "com\/android\/server\/wm\/BlackFrame.java" + }, + "51628177": { + "message": "Attempted to get windowing mode of a display that does not exist: %d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "83950285": { + "message": "removeAnimation(%d)", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimationController.java" + }, + "91350919": { + "message": "Attempted to set IME flag to a display that does not exist: %d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "95281111": { + "message": "Attempted to get IME flag of a display that does not exist: %d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "95902367": { + "message": "Relayout of %s: focusMayChange=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "100936473": { + "message": "Wallpaper animation!", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "115108840": { + "message": "Removing startingView=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "118187173": { + "message": "Enqueueing ADD_STARTING", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "123161180": { + "message": "SEVER CHILDREN", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowSurfaceController.java" + }, + "150351993": { + "message": "addWindow: %s startingWindow=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "152914409": { + "message": " BLACK %s: CREATE layer=%d", + "level": "INFO", + "group": "WM_SHOW_SURFACE_ALLOC", + "at": "com\/android\/server\/wm\/BlackFrame.java" + }, + "154699456": { + "message": "Last window, removing starting window %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "173419252": { + "message": "No thumbnail header bitmap for: %d", + "level": "DEBUG", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "184362060": { + "message": "screenshotTask(%d): mCanceled=%b", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimationController.java" + }, + "186668272": { + "message": "Now changing app %s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "194124419": { + "message": "goodToGo(): Animation finished already, canceled=%s mPendingAnimations=%d", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "196230599": { + "message": "Moving existing starting %s from %s to %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "221540118": { + "message": "mUserActivityTimeout set to %d", + "level": "DEBUG", + "group": "WM_DEBUG_KEEP_SCREEN_ON", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, + "241961619": { + "message": "Adding %s to %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/WindowToken.java" + }, + "246676969": { + "message": "Attempted to add window with non-application token .%s Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "248210157": { + "message": "Finishing remote animation", + "level": "INFO", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "254883724": { + "message": "addWindowToken: Attempted to add binder token: %s for already created window token: %s displayId=%d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "255692476": { + "message": "**** GOOD TO GO", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "269576220": { + "message": "Resuming rotation after drag", + "level": "DEBUG", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DragState.java" + }, + "274773837": { + "message": "applyAnimation: anim=%s nextAppTransition=ANIM_CLIP_REVEAL transit=%s Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", + "at": "com\/android\/server\/wm\/AppTransition.java" + }, + "285317231": { + "message": "Input focus has changed to %s", + "level": "DEBUG", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/InputMonitor.java" + }, + "288485303": { + "message": "Attempted to set remove mode to a display that does not exist: %d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "289967521": { + "message": "Check opening app=%s: allDrawn=%b startingDisplayed=%b startingMoved=%b isRelaunching()=%b startingWindow=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "292904800": { + "message": "Deferring rotation, animation in progress.", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayRotation.java" + }, + "302992539": { + "message": "addAnimation(%s)", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimationController.java" + }, + "309039362": { + "message": "SURFACE MATRIX [%f,%f,%f,%f]: %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowSurfaceController.java" + }, + "342460966": { + "message": "DRAG %s: pos=(%d,%d)", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/DragState.java" + }, + "344795667": { + "message": "*** APP TRANSITION TIMEOUT. displayId=%d isTransitionSet()=%b mOpeningApps.size()=%d mClosingApps.size()=%d mChangingApps.size()=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransition.java" + }, + "355720268": { + "message": "stopFreezingDisplayLocked: Unfreezing now", + "level": "DEBUG", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "371641947": { + "message": "Window Manager Crash %s", + "level": "WTF", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "374972436": { + "message": "performEnableScreen: Waiting for anim complete", + "level": "INFO", + "group": "WM_DEBUG_BOOT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "385096046": { + "message": "Delaying loss of focus...", + "level": "INFO", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "399841913": { + "message": "SURFACE RECOVER DESTROY: %s", + "level": "INFO", + "group": "WM_SHOW_SURFACE_ALLOC", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, + "416664944": { + "message": "No longer freezing: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "417311568": { + "message": "onResize: Resizing %s", + "level": "DEBUG", + "group": "WM_DEBUG_RESIZE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "424524729": { + "message": "Attempted to add wallpaper window with unknown token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "435494046": { + "message": "Attempted to add window to a display for which the application does not have access: %d. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "457951957": { + "message": "\tNot visible=%s", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java" + }, + "463993897": { + "message": "Aborted waiting for drawn: %s", + "level": "WARN", + "group": "WM_DEBUG_SCREEN_ON", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "474000473": { + "message": "No stack above target stack=%s", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimation.java" + }, + "481370485": { + "message": "Computed rotation=%d for display id=%d based on lastOrientation=%d and oldRotation=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayRotation.java" + }, + "490877640": { + "message": "onStackOrderChanged(): stack=%s", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimation.java" + }, + "492980365": { + "message": "TRANSIT_TASK_OPEN_BEHIND, adding %s to mOpeningApps", + "level": "DEBUG", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "495032901": { + "message": "Expected target stack=%s to restored behind stack=%s but it is behind stack=%s", + "level": "WARN", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimation.java" + }, + "508887531": { + "message": "applyAnimation voice: anim=%s transit=%s isEntrance=%b Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", + "at": "com\/android\/server\/wm\/AppTransition.java" + }, + "557227556": { + "message": "onAnimationFinished(): Notify animation finished:", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "558823034": { + "message": "SURFACE isOpaque=%b: %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowSurfaceController.java" + }, + "585096182": { + "message": "SURFACE isColorSpaceAgnostic=%b: %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowSurfaceController.java" + }, + "594260577": { + "message": "createWallpaperAnimations()", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "600140673": { + "message": "checkBootAnimationComplete: Waiting for anim complete", + "level": "INFO", + "group": "WM_DEBUG_BOOT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "608694300": { + "message": " NEW SURFACE SESSION %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/Session.java" + }, + "620368427": { + "message": "******* TELLING SURFACE FLINGER WE ARE BOOTED!", + "level": "INFO", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "628276090": { + "message": "Delaying app transition for screen rotation animation to finish", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "631792420": { + "message": "Attempted to add window with token that is not a window: %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "633654009": { + "message": "SURFACE POS (setPositionInTransaction) @ (%f,%f): %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowSurfaceController.java" + }, + "644675193": { + "message": "Real start recents", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimation.java" + }, + "646155519": { + "message": "Started intent=%s", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimation.java" + }, + "662572728": { + "message": "Attempted to add a toast window with bad token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "665256544": { + "message": "All windows drawn!", + "level": "DEBUG", + "group": "WM_DEBUG_SCREEN_ON", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "668425960": { + "message": "Notify removed startingWindow %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, "676824470": { "message": "Test completed successfully: %b %d %o %x %e %g %f %% %s.", "level": "ERROR", "group": "TEST_GROUP", "at": "com\/android\/server\/wm\/ProtoLogGroup.java" + }, + "685047360": { + "message": "Resizing window %s", + "level": "VERBOSE", + "group": "WM_DEBUG_RESIZE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "690411811": { + "message": "goodToGo(): No apps to animate", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "693423992": { + "message": "setAnimationLocked: setting mFocusMayChange true", + "level": "INFO", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "704998117": { + "message": "Failed to create surface control for %s", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "745391677": { + "message": " CREATE SURFACE %s IN SESSION %s: pid=%d format=%d flags=0x%x \/ %s", + "level": "INFO", + "group": "WM_SHOW_SURFACE_ALLOC", + "at": "com\/android\/server\/wm\/WindowStateAnimator.java" + }, + "758852025": { + "message": "Surface returned was null: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "765395228": { + "message": "onAnimationFinished(): controller=%s reorderMode=%d", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimation.java" + }, + "791468751": { + "message": "Pausing rotation during re-position", + "level": "DEBUG", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/TaskPositioner.java" + }, + "794570322": { + "message": "Now closing app %s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "811802785": { + "message": "Changing app %s hidden=%b performLayout=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "829434921": { + "message": "Draw state now committed in %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/WindowStateAnimator.java" + }, + "835814848": { + "message": "%s", + "level": "INFO", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "845234215": { + "message": "App is requesting an orientation, return %d for display id=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "847534382": { + "message": "Non-null appWindowToken for system window of rootType=%d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "853091290": { + "message": "Moved stack=%s behind stack=%s", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimation.java" + }, + "868946719": { + "message": "notifyAppResumed: wasStopped=%b %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "873914452": { + "message": "goodToGo()", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "884043983": { + "message": "removeDeadWindows: %s", + "level": "WARN", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "892244061": { + "message": "Waiting for drawn %s: removed=%b visible=%b mHasSurface=%b drawState=%d", + "level": "INFO", + "group": "WM_DEBUG_SCREEN_ON", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "898863925": { + "message": "Attempted to add QS dialog window with unknown token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "913494177": { + "message": "removeAllWindowsIfPossible: removing win=%s", + "level": "WARN", + "group": "WM_DEBUG_WINDOW_MOVEMENT", + "at": "com\/android\/server\/wm\/WindowToken.java" + }, + "916191774": { + "message": "Orientation change complete in %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/WindowStateAnimator.java" + }, + "917739349": { + "message": "Set focused app to: %s moveFocusNow=%b displayId=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/ActivityDisplay.java" + }, + "954470154": { + "message": "FORCED DISPLAY SCALING DISABLED", + "level": "INFO", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "990058731": { + "message": "notifyAppStopped: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "1001904964": { + "message": "***** BOOT TIMEOUT: forcing display enabled", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1004585481": { + "message": "%s forcing orientation to %d for display id=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "1021057640": { + "message": "Marking app token %s with replacing child windows.", + "level": "DEBUG", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "1051545910": { + "message": "Exit animation finished in %s: remove=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "1073230342": { + "message": "startAnimation", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java" + }, + "1089714158": { + "message": " FREEZE %s: DESTROY", + "level": "INFO", + "group": "WM_SHOW_SURFACE_ALLOC", + "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java" + }, + "1108406230": { + "message": "stopFreezingDisplayLocked: Returning mWaitingForConfig=%b, mAppsFreezingScreen=%d, mWindowsFreezingScreen=%d, mClientFreezingScreen=%b, mOpeningApps.size()=%d", + "level": "DEBUG", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1112047265": { + "message": "finishDrawingWindow: %s mDrawState=%s", + "level": "DEBUG", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1115417974": { + "message": "FORCED DISPLAY SIZE: %dx%d", + "level": "INFO", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1140424002": { + "message": "Finished screen turning on...", + "level": "INFO", + "group": "WM_DEBUG_SCREEN_ON", + "at": "com\/android\/server\/wm\/DisplayPolicy.java" + }, + "1160771501": { + "message": "Resize reasons for w=%s: %s surfaceResized=%b configChanged=%b dragResizingChanged=%b reportOrientationChanged=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_RESIZE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "1166381079": { + "message": "Execute app transition: %s, displayId: %d Callers=%s", + "level": "WARN", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "1195433019": { + "message": "Clearing startingData for token=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "1208313423": { + "message": "addWindowToken: Attempted to add token: %s for non-exiting displayId=%d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1219600119": { + "message": "addWindow: win=%s Callers=%s", + "level": "DEBUG", + "group": "WM_DEBUG_FOCUS", + "at": "com\/android\/server\/wm\/WindowToken.java" + }, + "1220075598": { + "message": "SURFACE SIZE %dx%d: %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowSurfaceController.java" + }, + "1224307091": { + "message": "checkBootAnimationComplete: Animation complete!", + "level": "INFO", + "group": "WM_DEBUG_BOOT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1244668962": { + "message": "Added starting %s: startingWindow=%s startingView=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "1288731814": { + "message": "WindowState.hideLw: setting mFocusMayChange true", + "level": "INFO", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "1325649102": { + "message": "Bad requesting window %s", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1329340614": { + "message": "Orientation not waiting for draw in %s, surfaceController %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "1331177619": { + "message": "Attempted to add a toast window with unknown token %s. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1358462645": { + "message": "Looking for focus: %s, flags=%d, canReceive=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "1401700824": { + "message": "Window drawn win=%s", + "level": "DEBUG", + "group": "WM_DEBUG_SCREEN_ON", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1404220922": { + "message": "Translucent=%s Floating=%s ShowWallpaper=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "1422781269": { + "message": "Resuming rotation after re-position", + "level": "DEBUG", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/TaskPositioner.java" + }, + "1423418408": { + "message": "unable to restore pointer icon", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1423592961": { + "message": "<<< CLOSE TRANSACTION removeReplacedWindows", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, + "1430336882": { + "message": "findFocusedWindow: focusedApp windows not focusable using new focus @ %s", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "1434383382": { + "message": "Attempted to get flag of a display that does not exist: %d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1448683958": { + "message": "Override pending remote transitionSet=%b adapter=%s", + "level": "INFO", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransition.java" + }, + "1457990604": { + "message": "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM_IN_PLACE transit=%s Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", + "at": "com\/android\/server\/wm\/AppTransition.java" + }, + "1469292670": { + "message": "Changing focus from %s to %s displayId=%d Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "1495525537": { + "message": "createWallpaperAnimations()", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimationController.java" + }, + "1496418389": { + "message": "Removing starting %s from %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "1497304204": { + "message": "Deferring rotation, rotation is paused.", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayRotation.java" + }, + "1504168072": { + "message": "removeIfPossible: %s callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "1518495446": { + "message": "removeWindowToken: Attempted to remove non-existing token: %s", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1519757176": { + "message": "setHomeApp(%s)", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimationController.java" + }, + "1521476038": { + "message": "Attempted to set flag to a display that does not exist: %d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1525976603": { + "message": "cancelAnimation(): reason=%s", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimationController.java" + }, + "1531527061": { + "message": "createAnimationAdapter(): token=%s", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "1563755163": { + "message": "Permission Denial: %s from pid=%d, uid=%d requires %s", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1573332272": { + "message": "Display id=%d selected orientation %d, got rotation %d", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayRotation.java" + }, + "1577579529": { + "message": "win=%s destroySurfaces: appStopped=%b win.mWindowRemovalAllowed=%b win.mRemoveOnExit=%b", + "level": "ERROR", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "1589610525": { + "message": "applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS: anim=%s transit=%s isEntrance=true Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", + "at": "com\/android\/server\/wm\/AppTransition.java" + }, + "1628345525": { + "message": "Now opening app %s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "1634557978": { + "message": "**** Dismissing screen rotation animation", + "level": "INFO", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1635462459": { + "message": "onMovedByResize: Moving %s", + "level": "DEBUG", + "group": "WM_DEBUG_RESIZE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "1637745145": { + "message": "Clear freezing of %s force=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "1720696061": { + "message": "Adding window to Display that has been removed.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1739298851": { + "message": "removeWindowToken: Attempted to remove token: %s for non-exiting displayId=%d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1747941491": { + "message": "SURFACE controller=%s alpha=%f matrix=[%f*%f,%f*%f][%f*%f,%f*%f]: %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowStateAnimator.java" + }, + "1756082882": { + "message": "Orientation change skips hidden %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/WindowStateAnimator.java" + }, + "1762317752": { + "message": "Expected target stack=%s to be top most but found stack=%s", + "level": "WARN", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimation.java" + }, + "1764592478": { + "message": "reparent: moving app token=%s to task=%d at %d", + "level": "INFO", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "1774661765": { + "message": "Devices still not ready after waiting %d milliseconds before attempting to detect safe mode.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1814552834": { + "message": "performLayout: App token exiting now removed %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "1836306327": { + "message": "Skipping set freeze of %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, + "1865125884": { + "message": "finishScreenTurningOn: mAwake=%b, mScreenOnEarly=%b, mScreenOnFully=%b, mKeyguardDrawComplete=%b, mWindowManagerDrawComplete=%b", + "level": "DEBUG", + "group": "WM_DEBUG_SCREEN_ON", + "at": "com\/android\/server\/wm\/DisplayPolicy.java" + }, + "1865246212": { + "message": "\tapp=%s", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "1866772666": { + "message": "SAFE MODE not enabled", + "level": "INFO", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "1878395049": { + "message": "Loading animation for app transition. transit=%s enter=%b frame=%s insets=%s surfaceInsets=%s", + "level": "DEBUG", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "1883987026": { + "message": "removeAppToken make exiting: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "1891501279": { + "message": "cancelAnimation(): reason=%s", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "1921821199": { + "message": "Preserving %s until the new one is added", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "1947239194": { + "message": "Deferring rotation, still finishing previous rotation", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayRotation.java" + }, + "1964565370": { + "message": "Starting remote animation", + "level": "INFO", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, + "1984470582": { + "message": "Creating TaskScreenshotAnimatable: task: %s width: %d height: %d", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/TaskScreenshotAnimatable.java" + }, + "1984738415": { + "message": "Now animating app in place %s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "1984782949": { + "message": ">>> OPEN TRANSACTION animate", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowAnimator.java" + }, + "1993685727": { + "message": "Setting mOrientationChangeComplete=true because wtoken %s numInteresting=%d numDrawn=%d", + "level": "INFO", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "2016061474": { + "message": "Prepare app transition: transit=%s %s alwaysKeepCurrent=%b displayId=%d Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransition.java" + }, + "2018454757": { + "message": "WS.removeImmediately: %s Already removed...", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "2028163120": { + "message": "applyAnimation: anim=%s nextAppTransition=ANIM_SCALE_UP transit=%s isEntrance=%s Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", + "at": "com\/android\/server\/wm\/AppTransition.java" + }, + "2034780299": { + "message": "CHECK_IF_BOOT_ANIMATION_FINISHED:", + "level": "INFO", + "group": "WM_DEBUG_BOOT", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "2045641491": { + "message": "Checking %d opening apps (frozen=%b timeout=%b)...", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS", + "at": "com\/android\/server\/wm\/AppTransitionController.java" + }, + "2054958632": { + "message": "Schedule remove starting %s startingWindow=%s startingView=%s Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "2057434754": { + "message": "\tvisible=%s", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java" + }, + "2076259606": { + "message": "Finish starting %s: first real window is shown, no animation", + "level": "VERBOSE", + "group": "WM_DEBUG_STARTING_WINDOW", + "at": "com\/android\/server\/wm\/AppWindowToken.java" + }, + "2083556954": { + "message": "Set mOrientationChanging of %s", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "2086878461": { + "message": "Could not send command %s with parameters %s. %s", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "2088592090": { + "message": "handleNotObscuredLocked: %s was holding screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by%s", + "level": "DEBUG", + "group": "WM_DEBUG_KEEP_SCREEN_ON", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, + "2096635066": { + "message": "Acquiring screen wakelock due to %s", + "level": "DEBUG", + "group": "WM_DEBUG_KEEP_SCREEN_ON", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, + "2114149926": { + "message": "Not removing %s because app died while it's visible", + "level": "VERBOSE", + "group": "WM_DEBUG_ADD_REMOVE", + "at": "com\/android\/server\/wm\/WindowState.java" + }, + "2128604122": { + "message": "findFocusedWindow: No focusable windows.", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, + "2128917433": { + "message": "onProposedRotationChanged, rotation=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayRotation.java" + }, + "2137411379": { + "message": "applyAnimation: anim=%s animAttr=0x%x transit=%s isEntrance=%b Callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", + "at": "com\/android\/server\/wm\/AppTransition.java" } }, "groups": { "TEST_GROUP": { "tag": "WindowManagetProtoLogTest" + }, + "WM_DEBUG_ADD_REMOVE": { + "tag": "WindowManager" + }, + "WM_DEBUG_APP_TRANSITIONS": { + "tag": "WindowManager" + }, + "WM_DEBUG_APP_TRANSITIONS_ANIM": { + "tag": "WindowManager" + }, + "WM_DEBUG_BOOT": { + "tag": "WindowManager" + }, + "WM_DEBUG_DRAW": { + "tag": "WindowManager" + }, + "WM_DEBUG_FOCUS": { + "tag": "WindowManager" + }, + "WM_DEBUG_FOCUS_LIGHT": { + "tag": "WindowManager" + }, + "WM_DEBUG_KEEP_SCREEN_ON": { + "tag": "WindowManager" + }, + "WM_DEBUG_ORIENTATION": { + "tag": "WindowManager" + }, + "WM_DEBUG_RECENTS_ANIMATIONS": { + "tag": "WindowManager" + }, + "WM_DEBUG_REMOTE_ANIMATIONS": { + "tag": "WindowManager" + }, + "WM_DEBUG_RESIZE": { + "tag": "WindowManager" + }, + "WM_DEBUG_SCREEN_ON": { + "tag": "WindowManager" + }, + "WM_DEBUG_STARTING_WINDOW": { + "tag": "WindowManager" + }, + "WM_DEBUG_WINDOW_MOVEMENT": { + "tag": "WindowManager" + }, + "WM_ERROR": { + "tag": "WindowManager" + }, + "WM_SHOW_SURFACE_ALLOC": { + "tag": "WindowManager" + }, + "WM_SHOW_TRANSACTIONS": { + "tag": "WindowManager" } } } diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 684dc22ee4d1..30cc007d454b 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -491,9 +491,9 @@ void CanvasContext::draw() { swap.dequeueDuration = 0; } else { swap.dequeueDuration = - us2ns(ANativeWindow_getLastDequeueDuration(mNativeSurface.get())); + ANativeWindow_getLastDequeueDuration(mNativeSurface.get()); } - swap.queueDuration = us2ns(ANativeWindow_getLastQueueDuration(mNativeSurface.get())); + swap.queueDuration = ANativeWindow_getLastQueueDuration(mNativeSurface.get()); } else { swap.dequeueDuration = 0; swap.queueDuration = 0; diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 6b47d1dff781..68480ced0692 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -27,7 +27,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; -import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; @@ -134,23 +133,27 @@ public class LocationManager { /** * This key is no longer in use. * - * Key used for a Bundle extra holding an Integer status value - * when a status change is broadcast using a PendingIntent. + * <p>Key used for a Bundle extra holding an Integer status value when a status change is + * broadcast using a PendingIntent. * - * @deprecated Status changes are deprecated and no longer broadcast. + * @deprecated Status changes are deprecated and no longer broadcast from Android Q onwards. */ @Deprecated public static final String KEY_STATUS_CHANGED = "status"; /** - * Key used for a Bundle extra holding an Boolean status value - * when a provider enabled/disabled event is broadcast using a PendingIntent. + * Key used for an extra holding a boolean enabled/disabled status value when a provider + * enabled/disabled event is broadcast using a PendingIntent. + * + * @see #requestLocationUpdates(String, long, long, PendingIntent) */ public static final String KEY_PROVIDER_ENABLED = "providerEnabled"; /** - * Key used for a Bundle extra holding a Location value - * when a location change is broadcast using a PendingIntent. + * Key used for an extra holding a {@link Location} value when a location change is broadcast + * using a PendingIntent. + * + * @see #requestLocationUpdates(String, long, long, PendingIntent) */ public static final String KEY_LOCATION_CHANGED = "location"; @@ -382,7 +385,7 @@ public class LocationManager { } /** - * Returns the current enabled/disabled state of location. + * Returns the current enabled/disabled state of location for the given user. * * @param userHandle the user to query * @return true if location is enabled and false if location is disabled. @@ -399,7 +402,7 @@ public class LocationManager { } /** - * Enables or disables the location setting. + * Enables or disables location for the given user. * * @param enabled true to enable location and false to disable location. * @param userHandle the user to set @@ -455,7 +458,7 @@ public class LocationManager { @SystemApi public boolean isProviderEnabledForUser( @NonNull String provider, @NonNull UserHandle userHandle) { - checkProvider(provider); + Preconditions.checkArgument(provider != null, "invalid null provider"); try { return mService.isProviderEnabledForUser(provider, userHandle.getIdentifier()); @@ -484,7 +487,7 @@ public class LocationManager { @RequiresPermission(WRITE_SECURE_SETTINGS) public boolean setProviderEnabledForUser( @NonNull String provider, boolean enabled, @NonNull UserHandle userHandle) { - checkProvider(provider); + Preconditions.checkArgument(provider != null, "invalid null provider"); return Settings.Secure.putStringForUser( mContext.getContentResolver(), @@ -494,57 +497,45 @@ public class LocationManager { } /** - * Get the last known location. - * - * <p>This location could be very old so use - * {@link Location#getElapsedRealtimeNanos} to calculate its age. It can - * also return null if no previous location is available. + * Gets the last known location from the fused provider, or null if there is no last known + * location. The returned location may be quite old in some circumstances, so the age of the + * location should always be checked. * - * <p>Always returns immediately. - * - * @return The last known location, or null if not available - * @throws SecurityException if no suitable permission is present + * @return the last known location, or null if not available + * @throws SecurityException if no suitable location permission is present * * @hide */ @Nullable + @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) public Location getLastLocation() { - String packageName = mContext.getPackageName(); - try { - return mService.getLastLocation(null, packageName); + return mService.getLastLocation(null, mContext.getPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Returns a Location indicating the data from the last known - * location fix obtained from the given provider. - * - * <p> This can be done - * without starting the provider. Note that this location could - * be out-of-date, for example if the device was turned off and - * moved to another location. - * - * <p> If the provider is currently disabled, null is returned. + * Gets the last known location from the given provider, or null if there is no last known + * location. The returned location may be quite old in some circumstances, so the age of the + * location should always be checked. * * @param provider the name of the provider - * @return the last known location for the provider, or null - * + * @return the last known location for the given provider, or null if not available * @throws SecurityException if no suitable permission is present * @throws IllegalArgumentException if provider is null or doesn't exist */ @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) @Nullable public Location getLastKnownLocation(@NonNull String provider) { - checkProvider(provider); - String packageName = mContext.getPackageName(); + Preconditions.checkArgument(provider != null, "invalid null provider"); + LocationRequest request = LocationRequest.createFromDeprecatedProvider( provider, 0, 0, true); try { - return mService.getLastLocation(request, packageName); + return mService.getLastLocation(request, mContext.getPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -554,7 +545,7 @@ public class LocationManager { * Register for a single location update using the named provider and * a callback. * - * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} + * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener, Looper)} * for more detail on how to use this method. * * @param provider the name of the provider with which to register @@ -568,12 +559,16 @@ public class LocationManager { * @throws IllegalArgumentException if provider is null or doesn't exist * @throws IllegalArgumentException if listener is null * @throws SecurityException if no suitable permission is present + * @deprecated This method can drain much more battery than expected if it is not possible to + * calculate location. Prefer any of the requestLocationUpdates() methods which require explicit + * removal. */ + @Deprecated @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) public void requestSingleUpdate( @NonNull String provider, @NonNull LocationListener listener, @Nullable Looper looper) { - checkProvider(provider); - checkListener(listener); + Preconditions.checkArgument(provider != null, "invalid null provider"); + Preconditions.checkArgument(listener != null, "invalid null listener"); LocationRequest request = LocationRequest.createFromDeprecatedProvider( provider, 0, 0, true); @@ -599,14 +594,17 @@ public class LocationManager { * @throws IllegalArgumentException if criteria is null * @throws IllegalArgumentException if listener is null * @throws SecurityException if no suitable permission is present + * @deprecated This method can drain much more battery than expected if it is not possible to + * calculate location. Prefer any of the requestLocationUpdates() methods which require explicit + * removal. */ @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) public void requestSingleUpdate( @NonNull Criteria criteria, @NonNull LocationListener listener, @Nullable Looper looper) { - checkCriteria(criteria); - checkListener(listener); + Preconditions.checkArgument(criteria != null, "invalid null criteria"); + Preconditions.checkArgument(listener != null, "invalid null listener"); LocationRequest request = LocationRequest.createFromDeprecatedCriteria( criteria, 0, 0, true); @@ -625,10 +623,13 @@ public class LocationManager { * @throws IllegalArgumentException if provider is null or doesn't exist * @throws IllegalArgumentException if intent is null * @throws SecurityException if no suitable permission is present + * @deprecated This method can drain much more battery than expected if it is not possible to + * calculate location. Prefer any of the requestLocationUpdates() methods which require explicit + * removal. */ @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull String provider, @NonNull PendingIntent intent) { - checkProvider(provider); + Preconditions.checkArgument(provider != null, "invalid null provider"); checkPendingIntent(intent); LocationRequest request = LocationRequest.createFromDeprecatedProvider( @@ -649,10 +650,13 @@ public class LocationManager { * @throws IllegalArgumentException if provider is null or doesn't exist * @throws IllegalArgumentException if intent is null * @throws SecurityException if no suitable permission is present + * @deprecated This method can drain much more battery than expected if it is not possible to + * calculate location. Prefer any of the requestLocationUpdates() methods which require explicit + * removal. */ @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull Criteria criteria, @NonNull PendingIntent intent) { - checkCriteria(criteria); + Preconditions.checkArgument(criteria != null, "invalid null criteria"); checkPendingIntent(intent); LocationRequest request = LocationRequest.createFromDeprecatedCriteria( @@ -661,84 +665,121 @@ public class LocationManager { } /** - * Register for location updates using the named provider, and a - * pending intent. - * - * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} - * for more detail on how to use this method. + * Register for location updates from the given provider with the given arguments. {@link + * LocationListener} callbacks will take place on the given {@link Looper} or {@link Executor}. + * If a null {@link Looper} is supplied, the Looper of the calling thread will be used instead. + * Only one request can be registered for each unique listener, so any subsequent requests with + * the same listener will overwrite all associated arguments. + * + * <p> It may take a while to receive the first location update. If an immediate location is + * required, applications may use the {@link #getLastKnownLocation(String)} method. + * + * <p> The location update interval can be controlled using the minimum time parameter. The + * elapsed time between location updates will never be less than this parameter, although it may + * be more depending on location availability and other factors. Choosing a sensible value for + * the minimum time parameter is important to conserve battery life. Every location update + * requires power from a variety of sensors. Select a minimum time parameter as high as possible + * while still providing a reasonable user experience. If your application is not in the + * foreground and showing location to the user then your application should consider switching + * to the {@link #PASSIVE_PROVIDER} instead. + * + * <p> The minimum distance parameter can also be used to control the frequency of location + * updates. If it is greater than 0 then the location provider will only send your application + * an update when the location has changed by at least minDistance meters, AND when the minimum + * time has elapsed. However it is more difficult for location providers to save power using the + * minimum distance parameter, so the minimum time parameter should be the primary tool for + * conserving battery life. + * + * <p> If your application wants to passively observe location updates triggered by other + * applications, but not consume any additional power otherwise, then use the {@link + * #PASSIVE_PROVIDER}. This provider does not turn on or modify active location providers, so + * you do not need to be as careful about minimum time and minimum distance parameters. However, + * if your application performs heavy work on a location update (such as network activity) then + * you should select non-zero values for the parameters to rate-limit your update frequency in + * the case another application enables a location provider with extremely fast updates. + * + * <p>In case the provider you have selected is disabled, location updates will cease, and a + * provider availability update will be sent. As soon as the provider is enabled again, another + * provider availability update will be sent and location updates will immediately resume. + * + * <p> When location callbacks are invoked, the system will hold a wakelock on your + * application's behalf for some period of time, but not indefinitely. If your application + * requires a long running wakelock within the location callback, you should acquire it + * yourself. + * + * <p class="note"> Prior to Jellybean, the minTime parameter was only a hint, and some location + * provider implementations ignored it. For Jellybean and onwards however, it is mandatory for + * Android compatible devices to observe both the minTime and minDistance parameters. + * + * <p>To unregister for location updates, use {@link #removeUpdates(LocationListener)}. * * @param provider the name of the provider with which to register - * @param minTime minimum time interval between location updates, in milliseconds - * @param minDistance minimum distance between location updates, in meters - * @param listener a {@link LocationListener} whose - * {@link LocationListener#onLocationChanged} method will be called for - * each location update + * @param minTimeMs minimum time interval between location updates in milliseconds + * @param minDistanceM minimum distance between location updates in meters + * @param listener the listener to receive location updates * * @throws IllegalArgumentException if provider is null or doesn't exist - * on this device * @throws IllegalArgumentException if listener is null * @throws RuntimeException if the calling thread has no Looper * @throws SecurityException if no suitable permission is present */ @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) - public void requestLocationUpdates(@NonNull String provider, long minTime, float minDistance, + public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM, @NonNull LocationListener listener) { - checkProvider(provider); - checkListener(listener); + Preconditions.checkArgument(provider != null, "invalid null provider"); + Preconditions.checkArgument(listener != null, "invalid null listener"); LocationRequest request = LocationRequest.createFromDeprecatedProvider( - provider, minTime, minDistance, false); + provider, minTimeMs, minDistanceM, false); requestLocationUpdates(request, listener, null); } /** * Register for location updates using the named provider, and a callback on - * the specified looper thread. + * the specified {@link Looper}. * - * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} - * for more detail on how to use this method. + * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)} + * for more detail on how this method works. * * @param provider the name of the provider with which to register - * @param minTime minimum time interval between location updates, in milliseconds - * @param minDistance minimum distance between location updates, in meters - * @param listener a {@link LocationListener} whose - * {@link LocationListener#onLocationChanged} method will be called for - * each location update - * @param looper a Looper object whose message queue will be used to - * implement the callback mechanism, or null to make callbacks on the calling - * thread + * @param minTimeMs minimum time interval between location updates in milliseconds + * @param minDistanceM minimum distance between location updates in meters + * @param listener the listener to receive location updates + * @param looper the looper handling listener callbacks, or null to use the looper of the + * calling thread * * @throws IllegalArgumentException if provider is null or doesn't exist * @throws IllegalArgumentException if listener is null * @throws SecurityException if no suitable permission is present */ @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) - public void requestLocationUpdates(@NonNull String provider, long minTime, float minDistance, + public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM, @NonNull LocationListener listener, @Nullable Looper looper) { - checkProvider(provider); - checkListener(listener); + Preconditions.checkArgument(provider != null, "invalid null provider"); + Preconditions.checkArgument(listener != null, "invalid null listener"); LocationRequest request = LocationRequest.createFromDeprecatedProvider( - provider, minTime, minDistance, false); + provider, minTimeMs, minDistanceM, false); requestLocationUpdates(request, listener, looper); } /** - * Register for location updates from the given provider with the given arguments. {@link - * LocationListener} callbacks will take place on the given {@link Executor}. Only one request - * can be registered for each unique listener, so any subsequent requests with the same listener - * will overwrite all associated arguments. - * - * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener, Looper)} for - * more information. - * - * @param provider the name of the provider used for location updates - * @param minTimeMs minimum time interval between location updates, in milliseconds - * @param minDistanceM minimum distance between location updates, in meters - * @param executor all listener updates will take place on this {@link Executor} - * @param listener a {@link LocationListener} that will be called when updates are available - * @throws IllegalArgumentException if provider, listener, or looper is null or nonexistant - * @throws SecurityException if no suitable permission is present + * Register for location updates using the named provider, and a callback on + * the specified {@link Executor}. + * + * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)} + * for more detail on how this method works. + * + * @param provider the name of the provider with which to register + * @param minTimeMs minimum time interval between location updates in milliseconds + * @param minDistanceM minimum distance between location updates in meters + * @param executor the executor handling listener callbacks + * @param listener the listener to receive location updates + * + * @throws IllegalArgumentException if provider is null or doesn't exist + * @throws IllegalArgumentException if executor is null + * @throws IllegalArgumentException if listener is null + * @throws SecurityException if no suitable permission is present */ @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) public void requestLocationUpdates( @@ -753,50 +794,49 @@ public class LocationManager { } /** - * Register for location updates using a Criteria, and a callback - * on the specified looper thread. + * Register for location updates using a provider selected through the given Criteria, and a + * callback on the specified {@link Looper}. * - * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} - * for more detail on how to use this method. + * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)} + * for more detail on how this method works. * - * @param minTime minimum time interval between location updates, in milliseconds - * @param minDistance minimum distance between location updates, in meters - * @param criteria contains parameters for the location manager to choose the - * appropriate provider and parameters to compute the location - * @param listener a {@link LocationListener} whose - * {@link LocationListener#onLocationChanged} method will be called for - * each location update - * @param looper a Looper object whose message queue will be used to - * implement the callback mechanism, or null to make callbacks on the calling - * thread + * @param minTimeMs minimum time interval between location updates in milliseconds + * @param minDistanceM minimum distance between location updates in meters + * @param criteria contains parameters to choose the appropriate provider for location updates + * @param listener the listener to receive location updates * * @throws IllegalArgumentException if criteria is null * @throws IllegalArgumentException if listener is null * @throws SecurityException if no suitable permission is present */ @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) - public void requestLocationUpdates(long minTime, float minDistance, @NonNull Criteria criteria, - @NonNull LocationListener listener, @Nullable Looper looper) { - checkCriteria(criteria); - checkListener(listener); + public void requestLocationUpdates(long minTimeMs, float minDistanceM, + @NonNull Criteria criteria, @NonNull LocationListener listener, + @Nullable Looper looper) { + Preconditions.checkArgument(criteria != null, "invalid null criteria"); + Preconditions.checkArgument(listener != null, "invalid null listener"); LocationRequest request = LocationRequest.createFromDeprecatedCriteria( - criteria, minTime, minDistance, false); + criteria, minTimeMs, minDistanceM, false); requestLocationUpdates(request, listener, looper); } /** - * Uses the given {@link Criteria} to select a single provider to use for location updates. + * Register for location updates using a provider selected through the given Criteria, and a + * callback on the specified {@link Executor}. + * + * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)} + * for more detail on how this method works. * - * <p>See {@link #requestLocationUpdates(String, long, float, Executor, LocationListener)} for - * more information. + * @param minTimeMs minimum time interval between location updates in milliseconds + * @param minDistanceM minimum distance between location updates in meters + * @param criteria contains parameters to choose the appropriate provider for location updates + * @param executor the executor handling listener callbacks + * @param listener the listener to receive location updates * - * @param minTimeMs minimum time interval between location updates, in milliseconds - * @param minDistanceM minimum distance between location updates, in meters - * @param criteria the {@link Criteria} used to select a provider for location updates - * @param executor all listener updates will take place on this {@link Executor} - * @param listener a {@link LocationListener} that will be called when updates are available - * @throws IllegalArgumentException if criteria, listener, or looper is null + * @throws IllegalArgumentException if criteria is null + * @throws IllegalArgumentException if executor is null + * @throws IllegalArgumentException if listener is null * @throws SecurityException if no suitable permission is present */ @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) @@ -812,191 +852,81 @@ public class LocationManager { } /** - * Register for location updates using the named provider, and a - * pending intent. + * Register for location updates using the named provider, and callbacks delivered via the + * provided {@link PendingIntent}. * - * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} - * for more detail on how to use this method. + * <p>The delivered pending intents will contain extras with the callback information. The keys + * used for the extras are {@link #KEY_LOCATION_CHANGED} and {@link #KEY_PROVIDER_ENABLED}. See + * the documentation for each respective extra key for information on the values. + * + * <p>To unregister for location updates, use {@link #removeUpdates(PendingIntent)}. + * + * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)} + * for more detail on how this method works. * * @param provider the name of the provider with which to register - * @param minTime minimum time interval between location updates, in milliseconds - * @param minDistance minimum distance between location updates, in meters - * @param intent a {@link PendingIntent} to be sent for each location update + * @param minTimeMs minimum time interval between location updates in milliseconds + * @param minDistanceM minimum distance between location updates in meters + * @param pendingIntent the pending intent to send location updates * * @throws IllegalArgumentException if provider is null or doesn't exist - * on this device - * @throws IllegalArgumentException if intent is null + * @throws IllegalArgumentException if pendingIntent is null * @throws SecurityException if no suitable permission is present */ @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) - public void requestLocationUpdates(@NonNull String provider, long minTime, float minDistance, - @NonNull PendingIntent intent) { - checkProvider(provider); - checkPendingIntent(intent); + public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM, + @NonNull PendingIntent pendingIntent) { + Preconditions.checkArgument(provider != null, "invalid null provider"); + checkPendingIntent(pendingIntent); LocationRequest request = LocationRequest.createFromDeprecatedProvider( - provider, minTime, minDistance, false); - requestLocationUpdates(request, intent); + provider, minTimeMs, minDistanceM, false); + requestLocationUpdates(request, pendingIntent); } /** - * Register for location updates using a Criteria and pending intent. - * - * <p>The <code>requestLocationUpdates()</code> and - * <code>requestSingleUpdate()</code> register the current activity to be - * updated periodically by the named provider, or by the provider matching - * the specified {@link Criteria}, with location and status updates. - * - * <p> It may take a while to receive the first location update. If - * an immediate location is required, applications may use the - * {@link #getLastKnownLocation(String)} method. - * - * <p> Location updates are received either by {@link LocationListener} - * callbacks, or by broadcast intents to a supplied {@link PendingIntent}. - * - * <p> If the caller supplied a pending intent, then location updates - * are sent with a key of {@link #KEY_LOCATION_CHANGED} and a - * {@link android.location.Location} value. - * - * <p> The location update interval can be controlled using the minTime parameter. - * The elapsed time between location updates will never be less than - * minTime, although it can be more depending on the Location Provider - * implementation and the update interval requested by other applications. - * - * <p> Choosing a sensible value for minTime is important to conserve - * battery life. Each location update requires power from - * GPS, WIFI, Cell and other radios. Select a minTime value as high as - * possible while still providing a reasonable user experience. - * If your application is not in the foreground and showing - * location to the user then your application should avoid using an active - * provider (such as {@link #NETWORK_PROVIDER} or {@link #GPS_PROVIDER}), - * but if you insist then select a minTime of 5 * 60 * 1000 (5 minutes) - * or greater. If your application is in the foreground and showing - * location to the user then it is appropriate to select a faster - * update interval. - * - * <p> The minDistance parameter can also be used to control the - * frequency of location updates. If it is greater than 0 then the - * location provider will only send your application an update when - * the location has changed by at least minDistance meters, AND - * at least minTime milliseconds have passed. However it is more - * difficult for location providers to save power using the minDistance - * parameter, so minTime should be the primary tool to conserving battery - * life. - * - * <p> If your application wants to passively observe location - * updates triggered by other applications, but not consume - * any additional power otherwise, then use the {@link #PASSIVE_PROVIDER} - * This provider does not actively turn on or modify active location - * providers, so you do not need to be as careful about minTime and - * minDistance. However if your application performs heavy work - * on a location update (such as network activity) then you should - * select non-zero values for minTime and/or minDistance to rate-limit - * your update frequency in the case another application enables a - * location provider with extremely fast updates. - * - * <p>In case the provider is disabled by the user, updates will stop, - * and a provider availability update will be sent. - * As soon as the provider is enabled again, - * location updates will immediately resume and a provider availability - * update sent. Providers can also send status updates, at any time, - * with extra's specific to the provider. If a callback was supplied - * then status and availability updates are via - * {@link LocationListener#onProviderDisabled}, - * {@link LocationListener#onProviderEnabled} or - * {@link LocationListener#onStatusChanged}. Alternately, if a - * pending intent was supplied then status and availability updates - * are broadcast intents with extra keys of - * {@link #KEY_PROVIDER_ENABLED} or {@link #KEY_STATUS_CHANGED}. - * - * <p> If a {@link LocationListener} is used but with no Looper specified - * then the calling thread must already - * be a {@link android.os.Looper} thread such as the main thread of the - * calling Activity. If a Looper is specified with a {@link LocationListener} - * then callbacks are made on the supplied Looper thread. - * - * <p> When location callbacks are invoked, the system will hold a wakelock - * on your application's behalf for some period of time, but not - * indefinitely. If your application requires a long running wakelock - * within the location callback, you should acquire it yourself. - * - * <p class="note"> Prior to Jellybean, the minTime parameter was - * only a hint, and some location provider implementations ignored it. - * From Jellybean and onwards it is mandatory for Android compatible - * devices to observe both the minTime and minDistance parameters. - * - * @param minTime minimum time interval between location updates, in milliseconds - * @param minDistance minimum distance between location updates, in meters - * @param criteria contains parameters for the location manager to choose the - * appropriate provider and parameters to compute the location - * @param intent a {@link PendingIntent} to be sent for each location update + * Register for location updates using a provider selected through the given Criteria, and + * callbacks delivered via the provided {@link PendingIntent}. * - * @throws IllegalArgumentException if criteria is null - * @throws IllegalArgumentException if intent is null + * <p>See {@link #requestLocationUpdates(String, long, float, PendingIntent)} for more detail on + * how this method works. + * + * @param minTimeMs minimum time interval between location updates in milliseconds + * @param minDistanceM minimum distance between location updates in meters + * @param criteria contains parameters to choose the appropriate provider for location updates + * @param pendingIntent the pending intent to send location updates + * + * @throws IllegalArgumentException if provider is null or doesn't exist + * @throws IllegalArgumentException if pendingIntent is null * @throws SecurityException if no suitable permission is present */ @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) - public void requestLocationUpdates(long minTime, float minDistance, @NonNull Criteria criteria, - @NonNull PendingIntent intent) { - checkCriteria(criteria); - checkPendingIntent(intent); + public void requestLocationUpdates(long minTimeMs, float minDistanceM, + @NonNull Criteria criteria, @NonNull PendingIntent pendingIntent) { + Preconditions.checkArgument(criteria != null, "invalid null criteria"); + checkPendingIntent(pendingIntent); LocationRequest request = LocationRequest.createFromDeprecatedCriteria( - criteria, minTime, minDistance, false); - requestLocationUpdates(request, intent); + criteria, minTimeMs, minDistanceM, false); + requestLocationUpdates(request, pendingIntent); } /** - * Register for fused location updates using a LocationRequest and callback. - * - * <p>Upon a location update, the system delivers the new {@link Location} to the - * provided {@link LocationListener}, by calling its {@link - * LocationListener#onLocationChanged} method.</p> - * - * <p>The system will automatically select and enable the best providers - * to compute a location for your application. It may use only passive - * locations, or just a single location source, or it may fuse together - * multiple location sources in order to produce the best possible - * result, depending on the quality of service requested in the - * {@link LocationRequest}. - * - * <p>LocationRequest can be null, in which case the system will choose - * default, low power parameters for location updates. You will occasionally - * receive location updates as available, without a major power impact on the - * system. If your application just needs an occasional location update - * without any strict demands, then pass a null LocationRequest. + * Register for location updates using a {@link LocationRequest}, and a callback on the + * specified {@link Looper}. * - * <p>Only one LocationRequest can be registered for each unique callback - * or pending intent. So a subsequent request with the same callback or - * pending intent will over-write the previous LocationRequest. + * <p>The system will automatically select and enable the best provider based on the given + * {@link LocationRequest}. The LocationRequest can be null, in which case the system will + * choose default low power parameters for location updates, but this is heavily discouraged, + * and an explicit LocationRequest should always be provided. * - * <p> If a pending intent is supplied then location updates - * are sent with a key of {@link #KEY_LOCATION_CHANGED} and a - * {@link android.location.Location} value. If a callback is supplied - * then location updates are made using the - * {@link LocationListener#onLocationChanged} callback, on the specified - * Looper thread. If a {@link LocationListener} is used - * but with a null Looper then the calling thread must already - * be a {@link android.os.Looper} thread (such as the main thread) and - * callbacks will occur on this thread. + * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)} + * for more detail on how this method works. * - * <p> Provider status updates and availability updates are deprecated - * because the system is performing provider fusion on the applications - * behalf. So {@link LocationListener#onProviderDisabled}, - * {@link LocationListener#onProviderEnabled}, {@link LocationListener#onStatusChanged} - * will not be called, and intents with extra keys of - * {@link #KEY_PROVIDER_ENABLED} or {@link #KEY_STATUS_CHANGED} will not - * be received. - * - * <p> To unregister for Location updates, use: {@link #removeUpdates(LocationListener)}. - * - * @param locationRequest quality of service required, null for default low power - * @param listener a {@link LocationListener} whose - * {@link LocationListener#onLocationChanged} method will be called when - * the location update is available - * @param looper a Looper object whose message queue will be used to - * implement the callback mechanism, or null to make callbacks on the calling - * thread + * @param locationRequest the location request containing location parameters + * @param listener the listener to receive location updates + * @param looper the looper handling listener callbacks, or null to use the looper of the + * calling thread * * @throws IllegalArgumentException if listener is null * @throws SecurityException if no suitable permission is present @@ -1007,7 +937,7 @@ public class LocationManager { @TestApi @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) public void requestLocationUpdates( - @NonNull LocationRequest locationRequest, + @Nullable LocationRequest locationRequest, @NonNull LocationListener listener, @Nullable Looper looper) { requestLocationUpdates(locationRequest, @@ -1016,45 +946,44 @@ public class LocationManager { } /** - * Register for location updates with the given {@link LocationRequest}. + * Register for location updates using a {@link LocationRequest}, and a callback on the + * specified {@link Executor}. * - * <p>See {@link #requestLocationUpdates(String, long, float, Executor, LocationListener)} for - * more information. + * <p>See {@link #requestLocationUpdates(LocationRequest, LocationListener, Looper)} for more + * detail on how this method works. + * + * @param locationRequest the location request containing location parameters + * @param executor the executor handling listener callbacks + * @param listener the listener to receive location updates + * + * @throws IllegalArgumentException if executor is null + * @throws IllegalArgumentException if listener is null + * @throws SecurityException if no suitable permission is present * - * @param locationRequest the {@link LocationRequest} being made - * @param executor all listener updates will take place on this {@link Executor} - * @param listener a {@link LocationListener} that will be called when updates are - * available - * @throws IllegalArgumentException if locationRequest, listener, or executor is null - * @throws SecurityException if no suitable permission is present * @hide */ @SystemApi @TestApi @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) public void requestLocationUpdates( - @NonNull LocationRequest locationRequest, + @Nullable LocationRequest locationRequest, @NonNull @CallbackExecutor Executor executor, @NonNull LocationListener listener) { requestLocationUpdates(locationRequest, new LocationListenerTransport(executor, listener)); } /** - * Register for fused location updates using a LocationRequest and a pending intent. - * - * <p>Upon a location update, the system delivers the new {@link Location} with your provided - * {@link PendingIntent}, as the value for {@link LocationManager#KEY_LOCATION_CHANGED} - * in the intent's extras.</p> - * - * <p> To unregister for Location updates, use: {@link #removeUpdates(PendingIntent)}. + * Register for location updates using a {@link LocationRequest}, and callbacks delivered via + * the provided {@link PendingIntent}. * - * <p> See {@link #requestLocationUpdates(LocationRequest, LocationListener, Looper)} - * for more detail. + * <p>See {@link #requestLocationUpdates(LocationRequest, LocationListener, Looper)} and + * {@link #requestLocationUpdates(String, long, float, PendingIntent)} for more detail on how + * this method works. * - * @param locationRequest quality of service required, null for default low power - * @param pendingIntent a {@link PendingIntent} to be sent for the location update + * @param locationRequest the location request containing location parameters + * @param pendingIntent the pending intent to send location updates * - * @throws IllegalArgumentException if intent is null + * @throws IllegalArgumentException if pendingIntent is null * @throws SecurityException if no suitable permission is present * * @hide @@ -1063,7 +992,7 @@ public class LocationManager { @TestApi @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) public void requestLocationUpdates( - @NonNull LocationRequest locationRequest, + @Nullable LocationRequest locationRequest, @NonNull PendingIntent pendingIntent) { Preconditions.checkArgument(locationRequest != null, "invalid null location request"); Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent"); @@ -1080,8 +1009,8 @@ public class LocationManager { } } - private void requestLocationUpdates(LocationRequest request, - LocationListenerTransport transport) { + private void requestLocationUpdates(@Nullable LocationRequest request, + @NonNull LocationListenerTransport transport) { synchronized (mListeners) { LocationListenerTransport oldTransport = mListeners.put(transport.getKey(), transport); if (oldTransport != null) { @@ -1105,31 +1034,41 @@ public class LocationManager { * chipset is in the process of getting the first fix. If the client has cached the location, * it can inject the {@link Location}, so if an app requests for a {@link Location} from {@link * #getLastKnownLocation(String)}, the location information is still useful before getting - * the first fix.</p> - * - * <p> Useful in products like Auto. + * the first fix. * - * @param newLocation newly available {@link Location} object - * @return true if update was successful, false if not + * @param location newly available {@link Location} object + * @return true if the location was successfully injected, false otherwise * - * @throws SecurityException if no suitable permission is present + * @throws IllegalArgumentException if location is null + * @throws SecurityException if permissions are not present * * @hide */ @RequiresPermission(allOf = {LOCATION_HARDWARE, ACCESS_FINE_LOCATION}) - public boolean injectLocation(@NonNull Location newLocation) { + public boolean injectLocation(@NonNull Location location) { + if (location == null) { + IllegalArgumentException e = new IllegalArgumentException("invalid null location"); + if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) { + throw e; + } else { + Log.w(TAG, e); + return false; + } + } + try { - return mService.injectLocation(newLocation); + return mService.injectLocation(location); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Removes location updates for the specified LocationListener. Following this call, updates - * will no longer occur for this listener. + * Removes location updates for the specified {@link LocationListener}. Following this call, + * the listener will no longer receive location updates. * * @param listener listener that no longer needs location updates + * * @throws IllegalArgumentException if listener is null */ public void removeUpdates(@NonNull LocationListener listener) { @@ -1151,10 +1090,11 @@ public class LocationManager { } /** - * Removes all location updates for the specified pending intent. Following this call, updates - * will no longer occur for this pending intent. + * Removes location updates for the specified {@link PendingIntent}. Following this call, the + * PendingIntent will no longer receive location updates. * * @param pendingIntent pending intent that no longer needs location updates + * * @throws IllegalArgumentException if pendingIntent is null */ public void removeUpdates(@NonNull PendingIntent pendingIntent) { @@ -1168,11 +1108,11 @@ public class LocationManager { } /** - * Returns a list of the names of all known location providers. - * <p>All providers are returned, including ones that are not permitted to - * be accessed by the calling activity or are currently disabled. + * Returns a list of the names of all known location providers. All providers are returned, + * including ones that are not permitted to be accessed by the calling activity or are currently + * disabled. * - * @return list of Strings containing names of the provider + * @return list of provider names */ public @NonNull List<String> getAllProviders() { try { @@ -1183,11 +1123,11 @@ public class LocationManager { } /** - * Returns a list of the names of location providers. + * Returns a list of the names of location providers. Only providers that the caller has + * permission to access will be returned. * - * @param enabledOnly if true then only the providers which are currently - * enabled are returned. - * @return list of Strings containing names of the providers + * @param enabledOnly if true then only enabled providers are included + * @return list of provider names */ public @NonNull List<String> getProviders(boolean enabledOnly) { try { @@ -1198,17 +1138,18 @@ public class LocationManager { } /** - * Returns a list of the names of LocationProviders that satisfy the given - * criteria, or null if none do. Only providers that are permitted to be - * accessed by the calling activity will be returned. + * Returns a list of the names of providers that satisfy the given criteria. Only providers that + * the caller has permission to access will be returned. + * + * @param criteria the criteria that providers must match + * @param enabledOnly if true then only enabled providers are included + * @return list of provider names * - * @param criteria the criteria that the returned providers must match - * @param enabledOnly if true then only the providers which are currently - * enabled are returned. - * @return list of Strings containing names of the providers + * @throws IllegalArgumentException if criteria is null */ public @NonNull List<String> getProviders(@NonNull Criteria criteria, boolean enabledOnly) { - checkCriteria(criteria); + Preconditions.checkArgument(criteria != null, "invalid null criteria"); + try { return mService.getProviders(criteria, enabledOnly); } catch (RemoteException e) { @@ -1217,11 +1158,10 @@ public class LocationManager { } /** - * Returns the name of the provider that best meets the given criteria. Only providers - * that are permitted to be accessed by the calling activity will be - * returned. If several providers meet the criteria, the one with the best - * accuracy is returned. If no provider meets the criteria, - * the criteria are loosened in the following sequence: + * Returns the name of the provider that best meets the given criteria. Only providers that are + * permitted to be accessed by the caller will be returned. If several providers meet the + * criteria, the one with the best accuracy is returned. If no provider meets the criteria, the + * criteria are loosened in the following order: * * <ul> * <li> power requirement @@ -1231,15 +1171,17 @@ public class LocationManager { * <li> altitude * </ul> * - * <p> Note that the requirement on monetary cost is not removed - * in this process. + * <p> Note that the requirement on monetary cost is not removed in this process. * * @param criteria the criteria that need to be matched - * @param enabledOnly if true then only a provider that is currently enabled is returned - * @return name of the provider that best matches the requirements + * @param enabledOnly if true then only enabled providers are included + * @return name of the provider that best matches the criteria, or null if none match + * + * @throws IllegalArgumentException if criteria is null */ public @Nullable String getBestProvider(@NonNull Criteria criteria, boolean enabledOnly) { - checkCriteria(criteria); + Preconditions.checkArgument(criteria != null, "invalid null criteria"); + try { return mService.getBestProvider(criteria, enabledOnly); } catch (RemoteException e) { @@ -1248,24 +1190,22 @@ public class LocationManager { } /** - * Returns the information associated with the location provider of the - * given name, or null if no provider exists by that name. + * Returns the information about the location provider with the given name, or null if no + * provider exists by that name. * - * @param name the provider name - * @return a LocationProvider, or null + * @param provider the provider name + * @return location provider information, or null if provider does not exist * - * @throws IllegalArgumentException if name is null or does not exist - * @throws SecurityException if the caller is not permitted to access the - * given provider. + * @throws IllegalArgumentException if provider is null */ - public @Nullable LocationProvider getProvider(@NonNull String name) { - checkProvider(name); + public @Nullable LocationProvider getProvider(@NonNull String provider) { + Preconditions.checkArgument(provider != null, "invalid null provider"); try { - ProviderProperties properties = mService.getProviderProperties(name); + ProviderProperties properties = mService.getProviderProperties(provider); if (properties == null) { return null; } - return new LocationProvider(name, properties); + return new LocationProvider(provider, properties); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1292,10 +1232,10 @@ public class LocationManager { * Sends additional commands to a location provider. Can be used to support provider specific * extensions to the Location Manager API. * - * @param provider name of the location provider. - * @param command name of the command to send to the provider. - * @param extras optional arguments for the command (or null). - * @return true always + * @param provider name of the location provider + * @param command name of the command to send to the provider + * @param extras optional arguments for the command, or null + * @return true always, the return value may be ignored */ public boolean sendExtraCommand( @NonNull String provider, @NonNull String command, @Nullable Bundle extras) { @@ -1469,7 +1409,7 @@ public class LocationManager { @TestApi @NonNull public List<LocationRequest> getTestProviderCurrentRequests(String providerName) { - checkProvider(providerName); + Preconditions.checkArgument(providerName != null, "invalid null provider"); try { return mService.getTestProviderCurrentRequests(providerName, mContext.getOpPackageName()); @@ -1558,10 +1498,9 @@ public class LocationManager { */ public void removeProximityAlert(@NonNull PendingIntent intent) { checkPendingIntent(intent); - String packageName = mContext.getPackageName(); try { - mService.removeGeofence(null, intent, packageName); + mService.removeGeofence(null, intent, mContext.getPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1609,7 +1548,7 @@ public class LocationManager { @NonNull Geofence fence, @NonNull PendingIntent intent) { checkPendingIntent(intent); - checkGeofence(fence); + Preconditions.checkArgument(fence != null, "invalid null geofence"); try { mService.requestGeofence(request, fence, intent, mContext.getPackageName()); @@ -1636,11 +1575,10 @@ public class LocationManager { */ public void removeGeofence(@NonNull Geofence fence, @NonNull PendingIntent intent) { checkPendingIntent(intent); - checkGeofence(fence); - String packageName = mContext.getPackageName(); + Preconditions.checkArgument(fence != null, "invalid null geofence"); try { - mService.removeGeofence(fence, intent, packageName); + mService.removeGeofence(fence, intent, mContext.getPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1659,10 +1597,9 @@ public class LocationManager { */ public void removeAllGeofences(@NonNull PendingIntent intent) { checkPendingIntent(intent); - String packageName = mContext.getPackageName(); try { - mService.removeGeofence(null, intent, packageName); + mService.removeGeofence(null, intent, mContext.getPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1723,15 +1660,16 @@ public class LocationManager { } /** - * Retrieves information about the current status of the GPS engine. - * This should only be called from the {@link GpsStatus.Listener#onGpsStatusChanged} - * callback to ensure that the data is copied atomically. + * Retrieves information about the current status of the GPS engine. This should only be called + * from within the {@link GpsStatus.Listener#onGpsStatusChanged} callback to ensure that the + * data is copied atomically. * - * The caller may either pass in a {@link GpsStatus} object to set with the latest - * status information, or pass null to create a new {@link GpsStatus} object. + * The caller may either pass in an existing {@link GpsStatus} object to be overwritten, or pass + * null to create a new {@link GpsStatus} object. * * @param status object containing GPS status details, or null. * @return status object containing updated GPS status. + * * @deprecated GpsStatus APIs are deprecated, use {@link GnssStatus} APIs instead. */ @Deprecated @@ -1756,12 +1694,21 @@ public class LocationManager { * @param listener GPS status listener object to register * @return true if the listener was successfully added * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present + * * @deprecated use {@link #registerGnssStatusCallback(GnssStatus.Callback)} instead. No longer * supported in apps targeting R and above. */ @Deprecated @RequiresPermission(ACCESS_FINE_LOCATION) public boolean addGpsStatusListener(GpsStatus.Listener listener) { + UnsupportedOperationException ex = new UnsupportedOperationException( + "GpsStatus APIs not supported in R and above, use GnssStatus APIs instead"); + if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) { + throw ex; + } else { + Log.w(TAG, ex); + } + try { return mGnssStatusListenerManager.addListener(listener, new Handler()); } catch (RemoteException e) { @@ -1773,11 +1720,20 @@ public class LocationManager { * Removes a GPS status listener. * * @param listener GPS status listener object to remove + * * @deprecated use {@link #unregisterGnssStatusCallback(GnssStatus.Callback)} instead. No longer * supported in apps targeting R and above. */ @Deprecated public void removeGpsStatusListener(GpsStatus.Listener listener) { + UnsupportedOperationException ex = new UnsupportedOperationException( + "GpsStatus APIs not supported in R and above, use GnssStatus APIs instead"); + if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) { + throw ex; + } else { + Log.w(TAG, ex); + } + try { mGnssStatusListenerManager.removeListener(listener); } catch (RemoteException e) { @@ -1790,7 +1746,9 @@ public class LocationManager { * * @param callback GNSS status callback object to register * @return true if the listener was successfully added + * * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present + * * @deprecated Use {@link #registerGnssStatusCallback(GnssStatus.Callback, Handler)} or {@link * #registerGnssStatusCallback(Executor, GnssStatus.Callback)} instead. */ @@ -1804,8 +1762,9 @@ public class LocationManager { * Registers a GNSS status callback. * * @param callback GNSS status callback object to register - * @param handler a handler with a looper that the callback runs on. + * @param handler a handler with a looper that the callback runs on * @return true if the listener was successfully added + * * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present */ @RequiresPermission(ACCESS_FINE_LOCATION) @@ -1826,8 +1785,9 @@ public class LocationManager { * Registers a GNSS status callback. * * @param callback GNSS status callback object to register - * @param executor the executor that the callback runs on. + * @param executor the executor that the callback runs on * @return true if the listener was successfully added + * * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present */ @RequiresPermission(ACCESS_FINE_LOCATION) @@ -1855,13 +1815,8 @@ public class LocationManager { } /** - * Adds an NMEA listener. - * - * @param listener a {@link GpsStatus.NmeaListener} object to register - * - * @return true if the listener was successfully added + * No-op method to keep backward-compatibility. * - * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present * @deprecated use {@link #addNmeaListener(OnNmeaMessageListener)} instead. * @removed */ @@ -1872,9 +1827,8 @@ public class LocationManager { } /** - * Removes an NMEA listener. + * No-op method to keep backward-compatibility. * - * @param listener a {@link GpsStatus.NmeaListener} object to remove * @deprecated use {@link #removeNmeaListener(OnNmeaMessageListener)} instead. * @removed */ @@ -1951,30 +1905,26 @@ public class LocationManager { /** * No-op method to keep backward-compatibility. - * Don't use it. Use {@link #registerGnssMeasurementsCallback} instead. + * * @hide - * @deprecated Not supported anymore. + * @deprecated Use {@link #registerGnssMeasurementsCallback} instead. * @removed */ @Deprecated @SystemApi - @SuppressLint("Doclava125") public boolean addGpsMeasurementListener(GpsMeasurementsEvent.Listener listener) { return false; } /** - * No-op method to keep backward-compatibility. Don't use it. Use {@link - * #unregisterGnssMeasurementsCallback} instead. + * No-op method to keep backward-compatibility. * * @hide - * @deprecated use {@link #unregisterGnssMeasurementsCallback(GnssMeasurementsEvent.Callback)} - * instead. + * @deprecated Use {@link #unregisterGnssMeasurementsCallback} instead. * @removed */ @Deprecated @SystemApi - @SuppressLint("Doclava125") public void removeGpsMeasurementListener(GpsMeasurementsEvent.Listener listener) {} /** @@ -2067,30 +2017,26 @@ public class LocationManager { /** * No-op method to keep backward-compatibility. - * Don't use it. Use {@link #registerGnssNavigationMessageCallback} instead. + * * @hide - * @deprecated Not supported anymore. + * @deprecated Use {@link #registerGnssNavigationMessageCallback} instead. * @removed */ @Deprecated @SystemApi - @SuppressLint("Doclava125") public boolean addGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) { return false; } /** * No-op method to keep backward-compatibility. - * Don't use it. Use {@link #unregisterGnssNavigationMessageCallback} instead. + * * @hide - * @deprecated use - * {@link #unregisterGnssNavigationMessageCallback(GnssNavigationMessage.Callback)} - * instead + * @deprecated Use {@link #unregisterGnssNavigationMessageCallback} instead. * @removed */ @Deprecated @SystemApi - @SuppressLint("Doclava125") public void removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {} /** @@ -2276,31 +2222,11 @@ public class LocationManager { } } - private static void checkProvider(String provider) { - if (provider == null) { - throw new IllegalArgumentException("invalid provider: " + provider); - } - } - - private static void checkCriteria(Criteria criteria) { - if (criteria == null) { - throw new IllegalArgumentException("invalid criteria: " + criteria); - } - } - - private static void checkListener(LocationListener listener) { - if (listener == null) { - throw new IllegalArgumentException("invalid listener: " + listener); - } - } - - private void checkPendingIntent(PendingIntent intent) { - if (intent == null) { - throw new IllegalArgumentException("invalid pending intent: " + intent); - } - if (!intent.isTargetedToPackage()) { + private void checkPendingIntent(PendingIntent pendingIntent) { + Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent"); + if (!pendingIntent.isTargetedToPackage()) { IllegalArgumentException e = new IllegalArgumentException( - "pending intent must be targeted to package"); + "invalid pending intent - must be targeted to package"); if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.JELLY_BEAN) { throw e; } else { @@ -2309,12 +2235,6 @@ public class LocationManager { } } - private static void checkGeofence(Geofence fence) { - if (fence == null) { - throw new IllegalArgumentException("invalid geofence: " + fence); - } - } - private class LocationListenerTransport extends ILocationListener.Stub { private final Executor mExecutor; diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 2d6cd242c702..f797da70e7d1 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -1857,12 +1857,37 @@ public class AudioManager { } /** + * @hide + * Sets the microphone from switch mute on or off. + * <p> + * This method should only be used by InputManager to notify + * Audio Subsystem about Microphone Mute switch state. + * + * @param on set <var>true</var> to mute the microphone; + * <var>false</var> to turn mute off + */ + @UnsupportedAppUsage + public void setMicrophoneMuteFromSwitch(boolean on) { + final IAudioService service = getService(); + try { + service.setMicrophoneMuteFromSwitch(on); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Checks whether the microphone mute is on or off. * * @return true if microphone is muted, false if it's not */ public boolean isMicrophoneMute() { - return AudioSystem.isMicrophoneMuted(); + final IAudioService service = getService(); + try { + return service.isMicrophoneMuted(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 71f52a1b7d8e..fc056109baa4 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -106,8 +106,12 @@ interface IAudioService { List<AudioProductStrategy> getAudioProductStrategies(); + boolean isMicrophoneMuted(); + void setMicrophoneMute(boolean on, String callingPackage, int userId); + oneway void setMicrophoneMuteFromSwitch(boolean on); + void setRingerModeExternal(int ringerMode, String caller); void setRingerModeInternal(int ringerMode, String caller); diff --git a/media/jni/Android.bp b/media/jni/Android.bp index 6257feb2f894..45ee210c80c9 100644 --- a/media/jni/Android.bp +++ b/media/jni/Android.bp @@ -59,7 +59,10 @@ cc_library_shared { "android.hidl.token@1.0-utils", ], - header_libs: ["libhardware_headers"], + header_libs: [ + "libhardware_headers", + "libmediadrm_headers", + ], static_libs: ["libgrallocusage"], diff --git a/media/jni/android_media_MediaDrm.h b/media/jni/android_media_MediaDrm.h index 5ebac1d61648..684069b0120a 100644 --- a/media/jni/android_media_MediaDrm.h +++ b/media/jni/android_media_MediaDrm.h @@ -20,15 +20,12 @@ #include "jni.h" #include <media/stagefright/foundation/ABase.h> -#include <media/IDrm.h> -#include <media/IDrmClient.h> +#include <mediadrm/IDrm.h> #include <utils/Errors.h> #include <utils/RefBase.h> namespace android { -struct IDrm; - class DrmListener: virtual public RefBase { public: diff --git a/mime/Android.bp b/mime/Android.bp index 17bad746e039..51290f6b1176 100644 --- a/mime/Android.bp +++ b/mime/Android.bp @@ -12,23 +12,84 @@ // See the License for the specific language governing permissions and // limitations under the License. + +java_defaults { + name: "mimemap-defaults", + srcs: [ + "java/android/content/type/DefaultMimeMapFactory.java", + ], + sdk_version: "core_platform", +} + java_library { name: "mimemap", + defaults: ["mimemap-defaults"], + static_libs: ["mimemap-res.jar"], + visibility: [ + "//frameworks/base:__subpackages__", + ], +} + +java_library { + name: "mimemap-testing", + defaults: ["mimemap-defaults"], + static_libs: ["mimemap-testing-res.jar"], + jarjar_rules: "jarjar-rules.txt", visibility: [ "//cts/tests/tests/mimemap:__subpackages__", "//frameworks/base:__subpackages__", ], +} - srcs: [ - "java/android/content/type/DefaultMimeMapFactory.java", +// The mimemap-res.jar and mimemap-testing-res.jar genrules produce a .jar that +// has the resource file in a subdirectory res/ and testres/, respectively. +// Those paths need to They need to be in different paths because one of them +// ends up on a bootclasspath jar whereas the other one ends up in a test jar. +// Bootclasspath resources hide test or application resources under the same +// path because ClassLoader.getResource(String) consults the parent ClassLoader +// first. +// +// Further notes: +// - the "cp" command will flatten any directory paths that occur in $(in), +// but here they happen to already be in the root directory. If we needed +// to preserve sub paths then we might want to zip the files first and then +// unzip them below the new parent directory. +// - the path names "res/" and "testres/" and duplicated in .java source files +// (DefaultMimeMapFactory.java and MimeMapTest.java, as of October 2019). +java_genrule { + name: "mimemap-res.jar", + tools: [ + "soong_zip", ], + srcs: [":mime.types"], + out: ["mimemap-res.jar"], + cmd: "mkdir $(genDir)/res/ && cp $(in) $(genDir)/res/ && $(location soong_zip) -C $(genDir) -o $(out) -D $(genDir)/res/", +} - java_resources: [ +// The same as mimemap-res.jar except that the resources are placed in a different directory. +// They get bundled with CTS so that CTS can compare a device's MimeMap implementation vs. +// the stock Android one from when CTS was built. +java_genrule { + name: "mimemap-testing-res.jar", + tools: [ + "soong_zip", + ], + srcs: [":mime.types"], + out: ["mimemap-testing-res.jar"], + cmd: "mkdir $(genDir)/testres/ && cp $(in) $(genDir)/testres/ && $(location soong_zip) -C $(genDir) -o $(out) -D $(genDir)/testres/", +} + +// Combination of all *mime.types resources. +filegroup { + name: "mime.types", + visibility: [ + "//visibility:private", + ], + srcs: [ ":debian.mime.types", ":android.mime.types", + ":vendor.mime.types", ], - - sdk_version: "core_platform", } filegroup { @@ -41,3 +102,14 @@ filegroup { "java-res/android.mime.types", ], } + +filegroup { + name: "vendor.mime.types", + visibility: [ + "//visibility:private", + ], + path: "java-res/", + srcs: [ + "java-res/vendor.mime.types", + ], +} diff --git a/mime/TEST_MAPPING b/mime/TEST_MAPPING new file mode 100644 index 000000000000..8daab754ea8a --- /dev/null +++ b/mime/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "CtsMimeMapTestCases" + } + ] +} diff --git a/mime/jarjar-rules.txt b/mime/jarjar-rules.txt new file mode 100644 index 000000000000..145d1dbf3d11 --- /dev/null +++ b/mime/jarjar-rules.txt @@ -0,0 +1 @@ +rule android.content.type.DefaultMimeMapFactory android.content.type.cts.StockAndroidMimeMapFactory
\ No newline at end of file diff --git a/mime/java-res/android.mime.types b/mime/java-res/android.mime.types index 1ca912e8510b..7a5299ff1b69 100644 --- a/mime/java-res/android.mime.types +++ b/mime/java-res/android.mime.types @@ -3,7 +3,7 @@ # # Android-specific MIME type <-> extension mappings # -# Each line below defines an mapping from one MIME type to the first of the +# Each line below defines a mapping from one MIME type to the first of the # listed extensions, and from listed extension back to the MIME type. # A mapping overrides any previous mapping _from_ that same MIME type or # extension (put() semantics), unless that MIME type / extension is prefixed with '?' diff --git a/mime/java-res/vendor.mime.types b/mime/java-res/vendor.mime.types new file mode 100644 index 000000000000..afb8f9e4ef39 --- /dev/null +++ b/mime/java-res/vendor.mime.types @@ -0,0 +1,41 @@ +############################################################################### +# +# Vendor-specific MIME type <-> extension mappings +# +# Each line below defines a mapping from one MIME type to the first of the +# listed extensions, and from listed extension back to the MIME type. +# +# This file can _add_ additional mappings that are not in the default set, +# but it it cannot _modify_ (replace or remove) any platform default mapping +# (defined in files mime.types and android.mime.types). +# +############################################################################### +# +# EXAMPLES +# +# A line of the form (without the leading '#''): +# +# mime ext1 ext2 ext3 +# +# affects the current mappings along the lines of the following pseudo code: +# +# mimeToExt.putIfAbsent("mime", "ext1"); +# extToMime.putIfAbsent("ext1", "mime"); +# extToMime.putIfAbsent("ext2", "mime"); +# extToMime.putIfAbsent("ext3", "mime"); +# +# Optionally, MIME types or extensions may be prefixed by a single '?', which +# will be ignored. I.e., the following example lines all have the same semantics: +# +# mime ext1 ext2 ext3 +# ?mime ext1 ext2 ext3 +# mime ?ext1 ext2 ?ext3 +# ?mime ?ext1 ?ext2 ?ext3 +# +# By default, this file contains no mappings (which means that the platform +# default mapping is used unmodified). +# +############################################################################### +# +# Add your custom mappings below this line (with no "#" at the start of the line): + diff --git a/mime/java/android/content/type/DefaultMimeMapFactory.java b/mime/java/android/content/type/DefaultMimeMapFactory.java index 545fb3cbb5cd..13039a4ab1e2 100644 --- a/mime/java/android/content/type/DefaultMimeMapFactory.java +++ b/mime/java/android/content/type/DefaultMimeMapFactory.java @@ -20,9 +20,13 @@ import libcore.net.MimeMap; import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; +import java.util.function.Function; import java.util.regex.Pattern; /** @@ -44,24 +48,33 @@ public class DefaultMimeMapFactory { * Android's default mapping between MIME types and extensions. */ public static MimeMap create() { - return parseFromResources("/mime.types", "/android.mime.types"); + Class c = DefaultMimeMapFactory.class; + // The resources are placed into the res/ path by the "mimemap-res.jar" genrule. + return create(resourceName -> c.getResourceAsStream("/res/" + resourceName)); } private static final Pattern SPLIT_PATTERN = Pattern.compile("\\s+"); - static MimeMap parseFromResources(String... resourceNames) { + /** + * Creates a {@link MimeMap} instance whose resources are loaded from the + * InputStreams looked up in {@code resourceSupplier}. + * + * @hide + */ + public static MimeMap create(Function<String, InputStream> resourceSupplier) { MimeMap.Builder builder = MimeMap.builder(); - for (String resourceName : resourceNames) { - parseTypes(builder, resourceName); - } + parseTypes(builder, true, resourceSupplier, "mime.types"); + parseTypes(builder, true, resourceSupplier, "android.mime.types"); + parseTypes(builder, false, resourceSupplier, "vendor.mime.types"); return builder.build(); } - private static void parseTypes(MimeMap.Builder builder, String resource) { - try (BufferedReader r = new BufferedReader( - new InputStreamReader(DefaultMimeMapFactory.class.getResourceAsStream(resource)))) { + private static void parseTypes(MimeMap.Builder builder, boolean allowOverwrite, + Function<String, InputStream> resourceSupplier, String resourceName) { + try (InputStream inputStream = Objects.requireNonNull(resourceSupplier.apply(resourceName)); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { String line; - while ((line = r.readLine()) != null) { + while ((line = reader.readLine()) != null) { int commentPos = line.indexOf('#'); if (commentPos >= 0) { line = line.substring(0, commentPos); @@ -71,11 +84,28 @@ public class DefaultMimeMapFactory { continue; } List<String> specs = Arrays.asList(SPLIT_PATTERN.split(line)); + if (!allowOverwrite) { + // Pretend that the mimeType and each file extension listed in the line + // carries a "?" prefix, which means that it can add new mappings but + // not modify existing mappings (putIfAbsent() semantics). + specs = ensurePrefix("?", specs); + } builder.put(specs.get(0), specs.subList(1, specs.size())); } } catch (IOException | RuntimeException e) { - throw new RuntimeException("Failed to parse " + resource, e); + throw new RuntimeException("Failed to parse " + resourceName, e); + } + } + + private static List<String> ensurePrefix(String prefix, List<String> strings) { + List<String> result = new ArrayList<>(strings.size()); + for (String s : strings) { + if (!s.startsWith(prefix)) { + s = prefix + s; + } + result.add(s); } + return result; } } diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/InitializeRecoverableSecondaryKeyTask.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/InitializeRecoverableSecondaryKeyTask.java new file mode 100644 index 000000000000..d436554341b8 --- /dev/null +++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/InitializeRecoverableSecondaryKeyTask.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 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. + */ + +package com.android.server.backup.encryption.tasks; + +import android.content.Context; +import android.security.keystore.recovery.InternalRecoveryServiceException; +import android.security.keystore.recovery.LockScreenRequiredException; +import android.security.keystore.recovery.RecoveryController; +import android.util.Slog; + +import com.android.server.backup.encryption.CryptoSettings; +import com.android.server.backup.encryption.client.CryptoBackupServer; +import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey; +import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager; + +import java.security.InvalidKeyException; +import java.security.UnrecoverableKeyException; +import java.util.Collections; +import java.util.Optional; + +/** + * Initializes the device for encrypted backup, through generating a secondary key, and setting its + * alias in the settings. + * + * <p>If the device is already initialized, this is a no-op. + */ +public class InitializeRecoverableSecondaryKeyTask { + private static final String TAG = "InitializeRecoverableSecondaryKeyTask"; + + private final Context mContext; + private final CryptoSettings mCryptoSettings; + private final RecoverableKeyStoreSecondaryKeyManager mSecondaryKeyManager; + private final CryptoBackupServer mBackupServer; + + /** + * A new instance. + * + * @param cryptoSettings Settings to store the active key alias. + * @param secondaryKeyManager Key manager to generate the new active secondary key. + * @param backupServer Server with which to sync the active key alias. + */ + public InitializeRecoverableSecondaryKeyTask( + Context context, + CryptoSettings cryptoSettings, + RecoverableKeyStoreSecondaryKeyManager secondaryKeyManager, + CryptoBackupServer backupServer) { + mContext = context; + mCryptoSettings = cryptoSettings; + mSecondaryKeyManager = secondaryKeyManager; + mBackupServer = backupServer; + } + + /** + * Initializes the device for encrypted backup, by generating a recoverable secondary key, then + * sending that alias to the backup server and saving it in local settings. + * + * <p>If there is already an active secondary key then does nothing. If the active secondary key + * is destroyed then throws {@link InvalidKeyException}. + * + * <p>If a key rotation is pending and able to finish (i.e., the new key has synced with the + * remote trusted hardware module), then it completes the rotation before returning the key. + * + * @return The active secondary key. + * @throws InvalidKeyException if the secondary key is in a bad state. + */ + public RecoverableKeyStoreSecondaryKey run() + throws InvalidKeyException, LockScreenRequiredException, UnrecoverableKeyException, + InternalRecoveryServiceException { + // Complete any pending key rotations + new RotateSecondaryKeyTask( + mContext, + mSecondaryKeyManager, + mBackupServer, + mCryptoSettings, + RecoveryController.getInstance(mContext)) + .run(); + + return runInternal(); + } + + private RecoverableKeyStoreSecondaryKey runInternal() + throws InvalidKeyException, LockScreenRequiredException, UnrecoverableKeyException, + InternalRecoveryServiceException { + Optional<RecoverableKeyStoreSecondaryKey> maybeActiveKey = loadFromSetting(); + + if (maybeActiveKey.isPresent()) { + assertKeyNotDestroyed(maybeActiveKey.get()); + Slog.d(TAG, "Secondary key already initialized: " + maybeActiveKey.get().getAlias()); + return maybeActiveKey.get(); + } + + Slog.v(TAG, "Initializing for crypto: generating a secondary key."); + RecoverableKeyStoreSecondaryKey key = mSecondaryKeyManager.generate(); + + String alias = key.getAlias(); + Slog.i(TAG, "Generated new secondary key " + alias); + + // No tertiary keys yet as we are creating a brand new secondary (without rotation). + mBackupServer.setActiveSecondaryKeyAlias(alias, /*tertiaryKeys=*/ Collections.emptyMap()); + Slog.v(TAG, "Successfully synced %s " + alias + " with server."); + + mCryptoSettings.initializeWithKeyAlias(alias); + Slog.v(TAG, "Successfully saved " + alias + " as active secondary to disk."); + + return key; + } + + private void assertKeyNotDestroyed(RecoverableKeyStoreSecondaryKey key) + throws InvalidKeyException { + if (key.getStatus(mContext) == RecoverableKeyStoreSecondaryKey.Status.DESTROYED) { + throw new InvalidKeyException("Key destroyed: " + key.getAlias()); + } + } + + private Optional<RecoverableKeyStoreSecondaryKey> loadFromSetting() + throws InvalidKeyException, UnrecoverableKeyException, + InternalRecoveryServiceException { + + // TODO: b/141856950. + if (!mCryptoSettings.getIsInitialized()) { + return Optional.empty(); + } + + Optional<String> maybeAlias = mCryptoSettings.getActiveSecondaryKeyAlias(); + if (!maybeAlias.isPresent()) { + throw new InvalidKeyException( + "Settings said crypto was initialized, but there was no active secondary" + + " alias"); + } + + String alias = maybeAlias.get(); + + Optional<RecoverableKeyStoreSecondaryKey> key; + key = mSecondaryKeyManager.get(alias); + + if (!key.isPresent()) { + throw new InvalidKeyException( + "Initialized with key but it was not in key store: " + alias); + } + + return key; + } +} diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/InitializeRecoverableSecondaryKeyTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/InitializeRecoverableSecondaryKeyTaskTest.java new file mode 100644 index 000000000000..4a7ae03bd0db --- /dev/null +++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/InitializeRecoverableSecondaryKeyTaskTest.java @@ -0,0 +1,165 @@ +/* + * Copyright (C) 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. + */ + +package com.android.server.backup.encryption.tasks; + +import static android.security.keystore.recovery.RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertThrows; + +import android.app.Application; +import android.security.keystore.recovery.RecoveryController; + +import androidx.test.core.app.ApplicationProvider; + +import com.android.server.backup.encryption.CryptoSettings; +import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey; +import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager; +import com.android.server.testing.fakes.FakeCryptoBackupServer; +import com.android.server.testing.shadows.ShadowRecoveryController; + +import java.security.InvalidKeyException; +import java.security.SecureRandom; +import java.util.Optional; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +@Config(shadows = {ShadowRecoveryController.class}) +@RunWith(RobolectricTestRunner.class) +public class InitializeRecoverableSecondaryKeyTaskTest { + @Mock private CryptoSettings mMockCryptoSettings; + + private Application mApplication; + private InitializeRecoverableSecondaryKeyTask mTask; + private CryptoSettings mCryptoSettings; + private FakeCryptoBackupServer mFakeCryptoBackupServer; + private RecoverableKeyStoreSecondaryKeyManager mSecondaryKeyManager; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + ShadowRecoveryController.reset(); + + mApplication = ApplicationProvider.getApplicationContext(); + mFakeCryptoBackupServer = new FakeCryptoBackupServer(); + mCryptoSettings = CryptoSettings.getInstanceForTesting(mApplication); + mSecondaryKeyManager = + new RecoverableKeyStoreSecondaryKeyManager( + RecoveryController.getInstance(mApplication), new SecureRandom()); + + mTask = + new InitializeRecoverableSecondaryKeyTask( + mApplication, mCryptoSettings, mSecondaryKeyManager, mFakeCryptoBackupServer); + } + + @Test + public void testRun_generatesNewKeyInRecoveryController() throws Exception { + RecoverableKeyStoreSecondaryKey key = mTask.run(); + + assertThat(RecoveryController.getInstance(mApplication).getAliases()) + .contains(key.getAlias()); + } + + @Test + public void testRun_setsAliasOnServer() throws Exception { + RecoverableKeyStoreSecondaryKey key = mTask.run(); + + assertThat(mFakeCryptoBackupServer.getActiveSecondaryKeyAlias().get()) + .isEqualTo(key.getAlias()); + } + + @Test + public void testRun_setsAliasInSettings() throws Exception { + RecoverableKeyStoreSecondaryKey key = mTask.run(); + + assertThat(mCryptoSettings.getActiveSecondaryKeyAlias().get()).isEqualTo(key.getAlias()); + } + + @Test + public void testRun_initializesSettings() throws Exception { + mTask.run(); + + assertThat(mCryptoSettings.getIsInitialized()).isTrue(); + } + + @Test + public void testRun_initializeSettingsFails_throws() throws Exception { + useMockCryptoSettings(); + doThrow(IllegalArgumentException.class) + .when(mMockCryptoSettings) + .initializeWithKeyAlias(any()); + + + assertThrows(IllegalArgumentException.class, () -> mTask.run()); + } + + @Test + public void testRun_doesNotGenerateANewKeyIfOneIsAvailable() throws Exception { + RecoverableKeyStoreSecondaryKey key1 = mTask.run(); + RecoverableKeyStoreSecondaryKey key2 = mTask.run(); + + assertThat(key1.getAlias()).isEqualTo(key2.getAlias()); + assertThat(key2.getSecretKey()).isEqualTo(key2.getSecretKey()); + } + + @Test + public void testRun_existingKeyButDestroyed_throws() throws Exception { + RecoverableKeyStoreSecondaryKey key = mTask.run(); + ShadowRecoveryController.setRecoveryStatus( + key.getAlias(), RECOVERY_STATUS_PERMANENT_FAILURE); + + assertThrows(InvalidKeyException.class, () -> mTask.run()); + } + + @Test + public void testRun_settingsInitializedButNotSecondaryKeyAlias_throws() { + useMockCryptoSettings(); + when(mMockCryptoSettings.getIsInitialized()).thenReturn(true); + when(mMockCryptoSettings.getActiveSecondaryKeyAlias()).thenReturn(Optional.empty()); + + assertThrows(InvalidKeyException.class, () -> mTask.run()); + } + + @Test + public void testRun_keyAliasSetButNotInStore_throws() { + useMockCryptoSettings(); + when(mMockCryptoSettings.getIsInitialized()).thenReturn(true); + when(mMockCryptoSettings.getActiveSecondaryKeyAlias()) + .thenReturn(Optional.of("missingAlias")); + + assertThrows(InvalidKeyException.class, () -> mTask.run()); + } + + private void useMockCryptoSettings() { + mTask = + new InitializeRecoverableSecondaryKeyTask( + mApplication, + mMockCryptoSettings, + mSecondaryKeyManager, + mFakeCryptoBackupServer); + } +} diff --git a/packages/SystemUI/res/drawable-xhdpi/tv_card_gradient_protection.png b/packages/SystemUI/res/drawable-xhdpi/tv_card_gradient_protection.png Binary files differnew file mode 100644 index 000000000000..135dabb63069 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/tv_card_gradient_protection.png diff --git a/packages/SystemUI/res/drawable/circle_red.xml b/packages/SystemUI/res/drawable/circle_red.xml new file mode 100644 index 000000000000..fd3c125e5ab8 --- /dev/null +++ b/packages/SystemUI/res/drawable/circle_red.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 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. + --> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="oval"> + <solid android:color="@color/red"/> +</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/tv_bg_item_app_info.xml b/packages/SystemUI/res/drawable/tv_bg_item_app_info.xml new file mode 100644 index 000000000000..1bbb8c3e8ef0 --- /dev/null +++ b/packages/SystemUI/res/drawable/tv_bg_item_app_info.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 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. + --> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <corners android:radius="24dp"/> + <solid android:color="@color/tv_audio_recording_bar_chip_background"/> +</shape> diff --git a/packages/SystemUI/res/drawable/tv_gradient_protection.xml b/packages/SystemUI/res/drawable/tv_gradient_protection.xml new file mode 100644 index 000000000000..ee5cbc7e6ba0 --- /dev/null +++ b/packages/SystemUI/res/drawable/tv_gradient_protection.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 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. + --> + +<!-- gradient protection for cards --> +<bitmap xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/tv_card_gradient_protection" + android:tileMode="repeat" +/> diff --git a/packages/SystemUI/res/drawable/tv_ic_mic_white.xml b/packages/SystemUI/res/drawable/tv_ic_mic_white.xml new file mode 100644 index 000000000000..1bea8a19c8b9 --- /dev/null +++ b/packages/SystemUI/res/drawable/tv_ic_mic_white.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 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 + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:viewportWidth="44" + android:viewportHeight="44" + android:width="44dp" + android:height="44dp"> + <path + android:pathData="M22 25.6666667C25.0433333 25.6666667 27.4816667 23.21 27.4816667 20.1666667L27.5 9.16666667C27.5 6.12333333 25.0433333 3.66666667 22 3.66666667C18.9566667 3.66666667 16.5 6.12333333 16.5 9.16666667L16.5 20.1666667C16.5 23.21 18.9566667 25.6666667 22 25.6666667ZM31.7166667 20.1666667C31.7166667 25.6666667 27.06 29.5166667 22 29.5166667C16.94 29.5166667 12.2833333 25.6666667 12.2833333 20.1666667L9.16666667 20.1666667C9.16666667 26.4183333 14.1533333 31.5883333 20.1666667 32.4866667L20.1666667 38.5L23.8333333 38.5L23.8333333 32.4866667C29.8466667 31.6066667 34.8333333 26.4366667 34.8333333 20.1666667L31.7166667 20.1666667Z" + android:fillColor="@android:color/white" /> +</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/qs_carrier_group.xml b/packages/SystemUI/res/layout/qs_carrier_group.xml index 56efb4911cd0..f2b0606979cc 100644 --- a/packages/SystemUI/res/layout/qs_carrier_group.xml +++ b/packages/SystemUI/res/layout/qs_carrier_group.xml @@ -29,6 +29,9 @@ android:id="@+id/no_carrier_text" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:minWidth="48dp" + android:minHeight="48dp" + android:gravity="center_vertical" android:textAppearance="@style/TextAppearance.QS.Status" android:textDirection="locale" android:marqueeRepeatLimit="marquee_forever" diff --git a/packages/SystemUI/res/layout/tv_item_app_info.xml b/packages/SystemUI/res/layout/tv_item_app_info.xml new file mode 100644 index 000000000000..b40589ec80c6 --- /dev/null +++ b/packages/SystemUI/res/layout/tv_item_app_info.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 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. + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_width="wrap_content" + android:layout_height="48dp" + android:layout_marginLeft="8dp" + android:paddingHorizontal="12dp" + android:gravity="center_vertical" + android:background="@drawable/tv_bg_item_app_info"> + + <ImageView + android:id="@+id/icon" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_marginRight="8dp"/> + + <TextView + android:id="@+id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/tv_audio_recording_bar_text" + android:fontFamily="sans-serif" + android:textSize="14sp"/> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout/tv_status_bar_audio_recording.xml b/packages/SystemUI/res/layout/tv_status_bar_audio_recording.xml new file mode 100644 index 000000000000..b9dffbb4de20 --- /dev/null +++ b/packages/SystemUI/res/layout/tv_status_bar_audio_recording.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 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. + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" + android:orientation="vertical"> + + <!-- Gradient Protector --> + <View + android:layout_width="match_parent" + android:layout_height="102.5dp" + android:background="@drawable/tv_gradient_protection"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="72dp" + android:background="@color/tv_audio_recording_bar_background" + android:gravity="center_vertical" + android:orientation="horizontal"> + + <ImageView + android:layout_width="48dp" + android:layout_height="48dp" + android:layout_marginLeft="42dp" + android:layout_marginVertical="12dp" + android:padding="8dp" + android:background="@drawable/circle_red" + android:scaleType="centerInside" + android:src="@drawable/tv_ic_mic_white"/> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="24dp" + android:text="Audio recording by" + android:textColor="@color/tv_audio_recording_bar_text" + android:fontFamily="sans-serif" + android:textSize="14sp"/> + + <LinearLayout + android:id="@+id/container" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + + </LinearLayout> + +</LinearLayout> diff --git a/packages/SystemUI/res/values/arrays_tv.xml b/packages/SystemUI/res/values/arrays_tv.xml index 9197bb51e1a6..1fe6141a53b7 100644 --- a/packages/SystemUI/res/values/arrays_tv.xml +++ b/packages/SystemUI/res/values/arrays_tv.xml @@ -33,4 +33,8 @@ <item>com.google.android.tungsten.setupwraith/.settings.usage.UsageDiagnosticsSettingActivity</item> <item>com.google.android.tvlauncher/.notifications.NotificationsSidePanelActivity</item> </string-array> + + <string-array name="audio_recording_disclosure_exempt_apps" translatable="false"> + <item>com.google.android.katniss</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values/colors_tv.xml b/packages/SystemUI/res/values/colors_tv.xml index 6e56d4a38d0c..db225428a348 100644 --- a/packages/SystemUI/res/values/colors_tv.xml +++ b/packages/SystemUI/res/values/colors_tv.xml @@ -21,4 +21,14 @@ <color name="recents_tv_card_title_text_color">#CCEEEEEE</color> <color name="recents_tv_dismiss_text_color">#7FEEEEEE</color> <color name="recents_tv_text_shadow_color">#7F000000</color> + + + <!-- Text color used in audio recording bar: G50 --> + <color name="tv_audio_recording_bar_text">#FFF8F9FA</color> + <!-- Background color for a chip in audio recording bar: G800 --> + <color name="tv_audio_recording_bar_chip_background">#FF3C4043</color> + <!-- Audio recording bar background color: G900 --> + <color name="tv_audio_recording_bar_background">#FF202124</color> + + <color name="red">#FFCC0000</color> </resources> diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java index e1b723e4d443..949941bc0d84 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java @@ -167,7 +167,7 @@ public class CarrierTextController { mSeparator = separator; mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class); mSimSlotsNumber = ((TelephonyManager) context.getSystemService( - Context.TELEPHONY_SERVICE)).getPhoneCount(); + Context.TELEPHONY_SERVICE)).getMaxPhoneCount(); mSimErrorState = new boolean[mSimSlotsNumber]; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 47d911df90a9..a6b3be23417e 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -219,7 +219,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private final Context mContext; private final boolean mIsPrimaryUser; - HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>(); + HashMap<Integer, SimData> mSimDatas = new HashMap<>(); HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>(); private int mRingMode; @@ -2512,8 +2512,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { @MainThread public void reportSimUnlocked(int subId) { if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")"); - int slotId = SubscriptionManager.getSlotIndex(subId); - handleSimStateChange(subId, slotId, State.READY); + handleSimStateChange(subId, getSlotId(subId), State.READY); } /** @@ -2586,6 +2585,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { } } + private int getSlotId(int subId) { + if (!mSimDatas.containsKey(subId)) { + refreshSimState(subId, SubscriptionManager.getSlotIndex(subId)); + } + return mSimDatas.get(subId).slotId; + } + private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() { @Override @@ -2710,7 +2716,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { for (int i = 0; i < list.size(); i++) { final SubscriptionInfo info = list.get(i); final int id = info.getSubscriptionId(); - int slotId = SubscriptionManager.getSlotIndex(id); + int slotId = getSlotId(id); if (state == getSimState(id) && bestSlotId > slotId) { resultId = id; bestSlotId = slotId; diff --git a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java index 818b5e1c69f4..c4dce1e70051 100644 --- a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java +++ b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java @@ -30,6 +30,7 @@ import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSTileHost; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.StatusBarStateControllerImpl; +import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl; import com.android.systemui.statusbar.phone.ManagedProfileController; import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl; @@ -234,4 +235,10 @@ public abstract class DependencyBinder { */ @Binds public abstract FalsingManager provideFalsingmanager(FalsingManagerProxy falsingManagerImpl); + + /** + */ + @Binds + public abstract SysuiStatusBarStateController providesSysuiStatusBarStateController( + StatusBarStateControllerImpl statusBarStateControllerImpl); } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java index d9b4297f2ae2..ba2dec0ff116 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java @@ -20,6 +20,7 @@ import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.power.PowerUI; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsModule; +import com.android.systemui.util.leak.GarbageMonitor; import dagger.Binds; import dagger.Module; @@ -48,4 +49,10 @@ public abstract class SystemUIBinder { @IntoMap @ClassKey(Recents.class) public abstract SystemUI bindRecents(Recents sysui); + + /** Inject into GarbageMonitor.Service. */ + @Binds + @IntoMap + @ClassKey(GarbageMonitor.Service.class) + public abstract SystemUI bindGarbageMonitorService(GarbageMonitor.Service service); } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java index c70b2fc3292a..bcbe672fbe97 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java @@ -23,7 +23,6 @@ import android.content.ContentProvider; import com.android.systemui.fragments.FragmentService; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.util.InjectionInflationController; -import com.android.systemui.util.leak.GarbageMonitor; import javax.inject.Named; import javax.inject.Singleton; @@ -43,7 +42,7 @@ import dagger.Component; public interface SystemUIRootComponent { /** - * Creates a GarbageMonitor. + * Creates a ContextComponentHelper. */ @Singleton ContextComponentHelper getContextComponentHelper(); @@ -72,12 +71,6 @@ public interface SystemUIRootComponent { InjectionInflationController.ViewCreator createViewCreator(); /** - * Creates a GarbageMonitor. - */ - @Singleton - GarbageMonitor createGarbageMonitor(); - - /** * Whether notification long press is allowed. */ @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/EdgeLight.java b/packages/SystemUI/src/com/android/systemui/assist/ui/EdgeLight.java index 9ae02c5e3104..baa3a4a938c1 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/EdgeLight.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/EdgeLight.java @@ -16,6 +16,8 @@ package com.android.systemui.assist.ui; +import android.util.Log; + import androidx.annotation.ColorInt; /** @@ -29,9 +31,12 @@ import androidx.annotation.ColorInt; * counter-clockwise. */ public final class EdgeLight { + + private static final String TAG = "EdgeLight"; + @ColorInt private int mColor; - private float mOffset; + private float mStart; private float mLength; /** Copies a list of EdgeLights. */ @@ -45,13 +50,13 @@ public final class EdgeLight { public EdgeLight(@ColorInt int color, float offset, float length) { mColor = color; - mOffset = offset; + mStart = offset; mLength = length; } public EdgeLight(EdgeLight sourceLight) { mColor = sourceLight.getColor(); - mOffset = sourceLight.getOffset(); + mStart = sourceLight.getStart(); mLength = sourceLight.getLength(); } @@ -77,23 +82,41 @@ public final class EdgeLight { } /** - * Returns the current offset, in units of the total device perimeter and measured from the - * bottom-left corner (see class description). + * Sets the endpoints of the edge light, both measured from the bottom-left corner (see class + * description). This is a convenience method to avoid separate setStart and setLength calls. */ - public float getOffset() { - return mOffset; + public void setEndpoints(float start, float end) { + if (start > end) { + Log.e(TAG, String.format("Endpoint must be >= start (add 1 if necessary). Got [%f, %f]", + start, end)); + return; + } + mStart = start; + mLength = end - start; + } + + /** + * Returns the current starting position, in units of the total device perimeter and measured + * from the bottom-left corner (see class description). + */ + public float getStart() { + return mStart; } /** * Sets the current offset, in units of the total device perimeter and measured from the * bottom-left corner (see class description). */ - public void setOffset(float offset) { - mOffset = offset; + public void setStart(float start) { + mStart = start; + } + + public float getEnd() { + return mStart + mLength; } /** Returns the center, measured from the bottom-left corner (see class description). */ public float getCenter() { - return mOffset + (mLength / 2.f); + return mStart + (mLength / 2.f); } } diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java index bb3bd781df66..570b911cd400 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java @@ -140,10 +140,10 @@ public class InvocationLightsView extends View float rightStart = mGuide.getRegionWidth(PerimeterPathGuide.Region.BOTTOM) + (cornerLengthNormalized - arcOffsetNormalized) * (1 - progress); - setLight(0, leftStart, lightLength); - setLight(1, leftStart + lightLength, lightLength); - setLight(2, rightStart - (lightLength * 2), lightLength); - setLight(3, rightStart - lightLength, lightLength); + setLight(0, leftStart, leftStart + lightLength); + setLight(1, leftStart + lightLength, leftStart + lightLength * 2); + setLight(2, rightStart - (lightLength * 2), rightStart - lightLength); + setLight(3, rightStart - lightLength, rightStart); setVisibility(View.VISIBLE); } invalidate(); @@ -155,7 +155,7 @@ public class InvocationLightsView extends View public void hide() { setVisibility(GONE); for (EdgeLight light : mAssistInvocationLights) { - light.setLength(0); + light.setEndpoints(0, 0); } attemptUnregisterNavBarListener(); } @@ -235,12 +235,11 @@ public class InvocationLightsView extends View } } - protected void setLight(int index, float offset, float length) { + protected void setLight(int index, float start, float end) { if (index < 0 || index >= 4) { Log.w(TAG, "invalid invocation light index: " + index); } - mAssistInvocationLights.get(index).setOffset(offset); - mAssistInvocationLights.get(index).setLength(length); + mAssistInvocationLights.get(index).setEndpoints(start, end); } /** @@ -268,9 +267,11 @@ public class InvocationLightsView extends View } private void renderLight(EdgeLight light, Canvas canvas) { - mGuide.strokeSegment(mPath, light.getOffset(), light.getOffset() + light.getLength()); - mPaint.setColor(light.getColor()); - canvas.drawPath(mPath, mPaint); + if (light.getLength() > 0) { + mGuide.strokeSegment(mPath, light.getStart(), light.getStart() + light.getLength()); + mPaint.setColor(light.getColor()); + canvas.drawPath(mPath, mPaint); + } } private void attemptRegisterNavBarListener() { diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java index 6b5a780d6647..c6812a75b3bf 100644 --- a/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java +++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java @@ -22,6 +22,7 @@ import static android.opengl.EGL14.EGL_CONFIG_CAVEAT; import static android.opengl.EGL14.EGL_CONTEXT_CLIENT_VERSION; import static android.opengl.EGL14.EGL_DEFAULT_DISPLAY; import static android.opengl.EGL14.EGL_DEPTH_SIZE; +import static android.opengl.EGL14.EGL_EXTENSIONS; import static android.opengl.EGL14.EGL_GREEN_SIZE; import static android.opengl.EGL14.EGL_NONE; import static android.opengl.EGL14.EGL_NO_CONTEXT; @@ -41,6 +42,7 @@ import static android.opengl.EGL14.eglGetDisplay; import static android.opengl.EGL14.eglGetError; import static android.opengl.EGL14.eglInitialize; import static android.opengl.EGL14.eglMakeCurrent; +import static android.opengl.EGL14.eglQueryString; import static android.opengl.EGL14.eglSwapBuffers; import static android.opengl.EGL14.eglTerminate; @@ -64,6 +66,7 @@ public class EglHelper { private static final int EGL_CONTEXT_PRIORITY_LEVEL_IMG = 0x3100; private static final int EGL_CONTEXT_PRIORITY_LOW_IMG = 0x3103; private static final boolean DEBUG = true; + private static final String EGL_IMG_CONTEXT_PRIORITY = "EGL_IMG_context_priority"; private EGLDisplay mEglDisplay; private EGLConfig mEglConfig; @@ -71,6 +74,7 @@ public class EglHelper { private EGLSurface mEglSurface; private final int[] mEglVersion = new int[2]; private boolean mEglReady; + private boolean mContextPrioritySupported; /** * Initialize EGL and prepare EglSurface. @@ -106,10 +110,22 @@ public class EglHelper { return false; } + mContextPrioritySupported = isContextPrioritySuppported(); + mEglReady = true; return true; } + private boolean isContextPrioritySuppported() { + String[] extensions = eglQueryString(mEglDisplay, EGL_EXTENSIONS).split(" "); + for (String extension : extensions) { + if (extension.equals(EGL_IMG_CONTEXT_PRIORITY)) { + return true; + } + } + return false; + } + private EGLConfig chooseEglConfig() { int[] configsCount = new int[1]; EGLConfig[] configs = new EGLConfig[1]; @@ -202,8 +218,15 @@ public class EglHelper { Log.d(TAG, "createEglContext start"); } - int[] attrib_list = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_LOW_IMG, EGL_NONE}; + int[] attrib_list = new int[5]; + int idx = 0; + attrib_list[idx++] = EGL_CONTEXT_CLIENT_VERSION; + attrib_list[idx++] = 2; + if (mContextPrioritySupported) { + attrib_list[idx++] = EGL_CONTEXT_PRIORITY_LEVEL_IMG; + attrib_list[idx++] = EGL_CONTEXT_PRIORITY_LOW_IMG; + } + attrib_list[idx++] = EGL_NONE; if (hasEglDisplay()) { mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attrib_list, 0); } else { diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java index 2542abdbef72..bd3297b3d39c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java @@ -277,20 +277,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta selectPosition(holder.getAdapterPosition(), v); } }); - if (mNeedsFocus) { - // Wait for this to get laid out then set its focus. - // Ensure that tile gets laid out so we get the callback. - holder.mTileView.requestLayout(); - holder.mTileView.addOnLayoutChangeListener(new OnLayoutChangeListener() { - @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, - int oldLeft, int oldTop, int oldRight, int oldBottom) { - holder.mTileView.removeOnLayoutChangeListener(this); - holder.mTileView.requestFocus(); - } - }); - mNeedsFocus = false; - } + focusOnHolder(holder); return; } @@ -330,16 +317,38 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta } else { if (position < mEditIndex && canRemoveTiles()) { showAccessibilityDialog(position, v); + } else if (position < mEditIndex && !canRemoveTiles()) { + startAccessibleMove(position); } else { startAccessibleAdd(position); } } } }); + if (position == mAccessibilityFromIndex) { + focusOnHolder(holder); + } } } } + private void focusOnHolder(Holder holder) { + if (mNeedsFocus) { + // Wait for this to get laid out then set its focus. + // Ensure that tile gets laid out so we get the callback. + holder.mTileView.requestLayout(); + holder.mTileView.addOnLayoutChangeListener(new OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + holder.mTileView.removeOnLayoutChangeListener(this); + holder.mTileView.requestFocus(); + } + }); + mNeedsFocus = false; + } + } + private boolean canRemoveTiles() { return mCurrentSpecs.size() > mMinNumTiles; } @@ -396,6 +405,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta mAccessibilityFromIndex = position; mAccessibilityFromLabel = mTiles.get(position).state.label; mAccessibilityAction = ACTION_MOVE; + mNeedsFocus = true; notifyDataSetChanged(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index 4de42cc2e6c7..22470c7f5af5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -95,6 +95,9 @@ public class CellularTile extends QSTileImpl<SignalState> { @Override public Intent getLongClickIntent() { + if (getState().state == Tile.STATE_UNAVAILABLE) { + return new Intent(Settings.ACTION_WIRELESS_SETTINGS); + } return getCellularSettingIntent(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java index 09f80455a1b0..16cdfaa18a53 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java @@ -237,6 +237,7 @@ public class NavigationBarController implements Callbacks { /** @return {@link AssistHandleViewController} (only on the default display). */ public AssistHandleViewController getAssistHandlerViewController() { - return getDefaultNavigationBarFragment().getAssistHandlerViewController(); + NavigationBarFragment navBar = getDefaultNavigationBarFragment(); + return navBar == null ? null : navBar.getAssistHandlerViewController(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifEvent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifEvent.java new file mode 100644 index 000000000000..2396d28bd46d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifEvent.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 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. + */ + +package com.android.systemui.statusbar.notification.logging; + +import android.annotation.IntDef; +import android.service.notification.NotificationListenerService.Ranking; +import android.service.notification.StatusBarNotification; + +import com.android.systemui.log.RichEvent; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * An event related to notifications. {@link NotifLog} stores and prints these events for debugging + * and triaging purposes. + */ +public class NotifEvent extends RichEvent { + public static final int TOTAL_EVENT_TYPES = 8; + private StatusBarNotification mSbn; + private Ranking mRanking; + + /** + * Creates a NotifEvent with an event type that matches with an index in the array + * getSupportedEvents() and {@link EventType}. + * + * The status bar notification and ranking objects are stored as shallow copies of the current + * state of the event when this event occurred. + */ + public NotifEvent(int logLevel, int type, String reason, StatusBarNotification sbn, + Ranking ranking) { + super(logLevel, type, reason); + mSbn = sbn.clone(); + mRanking = new Ranking(); + mRanking.populate(ranking); + mMessage += getExtraInfo(); + } + + private String getExtraInfo() { + StringBuilder extraInfo = new StringBuilder(); + + if (mSbn != null) { + extraInfo.append(" Sbn="); + extraInfo.append(mSbn); + } + + if (mRanking != null) { + extraInfo.append(" Ranking="); + extraInfo.append(mRanking); + } + + return extraInfo.toString(); + } + + /** + * Event labels for NotifEvents + * Index corresponds to the {@link EventType} + */ + @Override + public String[] getEventLabels() { + final String[] events = new String[]{ + "NotifAdded", + "NotifRemoved", + "NotifUpdated", + "HeadsUpStarted", + "HeadsUpEnded", + "Filter", + "Sort", + "NotifVisibilityChanged", + }; + + if (events.length != TOTAL_EVENT_TYPES) { + throw new IllegalStateException("NotifEvents events.length should match " + + TOTAL_EVENT_TYPES + + " events.length=" + events.length + + " TOTAL_EVENT_LENGTH=" + TOTAL_EVENT_TYPES); + } + return events; + } + + /** + * @return a copy of the status bar notification that changed with this event + */ + public StatusBarNotification getSbn() { + return mSbn; + } + + /** + * Builds a NotifEvent. + */ + public static class NotifEventBuilder extends RichEvent.Builder<NotifEventBuilder> { + private StatusBarNotification mSbn; + private Ranking mRanking; + + @Override + public NotifEventBuilder getBuilder() { + return this; + } + + /** + * Stores the status bar notification object. A shallow copy is stored in the NotifEvent's + * constructor. + */ + public NotifEventBuilder setSbn(StatusBarNotification sbn) { + mSbn = sbn; + return this; + } + + /** + * Stores the ranking object. A shallow copy is stored in the NotifEvent's + * constructor. + */ + public NotifEventBuilder setRanking(Ranking ranking) { + mRanking = ranking; + return this; + } + + @Override + public RichEvent build() { + return new NotifEvent(mLogLevel, mType, mReason, mSbn, mRanking); + } + } + + @IntDef({NOTIF_ADDED, NOTIF_REMOVED, NOTIF_UPDATED, HEADS_UP_STARTED, HEADS_UP_ENDED, FILTER, + SORT, NOTIF_VISIBILITY_CHANGED}) + /** + * Types of NotifEvents + */ + @Retention(RetentionPolicy.SOURCE) + public @interface EventType {} + public static final int NOTIF_ADDED = 0; + public static final int NOTIF_REMOVED = 1; + public static final int NOTIF_UPDATED = 2; + public static final int HEADS_UP_STARTED = 3; + public static final int HEADS_UP_ENDED = 4; + public static final int FILTER = 5; + public static final int SORT = 6; + public static final int NOTIF_VISIBILITY_CHANGED = 7; +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifLog.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifLog.java new file mode 100644 index 000000000000..d42cd82f9784 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifLog.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 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. + */ + +package com.android.systemui.statusbar.notification.logging; + +import android.service.notification.NotificationListenerService.Ranking; +import android.service.notification.StatusBarNotification; + +import com.android.systemui.DumpController; +import com.android.systemui.log.SysuiLog; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Logs systemui notification events for debugging and triaging purposes. Logs are dumped in + * bugreports or on demand: + * adb shell dumpsys activity service com.android.systemui/.SystemUIService \ + * dependency DumpController NotifLog + */ +@Singleton +public class NotifLog extends SysuiLog { + private static final String TAG = "NotifLog"; + private static final int MAX_DOZE_DEBUG_LOGS = 400; + private static final int MAX_DOZE_LOGS = 50; + + @Inject + public NotifLog(DumpController dumpController) { + super(dumpController, TAG, MAX_DOZE_DEBUG_LOGS, MAX_DOZE_LOGS); + } + + /** + * Logs a {@link NotifEvent} with a notification, ranking and message + * @return true if successfully logged, else false + */ + public boolean log(@NotifEvent.EventType int eventType, StatusBarNotification sbn, + Ranking ranking, String msg) { + return log(new NotifEvent.NotifEventBuilder() + .setType(eventType) + .setSbn(sbn) + .setRanking(ranking) + .setReason(msg) + .build()); + } + + /** + * Logs a {@link NotifEvent} + * @return true if successfully logged, else false + */ + public boolean log(@NotifEvent.EventType int eventType) { + return log(eventType, null, null, null); + } + + /** + * Logs a {@link NotifEvent} with a message + * @return true if successfully logged, else false + */ + public boolean log(@NotifEvent.EventType int eventType, String msg) { + return log(eventType, null, null, msg); + } + + /** + * Logs a {@link NotifEvent} with a notification + * @return true if successfully logged, else false + */ + public boolean log(@NotifEvent.EventType int eventType, StatusBarNotification sbn) { + return log(eventType, sbn, null, ""); + } + + /** + * Logs a {@link NotifEvent} with a ranking + * @return true if successfully logged, else false + */ + public boolean log(@NotifEvent.EventType int eventType, Ranking ranking) { + return log(eventType, null, ranking, ""); + } + + /** + * Logs a {@link NotifEvent} with a notification and ranking + * @return true if successfully logged, else false + */ + public boolean log(@NotifEvent.EventType int eventType, StatusBarNotification sbn, + Ranking ranking) { + return log(eventType, sbn, ranking, ""); + } + + /** + * Logs a {@link NotifEvent} with a notification entry + * @return true if successfully logged, else false + */ + public boolean log(@NotifEvent.EventType int eventType, NotificationEntry entry) { + return log(eventType, entry.sbn(), entry.ranking(), ""); + } + + /** + * Logs a {@link NotifEvent} with a notification entry + * @return true if successfully logged, else false + */ + public boolean log(@NotifEvent.EventType int eventType, NotificationEntry entry, + String msg) { + return log(eventType, entry.sbn(), entry.ranking(), msg); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index bd9ce3acb114..5ba19cca6532 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -41,6 +41,7 @@ import com.android.internal.graphics.ColorUtils; import com.android.internal.util.function.TriConsumer; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; +import com.android.systemui.DejankUtils; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.R; @@ -311,10 +312,12 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo // Docking pulses may take a long time, wallpapers should also fade away after a while. mWallpaperVisibilityTimedOut = false; if (shouldFadeAwayWallpaper()) { - mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(), - AlarmTimeout.MODE_IGNORE_IF_SCHEDULED); + DejankUtils.postAfterTraversal(() -> { + mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(), + AlarmTimeout.MODE_IGNORE_IF_SCHEDULED); + }); } else { - mTimeTicker.cancel(); + DejankUtils.postAfterTraversal(mTimeTicker::cancel); } if (mKeyguardUpdateMonitor.needsSlowUnlockTransition() && mState == ScrimState.UNLOCKED) { @@ -430,8 +433,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo // and docking. if (mWallpaperVisibilityTimedOut) { mWallpaperVisibilityTimedOut = false; - mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(), - AlarmTimeout.MODE_IGNORE_IF_SCHEDULED); + DejankUtils.postAfterTraversal(() -> { + mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(), + AlarmTimeout.MODE_IGNORE_IF_SCHEDULED); + }); } } } @@ -754,6 +759,16 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo } private void onFinished(Callback callback) { + if (!hasReachedFinalState(mScrimBehind) + || !hasReachedFinalState(mScrimInFront) + || !hasReachedFinalState(mScrimForBubble)) { + if (callback != null && callback != mCallback) { + // Since we only notify the callback that we're finished once everything has + // finished, we need to make sure that any changing callbacks are also invoked + callback.onFinished(); + } + return; + } if (mWakeLockHeld) { mWakeLock.release(TAG); mWakeLockHeld = false; @@ -773,9 +788,17 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo mInFrontTint = Color.TRANSPARENT; mBehindTint = Color.TRANSPARENT; mBubbleTint = Color.TRANSPARENT; + updateScrimColor(mScrimInFront, mInFrontAlpha, mInFrontTint); + updateScrimColor(mScrimBehind, mBehindAlpha, mBehindTint); + updateScrimColor(mScrimForBubble, mBubbleAlpha, mBubbleTint); } } + private boolean hasReachedFinalState(ScrimView scrim) { + return scrim.getViewAlpha() == getCurrentScrimAlpha(scrim) + && scrim.getTint() == getCurrentScrimTint(scrim); + } + private boolean isAnimating(View scrim) { return scrim.getTag(TAG_KEY_ANIM) != null; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 5fc2d9beab89..e79f14175377 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -347,10 +347,10 @@ public class StatusBar extends SystemUI implements DemoMode, private BrightnessMirrorController mBrightnessMirrorController; private boolean mBrightnessMirrorVisible; protected BiometricUnlockController mBiometricUnlockController; - private LightBarController mLightBarController; + @Inject LightBarController mLightBarController; protected LockscreenWallpaper mLockscreenWallpaper; @VisibleForTesting - protected AutoHideController mAutoHideController; + @Inject AutoHideController mAutoHideController; private int mNaturalBarHeight = -1; @@ -361,7 +361,7 @@ public class StatusBar extends SystemUI implements DemoMode, private int mStatusBarWindowState = WINDOW_STATE_SHOWING; protected StatusBarWindowController mStatusBarWindowController; @VisibleForTesting - KeyguardUpdateMonitor mKeyguardUpdateMonitor; + @Inject KeyguardUpdateMonitor mKeyguardUpdateMonitor; @VisibleForTesting DozeServiceHost mDozeServiceHost = new DozeServiceHost(); private boolean mWakeUpComingFromTouch; @@ -369,7 +369,7 @@ public class StatusBar extends SystemUI implements DemoMode, private final Object mQueueLock = new Object(); - protected StatusBarIconController mIconController; + @Inject StatusBarIconController mIconController; @Inject DozeLog mDozeLog; @Inject @@ -400,7 +400,7 @@ public class StatusBar extends SystemUI implements DemoMode, protected FalsingManager mFalsingManager; @VisibleForTesting - BroadcastDispatcher mBroadcastDispatcher; + @Inject BroadcastDispatcher mBroadcastDispatcher; // expanded notifications protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window @@ -413,8 +413,7 @@ public class StatusBar extends SystemUI implements DemoMode, // RemoteInputView to be activated after unlock private View mPendingRemoteInputView; - private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler = - Dependency.get(RemoteInputQuickSettingsDisabler.class); + @Inject RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler; private View mReportRejectedTouch; @@ -423,18 +422,17 @@ public class StatusBar extends SystemUI implements DemoMode, private final int[] mAbsPos = new int[2]; private final ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>(); - private NotificationGutsManager mGutsManager; - protected NotificationLogger mNotificationLogger; - protected NotificationEntryManager mEntryManager; + @Inject NotificationGutsManager mGutsManager; + @Inject NotificationLogger mNotificationLogger; + @Inject NotificationEntryManager mEntryManager; private NotificationListController mNotificationListController; - private NotificationInterruptionStateProvider mNotificationInterruptionStateProvider; - protected NotificationViewHierarchyManager mViewHierarchyManager; - protected ForegroundServiceController mForegroundServiceController; - protected AppOpsController mAppOpsController; - protected KeyguardViewMediator mKeyguardViewMediator; - private ZenModeController mZenController; - private final NotificationAlertingManager mNotificationAlertingManager = - Dependency.get(NotificationAlertingManager.class); + @Inject NotificationInterruptionStateProvider mNotificationInterruptionStateProvider; + @Inject NotificationViewHierarchyManager mViewHierarchyManager; + @Inject ForegroundServiceController mForegroundServiceController; + @Inject AppOpsController mAppOpsController; + @Inject KeyguardViewMediator mKeyguardViewMediator; + @Inject ZenModeController mZenController; + @Inject NotificationAlertingManager mNotificationAlertingManager; // for disabling the status bar private int mDisabled1 = 0; @@ -445,7 +443,7 @@ public class StatusBar extends SystemUI implements DemoMode, private final Rect mLastFullscreenStackBounds = new Rect(); private final Rect mLastDockedStackBounds = new Rect(); - private final DisplayMetrics mDisplayMetrics = Dependency.get(DisplayMetrics.class); + @Inject DisplayMetrics mDisplayMetrics; // XXX: gesture research private final GestureRecorder mGestureRec = DEBUG_GESTURES @@ -454,7 +452,7 @@ public class StatusBar extends SystemUI implements DemoMode, private ScreenPinningRequest mScreenPinningRequest; - private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class); + @Inject MetricsLogger mMetricsLogger; // ensure quick settings is disabled until the current user makes it through the setup wizard @VisibleForTesting @@ -491,14 +489,14 @@ public class StatusBar extends SystemUI implements DemoMode, private ViewMediatorCallback mKeyguardViewMediatorCallback; protected ScrimController mScrimController; protected DozeScrimController mDozeScrimController; - private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class); + @Inject UiOffloadThread mUiOffloadThread; protected boolean mDozing; private boolean mDozingRequested; - private NotificationMediaManager mMediaManager; - protected NotificationLockscreenUserManager mLockscreenUserManager; - protected NotificationRemoteInputManager mRemoteInputManager; + @Inject NotificationMediaManager mMediaManager; + @Inject NotificationLockscreenUserManager mLockscreenUserManager; + @Inject NotificationRemoteInputManager mRemoteInputManager; private boolean mWallpaperSupported; private final BroadcastReceiver mWallpaperChangedReceiver = new BroadcastReceiver() { @@ -569,18 +567,18 @@ public class StatusBar extends SystemUI implements DemoMode, }; private KeyguardUserSwitcher mKeyguardUserSwitcher; - protected UserSwitcherController mUserSwitcherController; - private NetworkController mNetworkController; - private BatteryController mBatteryController; + @Inject UserSwitcherController mUserSwitcherController; + @Inject NetworkController mNetworkController; + @Inject BatteryController mBatteryController; protected boolean mPanelExpanded; private UiModeManager mUiModeManager; protected boolean mIsKeyguard; private LogMaker mStatusBarStateLog; protected NotificationIconAreaController mNotificationIconAreaController; @Nullable private View mAmbientIndicationContainer; - private SysuiColorExtractor mColorExtractor; - private ScreenLifecycle mScreenLifecycle; - @VisibleForTesting WakefulnessLifecycle mWakefulnessLifecycle; + @Inject SysuiColorExtractor mColorExtractor; + @Inject ScreenLifecycle mScreenLifecycle; + @Inject @VisibleForTesting WakefulnessLifecycle mWakefulnessLifecycle; private final View.OnClickListener mGoToLockedShadeListener = v -> { if (mState == StatusBarState.KEYGUARD) { @@ -589,8 +587,7 @@ public class StatusBar extends SystemUI implements DemoMode, } }; private boolean mNoAnimationOnNextBarModeChange; - private final SysuiStatusBarStateController mStatusBarStateController = - (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class); + @Inject SysuiStatusBarStateController mStatusBarStateController; private final KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() { @@ -611,19 +608,18 @@ public class StatusBar extends SystemUI implements DemoMode, private HeadsUpAppearanceController mHeadsUpAppearanceController; private boolean mVibrateOnOpening; - private VibratorHelper mVibratorHelper; + @Inject VibratorHelper mVibratorHelper; private ActivityLaunchAnimator mActivityLaunchAnimator; protected StatusBarNotificationPresenter mPresenter; private NotificationActivityStarter mNotificationActivityStarter; private boolean mPulsing; - protected BubbleController mBubbleController; + @Inject BubbleController mBubbleController; private final BubbleController.BubbleExpandListener mBubbleExpandListener = (isExpanding, key) -> { mEntryManager.updateNotifications(); updateScrimController(); }; private ActivityIntentHelper mActivityIntentHelper; - private ShadeController mShadeController; @Override public void onActiveStateChanged(int code, int uid, String packageName, boolean active) { @@ -641,41 +637,13 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void start() { - mGroupManager = Dependency.get(NotificationGroupManager.class); - mGroupAlertTransferHelper = Dependency.get(NotificationGroupAlertTransferHelper.class); - mVisualStabilityManager = Dependency.get(VisualStabilityManager.class); - mNotificationLogger = Dependency.get(NotificationLogger.class); - mRemoteInputManager = Dependency.get(NotificationRemoteInputManager.class); - mNotificationListener = Dependency.get(NotificationListener.class); mNotificationListener.registerAsSystemService(); - mNetworkController = Dependency.get(NetworkController.class); - mUserSwitcherController = Dependency.get(UserSwitcherController.class); - mScreenLifecycle = Dependency.get(ScreenLifecycle.class); mScreenLifecycle.addObserver(mScreenObserver); - mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class); mWakefulnessLifecycle.addObserver(mWakefulnessObserver); - mBatteryController = Dependency.get(BatteryController.class); - mAssistManager = Dependency.get(AssistManager.class); mUiModeManager = mContext.getSystemService(UiModeManager.class); - mLockscreenUserManager = Dependency.get(NotificationLockscreenUserManager.class); - mGutsManager = Dependency.get(NotificationGutsManager.class); - mMediaManager = Dependency.get(NotificationMediaManager.class); - mEntryManager = Dependency.get(NotificationEntryManager.class); mBypassHeadsUpNotifier.setUp(mEntryManager); - mNotificationInterruptionStateProvider = - Dependency.get(NotificationInterruptionStateProvider.class); - mViewHierarchyManager = Dependency.get(NotificationViewHierarchyManager.class); - mForegroundServiceController = Dependency.get(ForegroundServiceController.class); - mAppOpsController = Dependency.get(AppOpsController.class); - mZenController = Dependency.get(ZenModeController.class); - mKeyguardViewMediator = getComponent(KeyguardViewMediator.class); - mColorExtractor = Dependency.get(SysuiColorExtractor.class); - mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class); - mNavigationBarController = Dependency.get(NavigationBarController.class); - mBubbleController = Dependency.get(BubbleController.class); mBubbleController.setExpandListener(mBubbleExpandListener); mActivityIntentHelper = new ActivityIntentHelper(mContext); - mBroadcastDispatcher = Dependency.get(BroadcastDispatcher.class); KeyguardSliceProvider sliceProvider = KeyguardSliceProvider.getAttachedInstance(); if (sliceProvider != null) { sliceProvider.initDependencies(mMediaManager, mStatusBarStateController, @@ -698,7 +666,6 @@ public class StatusBar extends SystemUI implements DemoMode, mVibrateOnOpening = mContext.getResources().getBoolean( R.bool.config_vibrateOnIconAnimation); - mVibratorHelper = Dependency.get(VibratorHelper.class); DateTimeView.setReceiverHandler(Dependency.get(Dependency.TIME_TICK_HANDLER)); putComponent(StatusBar.class, this); @@ -712,7 +679,6 @@ public class StatusBar extends SystemUI implements DemoMode, mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); - mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class); mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController); mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); @@ -901,7 +867,6 @@ public class StatusBar extends SystemUI implements DemoMode, .replace(R.id.status_bar_container, new CollapsedStatusBarFragment(), CollapsedStatusBarFragment.TAG) .commit(); - mIconController = Dependency.get(StatusBarIconController.class); mHeadsUpManager.setUp(mStatusBarWindow, mGroupManager, this, mVisualStabilityManager); Dependency.get(ConfigurationController.class).addCallback(mHeadsUpManager); @@ -947,11 +912,8 @@ public class StatusBar extends SystemUI implements DemoMode, } }); - mAutoHideController = Dependency.get(AutoHideController.class); mAutoHideController.setStatusBar(this); - mLightBarController = Dependency.get(LightBarController.class); - ScrimView scrimBehind = mStatusBarWindow.findViewById(R.id.scrim_behind); ScrimView scrimInFront = mStatusBarWindow.findViewById(R.id.scrim_in_front); ScrimView scrimForBubble = mStatusBarWindow.findViewById(R.id.scrim_for_bubble); @@ -1123,7 +1085,6 @@ public class StatusBar extends SystemUI implements DemoMode, final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback = (StatusBarRemoteInputCallback) Dependency.get( NotificationRemoteInputManager.Callback.class); - mShadeController = Dependency.get(ShadeController.class); final ActivityStarter activityStarter = Dependency.get(ActivityStarter.class); mNotificationActivityStarter = new StatusBarNotificationActivityStarter(mContext, @@ -1131,7 +1092,7 @@ public class StatusBar extends SystemUI implements DemoMode, mHeadsUpManager, activityStarter, mActivityLaunchAnimator, mBarService, mStatusBarStateController, mKeyguardManager, mDreamManager, mRemoteInputManager, mStatusBarRemoteInputCallback, mGroupManager, - mLockscreenUserManager, mShadeController, mKeyguardStateController, + mLockscreenUserManager, this, mKeyguardStateController, mNotificationInterruptionStateProvider, mMetricsLogger, new LockPatternUtils(mContext), Dependency.get(MAIN_HANDLER), Dependency.get(BG_HANDLER), mActivityIntentHelper, mBubbleController); @@ -1140,7 +1101,7 @@ public class StatusBar extends SystemUI implements DemoMode, mEntryManager.setRowBinder(rowBinder); rowBinder.setNotificationClicker(new NotificationClicker( - this, Dependency.get(BubbleController.class), mNotificationActivityStarter)); + this, mBubbleController, mNotificationActivityStarter)); mGroupAlertTransferHelper.bind(mEntryManager, mGroupManager); mNotificationListController.bind(); @@ -4227,12 +4188,11 @@ public class StatusBar extends SystemUI implements DemoMode, // all notifications protected ViewGroup mStackScroller; - protected NotificationGroupManager mGroupManager; - - protected NotificationGroupAlertTransferHelper mGroupAlertTransferHelper; + @Inject NotificationGroupManager mGroupManager; + @Inject NotificationGroupAlertTransferHelper mGroupAlertTransferHelper; // handling reordering - protected VisualStabilityManager mVisualStabilityManager; + @Inject VisualStabilityManager mVisualStabilityManager; protected AccessibilityManager mAccessibilityManager; @@ -4248,10 +4208,9 @@ public class StatusBar extends SystemUI implements DemoMode, protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; protected KeyguardManager mKeyguardManager; - private DeviceProvisionedController mDeviceProvisionedController - = Dependency.get(DeviceProvisionedController.class); + @Inject DeviceProvisionedController mDeviceProvisionedController; - protected NavigationBarController mNavigationBarController; + @Inject protected NavigationBarController mNavigationBarController; // UI-specific methods @@ -4267,7 +4226,7 @@ public class StatusBar extends SystemUI implements DemoMode, protected NotificationShelf mNotificationShelf; protected EmptyShadeView mEmptyShadeView; - protected AssistManager mAssistManager; + @Inject AssistManager mAssistManager; public boolean isDeviceInteractive() { return mDeviceInteractive; @@ -4326,7 +4285,7 @@ public class StatusBar extends SystemUI implements DemoMode, } } - protected NotificationListener mNotificationListener; + @Inject NotificationListener mNotificationListener; public void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) { if (snoozeOption.getSnoozeCriterion() != null) { @@ -4462,8 +4421,7 @@ public class StatusBar extends SystemUI implements DemoMode, executeActionDismissingKeyguard(() -> { try { intent.send(null, 0, null, null, null, null, getActivityOptions( - mActivityLaunchAnimator.getLaunchAnimation(associatedView, - mShadeController.isOccluded()))); + mActivityLaunchAnimator.getLaunchAnimation(associatedView, isOccluded()))); } catch (PendingIntent.CanceledException e) { // the stack trace isn't very helpful here. // Just log the exception message. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/AudioRecordingDisclosureBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/AudioRecordingDisclosureBar.java new file mode 100644 index 000000000000..d6d0a3603c25 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/AudioRecordingDisclosureBar.java @@ -0,0 +1,203 @@ +/* + * Copyright (C) 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. + */ + +package com.android.systemui.statusbar.tv; + +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; + +import android.app.AppOpsManager; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.graphics.PixelFormat; +import android.graphics.drawable.Drawable; +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.view.WindowManager; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.systemui.R; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +class AudioRecordingDisclosureBar { + private static final String TAG = "AudioRecordingDisclosureBar"; + private static final boolean DEBUG = false; + + private static final String LAYOUT_PARAMS_TITLE = "AudioRecordingDisclosureBar"; + private static final int ANIM_DURATION_MS = 150; + + private final Context mContext; + private final List<String> mAudioRecordingApps = new ArrayList<>(); + private View mView; + private ViewGroup mAppsInfoContainer; + + AudioRecordingDisclosureBar(Context context) { + mContext = context; + } + + void start() { + // Inflate and add audio recording disclosure bar + createView(); + + // Register AppOpsManager callback + final AppOpsManager appOpsManager = (AppOpsManager) mContext.getSystemService( + Context.APP_OPS_SERVICE); + appOpsManager.startWatchingActive( + new String[]{AppOpsManager.OPSTR_RECORD_AUDIO}, mContext.getMainExecutor(), + new OnActiveRecordingListener()); + } + + private void createView() { + mView = View.inflate(mContext, + R.layout.tv_status_bar_audio_recording, null); + mAppsInfoContainer = mView.findViewById(R.id.container); + + final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( + MATCH_PARENT, + WRAP_CONTENT, + WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, + PixelFormat.TRANSLUCENT); + layoutParams.gravity = Gravity.BOTTOM; + layoutParams.setTitle(LAYOUT_PARAMS_TITLE); + layoutParams.packageName = mContext.getPackageName(); + + final WindowManager windowManager = (WindowManager) mContext.getSystemService( + Context.WINDOW_SERVICE); + windowManager.addView(mView, layoutParams); + + // Set invisible first util it gains its actual size and we are able to hide it by moving + // off the screen + mView.setVisibility(View.INVISIBLE); + mView.getViewTreeObserver().addOnGlobalLayoutListener( + new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + // Now that we get the height, we can move the bar off ("below") the screen + final int height = mView.getHeight(); + mView.setTranslationY(height); + // ... and make it visible + mView.setVisibility(View.VISIBLE); + // Remove the observer + mView.getViewTreeObserver() + .removeOnGlobalLayoutListener(this); + } + }); + } + + private void showAudioRecordingDisclosureBar() { + mView.animate() + .translationY(0f) + .setDuration(ANIM_DURATION_MS) + .start(); + } + + private void addToAudioRecordingDisclosureBar(String packageName) { + final PackageManager pm = mContext.getPackageManager(); + final ApplicationInfo appInfo; + try { + appInfo = pm.getApplicationInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + return; + } + final CharSequence label = pm.getApplicationLabel(appInfo); + final Drawable icon = pm.getApplicationIcon(appInfo); + + final View view = LayoutInflater.from(mContext).inflate(R.layout.tv_item_app_info, + mAppsInfoContainer, false); + ((TextView) view.findViewById(R.id.title)).setText(label); + ((ImageView) view.findViewById(R.id.icon)).setImageDrawable(icon); + + mAppsInfoContainer.addView(view); + } + + private void removeFromAudioRecordingDisclosureBar(int index) { + mAppsInfoContainer.removeViewAt(index); + } + + private void hideAudioRecordingDisclosureBar() { + mView.animate() + .translationY(mView.getHeight()) + .setDuration(ANIM_DURATION_MS) + .start(); + } + + private class OnActiveRecordingListener implements AppOpsManager.OnOpActiveChangedListener { + private final List<String> mExemptApps; + + private OnActiveRecordingListener() { + mExemptApps = Arrays.asList(mContext.getResources().getStringArray( + R.array.audio_recording_disclosure_exempt_apps)); + } + + @Override + public void onOpActiveChanged(String op, int uid, String packageName, boolean active) { + if (DEBUG) { + Log.d(TAG, + "OP_RECORD_AUDIO active change, active" + active + ", app=" + packageName); + } + + if (mExemptApps.contains(packageName)) { + if (DEBUG) { + Log.d(TAG, "\t- exempt app"); + } + return; + } + + final boolean alreadyTracking = mAudioRecordingApps.contains(packageName); + if ((active && alreadyTracking) || (!active && !alreadyTracking)) { + if (DEBUG) { + Log.d(TAG, "\t- nothing changed"); + } + return; + } + + if (active) { + if (DEBUG) { + Log.d(TAG, "\t- new recording app"); + } + + if (mAudioRecordingApps.isEmpty()) { + showAudioRecordingDisclosureBar(); + } + + mAudioRecordingApps.add(packageName); + addToAudioRecordingDisclosureBar(packageName); + } else { + if (DEBUG) { + Log.d(TAG, "\t- not recording any more"); + } + + final int index = mAudioRecordingApps.indexOf(packageName); + removeFromAudioRecordingDisclosureBar(index); + mAudioRecordingApps.remove(index); + + if (mAudioRecordingApps.isEmpty()) { + hideAudioRecordingDisclosureBar(); + } + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java index 17d9cbe3af07..b80b6d54427c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java @@ -23,28 +23,33 @@ import android.os.ServiceManager; import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.SystemUI; import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.CommandQueue.Callbacks; + /** - * Status bar implementation for "large screen" products that mostly present no on-screen nav + * Status bar implementation for "large screen" products that mostly present no on-screen nav. + * Serves as a collection of UI components, rather than showing its own UI. + * The following is the list of elements that constitute the TV-specific status bar: + * <ul> + * <li> {@link AudioRecordingDisclosureBar} - shown whenever applications are conducting audio + * recording, discloses the responsible applications </li> + * </ul> */ - -public class TvStatusBar extends SystemUI implements Callbacks { - - private IStatusBarService mBarService; +public class TvStatusBar extends SystemUI implements CommandQueue.Callbacks { @Override public void start() { putComponent(TvStatusBar.class, this); - CommandQueue commandQueue = getComponent(CommandQueue.class); - commandQueue.addCallback(this); - mBarService = IStatusBarService.Stub.asInterface( + + final IStatusBarService barService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); + final CommandQueue commandQueue = getComponent(CommandQueue.class); + commandQueue.addCallback(this); try { - mBarService.registerStatusBar(commandQueue); + barService.registerStatusBar(commandQueue); } catch (RemoteException ex) { // If the system process isn't there we're doomed anyway. } - } + new AudioRecordingDisclosureBar(mContext).start(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java index 583f6b340d47..db4390686cd9 100644 --- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java +++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java @@ -49,7 +49,7 @@ import android.util.LongSparseArray; import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.SystemUI; -import com.android.systemui.SystemUIFactory; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.tileimpl.QSTileImpl; @@ -387,13 +387,15 @@ public class GarbageMonitor implements Dumpable { public static final boolean ADD_TO_DEFAULT_ON_DEBUGGABLE_BUILDS = true; private final GarbageMonitor gm; + private final ActivityStarter mActivityStarter; private ProcessMemInfo pmi; private boolean dumpInProgress; @Inject - public MemoryTile(QSHost host) { + public MemoryTile(QSHost host, GarbageMonitor monitor, ActivityStarter starter) { super(host); - gm = SystemUIFactory.getInstance().getRootComponent().createGarbageMonitor(); + gm = monitor; + mActivityStarter = starter; } @Override @@ -424,7 +426,7 @@ public class GarbageMonitor implements Dumpable { dumpInProgress = false; refreshState(); getHost().collapsePanels(); - mContext.startActivity(shareIntent); + mActivityStarter.postStartActivityDismissingKeyguard(shareIntent, 0); }); } }.start(); @@ -535,7 +537,12 @@ public class GarbageMonitor implements Dumpable { /** */ public static class Service extends SystemUI implements Dumpable { - private GarbageMonitor mGarbageMonitor; + private final GarbageMonitor mGarbageMonitor; + + @Inject + public Service(GarbageMonitor garbageMonitor) { + mGarbageMonitor = garbageMonitor; + } @Override public void start() { @@ -543,8 +550,6 @@ public class GarbageMonitor implements Dumpable { Settings.Secure.getInt( mContext.getContentResolver(), FORCE_ENABLE_LEAK_REPORTING, 0) != 0; - mGarbageMonitor = SystemUIFactory.getInstance().getRootComponent() - .createGarbageMonitor(); if (LEAK_REPORTING_ENABLED || forceEnable) { mGarbageMonitor.startLeakMonitor(); } diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java index edea92f5952a..2c70fb4c50ec 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java @@ -621,7 +621,9 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa .PRIORITY_CATEGORY_MEDIA) == 0; boolean disallowSystem = (policy.priorityCategories & NotificationManager.Policy .PRIORITY_CATEGORY_SYSTEM) == 0; - boolean disallowRinger = ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(policy); + // ringer controls notifications, ringer and system sounds, so only disallow ringer changes + // if all relevant (notifications + ringer + system) sounds are not allowed to bypass DND + boolean disallowRinger = ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(policy); if (mState.disallowAlarms == disallowAlarms && mState.disallowMedia == disallowMedia && mState.disallowRinger == disallowRinger diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java index 2e94c7c12cd8..ede717b6c575 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java @@ -125,7 +125,7 @@ public class CarrierTextControllerTest extends SysuiTestCase { mCarrierTextCallbackInfo = new CarrierTextController.CarrierTextCallbackInfo("", new CharSequence[]{}, false, new int[]{}); - when(mTelephonyManager.getPhoneCount()).thenReturn(3); + when(mTelephonyManager.getMaxPhoneCount()).thenReturn(3); mCarrierTextController = new TestCarrierTextController(mContext, SEPARATOR, true, true, mKeyguardUpdateMonitor); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java index 7d2ccdc8f0a9..618272cbcab0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java @@ -28,6 +28,7 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -240,4 +241,10 @@ public class NavigationBarControllerTest extends SysuiTestCase { verify(mSecondaryNavBar).disableAnimationsDuringHide(eq(500L)); } + + @Test + public void testGetAssistHandlerViewController_noCrash() { + reset(mNavigationBarController.mNavigationBars); + mNavigationBarController.getAssistHandlerViewController(); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java index 0bff5aa9e991..237f6ac0f420 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java @@ -80,7 +80,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; @RunWith(AndroidTestingRunner.class) -@RunWithLooper() +@RunWithLooper(setAsMainLooper = true) @SmallTest public class NavigationBarFragmentTest extends SysuiBaseFragmentTest { private static final int EXTERNAL_DISPLAY_ID = 2; @@ -217,7 +217,7 @@ public class NavigationBarFragmentTest extends SysuiBaseFragmentTest { // Set IME window status for default NavBar. mCommandQueue.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE, BACK_DISPOSITION_DEFAULT, true, false); - Handler.getMain().runWithScissors(() -> { }, 500); + processAllMessages(); // Verify IME window state will be updated in default NavBar & external NavBar state reset. assertEquals(NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN, @@ -228,7 +228,7 @@ public class NavigationBarFragmentTest extends SysuiBaseFragmentTest { // Set IME window status for external NavBar. mCommandQueue.setImeWindowStatus(EXTERNAL_DISPLAY_ID, null, IME_VISIBLE, BACK_DISPOSITION_DEFAULT, true, false); - Handler.getMain().runWithScissors(() -> { }, 500); + processAllMessages(); // Verify IME window state will be updated in external NavBar & default NavBar state reset. assertEquals(NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java index f1aaf3dbd055..214e26a4a2b5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java @@ -46,6 +46,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.colorextraction.ColorExtractor.GradientColors; import com.android.internal.util.function.TriConsumer; import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.systemui.DejankUtils; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.ScrimView; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -95,6 +96,7 @@ public class ScrimControllerTest extends SysuiTestCase { mDependency.injectMockDependency(KeyguardUpdateMonitor.class); when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled); when(mDozeParamenters.getDisplayNeedsBlanking()).thenReturn(true); + DejankUtils.setImmediate(true); mScrimController = new SynchronousScrimController(mScrimBehind, mScrimInFront, mScrimForBubble, (scrimState, scrimBehindAlpha, scrimInFrontColor) -> { @@ -113,6 +115,7 @@ public class ScrimControllerTest extends SysuiTestCase { @After public void tearDown() { mScrimController.finishAnimationsImmediately(); + DejankUtils.setImmediate(false); } @Test @@ -433,6 +436,7 @@ public class ScrimControllerTest extends SysuiTestCase { TRANSPARENT /* behind */, TRANSPARENT /* bubble */); + // Make sure at the very end of the animation, we're reset to transparent assertScrimTint(false /* front */, false /* behind */, false /* bubble */); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java index 32b0f76b2441..f163886193b4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java @@ -59,6 +59,7 @@ import android.support.test.metricshelper.MetricsAsserts; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; +import android.util.DisplayMetrics; import android.util.SparseArray; import android.view.ViewGroup.LayoutParams; @@ -73,16 +74,19 @@ import com.android.systemui.Dependency; import com.android.systemui.ForegroundServiceController; import com.android.systemui.InitController; import com.android.systemui.R; -import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; import com.android.systemui.UiOffloadThread; import com.android.systemui.appops.AppOpsController; import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.bubbles.BubbleController; +import com.android.systemui.classifier.FalsingManagerFake; +import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.doze.DozeEvent; import com.android.systemui.doze.DozeHost; +import com.android.systemui.doze.DozeLog; import com.android.systemui.keyguard.KeyguardViewMediator; +import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; import com.android.systemui.plugins.FalsingManager; @@ -98,14 +102,18 @@ import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.NotificationViewHierarchyManager; +import com.android.systemui.statusbar.PulseExpansionHandler; import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.StatusBarStateControllerImpl; +import com.android.systemui.statusbar.SysuiStatusBarStateController; +import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier; import com.android.systemui.statusbar.notification.NotificationAlertingManager; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationFilter; import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider; +import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.NotificationData; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -116,6 +124,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler; import com.android.systemui.statusbar.policy.UserSwitcherController; import org.junit.Before; @@ -133,7 +142,7 @@ import java.util.HashSet; @SmallTest @RunWith(AndroidTestingRunner.class) -@RunWithLooper +@RunWithLooper(setAsMainLooper = true) public class StatusBarTest extends SysuiTestCase { @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; @Mock private KeyguardStateController mKeyguardStateController; @@ -148,10 +157,7 @@ public class StatusBarTest extends SysuiTestCase { @Mock private ArrayList<NotificationEntry> mNotificationList; @Mock private BiometricUnlockController mBiometricUnlockController; @Mock private NotificationData mNotificationData; - @Mock - private NotificationInterruptionStateProvider.HeadsUpSuppressor mHeadsUpSuppressor; - - // Mock dependencies: + @Mock private NotificationInterruptionStateProvider.HeadsUpSuppressor mHeadsUpSuppressor; @Mock private NotificationViewHierarchyManager mViewHierarchyManager; @Mock private VisualStabilityManager mVisualStabilityManager; @Mock private NotificationListener mNotificationListener; @@ -163,51 +169,38 @@ public class StatusBarTest extends SysuiTestCase { @Mock private BatteryController mBatteryController; @Mock private DeviceProvisionedController mDeviceProvisionedController; @Mock private StatusBarNotificationPresenter mNotificationPresenter; - @Mock - private NotificationEntryListener mEntryListener; - @Mock - private NotificationFilter mNotificationFilter; - @Mock - private NotificationAlertingManager mNotificationAlertingManager; - @Mock - private NotificationLogger.ExpansionStateLogger mExpansionStateLogger; - @Mock - private KeyguardUpdateMonitor mKeyguardUpdateMonitor; - @Mock - private AmbientDisplayConfiguration mAmbientDisplayConfiguration; - @Mock - private StatusBarWindowView mStatusBarWindowView; - @Mock - private BroadcastDispatcher mBroadcastDispatcher; + @Mock private NotificationEntryListener mEntryListener; + @Mock private NotificationFilter mNotificationFilter; + @Mock private NotificationAlertingManager mNotificationAlertingManager; + @Mock private NotificationLogger.ExpansionStateLogger mExpansionStateLogger; + @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor; + @Mock private AmbientDisplayConfiguration mAmbientDisplayConfiguration; + @Mock private StatusBarWindowView mStatusBarWindowView; + @Mock private BroadcastDispatcher mBroadcastDispatcher; + @Mock private AssistManager mAssistManager; + @Mock private NotificationGutsManager mNotificationGutsManager; + @Mock private NotificationMediaManager mNotificationMediaManager; + @Mock private ForegroundServiceController mForegroundServiceController; + @Mock private AppOpsController mAppOpsController; + @Mock private NavigationBarController mNavigationBarController; + @Mock private BypassHeadsUpNotifier mBypassHeadsUpNotifier; + @Mock private SysuiColorExtractor mColorExtractor; + @Mock private DozeLog mDozeLog; + @Mock private PulseExpansionHandler mPulseExpansionHandler; + @Mock private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler; + @Mock private NotificationWakeUpCoordinator mNotificationWakeUpCoordinator; + @Mock private KeyguardBypassController mKeyguardBypassController; private TestableStatusBar mStatusBar; private FakeMetricsLogger mMetricsLogger; private PowerManager mPowerManager; - private TestableNotificationEntryManager mEntryManager; private TestableNotificationInterruptionStateProvider mNotificationInterruptionStateProvider; - private NotificationLogger mNotificationLogger; private CommandQueue mCommandQueue; @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); - mDependency.injectMockDependency(AssistManager.class); - mDependency.injectMockDependency(NotificationGutsManager.class); - mDependency.injectMockDependency(NotificationMediaManager.class); - mDependency.injectMockDependency(ForegroundServiceController.class); - mDependency.injectTestDependency(NotificationViewHierarchyManager.class, - mViewHierarchyManager); - mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager); - mDependency.injectTestDependency(NotificationListener.class, mNotificationListener); - mDependency.injectTestDependency(AppOpsController.class, mock(AppOpsController.class)); - mDependency.injectTestDependency(StatusBarStateController.class, mStatusBarStateController); - mDependency.injectTestDependency(DeviceProvisionedController.class, - mDeviceProvisionedController); - mDependency.injectMockDependency(BubbleController.class); mDependency.injectTestDependency(NotificationFilter.class, mNotificationFilter); - mDependency.injectTestDependency(NotificationAlertingManager.class, - mNotificationAlertingManager); - mDependency.injectTestDependency(BroadcastDispatcher.class, mBroadcastDispatcher); IPowerManager powerManagerService = mock(IPowerManager.class); mPowerManager = new PowerManager(mContext, powerManagerService, @@ -217,21 +210,17 @@ public class StatusBarTest extends SysuiTestCase { new TestableNotificationInterruptionStateProvider(mContext, mPowerManager, mDreamManager, mAmbientDisplayConfiguration, mNotificationFilter, mStatusBarStateController, mBatteryController); - mDependency.injectTestDependency(NotificationInterruptionStateProvider.class, - mNotificationInterruptionStateProvider); - mDependency.injectMockDependency(NavigationBarController.class); mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class)); mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class)); mMetricsLogger = new FakeMetricsLogger(); - mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger); - mEntryManager = new TestableNotificationEntryManager(mContext); - mNotificationLogger = new NotificationLogger(mNotificationListener, - Dependency.get(UiOffloadThread.class), mEntryManager, mStatusBarStateController, + TestableNotificationEntryManager entryManager = new TestableNotificationEntryManager( + mContext); + NotificationLogger notificationLogger = new NotificationLogger(mNotificationListener, + Dependency.get(UiOffloadThread.class), entryManager, mStatusBarStateController, mExpansionStateLogger); - mNotificationLogger.setVisibilityReporter(mock(Runnable.class)); - mDependency.injectTestDependency(NotificationLogger.class, mNotificationLogger); + notificationLogger.setVisibilityReporter(mock(Runnable.class)); mCommandQueue = mock(CommandQueue.class); when(mCommandQueue.asBinder()).thenReturn(new Binder()); @@ -260,32 +249,71 @@ public class StatusBarTest extends SysuiTestCase { mHeadsUpManager, mHeadsUpSuppressor); when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController); - mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, - mKeyguardIndicationController, mStackScroller, - mPowerManager, mNotificationPanelView, mBarService, mNotificationListener, - mNotificationLogger, mVisualStabilityManager, mViewHierarchyManager, - mEntryManager, mScrimController, mBiometricUnlockController, - mKeyguardViewMediator, mRemoteInputManager, mock(NotificationGroupManager.class), - mock(NotificationGroupAlertTransferHelper.class), mock(FalsingManager.class), - mock(StatusBarWindowController.class), mock(NotificationIconAreaController.class), - mDozeScrimController, mock(NotificationShelf.class), - mLockscreenUserManager, mCommandQueue, mNotificationPresenter, - mock(BubbleController.class), mock(NavigationBarController.class), - mock(AutoHideController.class), mKeyguardUpdateMonitor, mStatusBarWindowView, - mBroadcastDispatcher); + mStatusBar = new TestableStatusBar( + mStatusBarKeyguardViewManager, + mKeyguardIndicationController, + mStackScroller, + mPowerManager, + mNotificationPanelView, + mBarService, + mNotificationListener, + notificationLogger, + mVisualStabilityManager, + mViewHierarchyManager, + entryManager, + mScrimController, + mBiometricUnlockController, + mKeyguardViewMediator, + mRemoteInputManager, + mock(NotificationGroupManager.class), + mock(NotificationGroupAlertTransferHelper.class), + new FalsingManagerFake(), + mock(StatusBarWindowController.class), + mock(NotificationIconAreaController.class), + mDozeScrimController, + mock(NotificationShelf.class), + mLockscreenUserManager, + mCommandQueue, + mNotificationPresenter, + mock(BubbleController.class), + mNavigationBarController, + mock(AutoHideController.class), + mKeyguardUpdateMonitor, + mStatusBarWindowView, + mBroadcastDispatcher, + mAssistManager, + mNotificationGutsManager, + mNotificationMediaManager, + mForegroundServiceController, + mAppOpsController, + mStatusBarStateController, + mDeviceProvisionedController, + mNotificationAlertingManager, + mNotificationInterruptionStateProvider, + mMetricsLogger, + mHeadsUpManager, + mKeyguardStateController, + new ScreenLifecycle(), + mBypassHeadsUpNotifier, + mColorExtractor, + new DisplayMetrics(), + Dependency.get(UiOffloadThread.class), + mDozeLog, + mPulseExpansionHandler, + new RemoteInputQuickSettingsDisabler( + mContext, + new ConfigurationControllerImpl(mContext) + ), + mNotificationWakeUpCoordinator, + mKeyguardBypassController); mStatusBar.mContext = mContext; mStatusBar.mComponents = mContext.getComponents(); - SystemUIFactory.getInstance().getRootComponent() - .getStatusBarInjector() - .createStatusBar(mStatusBar); - mStatusBar.mKeyguardStateController = mKeyguardStateController; - mStatusBar.setHeadsUpManager(mHeadsUpManager); mStatusBar.putComponent(StatusBar.class, mStatusBar); Dependency.get(InitController.class).executePostInitTasks(); - mEntryManager.setUpForTest(mock(NotificationPresenter.class), mStackScroller, + entryManager.setUpForTest(mock(NotificationPresenter.class), mStackScroller, mHeadsUpManager, mNotificationData); - mEntryManager.addNotificationEntryListener(mEntryListener); - mNotificationLogger.setUpWithContainer(mStackScroller); + entryManager.addNotificationEntryListener(mEntryListener); + notificationLogger.setUpWithContainer(mStackScroller); } @Test @@ -821,7 +849,28 @@ public class StatusBarTest extends SysuiTestCase { AutoHideController autoHideController, KeyguardUpdateMonitor keyguardUpdateMonitor, StatusBarWindowView statusBarWindow, - BroadcastDispatcher broadcastDispatcher) { + BroadcastDispatcher broadcastDispatcher, + AssistManager assistManager, + NotificationGutsManager notificationGutsManager, + NotificationMediaManager notificationMediaManager, + ForegroundServiceController foregroundServiceController, + AppOpsController appOpsController, + SysuiStatusBarStateController statusBarStateController, + DeviceProvisionedController deviceProvisionedController, + NotificationAlertingManager notificationAlertingManager, + NotificationInterruptionStateProvider notificationInterruptionStateProvider, + MetricsLogger metricsLogger, + HeadsUpManagerPhone headsUpManager, + KeyguardStateController keyguardStateController, + ScreenLifecycle screenLifecycle, + BypassHeadsUpNotifier bypassHeadsUpNotifier, + SysuiColorExtractor colorExtractor, DisplayMetrics displayMetrics, + UiOffloadThread uiOffloadThread, + DozeLog dozeLog, + PulseExpansionHandler pulseExpansionHandler, + RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler, + NotificationWakeUpCoordinator notificationWakeUpCoordinator, + KeyguardBypassController keyguardBypassController) { mStatusBarKeyguardViewManager = man; mKeyguardIndicationController = key; mStackScroller = stack; @@ -856,6 +905,28 @@ public class StatusBarTest extends SysuiTestCase { mStatusBarWindow = statusBarWindow; mDozeServiceHost.mWakeLockScreenPerformsAuth = false; mBroadcastDispatcher = broadcastDispatcher; + mAssistManager = assistManager; + mGutsManager = notificationGutsManager; + mMediaManager = notificationMediaManager; + mForegroundServiceController = foregroundServiceController; + mAppOpsController = appOpsController; + mStatusBarStateController = statusBarStateController; + mDeviceProvisionedController = deviceProvisionedController; + mNotificationAlertingManager = notificationAlertingManager; + mNotificationInterruptionStateProvider = notificationInterruptionStateProvider; + mMetricsLogger = metricsLogger; + mHeadsUpManager = headsUpManager; + mKeyguardStateController = keyguardStateController; + mScreenLifecycle = screenLifecycle; + mBypassHeadsUpNotifier = bypassHeadsUpNotifier; + mColorExtractor = colorExtractor; + mDisplayMetrics = displayMetrics; + mUiOffloadThread = uiOffloadThread; + mDozeLog = dozeLog; + mPulseExpansionHandler = pulseExpansionHandler; + mRemoteInputQuickSettingsDisabler = remoteInputQuickSettingsDisabler; + mWakeUpCoordinator = notificationWakeUpCoordinator; + mKeyguardBypassController = keyguardBypassController; } private WakefulnessLifecycle createAwakeWakefulnessLifecycle() { @@ -874,10 +945,6 @@ public class StatusBarTest extends SysuiTestCase { mState = state; } - void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) { - mHeadsUpManager = headsUpManager; - } - public void setUserSetupForTest(boolean userSetup) { mUserSetup = userSetup; } diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java b/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java index dc7a9aaf966d..5ac3b69549c1 100644 --- a/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java +++ b/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java @@ -72,10 +72,16 @@ class EventDispatcher { * * @param prototype The prototype from which to create the injected events. * @param action The action of the event. + * @param rawEvent The original event prior to magnification or other transformations. * @param pointerIdBits The bits of the pointers to send. * @param policyFlags The policy flags associated with the event. */ - void sendMotionEvent(MotionEvent prototype, int action, int pointerIdBits, int policyFlags) { + void sendMotionEvent( + MotionEvent prototype, + int action, + MotionEvent rawEvent, + int pointerIdBits, + int policyFlags) { prototype.setAction(action); MotionEvent event = null; @@ -105,11 +111,8 @@ class EventDispatcher { // Make sure that the user will see the event. policyFlags |= WindowManagerPolicy.FLAG_PASS_TO_USER; - // TODO: For now pass null for the raw event since the touch - // explorer is the last event transformation and it does - // not care about the raw event. if (mReceiver != null) { - mReceiver.onMotionEvent(event, null, policyFlags); + mReceiver.onMotionEvent(event, rawEvent, policyFlags); } else { Slog.e(LOG_TAG, "Error sending event: no receiver specified."); } @@ -280,7 +283,12 @@ class EventDispatcher { if (!isInjectedPointerDown(pointerId)) { pointerIdBits |= (1 << pointerId); final int action = computeInjectionAction(MotionEvent.ACTION_DOWN, i); - sendMotionEvent(prototype, action, pointerIdBits, policyFlags); + sendMotionEvent( + prototype, + action, + mState.getLastReceivedEvent(), + pointerIdBits, + policyFlags); } } } @@ -303,7 +311,8 @@ class EventDispatcher { } pointerIdBits |= (1 << pointerId); final int action = computeInjectionAction(MotionEvent.ACTION_UP, i); - sendMotionEvent(prototype, action, pointerIdBits, policyFlags); + sendMotionEvent( + prototype, action, mState.getLastReceivedEvent(), pointerIdBits, policyFlags); } } } diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java index f4ac82157d04..c60e35e2cc6d 100644 --- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java +++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java @@ -183,9 +183,9 @@ public class TouchExplorer extends BaseEventStreamTransformation private void clear() { // If we have not received an event then we are in initial // state. Therefore, there is not need to clean anything. - MotionEvent event = mReceivedPointerTracker.getLastReceivedEvent(); + MotionEvent event = mState.getLastReceivedEvent(); if (event != null) { - clear(mReceivedPointerTracker.getLastReceivedEvent(), WindowManagerPolicy.FLAG_TRUSTED); + clear(event, WindowManagerPolicy.FLAG_TRUSTED); } } @@ -229,7 +229,7 @@ public class TouchExplorer extends BaseEventStreamTransformation Slog.d(LOG_TAG, mState.toString()); } - mReceivedPointerTracker.onMotionEvent(rawEvent); + mState.onReceivedMotionEvent(rawEvent); if (mGestureDetector.onMotionEvent(event, rawEvent, policyFlags)) { // Event was handled by the gesture detector. @@ -250,9 +250,9 @@ public class TouchExplorer extends BaseEventStreamTransformation } else if (mState.isTouchExploring()) { handleMotionEventStateTouchExploring(event, rawEvent, policyFlags); } else if (mState.isDragging()) { - handleMotionEventStateDragging(event, policyFlags); + handleMotionEventStateDragging(event, rawEvent, policyFlags); } else if (mState.isDelegating()) { - handleMotionEventStateDelegating(event, policyFlags); + handleMotionEventStateDelegating(event, rawEvent, policyFlags); } else if (mState.isGestureDetecting()) { // Already handled. } else { @@ -292,7 +292,7 @@ public class TouchExplorer extends BaseEventStreamTransformation } // Pointers should not be zero when running this command. - if (mReceivedPointerTracker.getLastReceivedEvent().getPointerCount() == 0) { + if (mState.getLastReceivedEvent().getPointerCount() == 0) { return; } // Try to use the standard accessibility API to long click @@ -368,11 +368,15 @@ public class TouchExplorer extends BaseEventStreamTransformation // We have just decided that the user is touch, // exploring so start sending events. - mSendHoverEnterAndMoveDelayed.addEvent(event); + mSendHoverEnterAndMoveDelayed.addEvent(event, mState.getLastReceivedEvent()); mSendHoverEnterAndMoveDelayed.forceSendAndRemove(); mSendHoverExitDelayed.cancel(); mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags); + event, + MotionEvent.ACTION_HOVER_MOVE, + mState.getLastReceivedEvent(), + pointerIdBits, + policyFlags); return true; } } @@ -387,7 +391,7 @@ public class TouchExplorer extends BaseEventStreamTransformation switch (event.getActionMasked()) { // The only way to leave the clear state is for a pointer to go down. case MotionEvent.ACTION_DOWN: - handleActionDown(event, policyFlags); + handleActionDown(event, rawEvent, policyFlags); break; default: // Some other nonsensical event. @@ -399,7 +403,7 @@ public class TouchExplorer extends BaseEventStreamTransformation * Handles ACTION_DOWN while in the clear or touch interacting states. This event represents the * first finger touching the screen. */ - private void handleActionDown(MotionEvent event, int policyFlags) { + private void handleActionDown(MotionEvent event, MotionEvent rawEvent, int policyFlags) { mAms.onTouchInteractionStart(); // If we still have not notified the user for the last @@ -432,10 +436,10 @@ public class TouchExplorer extends BaseEventStreamTransformation // The idea is to avoid getting stuck in STATE_TOUCH_INTERACTING final int pointerId = mReceivedPointerTracker.getPrimaryPointerId(); final int pointerIdBits = (1 << pointerId); - mSendHoverEnterAndMoveDelayed.post(event, pointerIdBits, policyFlags); + mSendHoverEnterAndMoveDelayed.post(event, rawEvent, pointerIdBits, policyFlags); } else { // Cache the event until we discern exploration from gesturing. - mSendHoverEnterAndMoveDelayed.addEvent(event); + mSendHoverEnterAndMoveDelayed.addEvent(event, rawEvent); } } } @@ -453,7 +457,7 @@ public class TouchExplorer extends BaseEventStreamTransformation case MotionEvent.ACTION_DOWN: // Continue the previous interaction. mSendTouchInteractionEndDelayed.cancel(); - handleActionDown(event, policyFlags); + handleActionDown(event, rawEvent, policyFlags); break; case MotionEvent.ACTION_POINTER_DOWN: handleActionPointerDown(); @@ -462,7 +466,7 @@ public class TouchExplorer extends BaseEventStreamTransformation handleActionMoveStateTouchInteracting(event, rawEvent, policyFlags); break; case MotionEvent.ACTION_UP: - handleActionUp(event, policyFlags); + handleActionUp(event, rawEvent, policyFlags); break; } } @@ -487,7 +491,7 @@ public class TouchExplorer extends BaseEventStreamTransformation handleActionMoveStateTouchExploring(event, rawEvent, policyFlags); break; case MotionEvent.ACTION_UP: - handleActionUp(event, policyFlags); + handleActionUp(event, rawEvent, policyFlags); break; default: break; @@ -520,7 +524,7 @@ public class TouchExplorer extends BaseEventStreamTransformation // figure out what the user is doing. if (mSendHoverEnterAndMoveDelayed.isPending()) { // Cache the event until we discern exploration from gesturing. - mSendHoverEnterAndMoveDelayed.addEvent(event); + mSendHoverEnterAndMoveDelayed.addEvent(event, rawEvent); } break; case 2: @@ -538,7 +542,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mDraggingPointerId = pointerId; event.setEdgeFlags(mReceivedPointerTracker.getLastReceivedDownEdgeFlags()); mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_DOWN, pointerIdBits, policyFlags); + event, MotionEvent.ACTION_DOWN, rawEvent, pointerIdBits, policyFlags); } else { // Two pointers moving arbitrary are delegated to the view hierarchy. mState.startDelegating(); @@ -558,13 +562,13 @@ public class TouchExplorer extends BaseEventStreamTransformation * Handles ACTION_UP while in the touch interacting state. This event represents all fingers * being lifted from the screen. */ - private void handleActionUp(MotionEvent event, int policyFlags) { + private void handleActionUp(MotionEvent event, MotionEvent rawEvent, int policyFlags) { mAms.onTouchInteractionEnd(); final int pointerId = event.getPointerId(event.getActionIndex()); final int pointerIdBits = (1 << pointerId); if (mSendHoverEnterAndMoveDelayed.isPending()) { // If we have not delivered the enter schedule an exit. - mSendHoverExitDelayed.post(event, pointerIdBits, policyFlags); + mSendHoverExitDelayed.post(event, rawEvent, pointerIdBits, policyFlags); } else { // The user is touch exploring so we send events for end. sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); @@ -588,7 +592,7 @@ public class TouchExplorer extends BaseEventStreamTransformation // Touch exploration. sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags); mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags); + event, MotionEvent.ACTION_HOVER_MOVE, rawEvent, pointerIdBits, policyFlags); break; case 2: if (mSendHoverEnterAndMoveDelayed.isPending()) { @@ -638,7 +642,8 @@ public class TouchExplorer extends BaseEventStreamTransformation * @param event The event to be handled. * @param policyFlags The policy flags associated with the event. */ - private void handleMotionEventStateDragging(MotionEvent event, int policyFlags) { + private void handleMotionEventStateDragging( + MotionEvent event, MotionEvent rawEvent, int policyFlags) { int pointerIdBits = 0; // Clear the dragging pointer id if it's no longer valid. if (event.findPointerIndex(mDraggingPointerId) == -1) { @@ -662,7 +667,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mState.startDelegating(); if (mDraggingPointerId != INVALID_POINTER_ID) { mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags); + event, MotionEvent.ACTION_UP, rawEvent, pointerIdBits, policyFlags); } mDispatcher.sendDownForAllNotInjectedPointers(event, policyFlags); } break; @@ -681,6 +686,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mDispatcher.sendMotionEvent( event, MotionEvent.ACTION_MOVE, + rawEvent, pointerIdBits, policyFlags); } else { @@ -690,7 +696,11 @@ public class TouchExplorer extends BaseEventStreamTransformation // Remove move history before send injected non-move events event = MotionEvent.obtainNoHistory(event); // Send an event to the end of the drag gesture. - mDispatcher.sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits, + mDispatcher.sendMotionEvent( + event, + MotionEvent.ACTION_UP, + rawEvent, + pointerIdBits, policyFlags); // Deliver all pointers to the view hierarchy. mDispatcher.sendDownForAllNotInjectedPointers(event, policyFlags); @@ -700,7 +710,11 @@ public class TouchExplorer extends BaseEventStreamTransformation mState.startDelegating(); event = MotionEvent.obtainNoHistory(event); // Send an event to the end of the drag gesture. - mDispatcher.sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits, + mDispatcher.sendMotionEvent( + event, + MotionEvent.ACTION_UP, + rawEvent, + pointerIdBits, policyFlags); // Deliver all pointers to the view hierarchy. mDispatcher.sendDownForAllNotInjectedPointers(event, policyFlags); @@ -713,7 +727,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mDraggingPointerId = INVALID_POINTER_ID; // Send an event to the end of the drag gesture. mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags); + event, MotionEvent.ACTION_UP, rawEvent, pointerIdBits, policyFlags); } } break; case MotionEvent.ACTION_UP: { @@ -726,7 +740,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mDraggingPointerId = INVALID_POINTER_ID; // Send an event to the end of the drag gesture. mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags); + event, MotionEvent.ACTION_UP, rawEvent, pointerIdBits, policyFlags); } } break; } @@ -738,7 +752,8 @@ public class TouchExplorer extends BaseEventStreamTransformation * @param event The event to be handled. * @param policyFlags The policy flags associated with the event. */ - private void handleMotionEventStateDelegating(MotionEvent event, int policyFlags) { + private void handleMotionEventStateDelegating( + MotionEvent event, MotionEvent rawEvent, int policyFlags) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: { Slog.e(LOG_TAG, "Delegating state can only be reached if " @@ -749,7 +764,7 @@ public class TouchExplorer extends BaseEventStreamTransformation case MotionEvent.ACTION_UP: { // Deliver the event. mDispatcher.sendMotionEvent( - event, event.getAction(), ALL_POINTER_ID_BITS, policyFlags); + event, event.getAction(), rawEvent, ALL_POINTER_ID_BITS, policyFlags); // Announce the end of a the touch interaction. mAms.onTouchInteractionEnd(); @@ -759,7 +774,7 @@ public class TouchExplorer extends BaseEventStreamTransformation default: { // Deliver the event. mDispatcher.sendMotionEvent( - event, event.getAction(), ALL_POINTER_ID_BITS, policyFlags); + event, event.getAction(), rawEvent, ALL_POINTER_ID_BITS, policyFlags); } } } @@ -792,7 +807,11 @@ public class TouchExplorer extends BaseEventStreamTransformation mSendTouchExplorationEndDelayed.post(); } mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, policyFlags); + event, + MotionEvent.ACTION_HOVER_EXIT, + mState.getLastReceivedEvent(), + pointerIdBits, + policyFlags); } } @@ -807,7 +826,11 @@ public class TouchExplorer extends BaseEventStreamTransformation if (event != null && event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) { final int pointerIdBits = event.getPointerIdBits(); mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_HOVER_ENTER, pointerIdBits, policyFlags); + event, + MotionEvent.ACTION_HOVER_ENTER, + mState.getLastReceivedEvent(), + pointerIdBits, + policyFlags); } } @@ -891,20 +914,23 @@ public class TouchExplorer extends BaseEventStreamTransformation private final String LOG_TAG_SEND_HOVER_DELAYED = "SendHoverEnterAndMoveDelayed"; private final List<MotionEvent> mEvents = new ArrayList<MotionEvent>(); + private final List<MotionEvent> mRawEvents = new ArrayList<MotionEvent>(); private int mPointerIdBits; private int mPolicyFlags; - public void post(MotionEvent event, int pointerIdBits, int policyFlags) { + public void post( + MotionEvent event, MotionEvent rawEvent, int pointerIdBits, int policyFlags) { cancel(); - addEvent(event); + addEvent(event, rawEvent); mPointerIdBits = pointerIdBits; mPolicyFlags = policyFlags; mHandler.postDelayed(this, mDetermineUserIntentTimeout); } - public void addEvent(MotionEvent event) { + public void addEvent(MotionEvent event, MotionEvent rawEvent) { mEvents.add(MotionEvent.obtain(event)); + mRawEvents.add(MotionEvent.obtain(rawEvent)); } public void cancel() { @@ -925,6 +951,10 @@ public class TouchExplorer extends BaseEventStreamTransformation for (int i = eventCount - 1; i >= 0; i--) { mEvents.remove(i).recycle(); } + final int rawEventcount = mRawEvents.size(); + for (int i = rawEventcount - 1; i >= 0; i--) { + mRawEvents.remove(i).recycle(); + } } public void forceSendAndRemove() { @@ -939,10 +969,10 @@ public class TouchExplorer extends BaseEventStreamTransformation mDispatcher.sendAccessibilityEvent( AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START); - if (!mEvents.isEmpty()) { + if (!mEvents.isEmpty() && !mRawEvents.isEmpty()) { // Deliver a down event. mDispatcher.sendMotionEvent(mEvents.get(0), MotionEvent.ACTION_HOVER_ENTER, - mPointerIdBits, mPolicyFlags); + mRawEvents.get(0), mPointerIdBits, mPolicyFlags); if (DEBUG) { Slog.d(LOG_TAG_SEND_HOVER_DELAYED, "Injecting motion event: ACTION_HOVER_ENTER"); @@ -952,7 +982,7 @@ public class TouchExplorer extends BaseEventStreamTransformation final int eventCount = mEvents.size(); for (int i = 1; i < eventCount; i++) { mDispatcher.sendMotionEvent(mEvents.get(i), MotionEvent.ACTION_HOVER_MOVE, - mPointerIdBits, mPolicyFlags); + mRawEvents.get(i), mPointerIdBits, mPolicyFlags); if (DEBUG) { Slog.d(LOG_TAG_SEND_HOVER_DELAYED, "Injecting motion event: ACTION_HOVER_MOVE"); @@ -970,12 +1000,15 @@ public class TouchExplorer extends BaseEventStreamTransformation private final String LOG_TAG_SEND_HOVER_DELAYED = "SendHoverExitDelayed"; private MotionEvent mPrototype; + private MotionEvent mRawEvent; private int mPointerIdBits; private int mPolicyFlags; - public void post(MotionEvent prototype, int pointerIdBits, int policyFlags) { + public void post( + MotionEvent prototype, MotionEvent rawEvent, int pointerIdBits, int policyFlags) { cancel(); mPrototype = MotionEvent.obtain(prototype); + mRawEvent = MotionEvent.obtain(rawEvent); mPointerIdBits = pointerIdBits; mPolicyFlags = policyFlags; mHandler.postDelayed(this, mDetermineUserIntentTimeout); @@ -993,8 +1026,14 @@ public class TouchExplorer extends BaseEventStreamTransformation } private void clear() { - mPrototype.recycle(); + if (mPrototype != null) { + mPrototype.recycle(); + } + if (mRawEvent != null) { + mRawEvent.recycle(); + } mPrototype = null; + mRawEvent = null; mPointerIdBits = -1; mPolicyFlags = 0; } @@ -1011,8 +1050,12 @@ public class TouchExplorer extends BaseEventStreamTransformation Slog.d(LOG_TAG_SEND_HOVER_DELAYED, "Injecting motion event:" + " ACTION_HOVER_EXIT"); } - mDispatcher.sendMotionEvent(mPrototype, MotionEvent.ACTION_HOVER_EXIT, - mPointerIdBits, mPolicyFlags); + mDispatcher.sendMotionEvent( + mPrototype, + MotionEvent.ACTION_HOVER_EXIT, + mRawEvent, + mPointerIdBits, + mPolicyFlags); if (!mSendTouchExplorationEndDelayed.isPending()) { mSendTouchExplorationEndDelayed.cancel(); mSendTouchExplorationEndDelayed.post(); diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java index 49938fa4c6b9..f463260a9d02 100644 --- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java +++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java @@ -71,6 +71,7 @@ public class TouchState { // Helper class to track received pointers. // Todo: collapse or hide this class so multiple classes don't modify it. private final ReceivedPointerTracker mReceivedPointerTracker; + private MotionEvent mLastReceivedEvent; public TouchState() { mReceivedPointerTracker = new ReceivedPointerTracker(); @@ -80,6 +81,10 @@ public class TouchState { public void clear() { setState(STATE_CLEAR); // Reset the pointer trackers. + if (mLastReceivedEvent != null) { + mLastReceivedEvent.recycle(); + mLastReceivedEvent = null; + } mReceivedPointerTracker.clear(); } @@ -89,6 +94,10 @@ public class TouchState { * @param rawEvent The raw touch event. */ public void onReceivedMotionEvent(MotionEvent rawEvent) { + if (mLastReceivedEvent != null) { + mLastReceivedEvent.recycle(); + } + mLastReceivedEvent = MotionEvent.obtain(rawEvent); mReceivedPointerTracker.onMotionEvent(rawEvent); } @@ -216,6 +225,11 @@ public class TouchState { return mReceivedPointerTracker; } + /** @return The last received event. */ + public MotionEvent getLastReceivedEvent() { + return mLastReceivedEvent; + } + /** This class tracks where and when a pointer went down. It does not track its movement. */ class ReceivedPointerTracker { private static final String LOG_TAG_RECEIVED_POINTER_TRACKER = "ReceivedPointerTracker"; @@ -232,8 +246,6 @@ public class TouchState { // or if it goes up the next one that most recently went down. private int mPrimaryPointerId; - // Keep track of the last up pointer data. - private MotionEvent mLastReceivedEvent; ReceivedPointerTracker() { clear(); @@ -254,11 +266,6 @@ public class TouchState { * @param event The event to process. */ public void onMotionEvent(MotionEvent event) { - if (mLastReceivedEvent != null) { - mLastReceivedEvent.recycle(); - } - mLastReceivedEvent = MotionEvent.obtain(event); - final int action = event.getActionMasked(); switch (action) { case MotionEvent.ACTION_DOWN: @@ -279,11 +286,6 @@ public class TouchState { } } - /** @return The last received event. */ - public MotionEvent getLastReceivedEvent() { - return mLastReceivedEvent; - } - /** @return The number of received pointers that are down. */ public int getReceivedPointerDownCount() { return Integer.bitCount(mReceivedPointersDown); diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index fea4e9047f83..81ce359cc078 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -631,8 +631,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku onClickIntent = mDevicePolicyManagerInternal.createShowAdminSupportIntent( providerUserId, true); } else { - final SuspendDialogInfo dialogInfo = mPackageManagerInternal - .getSuspendedDialogInfo(providerPackage, providerUserId); + final SuspendDialogInfo dialogInfo = + mPackageManagerInternal.getSuspendedDialogInfo(providerPackage, + suspendingPackage, providerUserId); onClickIntent = SuspendedAppActivity.createSuspendedAppInterceptIntent( providerPackage, suspendingPackage, dialogInfo, providerUserId); } diff --git a/services/core/Android.bp b/services/core/Android.bp index 80bc1af4d160..6a3b38e2ccdb 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -49,9 +49,11 @@ genrule { ], cmd: "cp $(location :generate-protolog.json) $(out) && " + "{ diff $(out) $(location :services.core.protolog.json) >/dev/null 2>&1 || " + - "{ echo -e '##### ProtoLog viewer config is stale. ### \nRun: \n " + - "cp $(location :generate-protolog.json) " + - "$(location :services.core.protolog.json)\n' >&2 && false; } }", + "{ echo -e '\\n\\n################################################################\\n#\\n" + + "# ERROR: ProtoLog viewer config is stale. To update it, run:\\n#\\n" + + "# cp $(location :generate-protolog.json) " + + "$(location :services.core.protolog.json)\\n#\\n" + + "################################################################\\n\\n' >&2 && false; } }", out: ["services.core.protolog.json"], } diff --git a/services/core/java/com/android/server/AnimationThread.java b/services/core/java/com/android/server/AnimationThread.java index c607b1e058bc..fad743eafdaa 100644 --- a/services/core/java/com/android/server/AnimationThread.java +++ b/services/core/java/com/android/server/AnimationThread.java @@ -64,7 +64,7 @@ public final class AnimationThread extends ServiceThread { */ @VisibleForTesting public static void dispose() { - synchronized (DisplayThread.class) { + synchronized (AnimationThread.class) { if (sInstance == null) { return; } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 18a8148eb815..9acafaec185e 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -495,7 +495,7 @@ public class ConnectivityService extends IConnectivityManager.Stub * arg1 = One of the NETWORK_TESTED_RESULT_* constants. * arg2 = NetID. */ - public static final int EVENT_NETWORK_TESTED = 41; + private static final int EVENT_NETWORK_TESTED = 41; /** * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the private DNS @@ -503,7 +503,7 @@ public class ConnectivityService extends IConnectivityManager.Stub * obj = PrivateDnsConfig * arg2 = netid */ - public static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42; + private static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42; /** * Request ConnectivityService display provisioning notification. @@ -511,12 +511,12 @@ public class ConnectivityService extends IConnectivityManager.Stub * arg2 = NetID. * obj = Intent to be launched when notification selected by user, null if !arg1. */ - public static final int EVENT_PROVISIONING_NOTIFICATION = 43; + private static final int EVENT_PROVISIONING_NOTIFICATION = 43; /** * This event can handle dismissing notification by given network id. */ - public static final int EVENT_TIMEOUT_NOTIFICATION = 44; + private static final int EVENT_TIMEOUT_NOTIFICATION = 44; /** * Used to specify whether a network should be used even if connectivity is partial. @@ -531,13 +531,13 @@ public class ConnectivityService extends IConnectivityManager.Stub * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification * should be shown. */ - public static final int PROVISIONING_NOTIFICATION_SHOW = 1; + private static final int PROVISIONING_NOTIFICATION_SHOW = 1; /** * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification * should be hidden. */ - public static final int PROVISIONING_NOTIFICATION_HIDE = 0; + private static final int PROVISIONING_NOTIFICATION_HIDE = 0; private static String eventName(int what) { return sMagicDecoderRing.get(what, Integer.toString(what)); @@ -1938,7 +1938,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - return mPolicyManagerInternal.isUidNetworkingBlocked(uid, uidRules, + return NetworkPolicyManagerInternal.isUidNetworkingBlocked(uid, uidRules, isNetworkMetered, isBackgroundRestricted); } @@ -2204,7 +2204,7 @@ public class ConnectivityService extends IConnectivityManager.Stub final String iface = networkAgent.linkProperties.getInterfaceName(); final int timeout; - int type = ConnectivityManager.TYPE_NONE; + final int type; if (networkAgent.networkCapabilities.hasTransport( NetworkCapabilities.TRANSPORT_CELLULAR)) { @@ -2219,11 +2219,10 @@ public class ConnectivityService extends IConnectivityManager.Stub 15); type = ConnectivityManager.TYPE_WIFI; } else { - // do not track any other networks - timeout = 0; + return; // do not track any other networks } - if (timeout > 0 && iface != null && type != ConnectivityManager.TYPE_NONE) { + if (timeout > 0 && iface != null) { try { mNMS.addIdleTimer(iface, timeout, type); } catch (Exception e) { @@ -2299,7 +2298,6 @@ public class ConnectivityService extends IConnectivityManager.Stub @VisibleForTesting protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208"; - private static final String DEFAULT_TCP_RWND_KEY = "net.tcp.default_init_rwnd"; private void updateTcpBufferSizes(String tcpBufferSizes) { String[] values = null; @@ -2375,7 +2373,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } @Override - protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { + protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, + @Nullable String[] args) { PriorityDump.dump(mPriorityDumper, fd, writer, args); } @@ -2837,7 +2836,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private NetworkMonitorCallbacks(NetworkAgentInfo nai) { mNetId = nai.network.netId; - mNai = new AutodestructReference(nai); + mNai = new AutodestructReference<>(nai); } @Override @@ -4292,7 +4291,7 @@ public class ConnectivityService extends IConnectivityManager.Stub public void onChange(boolean selfChange, Uri uri) { final Integer what = mUriEventMap.get(uri); if (what != null) { - mHandler.obtainMessage(what.intValue()).sendToTarget(); + mHandler.obtainMessage(what).sendToTarget(); } else { loge("No matching event to send for URI=" + uri); } @@ -4729,12 +4728,10 @@ public class ConnectivityService extends IConnectivityManager.Stub private static final String ATTR_MNC = "mnc"; private String getProvisioningUrlBaseFromFile() { - FileReader fileReader = null; - XmlPullParser parser = null; + XmlPullParser parser; Configuration config = mContext.getResources().getConfiguration(); - try { - fileReader = new FileReader(mProvisioningUrlFile); + try (FileReader fileReader = new FileReader(mProvisioningUrlFile)) { parser = Xml.newPullParser(); parser.setInput(fileReader); XmlUtils.beginDocument(parser, TAG_PROVISIONING_URLS); @@ -4769,12 +4766,6 @@ public class ConnectivityService extends IConnectivityManager.Stub loge("Xml parser exception reading Carrier Provisioning Urls file: " + e); } catch (IOException e) { loge("I/O exception reading Carrier Provisioning Urls file: " + e); - } finally { - if (fileReader != null) { - try { - fileReader.close(); - } catch (IOException e) {} - } } return null; } @@ -5104,8 +5095,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - // This checks that the passed capabilities either do not request a specific SSID/SignalStrength - // , or the calling app has permission to do so. + // This checks that the passed capabilities either do not request a + // specific SSID/SignalStrength, or the calling app has permission to do so. private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc, int callerPid, int callerUid) { if (null != nc.getSSID() && !checkSettingsPermission(callerPid, callerUid)) { @@ -5238,7 +5229,7 @@ public class ConnectivityService extends IConnectivityManager.Stub final int uid = Binder.getCallingUid(); Integer uidReqs = mBandwidthRequests.get(uid); if (uidReqs == null) { - uidReqs = new Integer(0); + uidReqs = 0; } mBandwidthRequests.put(uid, ++uidReqs); } @@ -5572,7 +5563,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties newLp, - LinkProperties oldLp) { + @NonNull LinkProperties oldLp) { int netId = networkAgent.network.netId; // The NetworkAgentInfo does not know whether clatd is running on its network or not, or @@ -5687,7 +5678,7 @@ public class ConnectivityService extends IConnectivityManager.Stub */ private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) { // Compare the route diff to determine which routes should be added and removed. - CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>( + CompareResult<RouteInfo> routeDiff = new CompareResult<>( oldLp != null ? oldLp.getAllRoutes() : null, newLp != null ? newLp.getAllRoutes() : null); @@ -5706,7 +5697,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } } for (RouteInfo route : routeDiff.added) { - if (route.hasGateway() == false) continue; + if (!route.hasGateway()) continue; if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId); try { mNMS.addRoute(netId, route); @@ -5935,8 +5926,8 @@ public class ConnectivityService extends IConnectivityManager.Stub * 3. the VPN is fully-routed * 4. the VPN interface is non-null * - * @See INetd#firewallAddUidInterfaceRules - * @See INetd#firewallRemoveUidInterfaceRules + * @see INetd#firewallAddUidInterfaceRules + * @see INetd#firewallRemoveUidInterfaceRules */ private boolean requiresVpnIsolation(@NonNull NetworkAgentInfo nai, NetworkCapabilities nc, LinkProperties lp) { @@ -7051,9 +7042,9 @@ public class ConnectivityService extends IConnectivityManager.Stub } @Override - public void onShellCommand(FileDescriptor in, FileDescriptor out, - FileDescriptor err, String[] args, ShellCallback callback, - ResultReceiver resultReceiver) { + public void onShellCommand(@NonNull FileDescriptor in, @NonNull FileDescriptor out, + FileDescriptor err, @NonNull String[] args, ShellCallback callback, + @NonNull ResultReceiver resultReceiver) { (new ShellCmd()).exec(this, in, out, err, args, callback, resultReceiver); } diff --git a/services/core/java/com/android/server/GnssManagerService.java b/services/core/java/com/android/server/GnssManagerService.java new file mode 100644 index 000000000000..b6e619effb08 --- /dev/null +++ b/services/core/java/com/android/server/GnssManagerService.java @@ -0,0 +1,800 @@ +/* + * Copyright (C) 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. + */ + +package com.android.server; + +import android.Manifest; +import android.app.ActivityManager; +import android.app.AppOpsManager; +import android.content.Context; +import android.location.GnssCapabilities; +import android.location.GnssMeasurementCorrections; +import android.location.IBatchedLocationCallback; +import android.location.IGnssMeasurementsListener; +import android.location.IGnssNavigationMessageListener; +import android.location.IGnssStatusListener; +import android.location.IGpsGeofenceHardware; +import android.location.INetInitiatedListener; +import android.location.Location; +import android.os.Binder; +import android.os.Handler; +import android.os.IBinder; +import android.os.IInterface; +import android.os.Process; +import android.os.RemoteException; +import android.stats.location.LocationStatsEnums; +import android.util.ArrayMap; +import android.util.Log; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.DumpUtils; +import com.android.internal.util.IndentingPrintWriter; +import com.android.server.LocationManagerServiceUtils.LinkedListener; +import com.android.server.LocationManagerServiceUtils.LinkedListenerBase; +import com.android.server.location.AbstractLocationProvider; +import com.android.server.location.CallerIdentity; +import com.android.server.location.GnssBatchingProvider; +import com.android.server.location.GnssCapabilitiesProvider; +import com.android.server.location.GnssLocationProvider; +import com.android.server.location.GnssMeasurementCorrectionsProvider; +import com.android.server.location.GnssMeasurementsProvider; +import com.android.server.location.GnssNavigationMessageProvider; +import com.android.server.location.GnssStatusListenerHelper; +import com.android.server.location.RemoteListenerHelper; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Function; + +/** Manages Gnss providers and related Gnss functions for LocationManagerService. */ +public class GnssManagerService { + private static final String TAG = "LocationManagerService"; + private static final boolean D = Log.isLoggable(TAG, Log.DEBUG); + + // Providers + private final GnssLocationProvider mGnssLocationProvider; + private final GnssStatusListenerHelper mGnssStatusProvider; + private final GnssMeasurementsProvider mGnssMeasurementsProvider; + private final GnssMeasurementCorrectionsProvider mGnssMeasurementCorrectionsProvider; + private final GnssNavigationMessageProvider mGnssNavigationMessageProvider; + private final GnssLocationProvider.GnssSystemInfoProvider mGnssSystemInfoProvider; + private final GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider; + private final GnssCapabilitiesProvider mGnssCapabilitiesProvider; + private final GnssBatchingProvider mGnssBatchingProvider; + + private final INetInitiatedListener mNetInitiatedListener; + private final IGpsGeofenceHardware mGpsGeofenceProxy; + private final LocationManagerService mLocationManagerService; + private final LocationUsageLogger mLocationUsageLogger; + + @GuardedBy("mGnssMeasurementsListeners") + private final ArrayMap<IBinder, + LinkedListener<IGnssMeasurementsListener>> + mGnssMeasurementsListeners = new ArrayMap<>(); + + @GuardedBy("mGnssNavigationMessageListeners") + private final ArrayMap< + IBinder, LinkedListener<IGnssNavigationMessageListener>> + mGnssNavigationMessageListeners = new ArrayMap<>(); + + @GuardedBy("mGnssStatusListeners") + private final ArrayMap<IBinder, LinkedListener<IGnssStatusListener>> + mGnssStatusListeners = new ArrayMap<>(); + + @GuardedBy("mGnssBatchingLock") + private IBatchedLocationCallback mGnssBatchingCallback; + + @GuardedBy("mGnssBatchingLock") + private LinkedListener<IBatchedLocationCallback> + mGnssBatchingDeathCallback; + + @GuardedBy("mGnssBatchingLock") + private boolean mGnssBatchingInProgress = false; + + private final Object mGnssBatchingLock = new Object(); + private final Context mContext; + private final Handler mHandler; + + public GnssManagerService(LocationManagerService locationManagerService, + Context context, + AbstractLocationProvider.LocationProviderManager gnssProviderManager, + LocationUsageLogger locationUsageLogger) { + this(locationManagerService, context, new GnssLocationProvider(context, gnssProviderManager, + FgThread.getHandler().getLooper()), locationUsageLogger); + } + + // Can use this constructor to inject GnssLocationProvider for testing + @VisibleForTesting + GnssManagerService(LocationManagerService locationManagerService, + Context context, + GnssLocationProvider gnssLocationProvider, + LocationUsageLogger locationUsageLogger) { + mContext = context; + mHandler = FgThread.getHandler(); + + mGnssLocationProvider = + gnssLocationProvider; + + mGnssStatusProvider = mGnssLocationProvider.getGnssStatusProvider(); + mGnssMeasurementsProvider = mGnssLocationProvider.getGnssMeasurementsProvider(); + mGnssMeasurementCorrectionsProvider = + mGnssLocationProvider.getGnssMeasurementCorrectionsProvider(); + mGnssNavigationMessageProvider = mGnssLocationProvider.getGnssNavigationMessageProvider(); + mGnssSystemInfoProvider = mGnssLocationProvider.getGnssSystemInfoProvider(); + mGnssMetricsProvider = mGnssLocationProvider.getGnssMetricsProvider(); + mGnssCapabilitiesProvider = mGnssLocationProvider.getGnssCapabilitiesProvider(); + mGnssBatchingProvider = mGnssLocationProvider.getGnssBatchingProvider(); + + mNetInitiatedListener = mGnssLocationProvider.getNetInitiatedListener(); + mGpsGeofenceProxy = mGnssLocationProvider.getGpsGeofenceProxy(); + mLocationManagerService = locationManagerService; + mLocationUsageLogger = locationUsageLogger; + + registerUidListener(); + } + + public static boolean isGnssSupported() { + return GnssLocationProvider.isSupported(); + } + + private boolean hasGnssPermissions(String packageName) { + mContext.enforceCallingPermission( + Manifest.permission.ACCESS_FINE_LOCATION, + "Fine location permission not granted."); + + int uid = Binder.getCallingUid(); + long identity = Binder.clearCallingIdentity(); + try { + return mContext.getSystemService( + AppOpsManager.class).checkOp(AppOpsManager.OP_FINE_LOCATION, uid, packageName) + == AppOpsManager.MODE_ALLOWED; + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + public GnssLocationProvider getGnssLocationProvider() { + return mGnssLocationProvider; + } + + public IGpsGeofenceHardware getGpsGeofenceProxy() { + return mGpsGeofenceProxy; + } + + /** + * Get year of GNSS hardware. + * + * @return year of GNSS hardware as an int if possible, otherwise zero + */ + public int getGnssYearOfHardware() { + if (mGnssSystemInfoProvider != null) { + return mGnssSystemInfoProvider.getGnssYearOfHardware(); + } else { + return 0; + } + } + + /** + * Get model name of GNSS hardware. + * + * @return GNSS hardware model name as a string if possible, otherwise null + */ + public String getGnssHardwareModelName() { + if (mGnssSystemInfoProvider != null) { + return mGnssSystemInfoProvider.getGnssHardwareModelName(); + } else { + return null; + } + } + + /** + * Get GNSS hardware capabilities. The capabilities are described in {@link + * android.location.GnssCapabilities} and their integer values correspond to the + * bit positions in the returned {@code long} value. + * + * @param packageName name of requesting package + * @return capabilities supported by the GNSS chipset + */ + public long getGnssCapabilities(String packageName) { + mContext.enforceCallingPermission( + android.Manifest.permission.LOCATION_HARDWARE, + "Location Hardware permission not granted to obtain GNSS chipset capabilities."); + if (!hasGnssPermissions(packageName) || mGnssCapabilitiesProvider == null) { + return GnssCapabilities.INVALID_CAPABILITIES; + } + return mGnssCapabilitiesProvider.getGnssCapabilities(); + } + + /** + * Get size of GNSS batch (GNSS location results are batched together for power savings). + * Requires LOCATION_HARDWARE and GNSS permissions. + * + * @param packageName name of requesting package + * @return size of the GNSS batch collection + */ + public int getGnssBatchSize(String packageName) { + mContext.enforceCallingPermission( + android.Manifest.permission.LOCATION_HARDWARE, + "Location Hardware permission not granted to access hardware batching"); + + if (!hasGnssPermissions(packageName)) { + Log.e(TAG, "getGnssBatchSize called without GNSS permissions"); + return 0; + } + if (mGnssBatchingProvider == null) { + Log.e( + TAG, + "Can not get GNSS batch size. GNSS batching provider " + + "not available."); + return 0; + } + + synchronized (mGnssBatchingLock) { + return mGnssBatchingProvider.getBatchSize(); + } + } + + /** + * Starts GNSS batch collection. GNSS positions are collected in a batch before being delivered + * as a collection. + * + * @param periodNanos duration over which to collect GPS positions before delivering as a + * batch + * @param wakeOnFifoFull specifying whether to wake on full queue + * @param packageName name of requesting package + * @return true of batch started successfully, false otherwise + */ + public boolean startGnssBatch(long periodNanos, boolean wakeOnFifoFull, String packageName) { + mContext.enforceCallingPermission( + android.Manifest.permission.LOCATION_HARDWARE, + "Location Hardware permission not granted to access hardware batching"); + + if (!hasGnssPermissions(packageName)) { + Log.e(TAG, "startGnssBatch called without GNSS permissions"); + return false; + } + if (mGnssBatchingProvider == null) { + Log.e( + TAG, + "Can not start GNSS batching. GNSS batching provider " + + "not available."); + return false; + } + + synchronized (mGnssBatchingLock) { + if (mGnssBatchingInProgress) { + // Current design does not expect multiple starts to be called repeatedly + Log.e(TAG, "startGnssBatch unexpectedly called w/o stopping prior batch"); + // Try to clean up anyway, and continue + stopGnssBatch(); + } + + mGnssBatchingInProgress = true; + return mGnssBatchingProvider.start(periodNanos, wakeOnFifoFull); + } + } + + /** + * Adds a GNSS batching callback for delivering GNSS location batch results. + * + * @param callback called when batching operation is complete to deliver GPS positions + * @param packageName name of requesting package + * @return true if callback is successfully added, false otherwise + */ + public boolean addGnssBatchingCallback(IBatchedLocationCallback callback, String packageName) { + mContext.enforceCallingPermission( + android.Manifest.permission.LOCATION_HARDWARE, + "Location Hardware permission not granted to access hardware batching"); + + if (!hasGnssPermissions(packageName)) { + Log.e(TAG, "addGnssBatchingCallback called without GNSS permissions"); + return false; + } + if (mGnssBatchingProvider == null) { + Log.e( + TAG, + "Can not add GNSS batching callback. GNSS batching provider " + + "not available."); + return false; + } + + CallerIdentity callerIdentity = + new CallerIdentity(Binder.getCallingUid(), Binder.getCallingPid(), packageName); + synchronized (mGnssBatchingLock) { + mGnssBatchingCallback = callback; + mGnssBatchingDeathCallback = + new LocationManagerServiceUtils.LinkedListener<>( + callback, + "BatchedLocationCallback", + callerIdentity, + (IBatchedLocationCallback listener) -> { + stopGnssBatch(); + removeGnssBatchingCallback(); + }); + if (!mGnssBatchingDeathCallback.linkToListenerDeathNotificationLocked( + callback.asBinder())) { + return false; + } + return true; + } + } + + /** + * Force flush GNSS location results from batch. + * + * @param packageName name of requesting package + */ + public void flushGnssBatch(String packageName) { + mContext.enforceCallingPermission( + android.Manifest.permission.LOCATION_HARDWARE, + "Location Hardware permission not granted to access hardware batching"); + + if (!hasGnssPermissions(packageName)) { + Log.e(TAG, "flushGnssBatch called without GNSS permissions"); + return; + } + + if (mGnssBatchingProvider == null) { + Log.e( + TAG, + "Can not flush GNSS batch. GNSS batching provider " + + "not available."); + return; + } + + synchronized (mGnssBatchingLock) { + if (!mGnssBatchingInProgress) { + Log.w(TAG, "flushGnssBatch called with no batch in progress"); + } + mGnssBatchingProvider.flush(); + } + } + + /** + * Removes GNSS batching callback. + */ + public void removeGnssBatchingCallback() { + mContext.enforceCallingPermission( + android.Manifest.permission.LOCATION_HARDWARE, + "Location Hardware permission not granted to access hardware batching"); + + if (mGnssBatchingProvider == null) { + Log.e( + TAG, + "Can not add GNSS batching callback. GNSS batching provider " + + "not available."); + return; + } + + synchronized (mGnssBatchingLock) { + mGnssBatchingDeathCallback.unlinkFromListenerDeathNotificationLocked( + mGnssBatchingCallback.asBinder()); + mGnssBatchingCallback = null; + mGnssBatchingDeathCallback = null; + } + } + + /** + * Stop GNSS batch collection. + * + * @return true if GNSS batch successfully stopped, false otherwise + */ + public boolean stopGnssBatch() { + mContext.enforceCallingPermission( + android.Manifest.permission.LOCATION_HARDWARE, + "Location Hardware permission not granted to access hardware batching"); + + if (mGnssBatchingProvider == null) { + Log.e( + TAG, + "Can not stop GNSS batch. GNSS batching provider " + + "not available."); + return false; + } + synchronized (mGnssBatchingLock) { + mGnssBatchingInProgress = false; + return mGnssBatchingProvider.stop(); + } + } + + private void registerUidListener() { + mContext.getSystemService( + ActivityManager.class).addOnUidImportanceListener( + (uid, importance) -> { + // listener invoked on ui thread, move to our thread to reduce risk + // of blocking ui thread + mHandler.post( + () -> { + onForegroundChanged(uid, + LocationManagerServiceUtils.isImportanceForeground( + importance)); + }); + }, + ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE); + } + + private void onForegroundChanged(int uid, boolean foreground) { + synchronized (mGnssMeasurementsListeners) { + updateListenersOnForegroundChangedLocked( + mGnssMeasurementsListeners, + mGnssMeasurementsProvider, + IGnssMeasurementsListener.Stub::asInterface, + uid, + foreground); + } + synchronized (mGnssNavigationMessageListeners) { + updateListenersOnForegroundChangedLocked( + mGnssNavigationMessageListeners, + mGnssNavigationMessageProvider, + IGnssNavigationMessageListener.Stub::asInterface, + uid, + foreground); + } + synchronized (mGnssStatusListeners) { + updateListenersOnForegroundChangedLocked( + mGnssStatusListeners, + mGnssStatusProvider, + IGnssStatusListener.Stub::asInterface, + uid, + foreground); + } + } + + private <TListener extends IInterface> void updateListenersOnForegroundChangedLocked( + ArrayMap<IBinder, ? extends LinkedListenerBase> + gnssDataListeners, + RemoteListenerHelper<TListener> gnssDataProvider, + Function<IBinder, TListener> mapBinderToListener, + int uid, + boolean foreground) { + for (Map.Entry<IBinder, ? extends LinkedListenerBase> entry : + gnssDataListeners.entrySet()) { + LinkedListenerBase linkedListener = entry.getValue(); + CallerIdentity callerIdentity = linkedListener.getCallerIdentity(); + if (callerIdentity.mUid != uid) { + continue; + } + + if (D) { + Log.d( + TAG, + linkedListener.getListenerName() + + " from uid " + + uid + + " is now " + + LocationManagerServiceUtils.foregroundAsString(foreground)); + } + + TListener listener = mapBinderToListener.apply(entry.getKey()); + if (foreground || mLocationManagerService.isThrottlingExemptLocked(callerIdentity)) { + gnssDataProvider.addListener(listener, callerIdentity); + } else { + gnssDataProvider.removeListener(listener); + } + } + } + + private <TListener extends IInterface> boolean addGnssDataListenerLocked( + TListener listener, + String packageName, + String listenerName, + RemoteListenerHelper<TListener> gnssDataProvider, + ArrayMap<IBinder, + LinkedListener<TListener>> gnssDataListeners, + Consumer<TListener> binderDeathCallback) { + if (!hasGnssPermissions(packageName)) { + Log.e(TAG, "addGnssDataListenerLocked called without GNSS permissions"); + return false; + } + + if (gnssDataProvider == null) { + Log.e( + TAG, + "Can not add GNSS data listener. GNSS data provider " + + "not available."); + return false; + } + + CallerIdentity callerIdentity = + new CallerIdentity(Binder.getCallingUid(), Binder.getCallingPid(), packageName); + LinkedListener<TListener> linkedListener = + new LocationManagerServiceUtils.LinkedListener<>( + listener, listenerName, callerIdentity, binderDeathCallback); + IBinder binder = listener.asBinder(); + if (!linkedListener.linkToListenerDeathNotificationLocked(binder)) { + return false; + } + + gnssDataListeners.put(binder, linkedListener); + long identity = Binder.clearCallingIdentity(); + try { + if (gnssDataProvider == mGnssMeasurementsProvider + || gnssDataProvider == mGnssStatusProvider) { + mLocationUsageLogger.logLocationApiUsage( + LocationStatsEnums.USAGE_STARTED, + gnssDataProvider == mGnssMeasurementsProvider + ? LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER + : LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK, + packageName, + /* LocationRequest= */ null, + /* hasListener= */ true, + /* hasIntent= */ false, + /* geofence= */ null, + LocationManagerServiceUtils.getPackageImportance(packageName, + mContext)); + } + if (mLocationManagerService.isThrottlingExemptLocked(callerIdentity) + || LocationManagerServiceUtils.isImportanceForeground( + LocationManagerServiceUtils.getPackageImportance(packageName, mContext))) { + gnssDataProvider.addListener(listener, callerIdentity); + } + return true; + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + private <TListener extends IInterface> void removeGnssDataListener( + TListener listener, + RemoteListenerHelper<TListener> gnssDataProvider, + ArrayMap<IBinder, + LinkedListener<TListener>> gnssDataListeners) { + if (gnssDataProvider == null) { + Log.e( + TAG, + "Can not remove GNSS data listener. GNSS data provider " + + "not available."); + return; + } + + IBinder binder = listener.asBinder(); + LinkedListener<TListener> linkedListener = + gnssDataListeners.remove(binder); + if (linkedListener == null) { + return; + } + long identity = Binder.clearCallingIdentity(); + try { + if (gnssDataProvider == mGnssMeasurementsProvider + || gnssDataProvider == mGnssStatusProvider) { + mLocationUsageLogger.logLocationApiUsage( + LocationStatsEnums.USAGE_ENDED, + gnssDataProvider == mGnssMeasurementsProvider + ? LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER + : LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK, + linkedListener.getCallerIdentity().mPackageName, + /* LocationRequest= */ null, + /* hasListener= */ true, + /* hasIntent= */ false, + /* geofence= */ null, + LocationManagerServiceUtils.getPackageImportance( + linkedListener.getCallerIdentity().mPackageName, mContext)); + } + } finally { + Binder.restoreCallingIdentity(identity); + } + linkedListener.unlinkFromListenerDeathNotificationLocked(binder); + gnssDataProvider.removeListener(listener); + } + + /** + * Registers listener for GNSS status changes. + * + * @param listener called when GNSS status changes + * @param packageName name of requesting package + * @return true if listener is successfully registered, false otherwise + */ + public boolean registerGnssStatusCallback(IGnssStatusListener listener, String packageName) { + synchronized (mGnssStatusListeners) { + return addGnssDataListenerLocked( + listener, + packageName, + "GnssStatusListener", + mGnssStatusProvider, + mGnssStatusListeners, + this::unregisterGnssStatusCallback); + } + } + + /** + * Unregisters listener for GNSS status changes. + * + * @param listener called when GNSS status changes + */ + public void unregisterGnssStatusCallback(IGnssStatusListener listener) { + synchronized (mGnssStatusListeners) { + removeGnssDataListener(listener, mGnssStatusProvider, mGnssStatusListeners); + } + } + + /** + * Adds a GNSS measurements listener. + * + * @param listener called when GNSS measurements are received + * @param packageName name of requesting package + * @return true if listener is successfully added, false otherwise + */ + public boolean addGnssMeasurementsListener( + IGnssMeasurementsListener listener, String packageName) { + synchronized (mGnssMeasurementsListeners) { + return addGnssDataListenerLocked( + listener, + packageName, + "GnssMeasurementsListener", + mGnssMeasurementsProvider, + mGnssMeasurementsListeners, + this::removeGnssMeasurementsListener); + } + } + + /** + * Injects GNSS measurement corrections. + * + * @param measurementCorrections GNSS measurement corrections + * @param packageName name of requesting package + */ + public void injectGnssMeasurementCorrections( + GnssMeasurementCorrections measurementCorrections, String packageName) { + mContext.enforceCallingPermission( + android.Manifest.permission.LOCATION_HARDWARE, + "Location Hardware permission not granted to inject GNSS measurement corrections."); + if (!hasGnssPermissions(packageName)) { + Log.e(TAG, "Can not inject GNSS corrections due to no permission."); + return; + } + if (mGnssMeasurementCorrectionsProvider == null) { + Log.e( + TAG, + "Can not inject GNSS corrections. GNSS measurement corrections provider " + + "not available."); + return; + } + mGnssMeasurementCorrectionsProvider.injectGnssMeasurementCorrections( + measurementCorrections); + } + + /** + * Removes a GNSS measurements listener. + * + * @param listener called when GNSS measurements are received + */ + public void removeGnssMeasurementsListener(IGnssMeasurementsListener listener) { + synchronized (mGnssMeasurementsListeners) { + removeGnssDataListener(listener, mGnssMeasurementsProvider, mGnssMeasurementsListeners); + } + } + + /** + * Adds a GNSS navigation message listener. + * + * @param listener called when navigation message is received + * @param packageName name of requesting package + * @return true if listener is successfully added, false otherwise + */ + public boolean addGnssNavigationMessageListener( + IGnssNavigationMessageListener listener, String packageName) { + synchronized (mGnssNavigationMessageListeners) { + return addGnssDataListenerLocked( + listener, + packageName, + "GnssNavigationMessageListener", + mGnssNavigationMessageProvider, + mGnssNavigationMessageListeners, + this::removeGnssNavigationMessageListener); + } + } + + /** + * Removes a GNSS navigation message listener. + * + * @param listener called when navigation message is received + */ + public void removeGnssNavigationMessageListener(IGnssNavigationMessageListener listener) { + removeGnssDataListener( + listener, mGnssNavigationMessageProvider, mGnssNavigationMessageListeners); + } + + /** + * Send Ni Response, indicating a location request initiated by a network carrier. + */ + public boolean sendNiResponse(int notifId, int userResponse) { + if (Binder.getCallingUid() != Process.myUid()) { + throw new SecurityException( + "calling sendNiResponse from outside of the system is not allowed"); + } + try { + return mNetInitiatedListener.sendNiResponse(notifId, userResponse); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in LocationManagerService.sendNiResponse"); + return false; + } + } + + /** + * Report location results to GNSS batching listener. + * + * @param locations batch of locations to report to GNSS batching callback + */ + public void onReportLocation(List<Location> locations) { + if (mGnssBatchingCallback == null) { + Log.e(TAG, "reportLocationBatch() called without active Callback"); + return; + } + + try { + mGnssBatchingCallback.onLocationBatch(locations); + } catch (RemoteException e) { + Log.e(TAG, "mGnssBatchingCallback.onLocationBatch failed", e); + } + } + + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; + + IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); + + if (args.length > 0 && args[0].equals("--gnssmetrics")) { + if (mGnssMetricsProvider != null) { + pw.append(mGnssMetricsProvider.getGnssMetricsAsProtoString()); + } + return; + } + + ipw.println("GnssMeasurement Listeners:"); + ipw.increaseIndent(); + synchronized (mGnssMeasurementsListeners) { + for (LinkedListenerBase listener : + mGnssMeasurementsListeners + .values()) { + ipw.println(listener + ": " + mLocationManagerService.isThrottlingExemptLocked( + listener.mCallerIdentity)); + } + } + ipw.decreaseIndent(); + + ipw.println("GnssNavigationMessage Listeners:"); + ipw.increaseIndent(); + synchronized (mGnssNavigationMessageListeners) { + for (LinkedListenerBase listener : + mGnssNavigationMessageListeners.values()) { + ipw.println(listener + ": " + mLocationManagerService.isThrottlingExemptLocked( + listener.mCallerIdentity)); + } + } + ipw.decreaseIndent(); + + ipw.println("GnssStatus Listeners:"); + ipw.increaseIndent(); + synchronized (mGnssStatusListeners) { + for (LinkedListenerBase listener : + mGnssStatusListeners.values()) { + ipw.println(listener + ": " + mLocationManagerService.isThrottlingExemptLocked( + listener.mCallerIdentity)); + } + } + ipw.decreaseIndent(); + + synchronized (mGnssBatchingLock) { + if (mGnssBatchingInProgress) { + ipw.println("GNSS batching in progress"); + } + } + } +} diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index 69f226f67aa6..35a06a977a58 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -49,16 +49,13 @@ import android.location.Address; import android.location.Criteria; import android.location.GeocoderParams; import android.location.Geofence; -import android.location.GnssCapabilities; import android.location.GnssMeasurementCorrections; import android.location.IBatchedLocationCallback; import android.location.IGnssMeasurementsListener; import android.location.IGnssNavigationMessageListener; import android.location.IGnssStatusListener; -import android.location.IGpsGeofenceHardware; import android.location.ILocationListener; import android.location.ILocationManager; -import android.location.INetInitiatedListener; import android.location.Location; import android.location.LocationManager; import android.location.LocationRequest; @@ -67,7 +64,6 @@ import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; -import android.os.IInterface; import android.os.PowerManager; import android.os.PowerManager.ServiceType; import android.os.PowerManagerInternal; @@ -81,7 +77,6 @@ import android.os.WorkSource.WorkChain; import android.provider.Settings; import android.stats.location.LocationStatsEnums; import android.text.TextUtils; -import android.util.ArrayMap; import android.util.ArraySet; import android.util.EventLog; import android.util.Log; @@ -102,13 +97,6 @@ import com.android.server.location.CallerIdentity; import com.android.server.location.GeocoderProxy; import com.android.server.location.GeofenceManager; import com.android.server.location.GeofenceProxy; -import com.android.server.location.GnssBatchingProvider; -import com.android.server.location.GnssCapabilitiesProvider; -import com.android.server.location.GnssLocationProvider; -import com.android.server.location.GnssMeasurementCorrectionsProvider; -import com.android.server.location.GnssMeasurementsProvider; -import com.android.server.location.GnssNavigationMessageProvider; -import com.android.server.location.GnssStatusListenerHelper; import com.android.server.location.LocationBlacklist; import com.android.server.location.LocationFudger; import com.android.server.location.LocationProviderProxy; @@ -117,7 +105,6 @@ import com.android.server.location.LocationRequestStatistics.PackageProviderKey; import com.android.server.location.LocationRequestStatistics.PackageStatistics; import com.android.server.location.MockProvider; import com.android.server.location.PassiveProvider; -import com.android.server.location.RemoteListenerHelper; import com.android.server.pm.permission.PermissionManagerServiceInternal; import java.io.ByteArrayOutputStream; @@ -132,9 +119,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.NoSuchElementException; -import java.util.function.Consumer; -import java.util.function.Function; /** * The service class that manages LocationProviders and issues location @@ -197,17 +181,13 @@ public class LocationManagerService extends ILocationManager.Stub { private GeofenceManager mGeofenceManager; private LocationFudger mLocationFudger; private GeocoderProxy mGeocodeProvider; - private GnssStatusListenerHelper mGnssStatusProvider; - private INetInitiatedListener mNetInitiatedListener; - private PassiveProvider mPassiveProvider; // track passive provider for special cases + @Nullable + private GnssManagerService mGnssManagerService; + private PassiveProvider mPassiveProvider; // track passive provider for special cases private LocationBlacklist mBlacklist; - private GnssMeasurementsProvider mGnssMeasurementsProvider; - private GnssMeasurementCorrectionsProvider mGnssMeasurementCorrectionsProvider; - private GnssNavigationMessageProvider mGnssNavigationMessageProvider; @GuardedBy("mLock") private String mExtraLocationControllerPackage; private boolean mExtraLocationControllerPackageEnabled; - private IGpsGeofenceHardware mGpsGeofenceProxy; // list of currently active providers @GuardedBy("mLock") @@ -239,32 +219,10 @@ public class LocationManagerService extends ILocationManager.Stub { private final ArraySet<String> mIgnoreSettingsPackageWhitelist = new ArraySet<>(); - @GuardedBy("mLock") - private final ArrayMap<IBinder, LinkedListener<IGnssMeasurementsListener>> - mGnssMeasurementsListeners = new ArrayMap<>(); - @GuardedBy("mLock") - private final ArrayMap<IBinder, LinkedListener<IGnssNavigationMessageListener>> - mGnssNavigationMessageListeners = new ArrayMap<>(); - @GuardedBy("mLock") - private final ArrayMap<IBinder, LinkedListener<IGnssStatusListener>> - mGnssStatusListeners = new ArrayMap<>(); - // current active user on the device - other users are denied location data private int mCurrentUserId = UserHandle.USER_SYSTEM; private int[] mCurrentUserProfiles = new int[]{UserHandle.USER_SYSTEM}; - private GnssLocationProvider.GnssSystemInfoProvider mGnssSystemInfoProvider; - private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider; - private GnssCapabilitiesProvider mGnssCapabilitiesProvider; - - private GnssBatchingProvider mGnssBatchingProvider; - @GuardedBy("mLock") - private IBatchedLocationCallback mGnssBatchingCallback; - @GuardedBy("mLock") - private LinkedListener<IBatchedLocationCallback> mGnssBatchingDeathCallback; - @GuardedBy("mLock") - private boolean mGnssBatchingInProgress = false; - @GuardedBy("mLock") @PowerManager.LocationPowerSaveMode private int mBatterySaverMode; @@ -287,7 +245,7 @@ public class LocationManagerService extends ILocationManager.Stub { com.android.internal.R.array.config_locationProviderPackageNames)); permissionManagerInternal.setLocationExtraPackagesProvider( userId -> mContext.getResources().getStringArray( - com.android.internal.R.array.config_locationExtraPackageNames)); + com.android.internal.R.array.config_locationExtraPackageNames)); // most startup is deferred until systemRunning() } @@ -567,7 +525,7 @@ public class LocationManagerService extends ILocationManager.Stub { @GuardedBy("mLock") private void onUidImportanceChangedLocked(int uid, int importance) { - boolean foreground = isImportanceForeground(importance); + boolean foreground = LocationManagerServiceUtils.isImportanceForeground(importance); HashSet<String> affectedProviders = new HashSet<>(mRecordsByProvider.size()); for (Entry<String, ArrayList<UpdateRecord>> entry : mRecordsByProvider.entrySet()) { String provider = entry.getKey(); @@ -576,7 +534,8 @@ public class LocationManagerService extends ILocationManager.Stub { && record.mIsForegroundUid != foreground) { if (D) { Log.d(TAG, "request from uid " + uid + " is now " - + foregroundAsString(foreground)); + + LocationManagerServiceUtils.foregroundAsString( + foreground)); } record.updateForeground(foreground); @@ -589,51 +548,6 @@ public class LocationManagerService extends ILocationManager.Stub { for (String provider : affectedProviders) { applyRequirementsLocked(provider); } - - updateGnssDataProviderOnUidImportanceChangedLocked(mGnssMeasurementsListeners, - mGnssMeasurementsProvider, IGnssMeasurementsListener.Stub::asInterface, - uid, foreground); - - updateGnssDataProviderOnUidImportanceChangedLocked(mGnssNavigationMessageListeners, - mGnssNavigationMessageProvider, IGnssNavigationMessageListener.Stub::asInterface, - uid, foreground); - - updateGnssDataProviderOnUidImportanceChangedLocked(mGnssStatusListeners, - mGnssStatusProvider, IGnssStatusListener.Stub::asInterface, uid, foreground); - } - - @GuardedBy("mLock") - private <TListener extends IInterface> void updateGnssDataProviderOnUidImportanceChangedLocked( - ArrayMap<IBinder, ? extends LinkedListenerBase> gnssDataListeners, - RemoteListenerHelper<TListener> gnssDataProvider, - Function<IBinder, TListener> mapBinderToListener, int uid, boolean foreground) { - for (Entry<IBinder, ? extends LinkedListenerBase> entry : gnssDataListeners.entrySet()) { - LinkedListenerBase linkedListener = entry.getValue(); - CallerIdentity callerIdentity = linkedListener.mCallerIdentity; - if (callerIdentity.mUid != uid) { - continue; - } - - if (D) { - Log.d(TAG, linkedListener.mListenerName + " from uid " - + uid + " is now " + foregroundAsString(foreground)); - } - - TListener listener = mapBinderToListener.apply(entry.getKey()); - if (foreground || isThrottlingExemptLocked(callerIdentity)) { - gnssDataProvider.addListener(listener, callerIdentity); - } else { - gnssDataProvider.removeListener(listener); - } - } - } - - private static String foregroundAsString(boolean foreground) { - return foreground ? "foreground" : "background"; - } - - private static boolean isImportanceForeground(int importance) { - return importance <= FOREGROUND_IMPORTANCE_CUTOFF; } @GuardedBy("mLock") @@ -768,28 +682,15 @@ public class LocationManagerService extends ILocationManager.Stub { mPassiveProvider = new PassiveProvider(mContext, passiveProviderManager); passiveProviderManager.attachLocked(mPassiveProvider); - if (GnssLocationProvider.isSupported()) { - // Create a gps location provider + if (GnssManagerService.isGnssSupported()) { + // Create a gps location provider manager LocationProvider gnssProviderManager = new LocationProvider(GPS_PROVIDER, true); mRealProviders.add(gnssProviderManager); addProviderLocked(gnssProviderManager); - GnssLocationProvider gnssProvider = new GnssLocationProvider(mContext, - gnssProviderManager, - mHandler.getLooper()); - gnssProviderManager.attachLocked(gnssProvider); - - mGnssSystemInfoProvider = gnssProvider.getGnssSystemInfoProvider(); - mGnssBatchingProvider = gnssProvider.getGnssBatchingProvider(); - mGnssMetricsProvider = gnssProvider.getGnssMetricsProvider(); - mGnssCapabilitiesProvider = gnssProvider.getGnssCapabilitiesProvider(); - mGnssStatusProvider = gnssProvider.getGnssStatusProvider(); - mNetInitiatedListener = gnssProvider.getNetInitiatedListener(); - mGnssMeasurementsProvider = gnssProvider.getGnssMeasurementsProvider(); - mGnssMeasurementCorrectionsProvider = - gnssProvider.getGnssMeasurementCorrectionsProvider(); - mGnssNavigationMessageProvider = gnssProvider.getGnssNavigationMessageProvider(); - mGpsGeofenceProxy = gnssProvider.getGpsGeofenceProxy(); + mGnssManagerService = new GnssManagerService(this, mContext, gnssProviderManager, + mLocationUsageLogger); + gnssProviderManager.attachLocked(mGnssManagerService.getGnssLocationProvider()); } /* @@ -857,15 +758,17 @@ public class LocationManagerService extends ILocationManager.Stub { Slog.e(TAG, "no geocoder provider found"); } - // bind to geofence provider - GeofenceProxy provider = GeofenceProxy.createAndBind( - mContext, com.android.internal.R.bool.config_enableGeofenceOverlay, - com.android.internal.R.string.config_geofenceProviderPackageName, - com.android.internal.R.array.config_locationProviderPackageNames, - mGpsGeofenceProxy, - null); - if (provider == null) { - Slog.d(TAG, "Unable to bind FLP Geofence proxy."); + if (mGnssManagerService != null) { + // bind to geofence provider + GeofenceProxy provider = GeofenceProxy.createAndBind( + mContext, com.android.internal.R.bool.config_enableGeofenceOverlay, + com.android.internal.R.string.config_geofenceProviderPackageName, + com.android.internal.R.array.config_locationProviderPackageNames, + mGnssManagerService.getGpsGeofenceProxy(), + null); + if (provider == null) { + Slog.d(TAG, "Unable to bind FLP Geofence proxy."); + } } // bind to hardware activity recognition @@ -939,7 +842,10 @@ public class LocationManagerService extends ILocationManager.Stub { } } - private class LocationProvider implements AbstractLocationProvider.LocationProviderManager { + /** + * Location provider manager, manages a LocationProvider. + */ + class LocationProvider implements AbstractLocationProvider.LocationProviderManager { private final String mName; @@ -948,7 +854,8 @@ public class LocationManagerService extends ILocationManager.Stub { // remember to clear binder identity before invoking any provider operation @GuardedBy("mLock") - @Nullable protected AbstractLocationProvider mProvider; + @Nullable + protected AbstractLocationProvider mProvider; @GuardedBy("mLock") private boolean mUseable; // combined state @@ -958,7 +865,8 @@ public class LocationManagerService extends ILocationManager.Stub { private boolean mEnabled; // state of provider @GuardedBy("mLock") - @Nullable private ProviderProperties mProperties; + @Nullable + private ProviderProperties mProperties; private LocationProvider(String name) { this(name, false); @@ -1095,6 +1003,9 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public void onReportLocation(List<Location> locations) { + if (mGnssManagerService == null) { + return; + } synchronized (mLock) { LocationProvider gpsProvider = getLocationProviderLocked(GPS_PROVIDER); if (gpsProvider == null || !gpsProvider.isUseableLocked()) { @@ -1102,16 +1013,7 @@ public class LocationManagerService extends ILocationManager.Stub { return; } - if (mGnssBatchingCallback == null) { - Slog.e(TAG, "reportLocationBatch() called without active Callback"); - return; - } - - try { - mGnssBatchingCallback.onLocationBatch(locations); - } catch (RemoteException e) { - Slog.e(TAG, "mGnssBatchingCallback.onLocationBatch failed", e); - } + mGnssManagerService.onReportLocation(locations); } } @@ -1300,7 +1202,8 @@ public class LocationManagerService extends ILocationManager.Stub { * A wrapper class holding either an ILocationListener or a PendingIntent to receive * location updates. */ - private final class Receiver extends LinkedListenerBase implements PendingIntent.OnFinished { + private final class Receiver extends LocationManagerServiceUtils.LinkedListenerBase implements + PendingIntent.OnFinished { private static final long WAKELOCK_TIMEOUT_MILLIS = 60 * 1000; private final int mAllowedResolutionLevel; // resolution level allowed to receiver @@ -1614,146 +1517,45 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public int getGnssYearOfHardware() { - if (mGnssSystemInfoProvider != null) { - return mGnssSystemInfoProvider.getGnssYearOfHardware(); - } else { - return 0; - } + return mGnssManagerService == null ? 0 : mGnssManagerService.getGnssYearOfHardware(); } @Override @Nullable public String getGnssHardwareModelName() { - if (mGnssSystemInfoProvider != null) { - return mGnssSystemInfoProvider.getGnssHardwareModelName(); - } else { - return null; - } - } - - private boolean hasGnssPermissions(String packageName) { - synchronized (mLock) { - int allowedResolutionLevel = getCallerAllowedResolutionLevel(); - checkResolutionLevelIsSufficientForProviderUseLocked( - allowedResolutionLevel, - GPS_PROVIDER); - - int pid = Binder.getCallingPid(); - int uid = Binder.getCallingUid(); - long identity = Binder.clearCallingIdentity(); - try { - return checkLocationAccess(pid, uid, packageName, allowedResolutionLevel); - } finally { - Binder.restoreCallingIdentity(identity); - } - } + return mGnssManagerService == null ? "" : mGnssManagerService.getGnssHardwareModelName(); } @Override public int getGnssBatchSize(String packageName) { - mContext.enforceCallingPermission(android.Manifest.permission.LOCATION_HARDWARE, - "Location Hardware permission not granted to access hardware batching"); - - if (hasGnssPermissions(packageName) && mGnssBatchingProvider != null) { - return mGnssBatchingProvider.getBatchSize(); - } else { - return 0; - } + return mGnssManagerService == null ? 0 : mGnssManagerService.getGnssBatchSize(packageName); } @Override public boolean addGnssBatchingCallback(IBatchedLocationCallback callback, String packageName) { - mContext.enforceCallingPermission(android.Manifest.permission.LOCATION_HARDWARE, - "Location Hardware permission not granted to access hardware batching"); - - if (!hasGnssPermissions(packageName) || mGnssBatchingProvider == null) { - return false; - } - - CallerIdentity callerIdentity = new CallerIdentity(Binder.getCallingUid(), - Binder.getCallingPid(), packageName); - synchronized (mLock) { - mGnssBatchingCallback = callback; - mGnssBatchingDeathCallback = new LinkedListener<>(callback, - "BatchedLocationCallback", callerIdentity, - (IBatchedLocationCallback listener) -> { - stopGnssBatch(); - removeGnssBatchingCallback(); - }); - if (!linkToListenerDeathNotificationLocked(callback.asBinder(), - mGnssBatchingDeathCallback)) { - return false; - } - return true; - } + return mGnssManagerService == null ? false : mGnssManagerService.addGnssBatchingCallback( + callback, packageName); } @Override public void removeGnssBatchingCallback() { - synchronized (mLock) { - unlinkFromListenerDeathNotificationLocked(mGnssBatchingCallback.asBinder(), - mGnssBatchingDeathCallback); - mGnssBatchingCallback = null; - mGnssBatchingDeathCallback = null; - } + if (mGnssManagerService != null) mGnssManagerService.removeGnssBatchingCallback(); } @Override public boolean startGnssBatch(long periodNanos, boolean wakeOnFifoFull, String packageName) { - mContext.enforceCallingPermission(android.Manifest.permission.LOCATION_HARDWARE, - "Location Hardware permission not granted to access hardware batching"); - - if (!hasGnssPermissions(packageName) || mGnssBatchingProvider == null) { - return false; - } - - synchronized (mLock) { - if (mGnssBatchingInProgress) { - // Current design does not expect multiple starts to be called repeatedly - Log.e(TAG, "startGnssBatch unexpectedly called w/o stopping prior batch"); - // Try to clean up anyway, and continue - stopGnssBatch(); - } - - mGnssBatchingInProgress = true; - return mGnssBatchingProvider.start(periodNanos, wakeOnFifoFull); - } + return mGnssManagerService == null ? false : mGnssManagerService.startGnssBatch(periodNanos, + wakeOnFifoFull, packageName); } @Override public void flushGnssBatch(String packageName) { - mContext.enforceCallingPermission(android.Manifest.permission.LOCATION_HARDWARE, - "Location Hardware permission not granted to access hardware batching"); - - if (!hasGnssPermissions(packageName)) { - Log.e(TAG, "flushGnssBatch called without GNSS permissions"); - return; - } - - synchronized (mLock) { - if (!mGnssBatchingInProgress) { - Log.w(TAG, "flushGnssBatch called with no batch in progress"); - } - - if (mGnssBatchingProvider != null) { - mGnssBatchingProvider.flush(); - } - } + if (mGnssManagerService != null) mGnssManagerService.flushGnssBatch(packageName); } @Override public boolean stopGnssBatch() { - mContext.enforceCallingPermission(android.Manifest.permission.LOCATION_HARDWARE, - "Location Hardware permission not granted to access hardware batching"); - - synchronized (mLock) { - if (mGnssBatchingProvider != null) { - mGnssBatchingInProgress = false; - return mGnssBatchingProvider.stop(); - } else { - return false; - } - } + return mGnssManagerService == null ? false : mGnssManagerService.stopGnssBatch(); } @GuardedBy("mLock") @@ -2191,7 +1993,7 @@ public class LocationManagerService extends ILocationManager.Stub { } @GuardedBy("mLock") - private boolean isThrottlingExemptLocked(CallerIdentity callerIdentity) { + public boolean isThrottlingExemptLocked(CallerIdentity callerIdentity) { if (callerIdentity.mUid == Process.SYSTEM_UID) { return true; } @@ -2236,8 +2038,10 @@ public class LocationManagerService extends ILocationManager.Stub { mRealRequest = request; mRequest = request; mReceiver = receiver; - mIsForegroundUid = isImportanceForeground( - mActivityManager.getPackageImportance(mReceiver.mCallerIdentity.mPackageName)); + mIsForegroundUid = + LocationManagerServiceUtils.isImportanceForeground( + mActivityManager.getPackageImportance( + mReceiver.mCallerIdentity.mPackageName)); if (D && receiver.mCallerIdentity.mPid == Process.myPid()) { mStackTrace = new Throwable(); @@ -2335,8 +2139,8 @@ public class LocationManagerService extends ILocationManager.Stub { if (receiver == null) { receiver = new Receiver(listener, null, pid, uid, packageName, workSource, hideFromAppOps); - if (!linkToListenerDeathNotificationLocked(receiver.getListener().asBinder(), - receiver)) { + if (!receiver.linkToListenerDeathNotificationLocked( + receiver.getListener().asBinder())) { return null; } mReceivers.put(binder, receiver); @@ -2558,8 +2362,8 @@ public class LocationManagerService extends ILocationManager.Stub { if (D) Log.i(TAG, "remove " + Integer.toHexString(System.identityHashCode(receiver))); if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) { - unlinkFromListenerDeathNotificationLocked(receiver.getListener().asBinder(), - receiver); + receiver.unlinkFromListenerDeathNotificationLocked( + receiver.getListener().asBinder()); receiver.clearPendingBroadcastsLocked(); } @@ -2606,7 +2410,6 @@ public class LocationManagerService extends ILocationManager.Stub { return null; } - // Figure out the provider. Either its explicitly request (deprecated API's), // or use the fused provider String name = request.getProvider(); @@ -2666,7 +2469,7 @@ public class LocationManagerService extends ILocationManager.Stub { if (D) { Log.d(TAG, "not returning last loc for no op app: " + packageName); } - lastLocation = null; + lastLocation = null; } } return lastLocation; @@ -2696,13 +2499,6 @@ public class LocationManagerService extends ILocationManager.Stub { mContext.enforceCallingPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, "Access Fine Location permission not granted to inject Location"); - if (location == null) { - if (D) { - Log.d(TAG, "injectLocation(): called with null location"); - } - return false; - } - synchronized (mLock) { LocationProvider provider = getLocationProviderLocked(location.getProvider()); if (provider == null || !provider.isUseableLocked()) { @@ -2807,219 +2603,58 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public boolean registerGnssStatusCallback(IGnssStatusListener listener, String packageName) { - return addGnssDataListener(listener, packageName, "GnssStatusListener", - mGnssStatusProvider, mGnssStatusListeners, - this::unregisterGnssStatusCallback); + return mGnssManagerService == null ? false : mGnssManagerService.registerGnssStatusCallback( + listener, packageName); } @Override public void unregisterGnssStatusCallback(IGnssStatusListener listener) { - removeGnssDataListener(listener, mGnssStatusProvider, mGnssStatusListeners); + if (mGnssManagerService != null) mGnssManagerService.unregisterGnssStatusCallback(listener); } @Override public boolean addGnssMeasurementsListener( IGnssMeasurementsListener listener, String packageName) { - return addGnssDataListener(listener, packageName, "GnssMeasurementsListener", - mGnssMeasurementsProvider, mGnssMeasurementsListeners, - this::removeGnssMeasurementsListener); + return mGnssManagerService == null ? false + : mGnssManagerService.addGnssMeasurementsListener(listener, packageName); } @Override public void removeGnssMeasurementsListener(IGnssMeasurementsListener listener) { - removeGnssDataListener(listener, mGnssMeasurementsProvider, mGnssMeasurementsListeners); - } - - private abstract static class LinkedListenerBase implements IBinder.DeathRecipient { - protected final CallerIdentity mCallerIdentity; - protected final String mListenerName; - - private LinkedListenerBase(@NonNull CallerIdentity callerIdentity, - @NonNull String listenerName) { - mCallerIdentity = callerIdentity; - mListenerName = listenerName; - } - - @Override - public String toString() { - return mListenerName + "[" + mCallerIdentity.mPackageName + "(" + mCallerIdentity.mPid - + ")]"; - } - } - - private static class LinkedListener<TListener> extends LinkedListenerBase { - private final TListener mListener; - private final Consumer<TListener> mBinderDeathCallback; - - private LinkedListener(@NonNull TListener listener, String listenerName, - @NonNull CallerIdentity callerIdentity, - @NonNull Consumer<TListener> binderDeathCallback) { - super(callerIdentity, listenerName); - mListener = listener; - mBinderDeathCallback = binderDeathCallback; - } - - @Override - public void binderDied() { - if (D) Log.d(TAG, "Remote " + mListenerName + " died."); - mBinderDeathCallback.accept(mListener); - } - } - - private <TListener extends IInterface> boolean addGnssDataListener( - TListener listener, String packageName, String listenerName, - RemoteListenerHelper<TListener> gnssDataProvider, - ArrayMap<IBinder, LinkedListener<TListener>> gnssDataListeners, - Consumer<TListener> binderDeathCallback) { - if (!hasGnssPermissions(packageName) || gnssDataProvider == null) { - return false; - } - - CallerIdentity callerIdentity = new CallerIdentity(Binder.getCallingUid(), - Binder.getCallingPid(), packageName); - LinkedListener<TListener> linkedListener = new LinkedListener<>(listener, - listenerName, callerIdentity, binderDeathCallback); - IBinder binder = listener.asBinder(); - synchronized (mLock) { - if (!linkToListenerDeathNotificationLocked(binder, linkedListener)) { - return false; - } - - gnssDataListeners.put(binder, linkedListener); - long identity = Binder.clearCallingIdentity(); - try { - if (gnssDataProvider == mGnssMeasurementsProvider - || gnssDataProvider == mGnssStatusProvider) { - mLocationUsageLogger.logLocationApiUsage( - LocationStatsEnums.USAGE_STARTED, - gnssDataProvider == mGnssMeasurementsProvider - ? LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER - : LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK, - packageName, - /* LocationRequest= */ null, - /* hasListener= */ true, - /* hasIntent= */ false, - /* geofence= */ null, - mActivityManager.getPackageImportance(packageName)); - } - if (isThrottlingExemptLocked(callerIdentity) - || isImportanceForeground( - mActivityManager.getPackageImportance(packageName))) { - gnssDataProvider.addListener(listener, callerIdentity); - } - return true; - } finally { - Binder.restoreCallingIdentity(identity); - } - } - } - - private <TListener extends IInterface> void removeGnssDataListener( - TListener listener, RemoteListenerHelper<TListener> gnssDataProvider, - ArrayMap<IBinder, LinkedListener<TListener>> gnssDataListeners) { - if (gnssDataProvider == null) { - return; - } - - IBinder binder = listener.asBinder(); - synchronized (mLock) { - LinkedListener<TListener> linkedListener = gnssDataListeners.remove(binder); - if (linkedListener == null) { - return; - } - long identity = Binder.clearCallingIdentity(); - try { - if (gnssDataProvider == mGnssMeasurementsProvider - || gnssDataProvider == mGnssStatusProvider) { - mLocationUsageLogger.logLocationApiUsage( - LocationStatsEnums.USAGE_ENDED, - gnssDataProvider == mGnssMeasurementsProvider - ? LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER - : LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK, - linkedListener.mCallerIdentity.mPackageName, - /* LocationRequest= */ null, - /* hasListener= */ true, - /* hasIntent= */ false, - /* geofence= */ null, - mActivityManager.getPackageImportance( - linkedListener.mCallerIdentity.mPackageName)); - } - } finally { - Binder.restoreCallingIdentity(identity); - } - unlinkFromListenerDeathNotificationLocked(binder, linkedListener); - gnssDataProvider.removeListener(listener); - } - } - - private boolean linkToListenerDeathNotificationLocked(IBinder binder, - LinkedListenerBase linkedListener) { - try { - binder.linkToDeath(linkedListener, 0 /* flags */); - return true; - } catch (RemoteException e) { - // if the remote process registering the listener is already dead, just swallow the - // exception and return - Log.w(TAG, "Could not link " + linkedListener.mListenerName + " death callback.", e); - return false; - } - } - - private boolean unlinkFromListenerDeathNotificationLocked(IBinder binder, - LinkedListenerBase linkedListener) { - try { - binder.unlinkToDeath(linkedListener, 0 /* flags */); - return true; - } catch (NoSuchElementException e) { - // if the death callback isn't connected (it should be...), log error, - // swallow the exception and return - Log.w(TAG, "Could not unlink " + linkedListener.mListenerName + " death callback.", e); - return false; + if (mGnssManagerService != null) { + mGnssManagerService.removeGnssMeasurementsListener( + listener); } } @Override public void injectGnssMeasurementCorrections( GnssMeasurementCorrections measurementCorrections, String packageName) { - mContext.enforceCallingPermission( - android.Manifest.permission.LOCATION_HARDWARE, - "Location Hardware permission not granted to inject GNSS measurement corrections."); - if (!hasGnssPermissions(packageName)) { - Slog.e(TAG, "Can not inject GNSS corrections due to no permission."); - return; + if (mGnssManagerService != null) { + mGnssManagerService.injectGnssMeasurementCorrections( + measurementCorrections, packageName); } - if (mGnssMeasurementCorrectionsProvider == null) { - Slog.e(TAG, "Can not inject GNSS corrections. GNSS measurement corrections provider " - + "not available."); - return; - } - mGnssMeasurementCorrectionsProvider.injectGnssMeasurementCorrections( - measurementCorrections); } @Override public long getGnssCapabilities(String packageName) { - mContext.enforceCallingPermission( - android.Manifest.permission.LOCATION_HARDWARE, - "Location Hardware permission not granted to obtain GNSS chipset capabilities."); - if (!hasGnssPermissions(packageName) || mGnssCapabilitiesProvider == null) { - return GnssCapabilities.INVALID_CAPABILITIES; - } - return mGnssCapabilitiesProvider.getGnssCapabilities(); + return mGnssManagerService == null ? 0L : mGnssManagerService.getGnssCapabilities( + packageName); } @Override public boolean addGnssNavigationMessageListener( IGnssNavigationMessageListener listener, String packageName) { - return addGnssDataListener(listener, packageName, "GnssNavigationMessageListener", - mGnssNavigationMessageProvider, mGnssNavigationMessageListeners, - this::removeGnssNavigationMessageListener); + return mGnssManagerService == null ? false + : mGnssManagerService.addGnssNavigationMessageListener(listener, packageName); } @Override public void removeGnssNavigationMessageListener(IGnssNavigationMessageListener listener) { - removeGnssDataListener(listener, mGnssNavigationMessageProvider, - mGnssNavigationMessageListeners); + if (mGnssManagerService != null) { + mGnssManagerService.removeGnssNavigationMessageListener( + listener); + } } @Override @@ -3059,24 +2694,13 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public boolean sendNiResponse(int notifId, int userResponse) { - if (Binder.getCallingUid() != Process.myUid()) { - throw new SecurityException( - "calling sendNiResponse from outside of the system is not allowed"); - } - try { - return mNetInitiatedListener.sendNiResponse(notifId, userResponse); - } catch (RemoteException e) { - Slog.e(TAG, "RemoteException in LocationManagerService.sendNiResponse"); - return false; - } + return mGnssManagerService == null ? false : mGnssManagerService.sendNiResponse(notifId, + userResponse); } @Override public ProviderProperties getProviderProperties(String providerName) { synchronized (mLock) { - checkResolutionLevelIsSufficientForProviderUseLocked(getCallerAllowedResolutionLevel(), - providerName); - LocationProvider provider = getLocationProviderLocked(providerName); if (provider == null) { return null; @@ -3149,10 +2773,10 @@ public class LocationManagerService extends ILocationManager.Stub { long identity = Binder.clearCallingIdentity(); try { return Settings.Secure.getIntForUser( - mContext.getContentResolver(), - Settings.Secure.LOCATION_MODE, - Settings.Secure.LOCATION_MODE_OFF, - userId) != Settings.Secure.LOCATION_MODE_OFF; + mContext.getContentResolver(), + Settings.Secure.LOCATION_MODE, + Settings.Secure.LOCATION_MODE_OFF, + userId) != Settings.Secure.LOCATION_MODE_OFF; } finally { Binder.restoreCallingIdentity(identity); } @@ -3566,11 +3190,8 @@ public class LocationManagerService extends ILocationManager.Stub { IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); synchronized (mLock) { - if (args.length > 0 && args[0].equals("--gnssmetrics")) { - if (mGnssMetricsProvider != null) { - pw.append(mGnssMetricsProvider.getGnssMetricsAsProtoString()); - } - return; + if (mGnssManagerService != null && args.length > 0 && args[0].equals("--gnssmetrics")) { + mGnssManagerService.dump(fd, pw, args); } ipw.println("Location Manager State:"); @@ -3604,27 +3225,6 @@ public class LocationManagerService extends ILocationManager.Stub { } ipw.decreaseIndent(); - ipw.println("GnssMeasurement Listeners:"); - ipw.increaseIndent(); - for (LinkedListenerBase listener : mGnssMeasurementsListeners.values()) { - ipw.println(listener + ": " + isThrottlingExemptLocked(listener.mCallerIdentity)); - } - ipw.decreaseIndent(); - - ipw.println("GnssNavigationMessage Listeners:"); - ipw.increaseIndent(); - for (LinkedListenerBase listener : mGnssNavigationMessageListeners.values()) { - ipw.println(listener + ": " + isThrottlingExemptLocked(listener.mCallerIdentity)); - } - ipw.decreaseIndent(); - - ipw.println("GnssStatus Listeners:"); - ipw.increaseIndent(); - for (LinkedListenerBase listener : mGnssStatusListeners.values()) { - ipw.println(listener + ": " + isThrottlingExemptLocked(listener.mCallerIdentity)); - } - ipw.decreaseIndent(); - ipw.println("Historical Records by Provider:"); ipw.increaseIndent(); for (Map.Entry<PackageProviderKey, PackageStatistics> entry @@ -3654,7 +3254,7 @@ public class LocationManagerService extends ILocationManager.Stub { mGeofenceManager.dump(ipw); ipw.decreaseIndent(); } - + if (mBlacklist != null) { mBlacklist.dump(ipw); } @@ -3694,11 +3294,11 @@ public class LocationManagerService extends ILocationManager.Stub { for (LocationProvider provider : mProviders) { provider.dumpLocked(fd, ipw, args); } - ipw.decreaseIndent(); + } - if (mGnssBatchingInProgress) { - ipw.println("GNSS batching in progress"); - } + if (mGnssManagerService != null) { + ipw.decreaseIndent(); + mGnssManagerService.dump(fd, pw, args); } } } diff --git a/services/core/java/com/android/server/LocationManagerServiceUtils.java b/services/core/java/com/android/server/LocationManagerServiceUtils.java new file mode 100644 index 000000000000..9c8ac19cc591 --- /dev/null +++ b/services/core/java/com/android/server/LocationManagerServiceUtils.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 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. + */ + +package com.android.server; + +import android.annotation.NonNull; +import android.app.ActivityManager; +import android.content.Context; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Log; + +import com.android.server.location.CallerIdentity; + +import java.util.NoSuchElementException; +import java.util.function.Consumer; + +/** + * Shared utilities for LocationManagerService and GnssManager. + */ +public class LocationManagerServiceUtils { + + private static final String TAG = "LocManagerServiceUtils"; + private static final boolean D = Log.isLoggable(TAG, Log.DEBUG); + + /** + * Listener that can be linked to a binder. + * @param <TListener> listener type + */ + public static class LinkedListener<TListener> extends + LinkedListenerBase { + private final TListener mListener; + private final Consumer<TListener> mBinderDeathCallback; + + public LinkedListener( + @NonNull TListener listener, + String listenerName, + @NonNull CallerIdentity callerIdentity, + @NonNull Consumer<TListener> binderDeathCallback) { + super(callerIdentity, listenerName); + mListener = listener; + mBinderDeathCallback = binderDeathCallback; + } + + @Override + public void binderDied() { + if (D) Log.d(TAG, "Remote " + mListenerName + " died."); + mBinderDeathCallback.accept(mListener); + } + } + + /** + * Skeleton class of listener that can be linked to a binder. + */ + public abstract static class LinkedListenerBase implements IBinder.DeathRecipient { + protected final CallerIdentity mCallerIdentity; + protected final String mListenerName; + + LinkedListenerBase( + @NonNull CallerIdentity callerIdentity, @NonNull String listenerName) { + mCallerIdentity = callerIdentity; + mListenerName = listenerName; + } + + @Override + public String toString() { + return mListenerName + "[" + mCallerIdentity.mPackageName + "(" + mCallerIdentity.mPid + + ")]"; + } + + public CallerIdentity getCallerIdentity() { + return mCallerIdentity; + } + + public String getListenerName() { + return mListenerName; + } + + /** + * Link listener (i.e. callback) to a binder, so that it will be called upon binder's death. + * + * @param binder that calls listener upon death + * @return true if listener is successfully linked to binder, false otherwise + */ + public boolean linkToListenerDeathNotificationLocked( + IBinder binder) { + try { + binder.linkToDeath(this, 0 /* flags */); + return true; + } catch (RemoteException e) { + // if the remote process registering the listener is already dead, just swallow the + // exception and return + Log.w(TAG, "Could not link " + mListenerName + " death callback.", e); + return false; + } + } + + /** + * Unlink death listener (i.e. callback) from binder. + * + * @param binder that calls listener upon death + * @return true if binder is successfully unlinked from binder, false otherwise + */ + public boolean unlinkFromListenerDeathNotificationLocked( + IBinder binder) { + try { + binder.unlinkToDeath(this, 0 /* flags */); + return true; + } catch (NoSuchElementException e) { + // if the death callback isn't connected (it should be...), log error, + // swallow the exception and return + Log.w(TAG, "Could not unlink " + mListenerName + " death callback.", e); + return false; + } + } + + } + + /** + * Convert boolean foreground into "foreground" or "background" string. + * + * @param foreground boolean indicating foreground + * @return "foreground" string if true, false otherwise + */ + public static String foregroundAsString(boolean foreground) { + return foreground ? "foreground" : "background"; + } + + + /** + * Classifies importance level as foreground or not. + * + * @param importance level as int + * @return boolean indicating if importance level is foreground or greater + */ + public static boolean isImportanceForeground(int importance) { + return importance <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; + } + + /** + * Get package importance level. + * + * @param packageName package name + * @return package importance level as int + */ + public static int getPackageImportance(String packageName, Context context) { + return ((ActivityManager) context.getSystemService( + Context.ACTIVITY_SERVICE)).getPackageImportance(packageName); + } +} diff --git a/services/core/java/com/android/server/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java index fa1653db3579..793e34292623 100644 --- a/services/core/java/com/android/server/MasterClearReceiver.java +++ b/services/core/java/com/android/server/MasterClearReceiver.java @@ -88,7 +88,7 @@ public class MasterClearReceiver extends BroadcastReceiver { } }; - if (mWipeExternalStorage || mWipeEsims) { + if (mWipeExternalStorage) { // thr will be started at the end of this task. new WipeDataTask(context, thr).execute(); } else { diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 67686e0c7236..3916f0d78931 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -208,6 +208,12 @@ class StorageManagerService extends IStorageManager.Stub */ private static final String ISOLATED_STORAGE_ENABLED = "isolated_storage_enabled"; + /** + * If {@code 1}, enables FuseDaemon to intercept file system ops. If {@code -1}, + * disables FuseDaemon. If {@code 0}, uses the default value from the build system. + */ + private static final String FUSE_ENABLED = "fuse_enabled"; + public static class Lifecycle extends SystemService { private StorageManagerService mStorageManagerService; @@ -817,8 +823,10 @@ class StorageManagerService extends IStorageManager.Stub DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT, mContext.getMainExecutor(), (properties) -> { refreshIsolatedStorageSettings(); + refreshFuseSettings(); }); refreshIsolatedStorageSettings(); + refreshFuseSettings(); } /** @@ -882,6 +890,18 @@ class StorageManagerService extends IStorageManager.Stub SystemProperties.set(StorageManager.PROP_ISOLATED_STORAGE, Boolean.toString(res)); } + private void refreshFuseSettings() { + int isFuseEnabled = DeviceConfig.getInt(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT, + FUSE_ENABLED, 0); + if (isFuseEnabled == 1) { + SystemProperties.set(StorageManager.PROP_FUSE, "true"); + } else if (isFuseEnabled == -1) { + SystemProperties.set(StorageManager.PROP_FUSE, "false"); + } + // else, keep the build config. + // This can be overridden be direct adjustment of persist.sys.prop + } + /** * MediaProvider has a ton of code that makes assumptions about storage * paths never changing, so we outright kill them to pick up new state. diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index ecbbef11b893..f91cf0cc1255 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -33,6 +33,9 @@ import android.os.IBinder; import android.os.Message; import android.os.RemoteException; import android.os.UserHandle; +import android.telephony.Annotation.DataFailureCause; +import android.telephony.Annotation.RadioPowerState; +import android.telephony.Annotation.SrvccState; import android.telephony.CallAttributes; import android.telephony.CallQuality; import android.telephony.CellInfo; @@ -245,7 +248,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private int mActiveDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; - @TelephonyManager.RadioPowerState + @RadioPowerState private int mRadioPowerState = TelephonyManager.RADIO_POWER_UNAVAILABLE; private final LocalLog mLocalLog = new LocalLog(100); @@ -382,7 +385,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mContext = context; mBatteryStats = BatteryStatsService.getService(); - int numPhones = TelephonyManager.getDefault().getPhoneCount(); + int numPhones = TelephonyManager.getDefault().getMaxPhoneCount(); if (DBG) log("TelephonyRegistry: ctor numPhones=" + numPhones); mNumPhones = numPhones; mCallState = new int[numPhones]; @@ -1718,7 +1721,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } public void notifyPreciseDataConnectionFailed(int phoneId, int subId, String apnType, - String apn, @DataFailCause.FailCause int failCause) { + String apn, @DataFailureCause int failCause) { if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) { return; } @@ -1748,7 +1751,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override - public void notifySrvccStateChanged(int subId, @TelephonyManager.SrvccState int state) { + public void notifySrvccStateChanged(int subId, @SrvccState int state) { if (!checkNotifyPermission("notifySrvccStateChanged()")) { return; } @@ -1855,8 +1858,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - public void notifyRadioPowerStateChanged(int phoneId, int subId, - @TelephonyManager.RadioPowerState int state) { + public void notifyRadioPowerStateChanged(int phoneId, int subId, @RadioPowerState int state) { if (!checkNotifyPermission("notifyRadioPowerStateChanged()")) { return; } @@ -2227,7 +2229,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private void broadcastPreciseDataConnectionStateChanged(int state, int networkType, String apnType, String apn, LinkProperties linkProperties, - @DataFailCause.FailCause int failCause) { + @DataFailureCause int failCause) { Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED); intent.putExtra(PhoneConstants.STATE_KEY, state); intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType); diff --git a/services/core/java/com/android/server/UiThread.java b/services/core/java/com/android/server/UiThread.java index b2fa6846a6d0..34fc9abec51e 100644 --- a/services/core/java/com/android/server/UiThread.java +++ b/services/core/java/com/android/server/UiThread.java @@ -21,6 +21,8 @@ import android.os.Looper; import android.os.Process; import android.os.Trace; +import com.android.internal.annotations.VisibleForTesting; + /** * Shared singleton thread for showing UI. This is a foreground thread, and in * additional should not have operations that can take more than a few ms scheduled @@ -68,4 +70,20 @@ public final class UiThread extends ServiceThread { return sHandler; } } + + /** + * Disposes current ui thread if it's initialized. Should only be used in tests to set up a + * new environment. + */ + @VisibleForTesting + public static void dispose() { + synchronized (UiThread.class) { + if (sInstance == null) { + return; + } + + getHandler().runWithScissors(sInstance::quit, 0 /* timeout */); + sInstance = null; + } + } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 7b69bea6014b..ee98af4020ad 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -233,6 +233,7 @@ import android.os.AppZygote; import android.os.BatteryStats; import android.os.Binder; import android.os.BinderProxy; +import android.os.BugreportParams; import android.os.Build; import android.os.Bundle; import android.os.Debug; @@ -2404,7 +2405,8 @@ public class ActivityManagerService extends IActivityManager.Stub final ActiveUids activeUids = new ActiveUids(this, false /* postChangesToAtm */); mProcessList.init(this, activeUids); mLowMemDetector = null; - mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids, handlerThread); + mOomAdjuster = hasHandlerThread + ? new OomAdjuster(this, mProcessList, activeUids, handlerThread) : null; mIntentFirewall = hasHandlerThread ? new IntentFirewall(new IntentFirewallInterface(), mHandler) : null; @@ -7439,6 +7441,7 @@ public class ActivityManagerService extends IActivityManager.Stub dst.setProcess(r); dst.notifyAll(); } + dst.mRestartCount = 0; updateOomAdjLocked(r, true, OomAdjuster.OOM_ADJ_REASON_GET_PROVIDER); maybeUpdateProviderUsageStatsLocked(r, src.info.packageName, src.info.authority); @@ -8255,22 +8258,22 @@ public class ActivityManagerService extends IActivityManager.Stub @Nullable String shareDescription, int bugreportType) { String type = null; switch (bugreportType) { - case ActivityManager.BUGREPORT_OPTION_FULL: + case BugreportParams.BUGREPORT_MODE_FULL: type = "bugreportfull"; break; - case ActivityManager.BUGREPORT_OPTION_INTERACTIVE: + case BugreportParams.BUGREPORT_MODE_INTERACTIVE: type = "bugreportplus"; break; - case ActivityManager.BUGREPORT_OPTION_REMOTE: + case BugreportParams.BUGREPORT_MODE_REMOTE: type = "bugreportremote"; break; - case ActivityManager.BUGREPORT_OPTION_WEAR: + case BugreportParams.BUGREPORT_MODE_WEAR: type = "bugreportwear"; break; - case ActivityManager.BUGREPORT_OPTION_TELEPHONY: + case BugreportParams.BUGREPORT_MODE_TELEPHONY: type = "bugreporttelephony"; break; - case ActivityManager.BUGREPORT_OPTION_WIFI: + case BugreportParams.BUGREPORT_MODE_WIFI: type = "bugreportwifi"; break; default: @@ -8305,7 +8308,7 @@ public class ActivityManagerService extends IActivityManager.Stub final boolean useApi = FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.USE_BUGREPORT_API); - if (useApi && bugreportType == ActivityManager.BUGREPORT_OPTION_INTERACTIVE) { + if (useApi) { // Create intent to trigger Bugreport API via Shell Intent triggerShellBugreport = new Intent(); triggerShellBugreport.setAction(INTENT_BUGREPORT_REQUESTED); @@ -8341,7 +8344,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void requestTelephonyBugReport(String shareTitle, String shareDescription) { requestBugReportWithDescription(shareTitle, shareDescription, - ActivityManager.BUGREPORT_OPTION_TELEPHONY); + BugreportParams.BUGREPORT_MODE_TELEPHONY); } /** @@ -8353,7 +8356,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void requestWifiBugReport(String shareTitle, String shareDescription) { requestBugReportWithDescription(shareTitle, shareDescription, - ActivityManager.BUGREPORT_OPTION_WIFI); + BugreportParams.BUGREPORT_MODE_WIFI); } /** @@ -8361,7 +8364,7 @@ public class ActivityManagerService extends IActivityManager.Stub */ @Override public void requestInteractiveBugReport() { - requestBugReportWithDescription(null, null, ActivityManager.BUGREPORT_OPTION_INTERACTIVE); + requestBugReportWithDescription(null, null, BugreportParams.BUGREPORT_MODE_INTERACTIVE); } /** @@ -8372,7 +8375,7 @@ public class ActivityManagerService extends IActivityManager.Stub public void requestInteractiveBugReportWithDescription(String shareTitle, String shareDescription) { requestBugReportWithDescription(shareTitle, shareDescription, - ActivityManager.BUGREPORT_OPTION_INTERACTIVE); + BugreportParams.BUGREPORT_MODE_INTERACTIVE); } /** @@ -8380,7 +8383,7 @@ public class ActivityManagerService extends IActivityManager.Stub */ @Override public void requestFullBugReport() { - requestBugReportWithDescription(null, null, ActivityManager.BUGREPORT_OPTION_FULL); + requestBugReportWithDescription(null, null, BugreportParams.BUGREPORT_MODE_FULL); } /** @@ -8388,7 +8391,7 @@ public class ActivityManagerService extends IActivityManager.Stub */ @Override public void requestRemoteBugReport() { - requestBugReportWithDescription(null, null, ActivityManager.BUGREPORT_OPTION_REMOTE); + requestBugReportWithDescription(null, null, BugreportParams.BUGREPORT_MODE_REMOTE); } public void registerProcessObserver(IProcessObserver observer) { @@ -13882,9 +13885,20 @@ public class ActivityManagerService extends IActivityManager.Stub return false; } + /** + * Remove the dying provider from known provider map and launching provider map. + * @param proc The dying process recoder + * @param cpr The provider to be removed. + * @param always If true, remove the provider from launching map always, no more restart attempt + * @return true if the given provider is in launching + */ private final boolean removeDyingProviderLocked(ProcessRecord proc, ContentProviderRecord cpr, boolean always) { - final boolean inLaunching = mLaunchingProviders.contains(cpr); + boolean inLaunching = mLaunchingProviders.contains(cpr); + if (inLaunching && !always && ++cpr.mRestartCount > ContentProviderRecord.MAX_RETRY_COUNT) { + // It's being launched but we've reached maximum attempts, force the removal + always = true; + } if (!inLaunching || always) { synchronized (cpr) { @@ -13936,6 +13950,8 @@ public class ActivityManagerService extends IActivityManager.Stub if (inLaunching && always) { mLaunchingProviders.remove(cpr); + cpr.mRestartCount = 0; + inLaunching = false; } return inLaunching; } @@ -14151,6 +14167,10 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { ContentProviderRecord cpr = mLaunchingProviders.get(i); if (cpr.launchingApp == app) { + if (++cpr.mRestartCount > ContentProviderRecord.MAX_RETRY_COUNT) { + // It's being launched but we've reached maximum attempts, mark it as bad + alwaysBad = true; + } if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) { restart = true; } else { diff --git a/services/core/java/com/android/server/am/ContentProviderRecord.java b/services/core/java/com/android/server/am/ContentProviderRecord.java index 46dfc7c60fd9..d8d8cccc05f3 100644 --- a/services/core/java/com/android/server/am/ContentProviderRecord.java +++ b/services/core/java/com/android/server/am/ContentProviderRecord.java @@ -38,6 +38,9 @@ import java.io.PrintWriter; import java.util.ArrayList; final class ContentProviderRecord implements ComponentName.WithComponentName { + // Maximum attempts to bring up the content provider before giving up. + static final int MAX_RETRY_COUNT = 3; + final ActivityManagerService service; public final ProviderInfo info; final int uid; @@ -54,6 +57,7 @@ final class ContentProviderRecord implements ComponentName.WithComponentName { ArrayMap<IBinder, ExternalProcessHandle> externalProcessTokenToHandle; // Count for external process for which we have no handles. int externalProcessNoHandleCount; + int mRestartCount; // number of times we tried before bringing up it successfully. ProcessRecord proc; // if non-null, hosting process. ProcessRecord launchingApp; // if non-null, waiting for this app to be launched. String stringName; diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index f8663147eb46..798185ad88f7 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -65,6 +65,7 @@ import android.content.pm.PermissionInfo; import android.content.pm.UserInfo; import android.database.ContentObserver; import android.hardware.camera2.CameraDevice.CAMERA_AUDIO_RESTRICTION; +import android.media.AudioAttributes; import android.net.Uri; import android.os.AsyncTask; import android.os.Binder; @@ -360,7 +361,7 @@ public class AppOpsService extends IAppOpsService.Stub { public int startNesting; public ArrayMap<String, Ops> pkgOps; - private SparseIntArray opModes; + public SparseIntArray opModes; // true indicates there is an interested observer, false there isn't but it has such an op public SparseBooleanArray foregroundOps; @@ -382,64 +383,6 @@ public class AppOpsService extends IAppOpsService.Stub { && (pendingState == UID_STATE_CACHED)); } - public int getOpModeCount() { - return opModes != null ? opModes.size() : 0; - } - - public int getOpCodeAt(int index) { - return opModes.keyAt(index); - } - - public boolean hasOpMode(int code) { - return opModes != null && opModes.indexOfKey(code) >= 0; - } - - public int getOpMode(int code) { - return opModes.get(code); - } - - public boolean putOpMode(int code, int mode) { - if (mode == AppOpsManager.opToDefaultMode(code)) { - return removeOpMode(code); - } - if (opModes == null) { - opModes = new SparseIntArray(); - } - int index = opModes.indexOfKey(code); - if (index < 0) { - opModes.put(code, mode); - return true; - } - if (opModes.valueAt(index) == mode) { - return false; - } - opModes.setValueAt(index, mode); - return true; - } - - public boolean removeOpMode(int code) { - if (opModes == null) { - return false; - } - int index = opModes.indexOfKey(code); - if (index < 0) { - return false; - } - opModes.removeAt(index); - if (opModes.size() == 0) { - opModes = null; - } - return true; - } - - @Nullable - public SparseIntArray cloneOpModes() { - if (opModes == null) { - return null; - } - return opModes.clone(); - } - int evalMode(int op, int mode) { if (mode == AppOpsManager.MODE_FOREGROUND) { return state <= AppOpsManager.resolveFirstUnrestrictedUidState(op) @@ -467,13 +410,14 @@ public class AppOpsService extends IAppOpsService.Stub { public void evalForegroundOps(SparseArray<ArraySet<ModeCallback>> watchers) { SparseBooleanArray which = null; hasForegroundWatchers = false; - for (int i = getOpModeCount() - 1; i >= 0; i--) { - int code = getOpCodeAt(i); - if (getOpMode(code) == AppOpsManager.MODE_FOREGROUND) { - if (which == null) { - which = new SparseBooleanArray(); + if (opModes != null) { + for (int i = opModes.size() - 1; i >= 0; i--) { + if (opModes.valueAt(i) == AppOpsManager.MODE_FOREGROUND) { + if (which == null) { + which = new SparseBooleanArray(); + } + evalForegroundWatchers(opModes.keyAt(i), watchers, which); } - evalForegroundWatchers(code, watchers, which); } } if (pkgOps != null) { @@ -1121,28 +1065,24 @@ public class AppOpsService extends IAppOpsService.Stub { return resOps; } - @Nullable - private ArrayList<AppOpsManager.OpEntry> collectOps(@NonNull UidState uidState, - @Nullable int[] ops) { - int opModeCount = uidState.getOpModeCount(); - if (opModeCount == 0) { + private ArrayList<AppOpsManager.OpEntry> collectOps(SparseIntArray uidOps, int[] ops) { + if (uidOps == null) { return null; } ArrayList<AppOpsManager.OpEntry> resOps = null; if (ops == null) { resOps = new ArrayList<>(); - for (int i = 0; i < opModeCount; i++) { - int code = uidState.getOpCodeAt(i); - resOps.add(new OpEntry(code, uidState.getOpMode(code))); + for (int j=0; j<uidOps.size(); j++) { + resOps.add(new OpEntry(uidOps.keyAt(j), uidOps.valueAt(j))); } } else { - for (int i = 0; i < ops.length; i++) { - int code = ops[i]; - if (uidState.hasOpMode(code)) { + for (int j=0; j<ops.length; j++) { + int index = uidOps.indexOfKey(ops[j]); + if (index >= 0) { if (resOps == null) { resOps = new ArrayList<>(); } - resOps.add(new OpEntry(code, uidState.getOpMode(code))); + resOps.add(new OpEntry(uidOps.keyAt(j), uidOps.valueAt(j))); } } } @@ -1288,11 +1228,11 @@ public class AppOpsService extends IAppOpsService.Stub { if (uidState == null) { return null; } - ArrayList<AppOpsManager.OpEntry> resOps = collectOps(uidState, ops); + ArrayList<AppOpsManager.OpEntry> resOps = collectOps(uidState.opModes, ops); if (resOps == null) { return null; } - ArrayList<AppOpsManager.PackageOps> res = new ArrayList<>(); + ArrayList<AppOpsManager.PackageOps> res = new ArrayList<AppOpsManager.PackageOps>(); AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps( null, uidState.uid, resOps); res.add(resPackage); @@ -1360,14 +1300,29 @@ public class AppOpsService extends IAppOpsService.Stub { return; } uidState = new UidState(uid); - uidState.putOpMode(code, mode); + uidState.opModes = new SparseIntArray(); + uidState.opModes.put(code, mode); mUidStates.put(uid, uidState); scheduleWriteLocked(); - } else { - boolean changed = uidState.putOpMode(code, mode); - if (changed) { + } else if (uidState.opModes == null) { + if (mode != defaultMode) { + uidState.opModes = new SparseIntArray(); + uidState.opModes.put(code, mode); scheduleWriteLocked(); } + } else { + if (uidState.opModes.indexOfKey(code) >= 0 && uidState.opModes.get(code) == mode) { + return; + } + if (mode == defaultMode) { + uidState.opModes.delete(code); + if (uidState.opModes.size() <= 0) { + uidState.opModes = null; + } + } else { + uidState.opModes.put(code, mode); + } + scheduleWriteLocked(); } uidState.evalForegroundOps(mOpModeWatchers); } @@ -1606,13 +1561,16 @@ public class AppOpsService extends IAppOpsService.Stub { for (int i = mUidStates.size() - 1; i >= 0; i--) { UidState uidState = mUidStates.valueAt(i); - if (uidState.uid == reqUid || reqUid == -1) { - for (int opModeIndex = uidState.getOpModeCount() - 1; opModeIndex >= 0; - opModeIndex--) { - final int code = uidState.getOpCodeAt(opModeIndex); - + SparseIntArray opModes = uidState.opModes; + if (opModes != null && (uidState.uid == reqUid || reqUid == -1)) { + final int uidOpCount = opModes.size(); + for (int j = uidOpCount - 1; j >= 0; j--) { + final int code = opModes.keyAt(j); if (AppOpsManager.opAllowsReset(code)) { - uidState.removeOpMode(code); + opModes.removeAt(j); + if (opModes.size() <= 0) { + uidState.opModes = null; + } for (String packageName : getPackagesForUid(uidState.uid)) { callbacks = addCallbacks(callbacks, code, uidState.uid, packageName, mOpModeWatchers.get(code)); @@ -1862,8 +1820,9 @@ public class AppOpsService extends IAppOpsService.Stub { } code = AppOpsManager.opToSwitch(code); UidState uidState = getUidStateLocked(uid, false); - if (uidState != null && uidState.hasOpMode(code)) { - final int rawMode = uidState.getOpMode(code); + if (uidState != null && uidState.opModes != null + && uidState.opModes.indexOfKey(code) >= 0) { + final int rawMode = uidState.opModes.get(code); return raw ? rawMode : uidState.evalMode(code, rawMode); } Op op = getOpLocked(code, uid, packageName, false, false); @@ -2032,8 +1991,8 @@ public class AppOpsService extends IAppOpsService.Stub { final int switchCode = AppOpsManager.opToSwitch(code); // If there is a non-default per UID policy (we set UID op mode only if // non-default) it takes over, otherwise use the per package policy. - if (uidState.hasOpMode(switchCode)) { - final int uidMode = uidState.evalMode(code, uidState.getOpMode(switchCode)); + if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) { + final int uidMode = uidState.evalMode(code, uidState.opModes.get(switchCode)); if (uidMode != AppOpsManager.MODE_ALLOWED) { if (DEBUG) Slog.d(TAG, "noteOperation: uid reject #" + uidMode + " for code " + switchCode + " (" + code + ") uid " + uid + " package " @@ -2334,8 +2293,8 @@ public class AppOpsService extends IAppOpsService.Stub { // If there is a non-default per UID policy (we set UID op mode only if // non-default) it takes over, otherwise use the per package policy. final int opCode = op.op; - if (uidState.hasOpMode(switchCode)) { - final int uidMode = uidState.evalMode(code, uidState.getOpMode(switchCode)); + if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) { + final int uidMode = uidState.evalMode(code, uidState.opModes.get(switchCode)); if (uidMode != AppOpsManager.MODE_ALLOWED && (!startIfModeDefault || uidMode != AppOpsManager.MODE_DEFAULT)) { if (DEBUG) Slog.d(TAG, "noteOperation: uid reject #" + uidMode + " for code " @@ -2654,8 +2613,9 @@ public class AppOpsService extends IAppOpsService.Stub { || !callback.isWatchingUid(uidState.uid)) { continue; } - boolean doAllPackages = uidState.hasOpMode(code) - && uidState.getOpMode(code) == AppOpsManager.MODE_FOREGROUND; + boolean doAllPackages = uidState.opModes != null + && uidState.opModes.indexOfKey(code) >= 0 + && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND; if (uidState.pkgOps != null) { for (int pkgi = uidState.pkgOps.size() - 1; pkgi >= 0; pkgi--) { final Op op = uidState.pkgOps.valueAt(pkgi).get(code); @@ -2978,9 +2938,12 @@ public class AppOpsService extends IAppOpsService.Stub { if (uidState == null) { continue; } - if (uidState.hasOpMode(AppOpsManager.OP_RUN_IN_BACKGROUND)) { - uidState.putOpMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uidState.getOpMode( - AppOpsManager.OP_RUN_IN_BACKGROUND)); + if (uidState.opModes != null) { + final int idx = uidState.opModes.indexOfKey(AppOpsManager.OP_RUN_IN_BACKGROUND); + if (idx >= 0) { + uidState.opModes.put(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, + uidState.opModes.valueAt(idx)); + } } if (uidState.pkgOps == null) { continue; @@ -3036,7 +2999,10 @@ public class AppOpsService extends IAppOpsService.Stub { final int code = Integer.parseInt(parser.getAttributeValue(null, "n")); final int mode = Integer.parseInt(parser.getAttributeValue(null, "m")); UidState uidState = getUidStateLocked(uid, true); - uidState.putOpMode(code, mode); + if (uidState.opModes == null) { + uidState.opModes = new SparseIntArray(); + } + uidState.opModes.put(code, mode); } else { Slog.w(TAG, "Unknown element under <uid-ops>: " + parser.getName()); @@ -3188,38 +3154,47 @@ public class AppOpsService extends IAppOpsService.Stub { out.startTag(null, "app-ops"); out.attribute(null, "v", String.valueOf(CURRENT_VERSION)); - final SparseArray<SparseIntArray> uidOpModes = new SparseArray<>(); + SparseArray<SparseIntArray> uidStatesClone; synchronized (this) { - final int uidStatesSize = mUidStates.size(); - for (int i = 0; i < uidStatesSize; i++) { - final SparseIntArray opModes = mUidStates.valueAt(i).cloneOpModes(); - if (opModes != null) { - final int uid = mUidStates.keyAt(i); - uidOpModes.put(uid, opModes); + uidStatesClone = new SparseArray<>(mUidStates.size()); + + final int uidStateCount = mUidStates.size(); + for (int uidStateNum = 0; uidStateNum < uidStateCount; uidStateNum++) { + UidState uidState = mUidStates.valueAt(uidStateNum); + int uid = mUidStates.keyAt(uidStateNum); + + SparseIntArray opModes = uidState.opModes; + if (opModes != null && opModes.size() > 0) { + uidStatesClone.put(uid, new SparseIntArray(opModes.size())); + + final int opCount = opModes.size(); + for (int opCountNum = 0; opCountNum < opCount; opCountNum++) { + uidStatesClone.get(uid).put( + opModes.keyAt(opCountNum), + opModes.valueAt(opCountNum)); + } } } } - final int uidOpModesSize = uidOpModes.size(); - for (int uidOpModesIndex = 0; uidOpModesIndex < uidOpModesSize; uidOpModesIndex++) { - final int uid = uidOpModes.keyAt(uidOpModesIndex); - final SparseIntArray opModes = uidOpModes.valueAt(uidOpModesIndex); - - out.startTag(null, "uid"); - out.attribute(null, "n", Integer.toString(uid)); - - final int opModesSize = opModes.size(); - for (int opModesIndex = 0; opModesIndex < opModesSize; opModesIndex++) { - final int code = opModes.keyAt(opModesIndex); - final int mode = opModes.valueAt(opModesIndex); - - out.startTag(null, "op"); - out.attribute(null, "n", Integer.toString(code)); - out.attribute(null, "m", Integer.toString(mode)); - out.endTag(null, "op"); + final int uidStateCount = uidStatesClone.size(); + for (int uidStateNum = 0; uidStateNum < uidStateCount; uidStateNum++) { + SparseIntArray opModes = uidStatesClone.valueAt(uidStateNum); + if (opModes != null && opModes.size() > 0) { + out.startTag(null, "uid"); + out.attribute(null, "n", + Integer.toString(uidStatesClone.keyAt(uidStateNum))); + final int opCount = opModes.size(); + for (int opCountNum = 0; opCountNum < opCount; opCountNum++) { + final int op = opModes.keyAt(opCountNum); + final int mode = opModes.valueAt(opCountNum); + out.startTag(null, "op"); + out.attribute(null, "n", Integer.toString(op)); + out.attribute(null, "m", Integer.toString(mode)); + out.endTag(null, "op"); + } + out.endTag(null, "uid"); } - - out.endTag(null, "uid"); } if (allOps != null) { @@ -4164,22 +4139,21 @@ public class AppOpsService extends IAppOpsService.Stub { } for (int i=0; i<mUidStates.size(); i++) { UidState uidState = mUidStates.valueAt(i); + final SparseIntArray opModes = uidState.opModes; final ArrayMap<String, Ops> pkgOps = uidState.pkgOps; if (dumpWatchers || dumpHistory) { continue; } if (dumpOp >= 0 || dumpPackage != null || dumpMode >= 0) { - boolean hasOp = dumpOp < 0 || uidState.hasOpMode(dumpOp); + boolean hasOp = dumpOp < 0 || (uidState.opModes != null + && uidState.opModes.indexOfKey(dumpOp) >= 0); boolean hasPackage = dumpPackage == null; boolean hasMode = dumpMode < 0; - if (!hasMode) { - int opModeCount = uidState.getOpModeCount(); - for (int opModeIndex = 0; opModeIndex < opModeCount; opModeIndex++) { - int code = uidState.getOpCodeAt(opModeIndex); - if (uidState.getOpMode(code) == dumpMode) { + if (!hasMode && opModes != null) { + for (int opi = 0; !hasMode && opi < opModes.size(); opi++) { + if (opModes.valueAt(opi) == dumpMode) { hasMode = true; - break; } } } @@ -4246,18 +4220,20 @@ public class AppOpsService extends IAppOpsService.Stub { } needSep = true; - final int opModeCount = uidState.getOpModeCount(); - for (int opModeIndex = 0; opModeIndex < opModeCount; opModeIndex++) { - final int code = uidState.getOpCodeAt(opModeIndex); - final int mode = uidState.getOpMode(code); - if (dumpOp >= 0 && dumpOp != code) { - continue; - } - if (dumpMode >= 0 && dumpMode != mode) { - continue; + if (opModes != null) { + final int opModeCount = opModes.size(); + for (int j = 0; j < opModeCount; j++) { + final int code = opModes.keyAt(j); + final int mode = opModes.valueAt(j); + if (dumpOp >= 0 && dumpOp != code) { + continue; + } + if (dumpMode >= 0 && dumpMode != mode) { + continue; + } + pw.print(" "); pw.print(AppOpsManager.opToName(code)); + pw.print(": mode="); pw.println(AppOpsManager.modeToName(mode)); } - pw.print(" "); pw.print(AppOpsManager.opToName(code)); - pw.print(": mode="); pw.println(AppOpsManager.modeToName(mode)); } if (pkgOps == null) { diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 77b3feec700e..e02c5be35d7b 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -59,6 +59,7 @@ import android.hardware.hdmi.HdmiAudioSystemClient; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiPlaybackClient; import android.hardware.hdmi.HdmiTvClient; +import android.hardware.input.InputManager; import android.hardware.usb.UsbManager; import android.media.AudioAttributes; import android.media.AudioFocusInfo; @@ -545,6 +546,10 @@ public class AudioService extends IAudioService.Stub private String mEnabledSurroundFormats; private boolean mSurroundModeChanged; + private boolean mMicMuteFromSwitch; + private boolean mMicMuteFromApi; + private boolean mMicMuteFromRestrictions; + @GuardedBy("mSettingsLock") private int mAssistantUid; @@ -882,6 +887,8 @@ public class AudioService extends IAudioService.Stub mRoleObserver.register(); onIndicateSystemReady(); + + setMicMuteFromSwitchInput(); } RoleObserver mRoleObserver; @@ -1021,6 +1028,8 @@ public class AudioService extends IAudioService.Stub sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, SENDMSG_QUEUE, 1, 0, null, 0); + + setMicMuteFromSwitchInput(); } private void onDispatchAudioServerStateChange(boolean state) { @@ -2837,20 +2846,45 @@ public class AudioService extends IAudioService.Stub != PackageManager.PERMISSION_GRANTED) { return; } - setMicrophoneMuteNoCallerCheck(on, userId); + mMicMuteFromApi = on; + setMicrophoneMuteNoCallerCheck(userId); + } + + /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */ + public void setMicrophoneMuteFromSwitch(boolean on) { + int userId = Binder.getCallingUid(); + if (userId != android.os.Process.SYSTEM_UID) { + Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!"); + return; + } + mMicMuteFromSwitch = on; + setMicrophoneMuteNoCallerCheck(userId); + } + + private void setMicMuteFromSwitchInput() { + InputManager im = mContext.getSystemService(InputManager.class); + final int isMicMuted = im.isMicMuted(); + if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) { + setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF); + } + } + + public boolean isMicrophoneMuted() { + return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi; } - private void setMicrophoneMuteNoCallerCheck(boolean on, int userId) { + private void setMicrophoneMuteNoCallerCheck(int userId) { + final boolean muted = isMicrophoneMuted(); if (DEBUG_VOL) { - Log.d(TAG, String.format("Mic mute %s, user=%d", on, userId)); + Log.d(TAG, String.format("Mic mute %d, user=%d", muted, userId)); } // only mute for the current user - if (getCurrentUserId() == userId) { + if (getCurrentUserId() == userId || userId == android.os.Process.SYSTEM_UID) { final boolean currentMute = AudioSystem.isMicrophoneMuted(); final long identity = Binder.clearCallingIdentity(); - AudioSystem.muteMicrophone(on); + AudioSystem.muteMicrophone(muted); Binder.restoreCallingIdentity(identity); - if (on != currentMute) { + if (muted != currentMute) { mContext.sendBroadcastAsUser( new Intent(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED) .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), UserHandle.ALL); @@ -3854,7 +3888,7 @@ public class AudioService extends IAudioService.Stub final boolean muteSystem = (zenPolicy.priorityCategories & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0; final boolean muteNotificationAndRing = ZenModeConfig - .areAllPriorityOnlyNotificationZenSoundsMuted( + .areAllPriorityOnlyRingerSoundsMuted( mNm.getConsolidatedNotificationPolicy()); return muteAlarms && isAlarm(streamType) || muteMedia && isMedia(streamType) @@ -3867,16 +3901,26 @@ public class AudioService extends IAudioService.Stub } /** - * DND total silence: media and alarms streams are tied to the muted ringer + * Notifications, ringer and system sounds are controlled by the ringer: * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)} - * DND alarms only: notification, ringer + system muted (by default tied to muted ringer mode) - * DND priority only: alarms, media, system streams can be muted separate from ringer based on + * DND total silence: media and alarms streams can be muted by DND + * DND alarms only: no streams additionally controlled by DND + * DND priority only: alarms, media, system streams can be muted by DND based on * zenPolicy (this method determines which streams) * @return true if changed, else false */ private boolean updateZenModeAffectedStreams() { + if (!mSystemReady) { + return false; + } + int zenModeAffectedStreams = 0; - if (mSystemReady && mNm.getZenMode() == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { + final int zenMode = mNm.getZenMode(); + + if (zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS) { + zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; + zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; + } else if (zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy(); if ((zenPolicy.priorityCategories & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) { @@ -3888,6 +3932,8 @@ public class AudioService extends IAudioService.Stub zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; } + // even if zen isn't muting the system stream, the ringer mode can still mute + // the system stream if ((zenPolicy.priorityCategories & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) { zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM; @@ -5378,7 +5424,8 @@ public class AudioService extends IAudioService.Stub final boolean isRestricted = newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); if (wasRestricted != isRestricted) { - setMicrophoneMuteNoCallerCheck(isRestricted, userId); + mMicMuteFromRestrictions = isRestricted; + setMicrophoneMuteNoCallerCheck(userId); } } diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index 7302b985181b..3d341ef67d6f 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -25,7 +25,6 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_NONE; import android.app.ActivityManager; -import android.app.AppOpsManager; import android.app.IActivityManager; import android.app.KeyguardManager; import android.app.UserSwitchObserver; @@ -257,12 +256,11 @@ public class BiometricService extends SystemService { private final Injector mInjector; @VisibleForTesting final IBiometricService.Stub mImpl; - private final AppOpsManager mAppOps; private final boolean mHasFeatureFingerprint; private final boolean mHasFeatureIris; private final boolean mHasFeatureFace; @VisibleForTesting - SettingObserver mSettingObserver; + final SettingObserver mSettingObserver; private final List<EnabledOnKeyguardCallback> mEnabledOnKeyguardCallbacks; private final Random mRandom = new Random(); @@ -411,8 +409,8 @@ public class BiometricService extends SystemService { }; private final class Authenticator { - int mType; - BiometricAuthenticator mAuthenticator; + final int mType; + final BiometricAuthenticator mAuthenticator; Authenticator(int type, BiometricAuthenticator authenticator) { mType = type; @@ -445,9 +443,9 @@ public class BiometricService extends SystemService { private final ContentResolver mContentResolver; private final List<BiometricService.EnabledOnKeyguardCallback> mCallbacks; - private Map<Integer, Boolean> mFaceEnabledOnKeyguard = new HashMap<>(); - private Map<Integer, Boolean> mFaceEnabledForApps = new HashMap<>(); - private Map<Integer, Boolean> mFaceAlwaysRequireConfirmation = new HashMap<>(); + private final Map<Integer, Boolean> mFaceEnabledOnKeyguard = new HashMap<>(); + private final Map<Integer, Boolean> mFaceEnabledForApps = new HashMap<>(); + private final Map<Integer, Boolean> mFaceAlwaysRequireConfirmation = new HashMap<>(); /** * Creates a content observer. @@ -864,14 +862,6 @@ public class BiometricService extends SystemService { } } - private void checkAppOp(String opPackageName, int callingUid) { - if (mAppOps.noteOp(AppOpsManager.OP_USE_BIOMETRIC, callingUid, - opPackageName) != AppOpsManager.MODE_ALLOWED) { - Slog.w(TAG, "Rejecting " + opPackageName + "; permission denied"); - throw new SecurityException("Permission denied"); - } - } - private void checkInternalPermission() { getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL, "Must have USE_BIOMETRIC_INTERNAL permission"); @@ -942,7 +932,6 @@ public class BiometricService extends SystemService { mInjector = injector; mImpl = new BiometricServiceWrapper(); - mAppOps = context.getSystemService(AppOpsManager.class); mEnabledOnKeyguardCallbacks = new ArrayList<>(); mSettingObserver = mInjector.getSettingObserver(context, mHandler, mEnabledOnKeyguardCallbacks); diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java index 66bd27c1a76b..aea6d8d24312 100644 --- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java +++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java @@ -16,6 +16,7 @@ package com.android.server.connectivity; +import android.annotation.NonNull; import android.net.ConnectivityManager; import android.net.IDnsResolver; import android.net.INetd; @@ -325,13 +326,13 @@ public class Nat464Xlat extends BaseNetworkObserver { * This is necessary because the LinkProperties in mNetwork come from the transport layer, which * has no idea that 464xlat is running on top of it. */ - public void fixupLinkProperties(LinkProperties oldLp, LinkProperties lp) { + public void fixupLinkProperties(@NonNull LinkProperties oldLp, @NonNull LinkProperties lp) { lp.setNat64Prefix(mNat64Prefix); if (!isRunning()) { return; } - if (lp == null || lp.getAllInterfaceNames().contains(mIface)) { + if (lp.getAllInterfaceNames().contains(mIface)) { return; } @@ -434,7 +435,7 @@ public class Nat464Xlat extends BaseNetworkObserver { @Override public void interfaceRemoved(String iface) { - mNetwork.handler().post(() -> { handleInterfaceRemoved(iface); }); + mNetwork.handler().post(() -> handleInterfaceRemoved(iface)); } @Override diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 7b3eae14c97a..6b70e5f00330 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -199,13 +199,22 @@ public class Vpn { */ private @NonNull List<String> mLockdownWhitelist = Collections.emptyList(); - /** - * List of UIDs for which networking should be blocked until VPN is ready, during brief periods - * when VPN is not running. For example, during system startup or after a crash. + /** + * A memory of what UIDs this class told netd to block for the lockdown feature. + * + * Netd maintains ranges of UIDs for which network should be restricted to using only the VPN + * for the lockdown feature. This class manages these UIDs and sends this information to netd. + * To avoid sending the same commands multiple times (which would be wasteful) and to be able + * to revoke lists (when the rules should change), it's simplest to keep this cache of what + * netd knows, so it can be diffed and sent most efficiently. + * + * The contents of this list must only be changed when updating the UIDs lists with netd, + * since it needs to keep in sync with the picture netd has of them. + * * @see mLockdown */ @GuardedBy("this") - private Set<UidRange> mBlockedUsers = new ArraySet<>(); + private final Set<UidRange> mBlockedUidsAsToldToNetd = new ArraySet<>(); // Handle of the user initiating VPN. private final int mUserHandle; @@ -254,7 +263,7 @@ public class Vpn { } /** - * Update current state, dispaching event to listeners. + * Update current state, dispatching event to listeners. */ @VisibleForTesting protected void updateState(DetailedState detailedState, String reason) { @@ -1325,7 +1334,7 @@ public class Vpn { * {@link Vpn} goes through a VPN connection or is blocked until one is * available, {@code false} to lift the requirement. * - * @see #mBlockedUsers + * @see #mBlockedUidsAsToldToNetd */ @GuardedBy("this") private void setVpnForcedLocked(boolean enforce) { @@ -1336,37 +1345,47 @@ public class Vpn { exemptedPackages = new ArrayList<>(mLockdownWhitelist); exemptedPackages.add(mPackage); } - final Set<UidRange> removedRanges = new ArraySet<>(mBlockedUsers); + final Set<UidRange> rangesToTellNetdToRemove = new ArraySet<>(mBlockedUidsAsToldToNetd); - Set<UidRange> addedRanges = Collections.emptySet(); + final Set<UidRange> rangesToTellNetdToAdd; if (enforce) { - addedRanges = createUserAndRestrictedProfilesRanges(mUserHandle, - /* allowedApplications */ null, - /* disallowedApplications */ exemptedPackages); + final Set<UidRange> rangesThatShouldBeBlocked = + createUserAndRestrictedProfilesRanges(mUserHandle, + /* allowedApplications */ null, + /* disallowedApplications */ exemptedPackages); // The UID range of the first user (0-99999) would block the IPSec traffic, which comes // directly from the kernel and is marked as uid=0. So we adjust the range to allow // it through (b/69873852). - for (UidRange range : addedRanges) { + for (UidRange range : rangesThatShouldBeBlocked) { if (range.start == 0) { - addedRanges.remove(range); + rangesThatShouldBeBlocked.remove(range); if (range.stop != 0) { - addedRanges.add(new UidRange(1, range.stop)); + rangesThatShouldBeBlocked.add(new UidRange(1, range.stop)); } } } - removedRanges.removeAll(addedRanges); - addedRanges.removeAll(mBlockedUsers); + rangesToTellNetdToRemove.removeAll(rangesThatShouldBeBlocked); + rangesToTellNetdToAdd = rangesThatShouldBeBlocked; + // The ranges to tell netd to add are the ones that should be blocked minus the + // ones it already knows to block. Note that this will change the contents of + // rangesThatShouldBeBlocked, but the list of ranges that should be blocked is + // not used after this so it's fine to destroy it. + rangesToTellNetdToAdd.removeAll(mBlockedUidsAsToldToNetd); + } else { + rangesToTellNetdToAdd = Collections.emptySet(); } - setAllowOnlyVpnForUids(false, removedRanges); - setAllowOnlyVpnForUids(true, addedRanges); + // If mBlockedUidsAsToldToNetd used to be empty, this will always be a no-op. + setAllowOnlyVpnForUids(false, rangesToTellNetdToRemove); + // If nothing should be blocked now, this will now be a no-op. + setAllowOnlyVpnForUids(true, rangesToTellNetdToAdd); } /** - * Either add or remove a list of {@link UidRange}s to the list of UIDs that are only allowed - * to make connections through sockets that have had {@code protect()} called on them. + * Tell netd to add or remove a list of {@link UidRange}s to the list of UIDs that are only + * allowed to make connections through sockets that have had {@code protect()} called on them. * * @param enforce {@code true} to add to the blacklist, {@code false} to remove. * @param ranges {@link Collection} of {@link UidRange}s to add (if {@param enforce} is @@ -1388,9 +1407,9 @@ public class Vpn { return false; } if (enforce) { - mBlockedUsers.addAll(ranges); + mBlockedUidsAsToldToNetd.addAll(ranges); } else { - mBlockedUsers.removeAll(ranges); + mBlockedUidsAsToldToNetd.removeAll(ranges); } return true; } @@ -1557,17 +1576,18 @@ public class Vpn { /** * @param uid The target uid. * - * @return {@code true} if {@code uid} is included in one of the mBlockedUsers ranges and the - * VPN is not connected, or if the VPN is connected but does not apply to the {@code uid}. + * @return {@code true} if {@code uid} is included in one of the mBlockedUidsAsToldToNetd + * ranges and the VPN is not connected, or if the VPN is connected but does not apply to + * the {@code uid}. * * @apiNote This method don't check VPN lockdown status. - * @see #mBlockedUsers + * @see #mBlockedUidsAsToldToNetd */ public synchronized boolean isBlockingUid(int uid) { if (mNetworkInfo.isConnected()) { return !appliesToUid(uid); } else { - return UidRange.containsUid(mBlockedUsers, uid); + return UidRange.containsUid(mBlockedUidsAsToldToNetd, uid); } } diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java index cfbf8bcd6433..96ba8ef6b20e 100644 --- a/services/core/java/com/android/server/hdmi/Constants.java +++ b/services/core/java/com/android/server/hdmi/Constants.java @@ -394,10 +394,6 @@ final class Constants { static final String PROPERTY_PREFERRED_ADDRESS_PLAYBACK = "persist.sys.hdmi.addr.playback"; static final String PROPERTY_PREFERRED_ADDRESS_TV = "persist.sys.hdmi.addr.tv"; - // Property name for the local device configurations. - // TODO(OEM): OEM should provide this property, and the value is the comma separated integer - // values which denotes the device type in HDMI Spec 1.4. - static final String PROPERTY_DEVICE_TYPE = "ro.hdmi.device_type"; // TODO(OEM): Set this to false to keep the playback device in sleep upon hotplug event. // True by default. diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 3856de47a522..c3354e1d7e0f 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -56,8 +56,8 @@ import android.media.AudioManager; import android.media.tv.TvInputManager; import android.media.tv.TvInputManager.TvInputCallback; import android.net.Uri; -import android.os.Build; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; @@ -68,6 +68,7 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings.Global; +import android.sysprop.HdmiProperties; import android.text.TextUtils; import android.util.ArraySet; import android.util.Slog; @@ -95,6 +96,8 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; /** * Provides a service for sending and processing HDMI control messages, @@ -452,7 +455,14 @@ public class HdmiControlService extends SystemService { public HdmiControlService(Context context) { super(context); - mLocalDevices = getIntList(SystemProperties.get(Constants.PROPERTY_DEVICE_TYPE)); + List<Integer> deviceTypes = HdmiProperties.device_type(); + if (deviceTypes.contains(null)) { + Slog.w(TAG, "Error parsing ro.hdmi.device.type: " + SystemProperties.get( + "ro.hdmi.device_type")); + deviceTypes = deviceTypes.stream().filter(Objects::nonNull).collect( + Collectors.toList()); + } + mLocalDevices = deviceTypes; mSettingsObserver = new SettingsObserver(mHandler); } diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 8fbad4c5910b..7e6e6680905e 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -47,6 +47,7 @@ import android.hardware.input.InputManager; import android.hardware.input.InputManagerInternal; import android.hardware.input.KeyboardLayout; import android.hardware.input.TouchCalibration; +import android.media.AudioManager; import android.os.Binder; import android.os.Bundle; import android.os.Environment; @@ -296,6 +297,9 @@ public class InputManagerService extends IInputManager.Stub /** Switch code: Camera lens cover. When set the lens is covered. */ public static final int SW_CAMERA_LENS_COVER = 0x09; + /** Switch code: Microphone. When set it is off. */ + public static final int SW_MUTE_DEVICE = 0x0e; + public static final int SW_LID_BIT = 1 << SW_LID; public static final int SW_TABLET_MODE_BIT = 1 << SW_TABLET_MODE; public static final int SW_KEYPAD_SLIDE_BIT = 1 << SW_KEYPAD_SLIDE; @@ -306,6 +310,7 @@ public class InputManagerService extends IInputManager.Stub public static final int SW_JACK_BITS = SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_JACK_PHYSICAL_INSERT_BIT | SW_LINEOUT_INSERT_BIT; public static final int SW_CAMERA_LENS_COVER_BIT = 1 << SW_CAMERA_LENS_COVER; + public static final int SW_MUTE_DEVICE_BIT = 1 << SW_MUTE_DEVICE; /** Whether to use the dev/input/event or uevent subsystem for the audio jack. */ final boolean mUseDevInputEventForAudioJack; @@ -972,6 +977,11 @@ public class InputManagerService extends IInputManager.Stub } @Override // Binder call + public int isMicMuted() { + return getSwitchState(-1, InputDevice.SOURCE_ANY, SW_MUTE_DEVICE); + } + + @Override // Binder call public void registerTabletModeChangedListener(ITabletModeChangedListener listener) { if (!checkCallingPermission(android.Manifest.permission.TABLET_MODE, "registerTabletModeChangedListener()")) { @@ -1804,6 +1814,12 @@ public class InputManagerService extends IInputManager.Stub mHandler.obtainMessage(MSG_DELIVER_TABLET_MODE_CHANGED, args).sendToTarget(); } + + if ((switchMask & SW_MUTE_DEVICE_BIT) != 0) { + final boolean micMute = ((switchValues & SW_MUTE_DEVICE_BIT) != 0); + AudioManager audioManager = mContext.getSystemService(AudioManager.class); + audioManager.setMicrophoneMuteFromSwitch(micMute); + } } // Native callback. diff --git a/services/core/java/com/android/server/integrity/engine/AppInstallMetadata.java b/services/core/java/com/android/server/integrity/engine/AppInstallMetadata.java new file mode 100644 index 000000000000..c2ed3df0ffff --- /dev/null +++ b/services/core/java/com/android/server/integrity/engine/AppInstallMetadata.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 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. + */ + +package com.android.server.integrity.engine; + +/** + * The app install metadata. + * + * <p>The integrity component retrieves metadata for app installs from package manager, passing it + * to the rule evaluation engine to evaluate the metadata against the rules. + */ +public final class AppInstallMetadata { + final String mPackageName; + // Raw string encoding for the SHA-256 hash of the certificate of the app. + final String mAppCertificate; + final String mInstallerName; + // Raw string encoding for the SHA-256 hash of the certificate of the installer. + final String mInstallerCertificate; + final int mVersionCode; + final boolean mIsPreInstalled; + + AppInstallMetadata(String packageName, String appCertificate, String installerName, + String installerCertificate, int versionCode, boolean isPreInstalled) { + this.mPackageName = packageName; + this.mAppCertificate = appCertificate; + this.mInstallerName = installerName; + this.mInstallerCertificate = installerCertificate; + this.mVersionCode = versionCode; + this.mIsPreInstalled = isPreInstalled; + } +} diff --git a/services/core/java/com/android/server/integrity/engine/RuleEvaluation.java b/services/core/java/com/android/server/integrity/engine/RuleEvaluation.java new file mode 100644 index 000000000000..93c9adaac12d --- /dev/null +++ b/services/core/java/com/android/server/integrity/engine/RuleEvaluation.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 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. + */ + +package com.android.server.integrity.engine; + +/** + * The engine used to evaluate rules against app installs. + * + * <p>Every app install is evaluated against rules (pushed by the verifier) by the evaluation engine + * to allow/block that install. + */ +public final class RuleEvaluation { + private static final String TAG = "RuleEvaluation"; + + // TODO: Add singleton injection. +} diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java index ea0fb47a49b3..9246311fcdc7 100644 --- a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java +++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java @@ -129,6 +129,9 @@ public class SyntheticPasswordCrypto { keyStore.load(null); SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null); + if (decryptionKey == null) { + throw new IllegalStateException("SP key is missing: " + keyAlias); + } byte[] intermediate = decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, blob); return decrypt(decryptionKey, intermediate); } catch (Exception e) { @@ -143,6 +146,9 @@ public class SyntheticPasswordCrypto { keyStore.load(null); SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null); + if (decryptionKey == null) { + throw new IllegalStateException("SP key is missing: " + keyAlias); + } byte[] intermediate = decrypt(decryptionKey, blob); return decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, intermediate); } catch (CertificateException | IOException | BadPaddingException @@ -193,6 +199,7 @@ public class SyntheticPasswordCrypto { keyStore = KeyStore.getInstance("AndroidKeyStore"); keyStore.load(null); keyStore.deleteEntry(keyAlias); + Slog.i(TAG, "SP key deleted: " + keyAlias); } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { Slog.e(TAG, "Failed to destroy blob", e); diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index f63aa5256078..65109230bb9a 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -1179,7 +1179,7 @@ public class ZenModeHelper { if (mZenMode == Global.ZEN_MODE_OFF || (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS - && !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(mConfig))) { + && !ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(mConfig))) { // in priority only with ringer not muted, save ringer mode changes // in dnd off, save ringer mode changes setPreviousRingerModeSetting(ringerModeNew); @@ -1200,7 +1200,7 @@ public class ZenModeHelper { && (mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS || mZenMode == Global.ZEN_MODE_ALARMS || (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS - && ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted( + && ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted( mConfig)))) { newZen = Global.ZEN_MODE_OFF; } else if (mZenMode != Global.ZEN_MODE_OFF) { @@ -1264,29 +1264,21 @@ public class ZenModeHelper { @Override public int getRingerModeAffectedStreams(int streams) { - // ringtone and notification streams are always affected by ringer mode - // system stream is affected by ringer mode when not in priority-only + // ringtone, notification and system streams are always affected by ringer mode + // zen muting is handled in AudioService.java's mZenModeAffectedStreams streams |= (1 << AudioSystem.STREAM_RING) | (1 << AudioSystem.STREAM_NOTIFICATION) | (1 << AudioSystem.STREAM_SYSTEM); if (mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS) { - // alarm and music streams affected by ringer mode when in total silence + // alarm and music streams affected by ringer mode (cannot be adjusted) when in + // total silence streams |= (1 << AudioSystem.STREAM_ALARM) | (1 << AudioSystem.STREAM_MUSIC); } else { streams &= ~((1 << AudioSystem.STREAM_ALARM) | (1 << AudioSystem.STREAM_MUSIC)); } - - if (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS - && ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(mConfig)) { - // system stream is not affected by ringer mode in priority only when the ringer - // is zen muted (all other notification categories are muted) - streams &= ~(1 << AudioSystem.STREAM_SYSTEM); - } else { - streams |= (1 << AudioSystem.STREAM_SYSTEM); - } return streams; } } diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java index 288ef0e618b6..f3c912817d05 100644 --- a/services/core/java/com/android/server/om/IdmapManager.java +++ b/services/core/java/com/android/server/om/IdmapManager.java @@ -30,20 +30,17 @@ import android.os.UserHandle; import android.util.Slog; import com.android.server.om.OverlayManagerServiceImpl.PackageManagerHelper; -import com.android.server.pm.Installer; import java.io.File; /** * Handle the creation and deletion of idmap files. * - * The actual work is performed by the idmap binary, launched through Installer - * and installd (or idmap2). + * The actual work is performed by the idmap binary, launched through idmap2d. * * Note: this class is subclassed in the OMS unit tests, and hence not marked as final. */ class IdmapManager { - private static final boolean FEATURE_FLAG_IDMAP2 = true; private static final boolean VENDOR_IS_Q_OR_LATER; static { final String value = SystemProperties.get("ro.vndk.version", "29"); @@ -58,12 +55,10 @@ class IdmapManager { VENDOR_IS_Q_OR_LATER = isQOrLater; } - private final Installer mInstaller; private final PackageManagerHelper mPackageManager; private final IdmapDaemon mIdmapDaemon; - IdmapManager(final Installer installer, final PackageManagerHelper packageManager) { - mInstaller = installer; + IdmapManager(final PackageManagerHelper packageManager) { mPackageManager = packageManager; mIdmapDaemon = IdmapDaemon.getInstance(); } @@ -78,18 +73,13 @@ class IdmapManager { final String targetPath = targetPackage.applicationInfo.getBaseCodePath(); final String overlayPath = overlayPackage.applicationInfo.getBaseCodePath(); try { - if (FEATURE_FLAG_IDMAP2) { - int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId); - boolean enforce = enforceOverlayable(overlayPackage); - if (mIdmapDaemon.verifyIdmap(overlayPath, policies, enforce, userId)) { - return true; - } - return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies, - enforce, userId) != null; - } else { - mInstaller.idmap(targetPath, overlayPath, sharedGid); + int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId); + boolean enforce = enforceOverlayable(overlayPackage); + if (mIdmapDaemon.verifyIdmap(overlayPath, policies, enforce, userId)) { return true; } + return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies, + enforce, userId) != null; } catch (Exception e) { Slog.w(TAG, "failed to generate idmap for " + targetPath + " and " + overlayPath + ": " + e.getMessage()); @@ -102,12 +92,7 @@ class IdmapManager { Slog.d(TAG, "remove idmap for " + oi.baseCodePath); } try { - if (FEATURE_FLAG_IDMAP2) { - return mIdmapDaemon.removeIdmap(oi.baseCodePath, userId); - } else { - mInstaller.removeIdmap(oi.baseCodePath); - return true; - } + return mIdmapDaemon.removeIdmap(oi.baseCodePath, userId); } catch (Exception e) { Slog.w(TAG, "failed to remove idmap for " + oi.baseCodePath + ": " + e.getMessage()); return false; @@ -125,19 +110,12 @@ class IdmapManager { private @NonNull String getIdmapPath(@NonNull final String overlayPackagePath, final int userId) { - if (FEATURE_FLAG_IDMAP2) { - try { - return mIdmapDaemon.getIdmapPath(overlayPackagePath, userId); - } catch (Exception e) { - Slog.w(TAG, "failed to get idmap path for " + overlayPackagePath + ": " - + e.getMessage()); - return ""; - } - } else { - final StringBuilder sb = new StringBuilder("/data/resource-cache/"); - sb.append(overlayPackagePath.substring(1).replace('/', '@')); - sb.append("@idmap"); - return sb.toString(); + try { + return mIdmapDaemon.getIdmapPath(overlayPackagePath, userId); + } catch (Exception e) { + Slog.w(TAG, "failed to get idmap path for " + overlayPackagePath + ": " + + e.getMessage()); + return ""; } } diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index f8b3fb259089..83bea9dd1efc 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -62,7 +62,6 @@ import com.android.server.FgThread; import com.android.server.IoThread; import com.android.server.LocalServices; import com.android.server.SystemService; -import com.android.server.pm.Installer; import com.android.server.pm.UserManagerService; import libcore.util.EmptyArray; @@ -230,8 +229,7 @@ public final class OverlayManagerService extends SystemService { private final AtomicBoolean mPersistSettingsScheduled = new AtomicBoolean(false); - public OverlayManagerService(@NonNull final Context context, - @NonNull final Installer installer) { + public OverlayManagerService(@NonNull final Context context) { super(context); try { traceBegin(TRACE_TAG_RRO, "OMS#OverlayManagerService"); @@ -239,7 +237,7 @@ public final class OverlayManagerService extends SystemService { new File(Environment.getDataSystemDirectory(), "overlays.xml"), "overlays"); mPackageManager = new PackageManagerHelper(); mUserManager = UserManagerService.getInstance(); - IdmapManager im = new IdmapManager(installer, mPackageManager); + IdmapManager im = new IdmapManager(mPackageManager); mSettings = new OverlayManagerSettings(); mImpl = new OverlayManagerServiceImpl(mPackageManager, im, mSettings, getDefaultOverlayPackages(), new OverlayChangeListener()); diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java index 86c709e0d208..61ea84f9dc7f 100644 --- a/services/core/java/com/android/server/pm/AppsFilter.java +++ b/services/core/java/com/android/server/pm/AppsFilter.java @@ -16,6 +16,8 @@ package com.android.server.pm; +import static android.content.pm.PackageParser.Component; +import static android.content.pm.PackageParser.IntentInfo; import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE; import android.Manifest; @@ -23,11 +25,8 @@ import android.annotation.Nullable; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ComponentParseUtils; -import android.content.pm.parsing.ComponentParseUtils.ParsedComponent; -import android.content.pm.parsing.ComponentParseUtils.ParsedIntentInfo; -import android.content.pm.parsing.ComponentParseUtils.ParsedProvider; +import android.content.pm.PackageParser; +import android.content.pm.ProviderInfo; import android.net.Uri; import android.os.Build; import android.os.Process; @@ -41,15 +40,14 @@ import android.util.SparseArray; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.ArrayUtils; import com.android.server.FgThread; import com.android.server.compat.PlatformCompat; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -127,7 +125,8 @@ public class AppsFilter { boolean isGloballyEnabled(); /** @return true if the feature is enabled for the given package. */ - boolean packageIsEnabled(AndroidPackage pkg); + boolean packageIsEnabled(PackageParser.Package pkg); + } private static class FeatureConfigImpl implements FeatureConfig { @@ -160,14 +159,14 @@ public class AppsFilter { } @Override - public boolean packageIsEnabled(AndroidPackage pkg) { + public boolean packageIsEnabled(PackageParser.Package pkg) { final PlatformCompat compatibility = mInjector.getCompatibility(); if (compatibility == null) { Slog.wtf(TAG, "PlatformCompat is null"); return mFeatureEnabled; } - return compatibility.isChangeEnabled(PackageManager.FILTER_APPLICATION_QUERY, - pkg.toAppInfo()); + return compatibility.isChangeEnabled( + PackageManager.FILTER_APPLICATION_QUERY, pkg.applicationInfo); } } @@ -197,13 +196,14 @@ public class AppsFilter { } /** Returns true if the querying package may query for the potential target package */ - private static boolean canQuery(AndroidPackage querying, AndroidPackage potentialTarget) { - if (querying.getQueriesIntents() == null || potentialTarget.getActivities() == null) { + private static boolean canQuery(PackageParser.Package querying, + PackageParser.Package potentialTarget) { + if (querying.mQueriesIntents == null) { return false; } - for (Intent intent : querying.getQueriesIntents()) { - if (matches(intent, potentialTarget.getProviders(), potentialTarget.getActivities(), - potentialTarget.getServices(), potentialTarget.getReceivers())) { + for (Intent intent : querying.mQueriesIntents) { + if (matches(intent, potentialTarget.providers, potentialTarget.activities, + potentialTarget.services, potentialTarget.receivers)) { return true; } } @@ -211,24 +211,24 @@ public class AppsFilter { } private static boolean matches(Intent intent, - @Nullable List<ParsedProvider> providerList, - List<? extends ParsedComponent<? extends ParsedIntentInfo>>... componentLists) { - for (int p = ArrayUtils.size(providerList) - 1; p >= 0; p--) { - ParsedProvider provider = providerList.get(p); + ArrayList<PackageParser.Provider> providerList, + ArrayList<? extends Component<? extends IntentInfo>>... componentLists) { + for (int p = providerList.size() - 1; p >= 0; p--) { + PackageParser.Provider provider = providerList.get(p); + final ProviderInfo providerInfo = provider.info; final Uri data = intent.getData(); if ("content".equalsIgnoreCase(intent.getScheme()) && data != null - && provider.getAuthority().equalsIgnoreCase(data.getAuthority())) { + && providerInfo.authority.equalsIgnoreCase(data.getAuthority())) { return true; } } for (int l = componentLists.length - 1; l >= 0; l--) { - List<? extends ParsedComponent<? extends ParsedIntentInfo>> components = - componentLists[l]; + ArrayList<? extends Component<? extends IntentInfo>> components = componentLists[l]; for (int c = components.size() - 1; c >= 0; c--) { - ParsedComponent<? extends ParsedIntentInfo> component = components.get(c); - List<? extends ParsedIntentInfo> intents = component.intents; + Component<? extends IntentInfo> component = components.get(c); + ArrayList<? extends IntentInfo> intents = component.intents; for (int i = intents.size() - 1; i >= 0; i--) { IntentFilter intentFilter = intents.get(i); if (intentFilter.match(intent.getAction(), intent.getType(), intent.getScheme(), @@ -273,44 +273,44 @@ public class AppsFilter { * @param newPkg the new package being added * @param existing all other packages currently on the device. */ - public void addPackage(AndroidPackage newPkg, Map<String, AndroidPackage> existing) { + public void addPackage(PackageParser.Package newPkg, + Map<String, PackageParser.Package> existing) { // let's re-evaluate the ability of already added packages to see this new package - if (newPkg.isForceQueryable() + if (newPkg.mForceQueryable || (mSystemAppsQueryable && (newPkg.isSystem() || newPkg.isUpdatedSystemApp()))) { - mForceQueryable.add(newPkg.getPackageName()); + mForceQueryable.add(newPkg.packageName); } else { for (String packageName : mQueriesViaIntent.keySet()) { - if (Objects.equals(packageName, newPkg.getPackageName())) { + if (packageName == newPkg.packageName) { continue; } - final AndroidPackage existingPackage = existing.get(packageName); + final PackageParser.Package existingPackage = existing.get(packageName); if (canQuery(existingPackage, newPkg)) { - mQueriesViaIntent.get(packageName).add(newPkg.getPackageName()); + mQueriesViaIntent.get(packageName).add(newPkg.packageName); } } } // if the new package declares them, let's evaluate its ability to see existing packages - mQueriesViaIntent.put(newPkg.getPackageName(), new HashSet<>()); - for (AndroidPackage existingPackage : existing.values()) { - if (Objects.equals(existingPackage.getPackageName(), newPkg.getPackageName())) { + mQueriesViaIntent.put(newPkg.packageName, new HashSet<>()); + for (PackageParser.Package existingPackage : existing.values()) { + if (existingPackage.packageName == newPkg.packageName) { continue; } - if (existingPackage.isForceQueryable() + if (existingPackage.mForceQueryable || (mSystemAppsQueryable && (newPkg.isSystem() || newPkg.isUpdatedSystemApp()))) { continue; } if (canQuery(newPkg, existingPackage)) { - mQueriesViaIntent.get(newPkg.getPackageName()) - .add(existingPackage.getPackageName()); + mQueriesViaIntent.get(newPkg.packageName).add(existingPackage.packageName); } } final HashSet<String> queriesPackages = new HashSet<>( - newPkg.getQueriesPackages() == null ? 0 : newPkg.getQueriesPackages().size()); - if (newPkg.getQueriesPackages() != null) { - queriesPackages.addAll(newPkg.getQueriesPackages()); + newPkg.mQueriesPackages == null ? 0 : newPkg.mQueriesPackages.size()); + if (newPkg.mQueriesPackages != null) { + queriesPackages.addAll(newPkg.mQueriesPackages); } - mQueriesViaPackage.put(newPkg.getPackageName(), queriesPackages); + mQueriesViaPackage.put(newPkg.packageName, queriesPackages); } /** @@ -405,8 +405,8 @@ public class AppsFilter { private boolean shouldFilterApplicationInternal( PackageSetting callingPkgSetting, PackageSetting targetPkgSetting, int userId) { - final String callingName = callingPkgSetting.pkg.getPackageName(); - final AndroidPackage targetPkg = targetPkgSetting.pkg; + final String callingName = callingPkgSetting.pkg.packageName; + final PackageParser.Package targetPkg = targetPkgSetting.pkg; if (!mFeatureConfig.packageIsEnabled(callingPkgSetting.pkg)) { if (DEBUG_LOGGING) { @@ -422,8 +422,8 @@ public class AppsFilter { } return true; } - final String targetName = targetPkg.getPackageName(); - if (callingPkgSetting.pkg.getTargetSdkVersion() < Build.VERSION_CODES.R) { + final String targetName = targetPkg.packageName; + if (callingPkgSetting.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.R) { if (DEBUG_LOGGING) { log(callingPkgSetting, targetPkgSetting, "caller pre-R"); } @@ -435,7 +435,7 @@ public class AppsFilter { } return false; } - if (targetPkg.isForceQueryable()) { + if (targetPkg.mForceQueryable) { if (DEBUG_LOGGING) { log(callingPkgSetting, targetPkgSetting, "manifest forceQueryable"); } @@ -470,11 +470,9 @@ public class AppsFilter { } return false; } - List<ComponentParseUtils.ParsedInstrumentation> instrumentations = - callingPkgSetting.pkg.getInstrumentations(); - if (ArrayUtils.size(instrumentations) > 0) { - for (int i = 0, max = instrumentations.size(); i < max; i++) { - if (Objects.equals(instrumentations.get(i).getTargetPackage(), targetName)) { + if (callingPkgSetting.pkg.instrumentation.size() > 0) { + for (int i = 0, max = callingPkgSetting.pkg.instrumentation.size(); i < max; i++) { + if (callingPkgSetting.pkg.instrumentation.get(i).info.targetPackage == targetName) { if (DEBUG_LOGGING) { log(callingPkgSetting, targetPkgSetting, "instrumentation"); } @@ -506,7 +504,7 @@ public class AppsFilter { private boolean isImplicitlyQueryableSystemApp(PackageSetting targetPkgSetting) { return targetPkgSetting.isSystem() && (mSystemAppsQueryable - || mForceQueryableByDevice.contains(targetPkgSetting.pkg.getPackageName())); + || mForceQueryableByDevice.contains(targetPkgSetting.pkg.packageName)); } public void dumpQueries( diff --git a/services/core/java/com/android/server/pm/ComponentResolver.java b/services/core/java/com/android/server/pm/ComponentResolver.java index 333a6e9cbfc2..8facce112b52 100644 --- a/services/core/java/com/android/server/pm/ComponentResolver.java +++ b/services/core/java/com/android/server/pm/ComponentResolver.java @@ -21,6 +21,7 @@ import static android.content.pm.PackageManagerInternal.PACKAGE_SETUP_WIZARD; import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING; import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE; +import static com.android.server.pm.PackageManagerService.fixProcessName; import android.content.ComponentName; import android.content.Intent; @@ -31,18 +32,13 @@ import android.content.pm.AuxiliaryResolveInfo; import android.content.pm.InstantAppResolveInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; +import android.content.pm.PackageParser; +import android.content.pm.PackageParser.ActivityIntentInfo; +import android.content.pm.PackageParser.ServiceIntentInfo; import android.content.pm.PackageUserState; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ComponentParseUtils.ParsedActivity; -import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo; -import android.content.pm.parsing.ComponentParseUtils.ParsedProvider; -import android.content.pm.parsing.ComponentParseUtils.ParsedProviderIntentInfo; -import android.content.pm.parsing.ComponentParseUtils.ParsedService; -import android.content.pm.parsing.ComponentParseUtils.ParsedServiceIntentInfo; -import android.content.pm.parsing.PackageInfoUtils; import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; @@ -53,19 +49,15 @@ import android.util.Pair; import android.util.Slog; import com.android.internal.annotations.GuardedBy; -import com.android.internal.util.ArrayUtils; import com.android.server.IntentResolver; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; -import java.util.function.Function; /** Resolves all Android component types [activities, services, providers and receivers]. */ public class ComponentResolver { @@ -166,7 +158,7 @@ public class ComponentResolver { /** All available receivers, for your resolving pleasure. */ @GuardedBy("mLock") - private final ActivityIntentResolver mReceivers = new ReceiverIntentResolver(); + private final ActivityIntentResolver mReceivers = new ActivityIntentResolver(); /** All available services, for your resolving pleasure. */ @GuardedBy("mLock") @@ -174,7 +166,7 @@ public class ComponentResolver { /** Mapping from provider authority [first directory in content URI codePath) to provider. */ @GuardedBy("mLock") - private final ArrayMap<String, ParsedProvider> mProvidersByAuthority = new ArrayMap<>(); + private final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = new ArrayMap<>(); /** Whether or not processing protected filters should be deferred. */ private boolean mDeferProtectedFilters = true; @@ -189,7 +181,7 @@ public class ComponentResolver { * /system partition in order to know which component is the setup wizard. This can * only ever be non-empty if {@link #mDeferProtectedFilters} is {@code true}. */ - private List<ParsedActivityIntentInfo> mProtectedFilters; + private List<PackageParser.ActivityIntentInfo> mProtectedFilters; ComponentResolver(UserManagerService userManager, PackageManagerInternal packageManagerInternal, @@ -200,28 +192,28 @@ public class ComponentResolver { } /** Returns the given activity */ - ParsedActivity getActivity(ComponentName component) { + PackageParser.Activity getActivity(ComponentName component) { synchronized (mLock) { return mActivities.mActivities.get(component); } } /** Returns the given provider */ - ParsedProvider getProvider(ComponentName component) { + PackageParser.Provider getProvider(ComponentName component) { synchronized (mLock) { return mProviders.mProviders.get(component); } } /** Returns the given receiver */ - ParsedActivity getReceiver(ComponentName component) { + PackageParser.Activity getReceiver(ComponentName component) { synchronized (mLock) { return mReceivers.mActivities.get(component); } } /** Returns the given service */ - ParsedService getService(ComponentName component) { + PackageParser.Service getService(ComponentName component) { synchronized (mLock) { return mServices.mServices.get(component); } @@ -234,7 +226,7 @@ public class ComponentResolver { } List<ResolveInfo> queryActivities(Intent intent, String resolvedType, int flags, - List<ParsedActivity> activities, int userId) { + List<PackageParser.Activity> activities, int userId) { synchronized (mLock) { return mActivities.queryIntentForPackage( intent, resolvedType, flags, activities, userId); @@ -248,7 +240,7 @@ public class ComponentResolver { } List<ResolveInfo> queryProviders(Intent intent, String resolvedType, int flags, - List<ParsedProvider> providers, int userId) { + List<PackageParser.Provider> providers, int userId) { synchronized (mLock) { return mProviders.queryIntentForPackage(intent, resolvedType, flags, providers, userId); } @@ -262,34 +254,25 @@ public class ComponentResolver { List<ProviderInfo> providerList = null; synchronized (mLock) { for (int i = mProviders.mProviders.size() - 1; i >= 0; --i) { - final ParsedProvider p = mProviders.mProviders.valueAt(i); - if (p.getAuthority() == null) { - continue; - } - - final PackageSetting ps = - (PackageSetting) sPackageManagerInternal.getPackageSetting( - p.getPackageName()); + final PackageParser.Provider p = mProviders.mProviders.valueAt(i); + final PackageSetting ps = (PackageSetting) p.owner.mExtras; if (ps == null) { continue; } - - AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName()); - if (pkg == null) { + if (p.info.authority == null) { continue; } - - if (processName != null && (!p.getProcessName().equals(processName) - || !UserHandle.isSameApp(pkg.getUid(), uid))) { + if (processName != null && (!p.info.processName.equals(processName) + || !UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) { continue; } // See PM.queryContentProviders()'s javadoc for why we have the metaData parameter. if (metaDataKey != null - && (p.getMetaData() == null || !p.getMetaData().containsKey(metaDataKey))) { + && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) { continue; } - final ProviderInfo info = PackageInfoUtils.generateProviderInfo( - pkg, p, flags, ps.readUserState(userId), userId); + final ProviderInfo info = PackageParser.generateProviderInfo( + p, flags, ps.readUserState(userId), userId); if (info == null) { continue; } @@ -302,23 +285,17 @@ public class ComponentResolver { return providerList; } - ProviderInfo queryProvider(String authority, int flags, int uid, int userId) { + ProviderInfo queryProvider(String authority, int flags, int userId) { synchronized (mLock) { - final ParsedProvider p = mProvidersByAuthority.get(authority); + final PackageParser.Provider p = mProvidersByAuthority.get(authority); if (p == null) { return null; } - final PackageSetting ps = (PackageSetting) sPackageManagerInternal.getPackageSetting( - p.getPackageName()); + final PackageSetting ps = (PackageSetting) p.owner.mExtras; if (ps == null) { return null; } - final AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName()); - if (pkg == null) { - return null; - } - return PackageInfoUtils.generateProviderInfo(pkg, p, flags, - ps.readUserState(userId), userId); + return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), userId); } } @@ -326,29 +303,20 @@ public class ComponentResolver { int userId) { synchronized (mLock) { for (int i = mProvidersByAuthority.size() - 1; i >= 0; --i) { - final ParsedProvider p = mProvidersByAuthority.valueAt(i); - if (!p.isSyncable()) { - continue; - } - - final PackageSetting ps = - (PackageSetting) sPackageManagerInternal.getPackageSetting( - p.getPackageName()); + final PackageParser.Provider p = mProvidersByAuthority.valueAt(i); + final PackageSetting ps = (PackageSetting) p.owner.mExtras; if (ps == null) { continue; } - - final AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName()); - if (pkg == null) { + if (!p.syncable) { continue; } - - if (safeMode && (pkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) == 0) { + if (safeMode + && (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { continue; } final ProviderInfo info = - PackageInfoUtils.generateProviderInfo(pkg, p, 0, - ps.readUserState(userId), userId); + PackageParser.generateProviderInfo(p, 0, ps.readUserState(userId), userId); if (info == null) { continue; } @@ -365,7 +333,7 @@ public class ComponentResolver { } List<ResolveInfo> queryReceivers(Intent intent, String resolvedType, int flags, - List<ParsedActivity> receivers, int userId) { + List<PackageParser.Activity> receivers, int userId) { synchronized (mLock) { return mReceivers.queryIntentForPackage(intent, resolvedType, flags, receivers, userId); } @@ -378,7 +346,7 @@ public class ComponentResolver { } List<ResolveInfo> queryServices(Intent intent, String resolvedType, int flags, - List<ParsedService> services, int userId) { + List<PackageParser.Service> services, int userId) { synchronized (mLock) { return mServices.queryIntentForPackage(intent, resolvedType, flags, services, userId); } @@ -392,15 +360,15 @@ public class ComponentResolver { } /** Asserts none of the providers defined in the given package haven't already been defined. */ - void assertProvidersNotDefined(AndroidPackage pkg) throws PackageManagerException { + void assertProvidersNotDefined(PackageParser.Package pkg) throws PackageManagerException { synchronized (mLock) { assertProvidersNotDefinedLocked(pkg); } } /** Add all components defined in the given package to the internal structures. */ - void addAllComponents(AndroidPackage pkg, boolean chatty) { - final ArrayList<ParsedActivityIntentInfo> newIntents = new ArrayList<>(); + void addAllComponents(PackageParser.Package pkg, boolean chatty) { + final ArrayList<PackageParser.ActivityIntentInfo> newIntents = new ArrayList<>(); synchronized (mLock) { addActivitiesLocked(pkg, newIntents, chatty); addReceiversLocked(pkg, chatty); @@ -410,19 +378,17 @@ public class ComponentResolver { final String setupWizardPackage = sPackageManagerInternal.getKnownPackageName( PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM); for (int i = newIntents.size() - 1; i >= 0; --i) { - final ParsedActivityIntentInfo intentInfo = newIntents.get(i); - final PackageSetting disabledPkgSetting = (PackageSetting) sPackageManagerInternal - .getDisabledSystemPackage(intentInfo.getPackageName()); - final AndroidPackage disabledPkg = - disabledPkgSetting == null ? null : disabledPkgSetting.pkg; - final List<ParsedActivity> systemActivities = - disabledPkg != null ? disabledPkg.getActivities() : null; + final PackageParser.ActivityIntentInfo intentInfo = newIntents.get(i); + final PackageParser.Package disabledPkg = sPackageManagerInternal + .getDisabledSystemPackage(intentInfo.activity.info.packageName); + final List<PackageParser.Activity> systemActivities = + disabledPkg != null ? disabledPkg.activities : null; adjustPriority(systemActivities, intentInfo, setupWizardPackage); } } /** Removes all components defined in the given package from the internal structures. */ - void removeAllComponents(AndroidPackage pkg, boolean chatty) { + void removeAllComponents(PackageParser.Package pkg, boolean chatty) { synchronized (mLock) { removeAllComponentsLocked(pkg, chatty); } @@ -441,7 +407,7 @@ public class ComponentResolver { if (mProtectedFilters == null || mProtectedFilters.size() == 0) { return; } - final List<ParsedActivityIntentInfo> protectedFilters = mProtectedFilters; + final List<ActivityIntentInfo> protectedFilters = mProtectedFilters; mProtectedFilters = null; final String setupWizardPackage = sPackageManagerInternal.getKnownPackageName( @@ -451,13 +417,13 @@ public class ComponentResolver { + " All protected intents capped to priority 0"); } for (int i = protectedFilters.size() - 1; i >= 0; --i) { - final ParsedActivityIntentInfo filter = protectedFilters.get(i); - if (filter.getPackageName().equals(setupWizardPackage)) { + final ActivityIntentInfo filter = protectedFilters.get(i); + if (filter.activity.info.packageName.equals(setupWizardPackage)) { if (DEBUG_FILTERS) { Slog.i(TAG, "Found setup wizard;" + " allow priority " + filter.getPriority() + ";" - + " package: " + filter.getPackageName() - + " activity: " + filter.getClassName() + + " package: " + filter.activity.info.packageName + + " activity: " + filter.activity.className + " priority: " + filter.getPriority()); } // skip setup wizard; allow it to keep the high priority filter @@ -465,8 +431,8 @@ public class ComponentResolver { } if (DEBUG_FILTERS) { Slog.i(TAG, "Protected action; cap priority to 0;" - + " package: " + filter.getPackageName() - + " activity: " + filter.getClassName() + + " package: " + filter.activity.info.packageName + + " activity: " + filter.activity.className + " origPrio: " + filter.getPriority()); } filter.setPriority(0); @@ -507,8 +473,8 @@ public class ComponentResolver { void dumpContentProviders(PrintWriter pw, DumpState dumpState, String packageName) { boolean printedSomething = false; - for (ParsedProvider p : mProviders.mProviders.values()) { - if (packageName != null && !packageName.equals(p.getPackageName())) { + for (PackageParser.Provider p : mProviders.mProviders.values()) { + if (packageName != null && !packageName.equals(p.info.packageName)) { continue; } if (!printedSomething) { @@ -518,17 +484,14 @@ public class ComponentResolver { pw.println("Registered ContentProviders:"); printedSomething = true; } - pw.print(" "); - ComponentName.printShortString(pw, p.getPackageName(), p.className); - pw.println(":"); - pw.print(" "); - pw.println(p.toString()); + pw.print(" "); p.printComponentShortName(pw); pw.println(":"); + pw.print(" "); pw.println(p.toString()); } printedSomething = false; - for (Map.Entry<String, ParsedProvider> entry : + for (Map.Entry<String, PackageParser.Provider> entry : mProvidersByAuthority.entrySet()) { - ParsedProvider p = entry.getValue(); - if (packageName != null && !packageName.equals(p.getPackageName())) { + PackageParser.Provider p = entry.getValue(); + if (packageName != null && !packageName.equals(p.info.packageName)) { continue; } if (!printedSomething) { @@ -540,43 +503,25 @@ public class ComponentResolver { } pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); pw.print(" "); pw.println(p.toString()); - - AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName()); - - if (pkg != null) { - // TODO(b/135203078): Print AppInfo? - pw.print(" applicationInfo="); pw.println(pkg.toAppInfo()); + if (p.info != null && p.info.applicationInfo != null) { + final String appInfo = p.info.applicationInfo.toString(); + pw.print(" applicationInfo="); pw.println(appInfo); } } } - void dumpServicePermissions(PrintWriter pw, DumpState dumpState) { + void dumpServicePermissions(PrintWriter pw, DumpState dumpState, String packageName) { if (dumpState.onTitlePrinted()) pw.println(); pw.println("Service permissions:"); - final Iterator<ParsedServiceIntentInfo> filterIterator = mServices.filterIterator(); + final Iterator<ServiceIntentInfo> filterIterator = mServices.filterIterator(); while (filterIterator.hasNext()) { - final ParsedServiceIntentInfo info = filterIterator.next(); - - ParsedService service = null; - - AndroidPackage pkg = sPackageManagerInternal.getPackage(info.getPackageName()); - if (pkg != null && pkg.getServices() != null) { - for (ParsedService parsedService : pkg.getServices()) { - if (Objects.equals(parsedService.className, info.getClassName())) { - service = parsedService; - } - } - } - - if (service == null) { - continue; - } - - final String permission = service.getPermission(); + final ServiceIntentInfo info = filterIterator.next(); + final ServiceInfo serviceInfo = info.service.info; + final String permission = serviceInfo.permission; if (permission != null) { pw.print(" "); - pw.print(service.getComponentName().flattenToShortString()); + pw.print(serviceInfo.getComponentName().flattenToShortString()); pw.print(": "); pw.println(permission); } @@ -584,12 +529,14 @@ public class ComponentResolver { } @GuardedBy("mLock") - private void addActivitiesLocked(AndroidPackage pkg, - List<ParsedActivityIntentInfo> newIntents, boolean chatty) { - final int activitiesSize = ArrayUtils.size(pkg.getActivities()); + private void addActivitiesLocked(PackageParser.Package pkg, + List<PackageParser.ActivityIntentInfo> newIntents, boolean chatty) { + final int activitiesSize = pkg.activities.size(); StringBuilder r = null; for (int i = 0; i < activitiesSize; i++) { - ParsedActivity a = pkg.getActivities().get(i); + PackageParser.Activity a = pkg.activities.get(i); + a.info.processName = + fixProcessName(pkg.applicationInfo.processName, a.info.processName); mActivities.addActivity(a, "activity", newIntents); if (DEBUG_PACKAGE_SCANNING && chatty) { if (r == null) { @@ -597,7 +544,7 @@ public class ComponentResolver { } else { r.append(' '); } - r.append(a.getName()); + r.append(a.info.name); } } if (DEBUG_PACKAGE_SCANNING && chatty) { @@ -606,17 +553,20 @@ public class ComponentResolver { } @GuardedBy("mLock") - private void addProvidersLocked(AndroidPackage pkg, boolean chatty) { - final int providersSize = ArrayUtils.size(pkg.getProviders()); + private void addProvidersLocked(PackageParser.Package pkg, boolean chatty) { + final int providersSize = pkg.providers.size(); StringBuilder r = null; for (int i = 0; i < providersSize; i++) { - EffectiveProvider p = new EffectiveProvider(pkg.getProviders().get(i)); + PackageParser.Provider p = pkg.providers.get(i); + p.info.processName = fixProcessName(pkg.applicationInfo.processName, + p.info.processName); mProviders.addProvider(p); - if (p.getAuthority() != null) { - String[] names = p.getAuthority().split(";"); - p.setEffectiveAuthority(null); + p.syncable = p.info.isSyncable; + if (p.info.authority != null) { + String[] names = p.info.authority.split(";"); + p.info.authority = null; for (int j = 0; j < names.length; j++) { - if (j == 1 && p.isSyncable()) { + if (j == 1 && p.syncable) { // We only want the first authority for a provider to possibly be // syncable, so if we already added this provider using a different // authority clear the syncable flag. We copy the provider before @@ -624,23 +574,23 @@ public class ComponentResolver { // to a provider that we don't want to change. // Only do this for the second authority since the resulting provider // object can be the same for all future authorities for this provider. - p = new EffectiveProvider(p); - p.setEffectiveSyncable(false); + p = new PackageParser.Provider(p); + p.syncable = false; } if (!mProvidersByAuthority.containsKey(names[j])) { mProvidersByAuthority.put(names[j], p); - if (p.getAuthority() == null) { - p.setEffectiveAuthority(names[j]); + if (p.info.authority == null) { + p.info.authority = names[j]; } else { - p.setEffectiveAuthority(p.getAuthority() + ";" + names[j]); + p.info.authority = p.info.authority + ";" + names[j]; } if (DEBUG_PACKAGE_SCANNING && chatty) { Log.d(TAG, "Registered content provider: " + names[j] - + ", className = " + p.getName() - + ", isSyncable = " + p.isSyncable()); + + ", className = " + p.info.name + + ", isSyncable = " + p.info.isSyncable); } } else { - final ParsedProvider other = + final PackageParser.Provider other = mProvidersByAuthority.get(names[j]); final ComponentName component = (other != null && other.getComponentName() != null) @@ -648,7 +598,7 @@ public class ComponentResolver { final String packageName = component != null ? component.getPackageName() : "?"; Slog.w(TAG, "Skipping provider name " + names[j] - + " (in package " + pkg.getAppInfoPackageName() + ")" + + " (in package " + pkg.applicationInfo.packageName + ")" + ": name already used by " + packageName); } } @@ -659,7 +609,7 @@ public class ComponentResolver { } else { r.append(' '); } - r.append(p.getName()); + r.append(p.info.name); } } if (DEBUG_PACKAGE_SCANNING && chatty) { @@ -668,11 +618,13 @@ public class ComponentResolver { } @GuardedBy("mLock") - private void addReceiversLocked(AndroidPackage pkg, boolean chatty) { - final int receiversSize = ArrayUtils.size(pkg.getReceivers()); + private void addReceiversLocked(PackageParser.Package pkg, boolean chatty) { + final int receiversSize = pkg.receivers.size(); StringBuilder r = null; for (int i = 0; i < receiversSize; i++) { - ParsedActivity a = pkg.getReceivers().get(i); + PackageParser.Activity a = pkg.receivers.get(i); + a.info.processName = fixProcessName(pkg.applicationInfo.processName, + a.info.processName); mReceivers.addActivity(a, "receiver", null); if (DEBUG_PACKAGE_SCANNING && chatty) { if (r == null) { @@ -680,7 +632,7 @@ public class ComponentResolver { } else { r.append(' '); } - r.append(a.getName()); + r.append(a.info.name); } } if (DEBUG_PACKAGE_SCANNING && chatty) { @@ -689,11 +641,13 @@ public class ComponentResolver { } @GuardedBy("mLock") - private void addServicesLocked(AndroidPackage pkg, boolean chatty) { - final int servicesSize = ArrayUtils.size(pkg.getServices()); + private void addServicesLocked(PackageParser.Package pkg, boolean chatty) { + final int servicesSize = pkg.services.size(); StringBuilder r = null; for (int i = 0; i < servicesSize; i++) { - ParsedService s = pkg.getServices().get(i); + PackageParser.Service s = pkg.services.get(i); + s.info.processName = fixProcessName(pkg.applicationInfo.processName, + s.info.processName); mServices.addService(s); if (DEBUG_PACKAGE_SCANNING && chatty) { if (r == null) { @@ -701,7 +655,7 @@ public class ComponentResolver { } else { r.append(' '); } - r.append(s.getName()); + r.append(s.info.name); } } if (DEBUG_PACKAGE_SCANNING && chatty) { @@ -709,12 +663,13 @@ public class ComponentResolver { } } + /** * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE * MODIFIED. Do not pass in a list that should not be changed. */ - private static <T> void getIntentListSubset(List<ParsedActivityIntentInfo> intentList, - Function<ParsedActivityIntentInfo, Iterator<T>> generator, Iterator<T> searchIterator) { + private static <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, + IterGenerator<T> generator, Iterator<T> searchIterator) { // loop through the set of actions; every one must be found in the intent filter while (searchIterator.hasNext()) { // we must have at least one filter in the list to consider a match @@ -725,14 +680,14 @@ public class ComponentResolver { final T searchAction = searchIterator.next(); // loop through the set of intent filters - final Iterator<ParsedActivityIntentInfo> intentIter = intentList.iterator(); + final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); while (intentIter.hasNext()) { - final ParsedActivityIntentInfo intentInfo = intentIter.next(); + final ActivityIntentInfo intentInfo = intentIter.next(); boolean selectionFound = false; // loop through the intent filter's selection criteria; at least one // of them must match the searched criteria - final Iterator<T> intentSelectionIter = generator.apply(intentInfo); + final Iterator<T> intentSelectionIter = generator.generate(intentInfo); while (intentSelectionIter != null && intentSelectionIter.hasNext()) { final T intentSelection = intentSelectionIter.next(); if (intentSelection != null && intentSelection.equals(searchAction)) { @@ -750,7 +705,7 @@ public class ComponentResolver { } } - private static boolean isProtectedAction(ParsedActivityIntentInfo filter) { + private static boolean isProtectedAction(ActivityIntentInfo filter) { final Iterator<String> actionsIter = filter.actionsIterator(); while (actionsIter != null && actionsIter.hasNext()) { final String filterAction = actionsIter.next(); @@ -764,20 +719,20 @@ public class ComponentResolver { /** * Finds a privileged activity that matches the specified activity names. */ - private static ParsedActivity findMatchingActivity( - List<ParsedActivity> activityList, ParsedActivity activityInfo) { - for (ParsedActivity sysActivity : activityList) { - if (sysActivity.getName().equals(activityInfo.getName())) { + private static PackageParser.Activity findMatchingActivity( + List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { + for (PackageParser.Activity sysActivity : activityList) { + if (sysActivity.info.name.equals(activityInfo.name)) { return sysActivity; } - if (sysActivity.getName().equals(activityInfo.targetActivity)) { + if (sysActivity.info.name.equals(activityInfo.targetActivity)) { return sysActivity; } - if (sysActivity.targetActivity != null) { - if (sysActivity.targetActivity.equals(activityInfo.getName())) { + if (sysActivity.info.targetActivity != null) { + if (sysActivity.info.targetActivity.equals(activityInfo.name)) { return sysActivity; } - if (sysActivity.targetActivity.equals(activityInfo.targetActivity)) { + if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { return sysActivity; } } @@ -798,23 +753,24 @@ public class ComponentResolver { * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is * allowed to obtain any priority on any action. */ - private void adjustPriority(List<ParsedActivity> systemActivities, - ParsedActivityIntentInfo intent, String setupWizardPackage) { + private void adjustPriority(List<PackageParser.Activity> systemActivities, + ActivityIntentInfo intent, String setupWizardPackage) { // nothing to do; priority is fine as-is if (intent.getPriority() <= 0) { return; } - AndroidPackage pkg = sPackageManagerInternal.getPackage(intent.getPackageName()); + final ActivityInfo activityInfo = intent.activity.info; + final ApplicationInfo applicationInfo = activityInfo.applicationInfo; final boolean privilegedApp = - ((pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); + ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); if (!privilegedApp) { // non-privileged applications can never define a priority >0 if (DEBUG_FILTERS) { Slog.i(TAG, "Non-privileged app; cap priority to 0;" - + " package: " + pkg.getPackageName() - + " activity: " + intent.getClassName() + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); @@ -838,8 +794,8 @@ public class ComponentResolver { mProtectedFilters.add(intent); if (DEBUG_FILTERS) { Slog.i(TAG, "Protected action; save for later;" - + " package: " + pkg.getPackageName() - + " activity: " + intent.getClassName() + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } return; @@ -848,12 +804,12 @@ public class ComponentResolver { Slog.i(TAG, "No setup wizard;" + " All protected intents capped to priority 0"); } - if (intent.getPackageName().equals(setupWizardPackage)) { + if (intent.activity.info.packageName.equals(setupWizardPackage)) { if (DEBUG_FILTERS) { Slog.i(TAG, "Found setup wizard;" + " allow priority " + intent.getPriority() + ";" - + " package: " + intent.getPackageName() - + " activity: " + intent.getClassName() + + " package: " + intent.activity.info.packageName + + " activity: " + intent.activity.className + " priority: " + intent.getPriority()); } // setup wizard gets whatever it wants @@ -861,8 +817,8 @@ public class ComponentResolver { } if (DEBUG_FILTERS) { Slog.i(TAG, "Protected action; cap priority to 0;" - + " package: " + intent.getPackageName() - + " activity: " + intent.getClassName() + + " package: " + intent.activity.info.packageName + + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); @@ -874,28 +830,14 @@ public class ComponentResolver { } // privileged app unbundled update ... try to find the same activity - - ParsedActivity foundActivity = null; - ParsedActivity activity = null; - - if (pkg.getActivities() != null) { - for (ParsedActivity parsedProvider : pkg.getActivities()) { - if (Objects.equals(parsedProvider.className, intent.getClassName())) { - activity = parsedProvider; - } - } - } - - if (activity != null) { - foundActivity = findMatchingActivity(systemActivities, activity); - } - + final PackageParser.Activity foundActivity = + findMatchingActivity(systemActivities, activityInfo); if (foundActivity == null) { // this is a new activity; it cannot obtain >0 priority if (DEBUG_FILTERS) { Slog.i(TAG, "New activity; cap priority to 0;" - + " package: " + pkg.getPackageName() - + " activity: " + intent.getClassName() + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); @@ -905,19 +847,19 @@ public class ComponentResolver { // found activity, now check for filter equivalence // a shallow copy is enough; we modify the list, not its contents - final List<ParsedActivityIntentInfo> intentListCopy = - new ArrayList<>(foundActivity.intents); + final List<ActivityIntentInfo> intentListCopy = new ArrayList<>(foundActivity.intents); + final List<ActivityIntentInfo> foundFilters = mActivities.findFilters(intent); // find matching action subsets final Iterator<String> actionsIterator = intent.actionsIterator(); if (actionsIterator != null) { - getIntentListSubset(intentListCopy, IntentFilter::actionsIterator, actionsIterator); + getIntentListSubset(intentListCopy, new ActionIterGenerator(), actionsIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched action; cap priority to 0;" - + " package: " + pkg.getPackageName() - + " activity: " + intent.getClassName() + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); @@ -928,14 +870,13 @@ public class ComponentResolver { // find matching category subsets final Iterator<String> categoriesIterator = intent.categoriesIterator(); if (categoriesIterator != null) { - getIntentListSubset(intentListCopy, IntentFilter::categoriesIterator, - categoriesIterator); + getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), categoriesIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched category; cap priority to 0;" - + " package: " + pkg.getPackageName() - + " activity: " + intent.getClassName() + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); @@ -946,13 +887,13 @@ public class ComponentResolver { // find matching schemes subsets final Iterator<String> schemesIterator = intent.schemesIterator(); if (schemesIterator != null) { - getIntentListSubset(intentListCopy, IntentFilter::schemesIterator, schemesIterator); + getIntentListSubset(intentListCopy, new SchemesIterGenerator(), schemesIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched scheme; cap priority to 0;" - + " package: " + pkg.getPackageName() - + " activity: " + intent.getClassName() + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); @@ -964,14 +905,14 @@ public class ComponentResolver { final Iterator<IntentFilter.AuthorityEntry> authoritiesIterator = intent.authoritiesIterator(); if (authoritiesIterator != null) { - getIntentListSubset(intentListCopy, IntentFilter::authoritiesIterator, + getIntentListSubset(intentListCopy, new AuthoritiesIterGenerator(), authoritiesIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched authority; cap priority to 0;" - + " package: " + pkg.getPackageName() - + " activity: " + intent.getClassName() + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); @@ -988,8 +929,8 @@ public class ComponentResolver { if (DEBUG_FILTERS) { Slog.i(TAG, "Found matching filter(s);" + " cap priority to " + cappedPriority + ";" - + " package: " + pkg.getPackageName() - + " activity: " + intent.getClassName() + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(cappedPriority); @@ -999,15 +940,15 @@ public class ComponentResolver { } @GuardedBy("mLock") - private void removeAllComponentsLocked(AndroidPackage pkg, boolean chatty) { + private void removeAllComponentsLocked(PackageParser.Package pkg, boolean chatty) { int componentSize; StringBuilder r; int i; - componentSize = ArrayUtils.size(pkg.getActivities()); + componentSize = pkg.activities.size(); r = null; for (i = 0; i < componentSize; i++) { - ParsedActivity a = pkg.getActivities().get(i); + PackageParser.Activity a = pkg.activities.get(i); mActivities.removeActivity(a, "activity"); if (DEBUG_REMOVE && chatty) { if (r == null) { @@ -1015,32 +956,32 @@ public class ComponentResolver { } else { r.append(' '); } - r.append(a.getName()); + r.append(a.info.name); } } if (DEBUG_REMOVE && chatty) { Log.d(TAG, " Activities: " + (r == null ? "<NONE>" : r)); } - componentSize = ArrayUtils.size(pkg.getProviders()); + componentSize = pkg.providers.size(); r = null; for (i = 0; i < componentSize; i++) { - ParsedProvider p = pkg.getProviders().get(i); + PackageParser.Provider p = pkg.providers.get(i); mProviders.removeProvider(p); - if (p.getAuthority() == null) { + if (p.info.authority == null) { // Another content provider with this authority existed when this app was // installed, so this authority is null. Ignore it as we don't have to // unregister the provider. continue; } - String[] names = p.getAuthority().split(";"); + String[] names = p.info.authority.split(";"); for (int j = 0; j < names.length; j++) { if (mProvidersByAuthority.get(names[j]) == p) { mProvidersByAuthority.remove(names[j]); if (DEBUG_REMOVE && chatty) { Log.d(TAG, "Unregistered content provider: " + names[j] - + ", className = " + p.getName() + ", isSyncable = " - + p.isSyncable()); + + ", className = " + p.info.name + ", isSyncable = " + + p.info.isSyncable); } } } @@ -1050,17 +991,17 @@ public class ComponentResolver { } else { r.append(' '); } - r.append(p.getName()); + r.append(p.info.name); } } if (DEBUG_REMOVE && chatty) { Log.d(TAG, " Providers: " + (r == null ? "<NONE>" : r)); } - componentSize = ArrayUtils.size(pkg.getReceivers()); + componentSize = pkg.receivers.size(); r = null; for (i = 0; i < componentSize; i++) { - ParsedActivity a = pkg.getReceivers().get(i); + PackageParser.Activity a = pkg.receivers.get(i); mReceivers.removeActivity(a, "receiver"); if (DEBUG_REMOVE && chatty) { if (r == null) { @@ -1068,17 +1009,17 @@ public class ComponentResolver { } else { r.append(' '); } - r.append(a.getName()); + r.append(a.info.name); } } if (DEBUG_REMOVE && chatty) { Log.d(TAG, " Receivers: " + (r == null ? "<NONE>" : r)); } - componentSize = ArrayUtils.size(pkg.getServices()); + componentSize = pkg.services.size(); r = null; for (i = 0; i < componentSize; i++) { - ParsedService s = pkg.getServices().get(i); + PackageParser.Service s = pkg.services.get(i); mServices.removeService(s); if (DEBUG_REMOVE && chatty) { if (r == null) { @@ -1086,7 +1027,7 @@ public class ComponentResolver { } else { r.append(' '); } - r.append(s.getName()); + r.append(s.info.name); } } if (DEBUG_REMOVE && chatty) { @@ -1095,26 +1036,26 @@ public class ComponentResolver { } @GuardedBy("mLock") - private void assertProvidersNotDefinedLocked(AndroidPackage pkg) + private void assertProvidersNotDefinedLocked(PackageParser.Package pkg) throws PackageManagerException { - final int providersSize = ArrayUtils.size(pkg.getProviders()); + final int providersSize = pkg.providers.size(); int i; for (i = 0; i < providersSize; i++) { - ParsedProvider p = pkg.getProviders().get(i); - if (p.getAuthority() != null) { - final String[] names = p.getAuthority().split(";"); + PackageParser.Provider p = pkg.providers.get(i); + if (p.info.authority != null) { + final String[] names = p.info.authority.split(";"); for (int j = 0; j < names.length; j++) { if (mProvidersByAuthority.containsKey(names[j])) { - final ParsedProvider other = mProvidersByAuthority.get(names[j]); + final PackageParser.Provider other = mProvidersByAuthority.get(names[j]); final String otherPackageName = (other != null && other.getComponentName() != null) ? other.getComponentName().getPackageName() : "?"; // if we're installing over the same already-installed package, this is ok - if (!otherPackageName.equals(pkg.getPackageName())) { + if (!otherPackageName.equals(pkg.packageName)) { throw new PackageManagerException( INSTALL_FAILED_CONFLICTING_PROVIDER, "Can't install because provider name " + names[j] - + " (in package " + pkg.getPackageName() + + " (in package " + pkg.applicationInfo.packageName + ") is already used by " + otherPackageName); } } @@ -1123,9 +1064,8 @@ public class ComponentResolver { } } - private static class ActivityIntentResolver - extends IntentResolver<ParsedActivityIntentInfo, ResolveInfo> { - + private static final class ActivityIntentResolver + extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { @Override public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId) { @@ -1146,24 +1086,24 @@ public class ComponentResolver { } List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, - int flags, List<ParsedActivity> packageActivities, int userId) { + int flags, List<PackageParser.Activity> packageActivities, int userId) { if (!sUserManager.exists(userId)) { return null; } if (packageActivities == null) { - return Collections.emptyList(); + return null; } mFlags = flags; final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; final int activitiesSize = packageActivities.size(); - ArrayList<ParsedActivityIntentInfo[]> listCut = new ArrayList<>(activitiesSize); + ArrayList<PackageParser.ActivityIntentInfo[]> listCut = new ArrayList<>(activitiesSize); - List<ParsedActivityIntentInfo> intentFilters; + ArrayList<PackageParser.ActivityIntentInfo> intentFilters; for (int i = 0; i < activitiesSize; ++i) { intentFilters = packageActivities.get(i).intents; if (intentFilters != null && intentFilters.size() > 0) { - ParsedActivityIntentInfo[] array = - new ParsedActivityIntentInfo[intentFilters.size()]; + PackageParser.ActivityIntentInfo[] array = + new PackageParser.ActivityIntentInfo[intentFilters.size()]; intentFilters.toArray(array); listCut.add(array); } @@ -1171,21 +1111,21 @@ public class ComponentResolver { return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); } - private void addActivity(ParsedActivity a, String type, - List<ParsedActivityIntentInfo> newIntents) { + private void addActivity(PackageParser.Activity a, String type, + List<PackageParser.ActivityIntentInfo> newIntents) { mActivities.put(a.getComponentName(), a); if (DEBUG_SHOW_INFO) { - final CharSequence label = a.nonLocalizedLabel != null - ? a.nonLocalizedLabel - : a.getName(); + final CharSequence label = a.info.nonLocalizedLabel != null + ? a.info.nonLocalizedLabel + : a.info.name; Log.v(TAG, " " + type + " " + label + ":"); } if (DEBUG_SHOW_INFO) { - Log.v(TAG, " Class=" + a.getName()); + Log.v(TAG, " Class=" + a.info.name); } final int intentsSize = a.intents.size(); for (int j = 0; j < intentsSize; j++) { - ParsedActivityIntentInfo intent = a.intents.get(j); + PackageParser.ActivityIntentInfo intent = a.intents.get(j); if (newIntents != null && "activity".equals(type)) { newIntents.add(intent); } @@ -1194,23 +1134,23 @@ public class ComponentResolver { intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); } if (!intent.debugCheck()) { - Log.w(TAG, "==> For Activity " + a.getName()); + Log.w(TAG, "==> For Activity " + a.info.name); } addFilter(intent); } } - private void removeActivity(ParsedActivity a, String type) { + private void removeActivity(PackageParser.Activity a, String type) { mActivities.remove(a.getComponentName()); if (DEBUG_SHOW_INFO) { Log.v(TAG, " " + type + " " - + (a.nonLocalizedLabel != null ? a.nonLocalizedLabel - : a.getName()) + ":"); - Log.v(TAG, " Class=" + a.getName()); + + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel + : a.info.name) + ":"); + Log.v(TAG, " Class=" + a.info.name); } final int intentsSize = a.intents.size(); for (int j = 0; j < intentsSize; j++) { - ParsedActivityIntentInfo intent = a.intents.get(j); + PackageParser.ActivityIntentInfo intent = a.intents.get(j); if (DEBUG_SHOW_INFO) { Log.v(TAG, " IntentFilter:"); intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); @@ -1221,11 +1161,11 @@ public class ComponentResolver { @Override protected boolean allowFilterResult( - ParsedActivityIntentInfo filter, List<ResolveInfo> dest) { + PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { + ActivityInfo filterAi = filter.activity.info; for (int i = dest.size() - 1; i >= 0; --i) { ActivityInfo destAi = dest.get(i).activityInfo; - if (Objects.equals(destAi.name, filter.getClassName()) - && Objects.equals(destAi.packageName, filter.getPackageName())) { + if (destAi.name == filterAi.name && destAi.packageName == filterAi.packageName) { return false; } } @@ -1233,39 +1173,34 @@ public class ComponentResolver { } @Override - protected ParsedActivityIntentInfo[] newArray(int size) { - return new ParsedActivityIntentInfo[size]; + protected ActivityIntentInfo[] newArray(int size) { + return new ActivityIntentInfo[size]; } @Override - protected boolean isFilterStopped(ParsedActivityIntentInfo filter, int userId) { + protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { if (!sUserManager.exists(userId)) return true; - - AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName()); - if (pkg == null) { - return false; - } - - PackageSetting ps = (PackageSetting) sPackageManagerInternal.getPackageSetting( - filter.getPackageName()); - if (ps == null) { - return false; + PackageParser.Package p = filter.activity.owner; + if (p != null) { + PackageSetting ps = (PackageSetting) p.mExtras; + if (ps != null) { + // System apps are never considered stopped for purposes of + // filtering, because there may be no way for the user to + // actually re-launch them. + return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 + && ps.getStopped(userId); + } } - - // System apps are never considered stopped for purposes of - // filtering, because there may be no way for the user to - // actually re-launch them. - return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 - && ps.getStopped(userId); + return false; } @Override protected boolean isPackageForFilter(String packageName, - ParsedActivityIntentInfo info) { - return packageName.equals(info.getPackageName()); + PackageParser.ActivityIntentInfo info) { + return packageName.equals(info.activity.owner.packageName); } - private void log(String reason, ParsedActivityIntentInfo info, int match, + private void log(String reason, ActivityIntentInfo info, int match, int userId) { Slog.w(TAG, reason + "; match: " @@ -1275,7 +1210,7 @@ public class ComponentResolver { } @Override - protected ResolveInfo newResult(ParsedActivityIntentInfo info, + protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, int match, int userId) { if (!sUserManager.exists(userId)) { if (DEBUG) { @@ -1283,29 +1218,7 @@ public class ComponentResolver { } return null; } - - ParsedActivity activity = null; - - AndroidPackage pkg = sPackageManagerInternal.getPackage(info.getPackageName()); - if (pkg == null) { - return null; - } - - // TODO(b/135203078): Consider more efficient ways of doing this. - List<ParsedActivity> activities = getResolveList(pkg); - if (activities != null) { - for (ParsedActivity parsedActivity : activities) { - if (Objects.equals(parsedActivity.className, info.getClassName())) { - activity = parsedActivity; - } - } - } - - if (activity == null) { - return null; - } - - if (!sPackageManagerInternal.isEnabledAndMatches(activity, mFlags, userId)) { + if (!sPackageManagerInternal.isEnabledAndMatches(info.activity.info, mFlags, userId)) { if (DEBUG) { log("!PackageManagerInternal.isEnabledAndMatches; mFlags=" + DebugUtils.flagsToString(PackageManager.class, "MATCH_", mFlags), @@ -1313,8 +1226,8 @@ public class ComponentResolver { } return null; } - PackageSetting ps = (PackageSetting) sPackageManagerInternal.getPackageSetting( - info.getPackageName()); + final PackageParser.Activity activity = info.activity; + PackageSetting ps = (PackageSetting) activity.owner.mExtras; if (ps == null) { if (DEBUG) { log("info.activity.owner.mExtras == null", info, match, userId); @@ -1323,10 +1236,10 @@ public class ComponentResolver { } final PackageUserState userState = ps.readUserState(userId); ActivityInfo ai = - PackageInfoUtils.generateActivityInfo(pkg, activity, mFlags, userState, userId); + PackageParser.generateActivityInfo(activity, mFlags, userState, userId); if (ai == null) { if (DEBUG) { - log("Failed to create ActivityInfo based on " + activity, info, match, + log("Failed to create ActivityInfo based on " + info.activity, info, match, userId); } return null; @@ -1376,7 +1289,7 @@ public class ComponentResolver { } res.handleAllWebDataURI = info.handleAllWebDataURI(); res.priority = info.getPriority(); - res.preferredOrder = pkg.getPreferredOrder(); + res.preferredOrder = activity.owner.mPreferredOrder; //System.out.println("Result: " + res.activityInfo.className + // " = " + res.priority); res.match = match; @@ -1401,64 +1314,40 @@ public class ComponentResolver { @Override protected void dumpFilter(PrintWriter out, String prefix, - ParsedActivityIntentInfo filter) { - ParsedActivity activity = null; - - AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName()); - if (pkg != null && pkg.getActivities() != null) { - for (ParsedActivity parsedActivity : pkg.getActivities()) { - if (Objects.equals(parsedActivity.className, filter.getClassName())) { - activity = parsedActivity; - } - } - } - + PackageParser.ActivityIntentInfo filter) { out.print(prefix); - out.print(Integer.toHexString(System.identityHashCode(activity))); + out.print(Integer.toHexString(System.identityHashCode(filter.activity))); out.print(' '); - ComponentName.printShortString(out, filter.getPackageName(), filter.getClassName()); + filter.activity.printComponentShortName(out); out.print(" filter "); out.println(Integer.toHexString(System.identityHashCode(filter))); } @Override - protected Object filterToLabel(ParsedActivityIntentInfo filter) { - return filter; + protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { + return filter.activity; } protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { - ParsedActivityIntentInfo activity = (ParsedActivityIntentInfo) label; + PackageParser.Activity activity = (PackageParser.Activity) label; out.print(prefix); out.print(Integer.toHexString(System.identityHashCode(activity))); out.print(' '); - ComponentName.printShortString(out, activity.getPackageName(), activity.getClassName()); + activity.printComponentShortName(out); if (count > 1) { out.print(" ("); out.print(count); out.print(" filters)"); } out.println(); } - protected List<ParsedActivity> getResolveList(AndroidPackage pkg) { - return pkg.getActivities(); - } - // Keys are String (activity class name), values are Activity. - private final ArrayMap<ComponentName, ParsedActivity> mActivities = + private final ArrayMap<ComponentName, PackageParser.Activity> mActivities = new ArrayMap<>(); private int mFlags; } - // Both receivers and activities share a class, but point to different get methods - private static final class ReceiverIntentResolver extends ActivityIntentResolver { - - @Override - protected List<ParsedActivity> getResolveList(AndroidPackage pkg) { - return pkg.getReceivers(); - } - } - private static final class ProviderIntentResolver - extends IntentResolver<ParsedProviderIntentInfo, ResolveInfo> { + extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { @Override public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId) { @@ -1478,24 +1367,24 @@ public class ComponentResolver { } List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, - int flags, List<ParsedProvider> packageProviders, int userId) { + int flags, List<PackageParser.Provider> packageProviders, int userId) { if (!sUserManager.exists(userId)) { return null; } if (packageProviders == null) { - return Collections.emptyList(); + return null; } mFlags = flags; final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; final int providersSize = packageProviders.size(); - ArrayList<ParsedProviderIntentInfo[]> listCut = new ArrayList<>(providersSize); + ArrayList<PackageParser.ProviderIntentInfo[]> listCut = new ArrayList<>(providersSize); - List<ParsedProviderIntentInfo> intentFilters; + ArrayList<PackageParser.ProviderIntentInfo> intentFilters; for (int i = 0; i < providersSize; ++i) { - intentFilters = packageProviders.get(i).getIntents(); + intentFilters = packageProviders.get(i).intents; if (intentFilters != null && intentFilters.size() > 0) { - ParsedProviderIntentInfo[] array = - new ParsedProviderIntentInfo[intentFilters.size()]; + PackageParser.ProviderIntentInfo[] array = + new PackageParser.ProviderIntentInfo[intentFilters.size()]; intentFilters.toArray(array); listCut.add(array); } @@ -1503,7 +1392,7 @@ public class ComponentResolver { return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); } - void addProvider(ParsedProvider p) { + void addProvider(PackageParser.Provider p) { if (mProviders.containsKey(p.getComponentName())) { Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); return; @@ -1512,39 +1401,39 @@ public class ComponentResolver { mProviders.put(p.getComponentName(), p); if (DEBUG_SHOW_INFO) { Log.v(TAG, " " - + (p.nonLocalizedLabel != null - ? p.nonLocalizedLabel - : p.getName()) + + (p.info.nonLocalizedLabel != null + ? p.info.nonLocalizedLabel + : p.info.name) + ":"); - Log.v(TAG, " Class=" + p.getName()); + Log.v(TAG, " Class=" + p.info.name); } - final int intentsSize = p.getIntents().size(); + final int intentsSize = p.intents.size(); int j; for (j = 0; j < intentsSize; j++) { - ParsedProviderIntentInfo intent = p.getIntents().get(j); + PackageParser.ProviderIntentInfo intent = p.intents.get(j); if (DEBUG_SHOW_INFO) { Log.v(TAG, " IntentFilter:"); intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); } if (!intent.debugCheck()) { - Log.w(TAG, "==> For Provider " + p.getName()); + Log.w(TAG, "==> For Provider " + p.info.name); } addFilter(intent); } } - void removeProvider(ParsedProvider p) { + void removeProvider(PackageParser.Provider p) { mProviders.remove(p.getComponentName()); if (DEBUG_SHOW_INFO) { - Log.v(TAG, " " + (p.nonLocalizedLabel != null - ? p.nonLocalizedLabel - : p.getName()) + ":"); - Log.v(TAG, " Class=" + p.getName()); + Log.v(TAG, " " + (p.info.nonLocalizedLabel != null + ? p.info.nonLocalizedLabel + : p.info.name) + ":"); + Log.v(TAG, " Class=" + p.info.name); } - final int intentsSize = p.getIntents().size(); + final int intentsSize = p.intents.size(); int j; for (j = 0; j < intentsSize; j++) { - ParsedProviderIntentInfo intent = p.getIntents().get(j); + PackageParser.ProviderIntentInfo intent = p.intents.get(j); if (DEBUG_SHOW_INFO) { Log.v(TAG, " IntentFilter:"); intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); @@ -1555,11 +1444,12 @@ public class ComponentResolver { @Override protected boolean allowFilterResult( - ParsedProviderIntentInfo filter, List<ResolveInfo> dest) { + PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { + ProviderInfo filterPi = filter.provider.info; for (int i = dest.size() - 1; i >= 0; i--) { ProviderInfo destPi = dest.get(i).providerInfo; - if (Objects.equals(destPi.name, filter.getClassName()) - && Objects.equals(destPi.packageName, filter.getPackageName())) { + if (destPi.name == filterPi.name + && destPi.packageName == filterPi.packageName) { return false; } } @@ -1567,68 +1457,47 @@ public class ComponentResolver { } @Override - protected ParsedProviderIntentInfo[] newArray(int size) { - return new ParsedProviderIntentInfo[size]; + protected PackageParser.ProviderIntentInfo[] newArray(int size) { + return new PackageParser.ProviderIntentInfo[size]; } @Override - protected boolean isFilterStopped(ParsedProviderIntentInfo filter, int userId) { + protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { if (!sUserManager.exists(userId)) { return true; } - - AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName()); - if (pkg == null) { - return false; - } - - PackageSetting ps = (PackageSetting) sPackageManagerInternal.getPackageSetting( - filter.getPackageName()); - if (ps == null) { - return false; + PackageParser.Package p = filter.provider.owner; + if (p != null) { + PackageSetting ps = (PackageSetting) p.mExtras; + if (ps != null) { + // System apps are never considered stopped for purposes of + // filtering, because there may be no way for the user to + // actually re-launch them. + return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 + && ps.getStopped(userId); + } } - - // System apps are never considered stopped for purposes of - // filtering, because there may be no way for the user to - // actually re-launch them. - return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 - && ps.getStopped(userId); + return false; } @Override protected boolean isPackageForFilter(String packageName, - ParsedProviderIntentInfo info) { - return packageName.equals(info.getPackageName()); + PackageParser.ProviderIntentInfo info) { + return packageName.equals(info.provider.owner.packageName); } @Override - protected ResolveInfo newResult(ParsedProviderIntentInfo filter, + protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, int match, int userId) { if (!sUserManager.exists(userId)) { return null; } - - ParsedProvider provider = null; - - AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName()); - if (pkg != null && pkg.getProviders() != null) { - for (ParsedProvider parsedProvider : pkg.getProviders()) { - if (Objects.equals(parsedProvider.className, filter.getClassName())) { - provider = parsedProvider; - } - } - } - - if (provider == null) { - return null; - } - - if (!sPackageManagerInternal.isEnabledAndMatches(provider, mFlags, userId)) { + final PackageParser.ProviderIntentInfo info = filter; + if (!sPackageManagerInternal.isEnabledAndMatches(info.provider.info, mFlags, userId)) { return null; } - - PackageSetting ps = (PackageSetting) sPackageManagerInternal.getPackageSetting( - filter.getPackageName()); + final PackageParser.Provider provider = info.provider; + PackageSetting ps = (PackageSetting) provider.owner.mExtras; if (ps == null) { return null; } @@ -1638,7 +1507,7 @@ public class ComponentResolver { final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0; // throw out filters that aren't visible to instant applications if (matchVisibleToInstantApp - && !(filter.isVisibleToInstantApp() || userState.instantApp)) { + && !(info.isVisibleToInstantApp() || userState.instantApp)) { return null; } // throw out instant application filters if we're not explicitly requesting them @@ -1650,8 +1519,8 @@ public class ComponentResolver { if (userState.instantApp && ps.isUpdateAvailable()) { return null; } - ProviderInfo pi = PackageInfoUtils.generateProviderInfo(pkg, provider, - mFlags, userState, userId); + ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, + userState, userId); if (pi == null) { return null; } @@ -1660,13 +1529,13 @@ public class ComponentResolver { if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { res.filter = filter; } - res.priority = filter.getPriority(); - res.preferredOrder = pkg.getPreferredOrder(); + res.priority = info.getPriority(); + res.preferredOrder = provider.owner.mPreferredOrder; res.match = match; - res.isDefault = filter.hasDefault; - res.labelRes = filter.labelRes; - res.nonLocalizedLabel = filter.nonLocalizedLabel; - res.icon = filter.icon; + res.isDefault = info.hasDefault; + res.labelRes = info.labelRes; + res.nonLocalizedLabel = info.nonLocalizedLabel; + res.icon = info.icon; res.system = res.providerInfo.applicationInfo.isSystemApp(); return res; } @@ -1678,37 +1547,26 @@ public class ComponentResolver { @Override protected void dumpFilter(PrintWriter out, String prefix, - ParsedProviderIntentInfo filter) { - ParsedProvider provider = null; - - AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName()); - if (pkg != null && pkg.getProviders() != null) { - for (ParsedProvider parsedProvider : pkg.getProviders()) { - if (Objects.equals(parsedProvider.className, filter.getClassName())) { - provider = parsedProvider; - } - } - } - + PackageParser.ProviderIntentInfo filter) { out.print(prefix); - out.print(Integer.toHexString(System.identityHashCode(provider))); + out.print(Integer.toHexString(System.identityHashCode(filter.provider))); out.print(' '); - ComponentName.printShortString(out, filter.getPackageName(), filter.getClassName()); + filter.provider.printComponentShortName(out); out.print(" filter "); out.println(Integer.toHexString(System.identityHashCode(filter))); } @Override - protected Object filterToLabel(ParsedProviderIntentInfo filter) { - return filter; + protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { + return filter.provider; } protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { - final ParsedProviderIntentInfo provider = (ParsedProviderIntentInfo) label; + final PackageParser.Provider provider = (PackageParser.Provider) label; out.print(prefix); out.print(Integer.toHexString(System.identityHashCode(provider))); out.print(' '); - ComponentName.printShortString(out, provider.getPackageName(), provider.getClassName()); + provider.printComponentShortName(out); if (count > 1) { out.print(" ("); out.print(count); @@ -1717,12 +1575,12 @@ public class ComponentResolver { out.println(); } - private final ArrayMap<ComponentName, ParsedProvider> mProviders = new ArrayMap<>(); + private final ArrayMap<ComponentName, PackageParser.Provider> mProviders = new ArrayMap<>(); private int mFlags; } private static final class ServiceIntentResolver - extends IntentResolver<ParsedServiceIntentInfo, ResolveInfo> { + extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { @Override public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId) { @@ -1740,22 +1598,22 @@ public class ComponentResolver { } List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, - int flags, List<ParsedService> packageServices, int userId) { + int flags, List<PackageParser.Service> packageServices, int userId) { if (!sUserManager.exists(userId)) return null; if (packageServices == null) { - return Collections.emptyList(); + return null; } mFlags = flags; final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; final int servicesSize = packageServices.size(); - ArrayList<ParsedServiceIntentInfo[]> listCut = new ArrayList<>(servicesSize); + ArrayList<PackageParser.ServiceIntentInfo[]> listCut = new ArrayList<>(servicesSize); - List<ParsedServiceIntentInfo> intentFilters; + ArrayList<PackageParser.ServiceIntentInfo> intentFilters; for (int i = 0; i < servicesSize; ++i) { intentFilters = packageServices.get(i).intents; if (intentFilters != null && intentFilters.size() > 0) { - ParsedServiceIntentInfo[] array = - new ParsedServiceIntentInfo[intentFilters.size()]; + PackageParser.ServiceIntentInfo[] array = + new PackageParser.ServiceIntentInfo[intentFilters.size()]; intentFilters.toArray(array); listCut.add(array); } @@ -1763,40 +1621,40 @@ public class ComponentResolver { return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); } - void addService(ParsedService s) { + void addService(PackageParser.Service s) { mServices.put(s.getComponentName(), s); if (DEBUG_SHOW_INFO) { Log.v(TAG, " " - + (s.nonLocalizedLabel != null - ? s.nonLocalizedLabel : s.getName()) + ":"); - Log.v(TAG, " Class=" + s.getName()); + + (s.info.nonLocalizedLabel != null + ? s.info.nonLocalizedLabel : s.info.name) + ":"); + Log.v(TAG, " Class=" + s.info.name); } final int intentsSize = s.intents.size(); int j; for (j = 0; j < intentsSize; j++) { - ParsedServiceIntentInfo intent = s.intents.get(j); + PackageParser.ServiceIntentInfo intent = s.intents.get(j); if (DEBUG_SHOW_INFO) { Log.v(TAG, " IntentFilter:"); intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); } if (!intent.debugCheck()) { - Log.w(TAG, "==> For Service " + s.getName()); + Log.w(TAG, "==> For Service " + s.info.name); } addFilter(intent); } } - void removeService(ParsedService s) { + void removeService(PackageParser.Service s) { mServices.remove(s.getComponentName()); if (DEBUG_SHOW_INFO) { - Log.v(TAG, " " + (s.nonLocalizedLabel != null - ? s.nonLocalizedLabel : s.getName()) + ":"); - Log.v(TAG, " Class=" + s.getName()); + Log.v(TAG, " " + (s.info.nonLocalizedLabel != null + ? s.info.nonLocalizedLabel : s.info.name) + ":"); + Log.v(TAG, " Class=" + s.info.name); } final int intentsSize = s.intents.size(); int j; for (j = 0; j < intentsSize; j++) { - ParsedServiceIntentInfo intent = s.intents.get(j); + PackageParser.ServiceIntentInfo intent = s.intents.get(j); if (DEBUG_SHOW_INFO) { Log.v(TAG, " IntentFilter:"); intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); @@ -1807,11 +1665,12 @@ public class ComponentResolver { @Override protected boolean allowFilterResult( - ParsedServiceIntentInfo filter, List<ResolveInfo> dest) { + PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { + ServiceInfo filterSi = filter.service.info; for (int i = dest.size() - 1; i >= 0; --i) { ServiceInfo destAi = dest.get(i).serviceInfo; - if (Objects.equals(destAi.name, filter.getClassName()) - && Objects.equals(destAi.packageName, filter.getPackageName())) { + if (destAi.name == filterSi.name + && destAi.packageName == filterSi.packageName) { return false; } } @@ -1819,69 +1678,48 @@ public class ComponentResolver { } @Override - protected ParsedServiceIntentInfo[] newArray(int size) { - return new ParsedServiceIntentInfo[size]; + protected PackageParser.ServiceIntentInfo[] newArray(int size) { + return new PackageParser.ServiceIntentInfo[size]; } @Override - protected boolean isFilterStopped(ParsedServiceIntentInfo filter, int userId) { + protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { if (!sUserManager.exists(userId)) return true; - - AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName()); - if (pkg == null) { - return false; - } - - PackageSetting ps = (PackageSetting) sPackageManagerInternal.getPackageSetting( - filter.getPackageName()); - if (ps == null) { - return false; + PackageParser.Package p = filter.service.owner; + if (p != null) { + PackageSetting ps = (PackageSetting) p.mExtras; + if (ps != null) { + // System apps are never considered stopped for purposes of + // filtering, because there may be no way for the user to + // actually re-launch them. + return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 + && ps.getStopped(userId); + } } - - // System apps are never considered stopped for purposes of - // filtering, because there may be no way for the user to - // actually re-launch them. - return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 - && ps.getStopped(userId); + return false; } @Override protected boolean isPackageForFilter(String packageName, - ParsedServiceIntentInfo info) { - return packageName.equals(info.getPackageName()); + PackageParser.ServiceIntentInfo info) { + return packageName.equals(info.service.owner.packageName); } @Override - protected ResolveInfo newResult(ParsedServiceIntentInfo filter, + protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, int match, int userId) { if (!sUserManager.exists(userId)) return null; - - ParsedService service = null; - - AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName()); - if (pkg != null && pkg.getServices() != null) { - for (ParsedService parsedService : pkg.getServices()) { - if (Objects.equals(parsedService.className, filter.getClassName())) { - service = parsedService; - } - } - } - - if (service == null) { - return null; - } - - if (!sPackageManagerInternal.isEnabledAndMatches(service, mFlags, userId)) { + final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo) filter; + if (!sPackageManagerInternal.isEnabledAndMatches(info.service.info, mFlags, userId)) { return null; } - - PackageSetting ps = (PackageSetting) sPackageManagerInternal.getPackageSetting( - filter.getPackageName()); + final PackageParser.Service service = info.service; + PackageSetting ps = (PackageSetting) service.owner.mExtras; if (ps == null) { return null; } final PackageUserState userState = ps.readUserState(userId); - ServiceInfo si = PackageInfoUtils.generateServiceInfo(pkg, service, mFlags, + ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, userState, userId); if (si == null) { return null; @@ -1891,7 +1729,7 @@ public class ComponentResolver { final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0; // throw out filters that aren't visible to ephemeral apps if (matchVisibleToInstantApp - && !(filter.isVisibleToInstantApp() || userState.instantApp)) { + && !(info.isVisibleToInstantApp() || userState.instantApp)) { return null; } // throw out ephemeral filters if we're not explicitly requesting them @@ -1908,13 +1746,13 @@ public class ComponentResolver { if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { res.filter = filter; } - res.priority = filter.getPriority(); - res.preferredOrder = pkg.getPreferredOrder(); + res.priority = info.getPriority(); + res.preferredOrder = service.owner.mPreferredOrder; res.match = match; - res.isDefault = filter.hasDefault; - res.labelRes = filter.labelRes; - res.nonLocalizedLabel = filter.nonLocalizedLabel; - res.icon = filter.icon; + res.isDefault = info.hasDefault; + res.labelRes = info.labelRes; + res.nonLocalizedLabel = info.nonLocalizedLabel; + res.icon = info.icon; res.system = res.serviceInfo.applicationInfo.isSystemApp(); return res; } @@ -1926,42 +1764,31 @@ public class ComponentResolver { @Override protected void dumpFilter(PrintWriter out, String prefix, - ParsedServiceIntentInfo filter) { - ParsedService service = null; - - AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName()); - if (pkg != null && pkg.getServices() != null) { - for (ParsedService parsedService : pkg.getServices()) { - if (Objects.equals(parsedService.className, filter.getClassName())) { - service = parsedService; - } - } - } - + PackageParser.ServiceIntentInfo filter) { out.print(prefix); - out.print(Integer.toHexString(System.identityHashCode(service))); + out.print(Integer.toHexString(System.identityHashCode(filter.service))); out.print(' '); - ComponentName.printShortString(out, filter.getPackageName(), filter.getClassName()); + filter.service.printComponentShortName(out); out.print(" filter "); out.print(Integer.toHexString(System.identityHashCode(filter))); - if (service != null && service.getPermission() != null) { - out.print(" permission "); out.println(service.getPermission()); + if (filter.service.info.permission != null) { + out.print(" permission "); out.println(filter.service.info.permission); } else { out.println(); } } @Override - protected Object filterToLabel(ParsedServiceIntentInfo filter) { - return filter; + protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { + return filter.service; } protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { - final ParsedServiceIntentInfo service = (ParsedServiceIntentInfo) label; + final PackageParser.Service service = (PackageParser.Service) label; out.print(prefix); out.print(Integer.toHexString(System.identityHashCode(service))); out.print(' '); - ComponentName.printShortString(out, service.getPackageName(), service.getClassName()); + service.printComponentShortName(out); if (count > 1) { out.print(" ("); out.print(count); out.print(" filters)"); } @@ -1969,7 +1796,7 @@ public class ComponentResolver { } // Keys are String (activity class name), values are Activity. - private final ArrayMap<ComponentName, ParsedService> mServices = new ArrayMap<>(); + private final ArrayMap<ComponentName, PackageParser.Service> mServices = new ArrayMap<>(); private int mFlags; } @@ -2058,7 +1885,7 @@ public class ComponentResolver { /** Generic to create an {@link Iterator} for a data type */ static class IterGenerator<E> { - public Iterator<E> generate(ParsedActivityIntentInfo info) { + public Iterator<E> generate(ActivityIntentInfo info) { return null; } } @@ -2066,7 +1893,7 @@ public class ComponentResolver { /** Create an {@link Iterator} for intent actions */ static class ActionIterGenerator extends IterGenerator<String> { @Override - public Iterator<String> generate(ParsedActivityIntentInfo info) { + public Iterator<String> generate(ActivityIntentInfo info) { return info.actionsIterator(); } } @@ -2074,7 +1901,7 @@ public class ComponentResolver { /** Create an {@link Iterator} for intent categories */ static class CategoriesIterGenerator extends IterGenerator<String> { @Override - public Iterator<String> generate(ParsedActivityIntentInfo info) { + public Iterator<String> generate(ActivityIntentInfo info) { return info.categoriesIterator(); } } @@ -2082,7 +1909,7 @@ public class ComponentResolver { /** Create an {@link Iterator} for intent schemes */ static class SchemesIterGenerator extends IterGenerator<String> { @Override - public Iterator<String> generate(ParsedActivityIntentInfo info) { + public Iterator<String> generate(ActivityIntentInfo info) { return info.schemesIterator(); } } @@ -2090,39 +1917,9 @@ public class ComponentResolver { /** Create an {@link Iterator} for intent authorities */ static class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { @Override - public Iterator<IntentFilter.AuthorityEntry> generate(ParsedActivityIntentInfo info) { + public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { return info.authoritiesIterator(); } } - // TODO(b/135203078): Document or remove this if possible. - class EffectiveProvider extends ParsedProvider { - - private String mEffectiveAuthority; - private boolean mEffectiveSyncable; - - public EffectiveProvider(ParsedProvider parsedProvider) { - this.setFrom(parsedProvider); - this.mEffectiveAuthority = parsedProvider.getAuthority(); - this.mEffectiveSyncable = parsedProvider.isSyncable(); - } - - public void setEffectiveAuthority(String authority) { - this.mEffectiveAuthority = authority; - } - - public void setEffectiveSyncable(boolean syncable) { - this.mEffectiveSyncable = syncable; - } - - @Override - public String getAuthority() { - return mEffectiveAuthority; - } - - @Override - public boolean isSyncable() { - return mEffectiveSyncable; - } - } } diff --git a/services/core/java/com/android/server/pm/InstantAppRegistry.java b/services/core/java/com/android/server/pm/InstantAppRegistry.java index f9113fa38825..9e04c4b69bd0 100644 --- a/services/core/java/com/android/server/pm/InstantAppRegistry.java +++ b/services/core/java/com/android/server/pm/InstantAppRegistry.java @@ -20,11 +20,9 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.Intent; -import android.content.pm.ApplicationInfo; import android.content.pm.InstantAppInfo; import android.content.pm.PackageManager; import android.content.pm.PackageParser; -import android.content.pm.parsing.AndroidPackage; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; @@ -139,7 +137,7 @@ class InstantAppRegistry { public byte[] getInstantAppCookieLPw(@NonNull String packageName, @UserIdInt int userId) { // Only installed packages can get their own cookie - AndroidPackage pkg = mService.mPackages.get(packageName); + PackageParser.Package pkg = mService.mPackages.get(packageName); if (pkg == null) { return null; } @@ -173,7 +171,7 @@ class InstantAppRegistry { } // Only an installed package can set its own cookie - AndroidPackage pkg = mService.mPackages.get(packageName); + PackageParser.Package pkg = mService.mPackages.get(packageName); if (pkg == null) { return false; } @@ -266,15 +264,15 @@ class InstantAppRegistry { } @GuardedBy("mService.mLock") - public void onPackageInstalledLPw(@NonNull AndroidPackage pkg, @NonNull int[] userIds) { - PackageSetting ps = mService.getPackageSetting(pkg.getPackageName()); + public void onPackageInstalledLPw(@NonNull PackageParser.Package pkg, @NonNull int[] userIds) { + PackageSetting ps = (PackageSetting) pkg.mExtras; if (ps == null) { return; } for (int userId : userIds) { // Ignore not installed apps - if (mService.mPackages.get(pkg.getPackageName()) == null || !ps.getInstalled(userId)) { + if (mService.mPackages.get(pkg.packageName) == null || !ps.getInstalled(userId)) { continue; } @@ -288,16 +286,16 @@ class InstantAppRegistry { // Remove the in-memory state removeUninstalledInstantAppStateLPw((UninstalledInstantAppState state) -> - state.mInstantAppInfo.getPackageName().equals(pkg.getPackageName()), + state.mInstantAppInfo.getPackageName().equals(pkg.packageName), userId); // Remove the on-disk state except the cookie - File instantAppDir = getInstantApplicationDir(pkg.getPackageName(), userId); + File instantAppDir = getInstantApplicationDir(pkg.packageName, userId); new File(instantAppDir, INSTANT_APP_METADATA_FILE).delete(); new File(instantAppDir, INSTANT_APP_ICON_FILE).delete(); // If app signature changed - wipe the cookie - File currentCookieFile = peekInstantCookieFile(pkg.getPackageName(), userId); + File currentCookieFile = peekInstantCookieFile(pkg.packageName, userId); if (currentCookieFile == null) { continue; } @@ -312,7 +310,7 @@ class InstantAppRegistry { // We prefer the modern computation procedure where all certs are taken // into account but also allow the value from the old computation to avoid // data loss. - if (pkg.getSigningDetails().checkCapability(currentCookieSha256, + if (pkg.mSigningDetails.checkCapability(currentCookieSha256, PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)) { return; } @@ -320,7 +318,7 @@ class InstantAppRegistry { // For backwards compatibility we accept match based on any signature, since we may have // recorded only the first for multiply-signed packages final String[] signaturesSha256Digests = - PackageUtils.computeSignaturesSha256Digests(pkg.getSigningDetails().signatures); + PackageUtils.computeSignaturesSha256Digests(pkg.mSigningDetails.signatures); for (String s : signaturesSha256Digests) { if (s.equals(currentCookieSha256)) { return; @@ -328,7 +326,7 @@ class InstantAppRegistry { } // Sorry, you are out of luck - different signatures - nuke data - Slog.i(LOG_TAG, "Signature for package " + pkg.getPackageName() + Slog.i(LOG_TAG, "Signature for package " + pkg.packageName + " changed - dropping cookie"); // Make sure a pending write for the old signed app is cancelled mCookiePersistence.cancelPendingPersistLPw(pkg, userId); @@ -337,15 +335,15 @@ class InstantAppRegistry { } @GuardedBy("mService.mLock") - public void onPackageUninstalledLPw(@NonNull AndroidPackage pkg, + public void onPackageUninstalledLPw(@NonNull PackageParser.Package pkg, @NonNull int[] userIds) { - PackageSetting ps = mService.getPackageSetting(pkg.getPackageName()); + PackageSetting ps = (PackageSetting) pkg.mExtras; if (ps == null) { return; } for (int userId : userIds) { - if (mService.mPackages.get(pkg.getPackageName()) != null && ps.getInstalled(userId)) { + if (mService.mPackages.get(pkg.packageName) != null && ps.getInstalled(userId)) { continue; } @@ -355,7 +353,7 @@ class InstantAppRegistry { removeInstantAppLPw(userId, ps.appId); } else { // Deleting an app prunes all instant state such as cookie - deleteDir(getInstantApplicationDir(pkg.getPackageName(), userId)); + deleteDir(getInstantApplicationDir(pkg.packageName, userId)); mCookiePersistence.cancelPendingPersistLPw(pkg, userId); removeAppLPw(userId, ps.appId); } @@ -489,7 +487,7 @@ class InstantAppRegistry { } @GuardedBy("mService.mLock") - private void addUninstalledInstantAppLPw(@NonNull AndroidPackage pkg, + private void addUninstalledInstantAppLPw(@NonNull PackageParser.Package pkg, @UserIdInt int userId) { InstantAppInfo uninstalledApp = createInstantAppInfoForPackage( pkg, userId, false); @@ -513,15 +511,14 @@ class InstantAppRegistry { writeInstantApplicationIconLPw(pkg, userId); } - private void writeInstantApplicationIconLPw(@NonNull AndroidPackage pkg, + private void writeInstantApplicationIconLPw(@NonNull PackageParser.Package pkg, @UserIdInt int userId) { - File appDir = getInstantApplicationDir(pkg.getPackageName(), userId); + File appDir = getInstantApplicationDir(pkg.packageName, userId); if (!appDir.exists()) { return; } - // TODO(b/135203078): Remove toAppInfo call? Requires significant additions/changes to PM - Drawable icon = pkg.toAppInfo().loadIcon(mService.mContext.getPackageManager()); + Drawable icon = pkg.applicationInfo.loadIcon(mService.mContext.getPackageManager()); final Bitmap bitmap; if (icon instanceof BitmapDrawable) { @@ -534,7 +531,7 @@ class InstantAppRegistry { icon.draw(canvas); } - File iconFile = new File(getInstantApplicationDir(pkg.getPackageName(), userId), + File iconFile = new File(getInstantApplicationDir(pkg.packageName, userId), INSTANT_APP_ICON_FILE); try (FileOutputStream out = new FileOutputStream(iconFile)) { @@ -693,16 +690,14 @@ class InstantAppRegistry { final int packageCount = mService.mPackages.size(); for (int i = 0; i < packageCount; i++) { - final AndroidPackage pkg = mService.mPackages.valueAt(i); + final PackageParser.Package pkg = mService.mPackages.valueAt(i); if (now - pkg.getLatestPackageUseTimeInMills() < maxInstalledCacheDuration) { continue; } - - final PackageSetting ps = mService.getPackageSetting(pkg.getPackageName()); - if (ps == null) { + if (!(pkg.mExtras instanceof PackageSetting)) { continue; } - + final PackageSetting ps = (PackageSetting) pkg.mExtras; boolean installedOnlyAsInstantApp = false; for (int userId : allUsers) { if (ps.getInstalled(userId)) { @@ -718,14 +713,14 @@ class InstantAppRegistry { if (packagesToDelete == null) { packagesToDelete = new ArrayList<>(); } - packagesToDelete.add(pkg.getPackageName()); + packagesToDelete.add(pkg.packageName); } } if (packagesToDelete != null) { packagesToDelete.sort((String lhs, String rhs) -> { - final AndroidPackage lhsPkg = mService.mPackages.get(lhs); - final AndroidPackage rhsPkg = mService.mPackages.get(rhs); + final PackageParser.Package lhsPkg = mService.mPackages.get(lhs); + final PackageParser.Package rhsPkg = mService.mPackages.get(rhs); if (lhsPkg == null && rhsPkg == null) { return 0; } else if (lhsPkg == null) { @@ -740,22 +735,17 @@ class InstantAppRegistry { rhsPkg.getLatestPackageUseTimeInMills()) { return -1; } else { - final PackageSetting lhsPs = mService.getPackageSetting( - lhsPkg.getPackageName()); - if (lhsPs == null) { - return 0; - } - - final PackageSetting rhsPs = mService.getPackageSetting( - rhsPkg.getPackageName()); - if (rhsPs == null) { - return 0; - } - - if (lhsPs.firstInstallTime > rhsPs.firstInstallTime) { - return 1; + if (lhsPkg.mExtras instanceof PackageSetting + && rhsPkg.mExtras instanceof PackageSetting) { + final PackageSetting lhsPs = (PackageSetting) lhsPkg.mExtras; + final PackageSetting rhsPs = (PackageSetting) rhsPkg.mExtras; + if (lhsPs.firstInstallTime > rhsPs.firstInstallTime) { + return 1; + } else { + return -1; + } } else { - return -1; + return 0; } } } @@ -828,8 +818,8 @@ class InstantAppRegistry { final int packageCount = mService.mPackages.size(); for (int i = 0; i < packageCount; i++) { - final AndroidPackage pkg = mService.mPackages.valueAt(i); - final PackageSetting ps = mService.getPackageSetting(pkg.getPackageName()); + final PackageParser.Package pkg = mService.mPackages.valueAt(i); + final PackageSetting ps = (PackageSetting) pkg.mExtras; if (ps == null || !ps.getInstantApp(userId)) { continue; } @@ -849,9 +839,9 @@ class InstantAppRegistry { private @NonNull InstantAppInfo createInstantAppInfoForPackage( - @NonNull AndroidPackage pkg, @UserIdInt int userId, + @NonNull PackageParser.Package pkg, @UserIdInt int userId, boolean addApplicationInfo) { - PackageSetting ps = mService.getPackageSetting(pkg.getPackageName()); + PackageSetting ps = (PackageSetting) pkg.mExtras; if (ps == null) { return null; } @@ -859,20 +849,19 @@ class InstantAppRegistry { return null; } - String[] requestedPermissions = new String[pkg.getRequestedPermissions().size()]; - pkg.getRequestedPermissions().toArray(requestedPermissions); + String[] requestedPermissions = new String[pkg.requestedPermissions.size()]; + pkg.requestedPermissions.toArray(requestedPermissions); Set<String> permissions = ps.getPermissionsState().getPermissions(userId); String[] grantedPermissions = new String[permissions.size()]; permissions.toArray(grantedPermissions); - ApplicationInfo appInfo = pkg.toAppInfo(); if (addApplicationInfo) { - return new InstantAppInfo(appInfo, + return new InstantAppInfo(pkg.applicationInfo, requestedPermissions, grantedPermissions); } else { - return new InstantAppInfo(appInfo.packageName, - appInfo.loadLabel(mService.mContext.getPackageManager()), + return new InstantAppInfo(pkg.applicationInfo.packageName, + pkg.applicationInfo.loadLabel(mService.mContext.getPackageManager()), requestedPermissions, grantedPermissions); } } @@ -898,10 +887,10 @@ class InstantAppRegistry { return uninstalledApps; } - private void propagateInstantAppPermissionsIfNeeded(@NonNull AndroidPackage pkg, + private void propagateInstantAppPermissionsIfNeeded(@NonNull PackageParser.Package pkg, @UserIdInt int userId) { InstantAppInfo appInfo = peekOrParseUninstalledInstantAppInfo( - pkg.getPackageName(), userId); + pkg.packageName, userId); if (appInfo == null) { return; } @@ -913,10 +902,8 @@ class InstantAppRegistry { for (String grantedPermission : appInfo.getGrantedPermissions()) { final boolean propagatePermission = mService.mSettings.canPropagatePermissionToInstantApp(grantedPermission); - if (propagatePermission && pkg.getRequestedPermissions().contains( - grantedPermission)) { - mService.grantRuntimePermission(pkg.getPackageName(), grantedPermission, - userId); + if (propagatePermission && pkg.requestedPermissions.contains(grantedPermission)) { + mService.grantRuntimePermission(pkg.packageName, grantedPermission, userId); } } } finally { @@ -1201,19 +1188,18 @@ class InstantAppRegistry { super(looper); } - public void schedulePersistLPw(@UserIdInt int userId, @NonNull AndroidPackage pkg, + public void schedulePersistLPw(@UserIdInt int userId, @NonNull PackageParser.Package pkg, @NonNull byte[] cookie) { // Before we used only the first signature to compute the SHA 256 but some // apps could be singed by multiple certs and the cert order is undefined. // We prefer the modern computation procedure where all certs are taken // into account and delete the file derived via the legacy hash computation. - File newCookieFile = computeInstantCookieFile(pkg.getPackageName(), - PackageUtils.computeSignaturesSha256Digest(pkg.getSigningDetails().signatures), - userId); - if (!pkg.getSigningDetails().hasSignatures()) { + File newCookieFile = computeInstantCookieFile(pkg.packageName, + PackageUtils.computeSignaturesSha256Digest(pkg.mSigningDetails.signatures), userId); + if (!pkg.mSigningDetails.hasSignatures()) { Slog.wtf(LOG_TAG, "Parsed Instant App contains no valid signatures!"); } - File oldCookieFile = peekInstantCookieFile(pkg.getPackageName(), userId); + File oldCookieFile = peekInstantCookieFile(pkg.packageName, userId); if (oldCookieFile != null && !newCookieFile.equals(oldCookieFile)) { oldCookieFile.delete(); } @@ -1223,12 +1209,12 @@ class InstantAppRegistry { PERSIST_COOKIE_DELAY_MILLIS); } - public @Nullable byte[] getPendingPersistCookieLPr(@NonNull AndroidPackage pkg, + public @Nullable byte[] getPendingPersistCookieLPr(@NonNull PackageParser.Package pkg, @UserIdInt int userId) { ArrayMap<String, SomeArgs> pendingWorkForUser = mPendingPersistCookies.get(userId); if (pendingWorkForUser != null) { - SomeArgs state = pendingWorkForUser.get(pkg.getPackageName()); + SomeArgs state = pendingWorkForUser.get(pkg.packageName); if (state != null) { return (byte[]) state.arg1; } @@ -1236,7 +1222,7 @@ class InstantAppRegistry { return null; } - public void cancelPendingPersistLPw(@NonNull AndroidPackage pkg, + public void cancelPendingPersistLPw(@NonNull PackageParser.Package pkg, @UserIdInt int userId) { removeMessages(userId, pkg); SomeArgs state = removePendingPersistCookieLPr(pkg, userId); @@ -1246,7 +1232,7 @@ class InstantAppRegistry { } private void addPendingPersistCookieLPw(@UserIdInt int userId, - @NonNull AndroidPackage pkg, @NonNull byte[] cookie, + @NonNull PackageParser.Package pkg, @NonNull byte[] cookie, @NonNull File cookieFile) { ArrayMap<String, SomeArgs> pendingWorkForUser = mPendingPersistCookies.get(userId); @@ -1257,16 +1243,16 @@ class InstantAppRegistry { SomeArgs args = SomeArgs.obtain(); args.arg1 = cookie; args.arg2 = cookieFile; - pendingWorkForUser.put(pkg.getPackageName(), args); + pendingWorkForUser.put(pkg.packageName, args); } - private SomeArgs removePendingPersistCookieLPr(@NonNull AndroidPackage pkg, + private SomeArgs removePendingPersistCookieLPr(@NonNull PackageParser.Package pkg, @UserIdInt int userId) { ArrayMap<String, SomeArgs> pendingWorkForUser = mPendingPersistCookies.get(userId); SomeArgs state = null; if (pendingWorkForUser != null) { - state = pendingWorkForUser.remove(pkg.getPackageName()); + state = pendingWorkForUser.remove(pkg.packageName); if (pendingWorkForUser.isEmpty()) { mPendingPersistCookies.remove(userId); } @@ -1277,7 +1263,7 @@ class InstantAppRegistry { @Override public void handleMessage(Message message) { int userId = message.what; - AndroidPackage pkg = (AndroidPackage) message.obj; + PackageParser.Package pkg = (PackageParser.Package) message.obj; SomeArgs state = removePendingPersistCookieLPr(pkg, userId); if (state == null) { return; @@ -1285,7 +1271,7 @@ class InstantAppRegistry { byte[] cookie = (byte[]) state.arg1; File cookieFile = (File) state.arg2; state.recycle(); - persistInstantApplicationCookie(cookie, pkg.getPackageName(), cookieFile, userId); + persistInstantApplicationCookie(cookie, pkg.packageName, cookieFile, userId); } } } diff --git a/services/core/java/com/android/server/pm/InstructionSets.java b/services/core/java/com/android/server/pm/InstructionSets.java index 0a065eba4309..ec48713b0874 100644 --- a/services/core/java/com/android/server/pm/InstructionSets.java +++ b/services/core/java/com/android/server/pm/InstructionSets.java @@ -16,7 +16,7 @@ package com.android.server.pm; -import android.content.pm.parsing.AndroidPackage; +import android.content.pm.ApplicationInfo; import android.os.Build; import android.os.SystemProperties; import android.text.TextUtils; @@ -35,16 +35,30 @@ import java.util.List; public class InstructionSets { private static final String PREFERRED_INSTRUCTION_SET = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]); + public static String[] getAppDexInstructionSets(ApplicationInfo info) { + if (info.primaryCpuAbi != null) { + if (info.secondaryCpuAbi != null) { + return new String[] { + VMRuntime.getInstructionSet(info.primaryCpuAbi), + VMRuntime.getInstructionSet(info.secondaryCpuAbi) }; + } else { + return new String[] { + VMRuntime.getInstructionSet(info.primaryCpuAbi) }; + } + } - public static String[] getAppDexInstructionSets(String primaryCpuAbi, String secondaryCpuAbi) { - if (primaryCpuAbi != null) { - if (secondaryCpuAbi != null) { + return new String[] { getPreferredInstructionSet() }; + } + + public static String[] getAppDexInstructionSets(PackageSetting ps) { + if (ps.primaryCpuAbiString != null) { + if (ps.secondaryCpuAbiString != null) { return new String[] { - VMRuntime.getInstructionSet(primaryCpuAbi), - VMRuntime.getInstructionSet(secondaryCpuAbi) }; + VMRuntime.getInstructionSet(ps.primaryCpuAbiString), + VMRuntime.getInstructionSet(ps.secondaryCpuAbiString) }; } else { return new String[] { - VMRuntime.getInstructionSet(primaryCpuAbi) }; + VMRuntime.getInstructionSet(ps.primaryCpuAbiString) }; } } @@ -110,12 +124,4 @@ public class InstructionSets { return VMRuntime.getInstructionSet(abis.primary); } - public static String getPrimaryInstructionSet(AndroidPackage pkg) { - if (pkg.getPrimaryCpuAbi() == null) { - return getPreferredInstructionSet(); - } - - return VMRuntime.getInstructionSet(pkg.getPrimaryCpuAbi()); - } - } diff --git a/services/core/java/com/android/server/pm/IntentFilterVerificationState.java b/services/core/java/com/android/server/pm/IntentFilterVerificationState.java index c97d85df00ab..a4e9d103b6da 100644 --- a/services/core/java/com/android/server/pm/IntentFilterVerificationState.java +++ b/services/core/java/com/android/server/pm/IntentFilterVerificationState.java @@ -17,7 +17,7 @@ package com.android.server.pm; import android.content.pm.PackageManager; -import android.content.pm.parsing.ComponentParseUtils; +import android.content.pm.PackageParser; import android.util.ArraySet; import android.util.Slog; @@ -35,7 +35,7 @@ public class IntentFilterVerificationState { private int mState; - private ArrayList<ComponentParseUtils.ParsedActivityIntentInfo> mFilters = new ArrayList<>(); + private ArrayList<PackageParser.ActivityIntentInfo> mFilters = new ArrayList<>(); private ArraySet<String> mHosts = new ArraySet<>(); private int mUserId; @@ -66,7 +66,7 @@ public class IntentFilterVerificationState { setState(STATE_VERIFICATION_PENDING); } - public ArrayList<ComponentParseUtils.ParsedActivityIntentInfo> getFilters() { + public ArrayList<PackageParser.ActivityIntentInfo> getFilters() { return mFilters; } @@ -123,7 +123,7 @@ public class IntentFilterVerificationState { return false; } - public void addFilter(ComponentParseUtils.ParsedActivityIntentInfo filter) { + public void addFilter(PackageParser.ActivityIntentInfo filter) { mFilters.add(filter); mHosts.addAll(filter.getHostsList()); } diff --git a/services/core/java/com/android/server/pm/KeySetManagerService.java b/services/core/java/com/android/server/pm/KeySetManagerService.java index 70c0f8d98447..93d3b77511bc 100644 --- a/services/core/java/com/android/server/pm/KeySetManagerService.java +++ b/services/core/java/com/android/server/pm/KeySetManagerService.java @@ -20,26 +20,23 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; import static com.android.server.pm.PackageManagerService.SCAN_INITIAL; +import com.android.internal.util.Preconditions; import android.content.pm.PackageParser; -import android.content.pm.parsing.AndroidPackage; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Base64; -import android.util.LongSparseArray; import android.util.Slog; - -import com.android.internal.util.Preconditions; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; +import android.util.LongSparseArray; import java.io.IOException; import java.io.PrintWriter; import java.security.PublicKey; -import java.util.Map; import java.util.Set; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + /* * Manages system-wide KeySet state. */ @@ -185,31 +182,33 @@ public class KeySetManagerService { * * Returns true if the package can safely be added to the keyset metadata. */ - public void assertScannedPackageValid(AndroidPackage pkg) + public void assertScannedPackageValid(PackageParser.Package pkg) throws PackageManagerException { - if (pkg == null || pkg.getPackageName() == null) { + if (pkg == null || pkg.packageName == null) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "Passed invalid package to keyset validation."); } - ArraySet<PublicKey> signingKeys = pkg.getSigningDetails().publicKeys; + ArraySet<PublicKey> signingKeys = pkg.mSigningDetails.publicKeys; if (signingKeys == null || !(signingKeys.size() > 0) || signingKeys.contains(null)) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "Package has invalid signing-key-set."); } - Map<String, ArraySet<PublicKey>> definedMapping = pkg.getKeySetMapping(); + ArrayMap<String, ArraySet<PublicKey>> definedMapping = pkg.mKeySetMapping; if (definedMapping != null) { if (definedMapping.containsKey(null) || definedMapping.containsValue(null)) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "Package has null defined key set."); } - for (ArraySet<PublicKey> value : definedMapping.values()) { - if (!(value.size() > 0) || value.contains(null)) { + int defMapSize = definedMapping.size(); + for (int i = 0; i < defMapSize; i++) { + if (!(definedMapping.valueAt(i).size() > 0) + || definedMapping.valueAt(i).contains(null)) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "Package has null/no public keys for defined key-sets."); } } } - Set<String> upgradeAliases = pkg.getUpgradeKeySets(); + ArraySet<String> upgradeAliases = pkg.mUpgradeKeySets; if (upgradeAliases != null) { if (definedMapping == null || !(definedMapping.keySet().containsAll(upgradeAliases))) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, @@ -218,17 +217,17 @@ public class KeySetManagerService { } } - public void addScannedPackageLPw(AndroidPackage pkg) { + public void addScannedPackageLPw(PackageParser.Package pkg) { Preconditions.checkNotNull(pkg, "Attempted to add null pkg to ksms."); - Preconditions.checkNotNull(pkg.getPackageName(), "Attempted to add null pkg to ksms."); - PackageSetting ps = mPackages.get(pkg.getPackageName()); - Preconditions.checkNotNull(ps, "pkg: " + pkg.getPackageName() + Preconditions.checkNotNull(pkg.packageName, "Attempted to add null pkg to ksms."); + PackageSetting ps = mPackages.get(pkg.packageName); + Preconditions.checkNotNull(ps, "pkg: " + pkg.packageName + "does not have a corresponding entry in mPackages."); - addSigningKeySetToPackageLPw(ps, pkg.getSigningDetails().publicKeys); - if (pkg.getKeySetMapping() != null) { - addDefinedKeySetsToPackageLPw(ps, pkg.getKeySetMapping()); - if (pkg.getUpgradeKeySets() != null) { - addUpgradeKeySetsToPackageLPw(ps, pkg.getUpgradeKeySets()); + addSigningKeySetToPackageLPw(ps, pkg.mSigningDetails.publicKeys); + if (pkg.mKeySetMapping != null) { + addDefinedKeySetsToPackageLPw(ps, pkg.mKeySetMapping); + if (pkg.mUpgradeKeySets != null) { + addUpgradeKeySetsToPackageLPw(ps, pkg.mUpgradeKeySets); } } } @@ -281,14 +280,15 @@ public class KeySetManagerService { * Remove any KeySets the package no longer defines. */ void addDefinedKeySetsToPackageLPw(PackageSetting pkg, - Map<String, ArraySet<PublicKey>> definedMapping) { + ArrayMap<String, ArraySet<PublicKey>> definedMapping) { ArrayMap<String, Long> prevDefinedKeySets = pkg.keySetData.getAliases(); /* add all of the newly defined KeySets */ - Map<String, Long> newKeySetAliases = new ArrayMap<>(); - for (Map.Entry<String, ArraySet<PublicKey>> entry : definedMapping.entrySet()) { - String alias = entry.getKey(); - ArraySet<PublicKey> pubKeys = entry.getValue(); + ArrayMap<String, Long> newKeySetAliases = new ArrayMap<String, Long>(); + final int defMapSize = definedMapping.size(); + for (int i = 0; i < defMapSize; i++) { + String alias = definedMapping.keyAt(i); + ArraySet<PublicKey> pubKeys = definedMapping.valueAt(i); if (alias != null && pubKeys != null && pubKeys.size() > 0) { KeySetHandle ks = addKeySetLPw(pubKeys); newKeySetAliases.put(alias, ks.getId()); @@ -313,10 +313,12 @@ public class KeySetManagerService { * after all of the defined KeySets have been added. */ void addUpgradeKeySetsToPackageLPw(PackageSetting pkg, - Set<String> upgradeAliases) { - for (String upgradeAlias : upgradeAliases) { - pkg.keySetData.addUpgradeKeySet(upgradeAlias); + ArraySet<String> upgradeAliases) { + final int uaSize = upgradeAliases.size(); + for (int i = 0; i < uaSize; i++) { + pkg.keySetData.addUpgradeKeySet(upgradeAliases.valueAt(i)); } + return; } /** @@ -362,14 +364,14 @@ public class KeySetManagerService { return true; } - public boolean checkUpgradeKeySetLocked(PackageSettingBase oldPS, AndroidPackage pkg) { + public boolean checkUpgradeKeySetLocked(PackageSettingBase oldPS, + PackageParser.Package newPkg) { // Upgrade keysets are being used. Determine if new package has a superset of the // required keys. long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); for (int i = 0; i < upgradeKeySets.length; i++) { Set<PublicKey> upgradeSet = getPublicKeysFromKeySetLPr(upgradeKeySets[i]); - if (upgradeSet != null - && pkg.getSigningDetails().publicKeys.containsAll(upgradeSet)) { + if (upgradeSet != null && newPkg.mSigningDetails.publicKeys.containsAll(upgradeSet)) { return true; } } diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index c844f1bd95ff..2b6c347fe726 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -40,13 +40,13 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageInstaller.SessionInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; +import android.content.pm.PackageParser; import android.content.pm.ParceledListSlice; import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutServiceInternal; import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener; import android.content.pm.UserInfo; -import android.content.pm.parsing.AndroidPackage; import android.graphics.Rect; import android.net.Uri; import android.os.Binder; @@ -62,6 +62,7 @@ import android.os.UserManager; import android.os.UserManagerInternal; import android.provider.Settings; import android.util.Log; +import android.util.Pair; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; @@ -445,7 +446,7 @@ public class LauncherAppsService extends SystemService { } final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); - final AndroidPackage pkg = pmInt.getPackage(appInfo.packageName); + final PackageParser.Package pkg = pmInt.getPackage(appInfo.packageName); if (pkg == null) { // Should not happen, but we shouldn't be failing if it does return false; @@ -456,8 +457,8 @@ public class LauncherAppsService extends SystemService { appInfo.packageName); } - private boolean requestsPermissions(@NonNull AndroidPackage pkg) { - return !ArrayUtils.isEmpty(pkg.getRequestedPermissions()); + private boolean requestsPermissions(@NonNull PackageParser.Package pkg) { + return !ArrayUtils.isEmpty(pkg.requestedPermissions); } private boolean hasDefaultEnableLauncherActivity(@NonNull String packageName) { @@ -1024,8 +1025,22 @@ public class LauncherAppsService extends SystemService { } @Override - public void onPackagesSuspended(String[] packages, Bundle launcherExtras) { + public void onPackagesSuspended(String[] packages) { UserHandle user = new UserHandle(getChangingUserId()); + PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class); + final ArrayList<Pair<String, Bundle>> packagesWithExtras = new ArrayList<>(); + final ArrayList<String> packagesWithoutExtras = new ArrayList<>(); + for (String pkg : packages) { + final Bundle launcherExtras = pmi.getSuspendedPackageLauncherExtras(pkg, + user.getIdentifier()); + if (launcherExtras != null) { + packagesWithExtras.add(new Pair<>(pkg, launcherExtras)); + } else { + packagesWithoutExtras.add(pkg); + } + } + final String[] packagesNullExtras = packagesWithoutExtras.toArray( + new String[packagesWithoutExtras.size()]); final int n = mListeners.beginBroadcast(); try { for (int i = 0; i < n; i++) { @@ -1033,7 +1048,13 @@ public class LauncherAppsService extends SystemService { BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(cookie.user, user, "onPackagesSuspended")) continue; try { - listener.onPackagesSuspended(user, packages, launcherExtras); + listener.onPackagesSuspended(user, packagesNullExtras, null); + for (int idx = 0; idx < packagesWithExtras.size(); idx++) { + Pair<String, Bundle> packageExtraPair = packagesWithExtras.get(idx); + listener.onPackagesSuspended(user, + new String[]{packageExtraPair.first}, + packageExtraPair.second); + } } catch (RemoteException re) { Slog.d(TAG, "Callback failed ", re); } @@ -1041,8 +1062,6 @@ public class LauncherAppsService extends SystemService { } finally { mListeners.finishBroadcast(); } - - super.onPackagesSuspended(packages, launcherExtras); } @Override diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java index ae7a4a7b81f5..d49ecdda679d 100644 --- a/services/core/java/com/android/server/pm/OtaDexoptService.java +++ b/services/core/java/com/android/server/pm/OtaDexoptService.java @@ -22,7 +22,7 @@ import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; import android.annotation.Nullable; import android.content.Context; import android.content.pm.IOtaDexopt; -import android.content.pm.parsing.AndroidPackage; +import android.content.pm.PackageParser; import android.os.Environment; import android.os.RemoteException; import android.os.ResultReceiver; @@ -118,8 +118,8 @@ public class OtaDexoptService extends IOtaDexopt.Stub { if (mDexoptCommands != null) { throw new IllegalStateException("already called prepare()"); } - final List<AndroidPackage> important; - final List<AndroidPackage> others; + final List<PackageParser.Package> important; + final List<PackageParser.Package> others; synchronized (mPackageManagerService.mLock) { // Important: the packages we need to run with ab-ota compiler-reason. important = PackageManagerServiceUtils.getPackagesForDexopt( @@ -133,12 +133,12 @@ public class OtaDexoptService extends IOtaDexopt.Stub { mDexoptCommands = new ArrayList<>(3 * mPackageManagerService.mPackages.size() / 2); } - for (AndroidPackage p : important) { + for (PackageParser.Package p : important) { mDexoptCommands.addAll(generatePackageDexopts(p, PackageManagerService.REASON_AB_OTA)); } - for (AndroidPackage p : others) { + for (PackageParser.Package p : others) { // We assume here that there are no core apps left. - if (p.isCoreApp()) { + if (p.coreApp) { throw new IllegalStateException("Found a core app that's not important"); } mDexoptCommands.addAll( @@ -150,8 +150,8 @@ public class OtaDexoptService extends IOtaDexopt.Stub { if (spaceAvailable < BULK_DELETE_THRESHOLD) { Log.i(TAG, "Low on space, deleting oat files in an attempt to free up space: " + PackageManagerServiceUtils.packagesToString(others)); - for (AndroidPackage pkg : others) { - mPackageManagerService.deleteOatArtifactsOfPackage(pkg.getPackageName()); + for (PackageParser.Package pkg : others) { + mPackageManagerService.deleteOatArtifactsOfPackage(pkg.packageName); } } long spaceAvailableNow = getAvailableSpace(); @@ -161,15 +161,15 @@ public class OtaDexoptService extends IOtaDexopt.Stub { if (DEBUG_DEXOPT) { try { // Output some data about the packages. - AndroidPackage lastUsed = Collections.max(important, + PackageParser.Package lastUsed = Collections.max(important, (pkg1, pkg2) -> Long.compare( pkg1.getLatestForegroundPackageUseTimeInMills(), pkg2.getLatestForegroundPackageUseTimeInMills())); Log.d(TAG, "A/B OTA: lastUsed time = " + lastUsed.getLatestForegroundPackageUseTimeInMills()); Log.d(TAG, "A/B OTA: deprioritized packages:"); - for (AndroidPackage pkg : others) { - Log.d(TAG, " " + pkg.getPackageName() + " - " + for (PackageParser.Package pkg : others) { + Log.d(TAG, " " + pkg.packageName + " - " + pkg.getLatestForegroundPackageUseTimeInMills()); } } catch (Exception ignored) { @@ -262,7 +262,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub { /** * Generate all dexopt commands for the given package. */ - private synchronized List<String> generatePackageDexopts(AndroidPackage pkg, + private synchronized List<String> generatePackageDexopts(PackageParser.Package pkg, int compilationReason) { // Intercept and collect dexopt requests final List<String> commands = new ArrayList<String>(); @@ -336,9 +336,8 @@ public class OtaDexoptService extends IOtaDexopt.Stub { optimizer.performDexOpt(pkg, null /* ISAs */, null /* CompilerStats.PackageStats */, - mPackageManagerService.getDexManager().getPackageUseInfoOrDefault( - pkg.getPackageName()), - new DexoptOptions(pkg.getPackageName(), compilationReason, + mPackageManagerService.getDexManager().getPackageUseInfoOrDefault(pkg.packageName), + new DexoptOptions(pkg.packageName, compilationReason, DexoptOptions.DEXOPT_BOOT_COMPLETE)); return commands; @@ -360,10 +359,10 @@ public class OtaDexoptService extends IOtaDexopt.Stub { } // Look into all packages. - Collection<AndroidPackage> pkgs = mPackageManagerService.getPackages(); + Collection<PackageParser.Package> pkgs = mPackageManagerService.getPackages(); int packagePaths = 0; int pathsSuccessful = 0; - for (AndroidPackage pkg : pkgs) { + for (PackageParser.Package pkg : pkgs) { if (pkg == null) { continue; } @@ -372,28 +371,27 @@ public class OtaDexoptService extends IOtaDexopt.Stub { if (!PackageDexOptimizer.canOptimizePackage(pkg)) { continue; } - if (pkg.getCodePath() == null) { + if (pkg.codePath == null) { Slog.w(TAG, "Package " + pkg + " can be optimized but has null codePath"); continue; } // If the path is in /system, /vendor, /product or /system_ext, ignore. It will // have been ota-dexopted into /data/ota and moved into the dalvik-cache already. - if (pkg.getCodePath().startsWith("/system") - || pkg.getCodePath().startsWith("/vendor") - || pkg.getCodePath().startsWith("/product") - || pkg.getCodePath().startsWith("/system_ext")) { + if (pkg.codePath.startsWith("/system") + || pkg.codePath.startsWith("/vendor") + || pkg.codePath.startsWith("/product") + || pkg.codePath.startsWith("/system_ext")) { continue; } - final String[] instructionSets = getAppDexInstructionSets(pkg.getPrimaryCpuAbi(), - pkg.getSecondaryCpuAbi()); + final String[] instructionSets = getAppDexInstructionSets(pkg.applicationInfo); final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly(); final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); for (String dexCodeInstructionSet : dexCodeInstructionSets) { for (String path : paths) { - String oatDir = PackageDexOptimizer.getOatDir( - new File(pkg.getCodePath())).getAbsolutePath(); + String oatDir = PackageDexOptimizer.getOatDir(new File(pkg.codePath)). + getAbsolutePath(); // TODO: Check first whether there is an artifact, to save the roundtrip time. diff --git a/services/core/java/com/android/server/pm/PackageAbiHelper.java b/services/core/java/com/android/server/pm/PackageAbiHelper.java index d7c161cc1a86..c21d0cf54d91 100644 --- a/services/core/java/com/android/server/pm/PackageAbiHelper.java +++ b/services/core/java/com/android/server/pm/PackageAbiHelper.java @@ -17,8 +17,7 @@ package com.android.server.pm; import android.annotation.Nullable; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ParsedPackage; +import android.content.pm.PackageParser; import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; @@ -26,21 +25,21 @@ import com.android.internal.annotations.VisibleForTesting; import java.io.File; import java.util.Set; -// TODO: Move to .parsing sub-package @VisibleForTesting public interface PackageAbiHelper { /** * Derive and get the location of native libraries for the given package, * which varies depending on where and how the package was installed. */ - NativeLibraryPaths getNativeLibraryPaths(AndroidPackage pkg, File appLib32InstallDir); + NativeLibraryPaths getNativeLibraryPaths( + PackageParser.Package pkg, File appLib32InstallDir); /** * Calculate the abis for a bundled app. These can uniquely be determined from the contents of * the system partition, i.e whether it contains 64 or 32 bit shared libraries etc. We do not * validate any of this information, and instead assume that the system was built sensibly. */ - Abis getBundledAppAbis(AndroidPackage pkg); + Abis getBundledAppAbis(PackageParser.Package pkg); /** * Derive the ABI of a non-system package located at {@code pkg}. This information @@ -49,7 +48,7 @@ public interface PackageAbiHelper { * If {@code extractLibs} is true, native libraries are extracted from the app if required. */ Pair<Abis, NativeLibraryPaths> derivePackageAbi( - AndroidPackage pkg, String cpuAbiOverride, boolean extractLibs) + PackageParser.Package pkg, String cpuAbiOverride, boolean extractLibs) throws PackageManagerException; /** @@ -70,11 +69,11 @@ public interface PackageAbiHelper { */ @Nullable String getAdjustedAbiForSharedUser( - Set<PackageSetting> packagesForUser, AndroidPackage scannedPackage); + Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage); /** * The native library paths and related properties that should be set on a - * {@link ParsedPackage}. + * {@link android.content.pm.PackageParser.Package}. */ final class NativeLibraryPaths { public final String nativeLibraryRootDir; @@ -92,11 +91,11 @@ public interface PackageAbiHelper { this.secondaryNativeLibraryDir = secondaryNativeLibraryDir; } - public void applyTo(ParsedPackage pkg) { - pkg.setNativeLibraryRootDir(nativeLibraryRootDir) - .setNativeLibraryRootRequiresIsa(nativeLibraryRootRequiresIsa) - .setNativeLibraryDir(nativeLibraryDir) - .setSecondaryNativeLibraryDir(secondaryNativeLibraryDir); + public void applyTo(PackageParser.Package pkg) { + pkg.applicationInfo.nativeLibraryRootDir = nativeLibraryRootDir; + pkg.applicationInfo.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa; + pkg.applicationInfo.nativeLibraryDir = nativeLibraryDir; + pkg.applicationInfo.secondaryNativeLibraryDir = secondaryNativeLibraryDir; } } @@ -113,13 +112,13 @@ public interface PackageAbiHelper { this.secondary = secondary; } - Abis(AndroidPackage pkg) { - this(pkg.getPrimaryCpuAbi(), pkg.getSecondaryCpuAbi()); + Abis(PackageParser.Package pkg) { + this(pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi); } - public void applyTo(ParsedPackage pkg) { - pkg.setPrimaryCpuAbi(primary) - .setSecondaryCpuAbi(secondary); + public void applyTo(PackageParser.Package pkg) { + pkg.applicationInfo.primaryCpuAbi = primary; + pkg.applicationInfo.secondaryCpuAbi = secondary; } public void applyTo(PackageSetting pkgSetting) { // pkgSetting might be null during rescan following uninstall of updates diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java index 6de5203f0f73..1d3d24c27041 100644 --- a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java +++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java @@ -28,7 +28,7 @@ import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; import android.annotation.Nullable; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.content.pm.parsing.AndroidPackage; +import android.content.pm.PackageParser; import android.os.Build; import android.os.Environment; import android.os.FileUtils; @@ -122,10 +122,10 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { @Override public NativeLibraryPaths getNativeLibraryPaths( - AndroidPackage pkg, File appLib32InstallDir) { - return getNativeLibraryPaths(new Abis(pkg), appLib32InstallDir, pkg.getCodePath(), - pkg.getBaseCodePath(), pkg.isSystemApp(), - pkg.isUpdatedSystemApp()); + PackageParser.Package pkg, File appLib32InstallDir) { + return getNativeLibraryPaths(new Abis(pkg), appLib32InstallDir, pkg.codePath, + pkg.applicationInfo.sourceDir, pkg.applicationInfo.isSystemApp(), + pkg.applicationInfo.isUpdatedSystemApp()); } private static NativeLibraryPaths getNativeLibraryPaths(final Abis abis, @@ -192,12 +192,12 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { } @Override - public Abis getBundledAppAbis(AndroidPackage pkg) { - final String apkName = deriveCodePathName(pkg.getCodePath()); + public Abis getBundledAppAbis(PackageParser.Package pkg) { + final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); // If "/system/lib64/apkname" exists, assume that is the per-package // native library directory to use; otherwise use "/system/lib/apkname". - final String apkRoot = calculateBundledApkRoot(pkg.getBaseCodePath()); + final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); final Abis abis = getBundledAppAbi(pkg, apkRoot, apkName); return abis; } @@ -210,8 +210,8 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { * {@code /oem} under which system libraries are installed. * @param apkName the name of the installed package. */ - private Abis getBundledAppAbi(AndroidPackage pkg, String apkRoot, String apkName) { - final File codeFile = new File(pkg.getCodePath()); + private Abis getBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { + final File codeFile = new File(pkg.codePath); final boolean has64BitLibs; final boolean has32BitLibs; @@ -263,7 +263,7 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { // ABI that's higher on the list, i.e, a device that's configured to prefer // 64 bit apps will see a 64 bit primary ABI, - if ((pkg.getFlags() & ApplicationInfo.FLAG_MULTIARCH) == 0) { + if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { Slog.e(PackageManagerService.TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); } @@ -284,14 +284,14 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { @Override public Pair<Abis, NativeLibraryPaths> derivePackageAbi( - AndroidPackage pkg, String cpuAbiOverride, boolean extractLibs) + PackageParser.Package pkg, String cpuAbiOverride, boolean extractLibs) throws PackageManagerException { // Give ourselves some initial paths; we'll come back for another // pass once we've determined ABI below. final NativeLibraryPaths initialLibraryPaths = getNativeLibraryPaths(new Abis(pkg), - PackageManagerService.sAppLib32InstallDir, pkg.getCodePath(), - pkg.getBaseCodePath(), pkg.isSystemApp(), - pkg.isUpdatedSystemApp()); + PackageManagerService.sAppLib32InstallDir, pkg.codePath, + pkg.applicationInfo.sourceDir, pkg.applicationInfo.isSystemApp(), + pkg.applicationInfo.isUpdatedSystemApp()); // We shouldn't attempt to extract libs from system app when it was not updated. if (PackageManagerService.isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { @@ -318,13 +318,12 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { // Null out the abis so that they can be recalculated. primaryCpuAbi = null; secondaryCpuAbi = null; - if ((pkg.getFlags() & ApplicationInfo.FLAG_MULTIARCH) != 0) { + if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0) { // Warn if we've set an abiOverride for multi-lib packages.. // By definition, we need to copy both 32 and 64 bit libraries for // such packages. - if (pkg.getCpuAbiOverride() != null - && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals( - pkg.getCpuAbiOverride())) { + if (pkg.cpuAbiOverride != null + && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { Slog.w(PackageManagerService.TAG, "Ignoring abiOverride for multi arch application."); } @@ -383,7 +382,7 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { if (abi32 >= 0) { final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; if (abi64 >= 0) { - if (pkg.isUse32BitAbi()) { + if (pkg.use32bitAbi) { secondaryCpuAbi = primaryCpuAbi; primaryCpuAbi = abi; } else { @@ -450,9 +449,9 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { final Abis abis = new Abis(primaryCpuAbi, secondaryCpuAbi); return new Pair<>(abis, getNativeLibraryPaths(abis, PackageManagerService.sAppLib32InstallDir, - pkg.getCodePath(), pkg.getBaseCodePath(), - pkg.isSystemApp(), - pkg.isUpdatedSystemApp())); + pkg.codePath, pkg.applicationInfo.sourceDir, + pkg.applicationInfo.isSystemApp(), + pkg.applicationInfo.isUpdatedSystemApp())); } /** @@ -471,11 +470,11 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { @Override @Nullable public String getAdjustedAbiForSharedUser( - Set<PackageSetting> packagesForUser, AndroidPackage scannedPackage) { + Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) { String requiredInstructionSet = null; - if (scannedPackage != null && scannedPackage.getPrimaryCpuAbi() != null) { + if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { requiredInstructionSet = VMRuntime.getInstructionSet( - scannedPackage.getPrimaryCpuAbi()); + scannedPackage.applicationInfo.primaryCpuAbi); } PackageSetting requirer = null; @@ -484,7 +483,7 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { // when scannedPackage is an update of an existing package. Without this check, // we will never be able to change the ABI of any package belonging to a shared // user, even if it's compatible with other packages. - if (scannedPackage != null && scannedPackage.getPackageName().equals(ps.name)) { + if (scannedPackage != null && scannedPackage.packageName.equals(ps.name)) { continue; } if (ps.primaryCpuAbiString == null) { @@ -522,7 +521,7 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { } else { // requirer == null implies that we're updating all ABIs in the set to // match scannedPackage. - adjustedAbi = scannedPackage.getPrimaryCpuAbi(); + adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; } return adjustedAbi; } diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index 2b422211077b..4f7c8c8da4a9 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -41,10 +41,10 @@ import static dalvik.system.DexFile.isProfileGuidedCompilerFilter; import android.annotation.Nullable; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageParser; import android.content.pm.SharedLibraryInfo; import android.content.pm.dex.ArtManager; import android.content.pm.dex.DexMetadataHelper; -import android.content.pm.parsing.AndroidPackage; import android.os.FileUtils; import android.os.PowerManager; import android.os.SystemClock; @@ -53,7 +53,6 @@ import android.os.UserHandle; import android.os.WorkSource; import android.util.Log; import android.util.Slog; -import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; @@ -110,9 +109,9 @@ public class PackageDexOptimizer { this.mSystemReady = from.mSystemReady; } - static boolean canOptimizePackage(AndroidPackage pkg) { + static boolean canOptimizePackage(PackageParser.Package pkg) { // We do not dexopt a package with no code. - if ((pkg.getFlags() & ApplicationInfo.FLAG_HAS_CODE) == 0) { + if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) { return false; } @@ -126,18 +125,18 @@ public class PackageDexOptimizer { * <p>Calls to {@link com.android.server.pm.Installer#dexopt} on {@link #mInstaller} are * synchronized on {@link #mInstallLock}. */ - int performDexOpt(AndroidPackage pkg, + int performDexOpt(PackageParser.Package pkg, String[] instructionSets, CompilerStats.PackageStats packageStats, PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) { - if (pkg.getUid() == -1) { - throw new IllegalArgumentException("Dexopt for " + pkg.getPackageName() + if (pkg.applicationInfo.uid == -1) { + throw new IllegalArgumentException("Dexopt for " + pkg.packageName + " has invalid uid."); } if (!canOptimizePackage(pkg)) { return DEX_OPT_SKIPPED; } synchronized (mInstallLock) { - final long acquireTime = acquireWakeLockLI(pkg.getUid()); + final long acquireTime = acquireWakeLockLI(pkg.applicationInfo.uid); try { return performDexOptLI(pkg, instructionSets, packageStats, packageUseInfo, options); @@ -152,20 +151,19 @@ public class PackageDexOptimizer { * It assumes the install lock is held. */ @GuardedBy("mInstallLock") - private int performDexOptLI(AndroidPackage pkg, + private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets, CompilerStats.PackageStats packageStats, PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) { - final List<SharedLibraryInfo> sharedLibraries = pkg.getUsesLibraryInfos(); + final List<SharedLibraryInfo> sharedLibraries = pkg.usesLibraryInfos; final String[] instructionSets = targetInstructionSets != null ? - targetInstructionSets : getAppDexInstructionSets(pkg.getPrimaryCpuAbi(), - pkg.getSecondaryCpuAbi()); + targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo); final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); final List<String> paths = pkg.getAllCodePaths(); - int sharedGid = UserHandle.getSharedAppGid(pkg.getUid()); + int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); if (sharedGid == -1) { - Slog.wtf(TAG, "Well this is awkward; package " + pkg.getAppInfoName() + " had UID " - + pkg.getUid(), new Throwable()); + Slog.wtf(TAG, "Well this is awkward; package " + pkg.applicationInfo.name + " had UID " + + pkg.applicationInfo.uid, new Throwable()); sharedGid = android.os.Process.NOBODY_UID; } @@ -173,21 +171,21 @@ public class PackageDexOptimizer { // For each code path in the package, this array contains the class loader context that // needs to be passed to dexopt in order to ensure correct optimizations. boolean[] pathsWithCode = new boolean[paths.size()]; - pathsWithCode[0] = (pkg.getFlags() & ApplicationInfo.FLAG_HAS_CODE) != 0; + pathsWithCode[0] = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0; for (int i = 1; i < paths.size(); i++) { - pathsWithCode[i] = (pkg.getSplitFlags()[i - 1] & ApplicationInfo.FLAG_HAS_CODE) != 0; + pathsWithCode[i] = (pkg.splitFlags[i - 1] & ApplicationInfo.FLAG_HAS_CODE) != 0; } String[] classLoaderContexts = DexoptUtils.getClassLoaderContexts( - pkg, sharedLibraries, pathsWithCode); + pkg.applicationInfo, sharedLibraries, pathsWithCode); // Sanity check that we do not call dexopt with inconsistent data. if (paths.size() != classLoaderContexts.length) { - String[] splitCodePaths = pkg.getSplitCodePaths(); + String[] splitCodePaths = pkg.applicationInfo.getSplitCodePaths(); throw new IllegalStateException("Inconsistent information " + "between PackageParser.Package and its ApplicationInfo. " + "pkg.getAllCodePaths=" + paths - + " pkg.getBaseCodePath=" + pkg.getBaseCodePath() - + " pkg.getSplitCodePaths=" + + " pkg.applicationInfo.getBaseCodePath=" + pkg.applicationInfo.getBaseCodePath() + + " pkg.applicationInfo.getSplitCodePaths=" + (splitCodePaths == null ? "null" : Arrays.toString(splitCodePaths))); } @@ -213,8 +211,7 @@ public class PackageDexOptimizer { } } - String profileName = ArtManager.getProfileName( - i == 0 ? null : pkg.getSplitNames()[i - 1]); + String profileName = ArtManager.getProfileName(i == 0 ? null : pkg.splitNames[i - 1]); String dexMetadataPath = null; if (options.isDexoptInstallWithDexMetadata()) { @@ -225,7 +222,7 @@ public class PackageDexOptimizer { final boolean isUsedByOtherApps = options.isDexoptAsSharedLibrary() || packageUseInfo.isUsedByOtherApps(path); - final String compilerFilter = getRealCompilerFilter(pkg, + final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo, options.getCompilerFilter(), isUsedByOtherApps); final boolean profileUpdated = options.isCheckForProfileUpdates() && isProfileUpdated(pkg, sharedGid, profileName, compilerFilter); @@ -260,7 +257,7 @@ public class PackageDexOptimizer { * DEX_OPT_SKIPPED if the path does not need to be deopt-ed. */ @GuardedBy("mInstallLock") - private int dexOptPath(AndroidPackage pkg, String path, String isa, + private int dexOptPath(PackageParser.Package pkg, String path, String isa, String compilerFilter, boolean profileUpdated, String classLoaderContext, int dexoptFlags, int uid, CompilerStats.PackageStats packageStats, boolean downgrade, String profileName, String dexMetadataPath, int compilationReason) { @@ -273,7 +270,7 @@ public class PackageDexOptimizer { String oatDir = getPackageOatDirIfSupported(pkg); Log.i(TAG, "Running dexopt (dexoptNeeded=" + dexoptNeeded + ") on: " + path - + " pkg=" + pkg.getAppInfoPackageName() + " isa=" + isa + + " pkg=" + pkg.applicationInfo.packageName + " isa=" + isa + " dexoptFlags=" + printDexoptFlags(dexoptFlags) + " targetFilter=" + compilerFilter + " oatDir=" + oatDir + " classLoaderContext=" + classLoaderContext); @@ -284,9 +281,9 @@ public class PackageDexOptimizer { // TODO: Consider adding 2 different APIs for primary and secondary dexopt. // installd only uses downgrade flag for secondary dex files and ignores it for // primary dex files. - mInstaller.dexopt(path, uid, pkg.getPackageName(), isa, dexoptNeeded, oatDir, - dexoptFlags, compilerFilter, pkg.getVolumeUuid(), classLoaderContext, - pkg.getSeInfo(), false /* downgrade*/, pkg.getTargetSdkVersion(), + mInstaller.dexopt(path, uid, pkg.packageName, isa, dexoptNeeded, oatDir, dexoptFlags, + compilerFilter, pkg.volumeUuid, classLoaderContext, pkg.applicationInfo.seInfo, + false /* downgrade*/, pkg.applicationInfo.targetSdkVersion, profileName, dexMetadataPath, getAugmentedReasonName(compilationReason, dexMetadataPath != null)); @@ -449,10 +446,9 @@ public class PackageDexOptimizer { /** * Dumps the dexopt state of the given package {@code pkg} to the given {@code PrintWriter}. */ - void dumpDexoptState(IndentingPrintWriter pw, AndroidPackage pkg, + void dumpDexoptState(IndentingPrintWriter pw, PackageParser.Package pkg, PackageDexUsage.PackageUseInfo useInfo) { - final String[] instructionSets = getAppDexInstructionSets(pkg.getPrimaryCpuAbi(), - pkg.getSecondaryCpuAbi()); + final String[] instructionSets = getAppDexInstructionSets(pkg.applicationInfo); final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly(); @@ -508,7 +504,7 @@ public class PackageDexOptimizer { // When an app or priv app is configured to run out of box, only verify it. if (info.isEmbeddedDexUsed() || (info.isPrivilegedApp() - && DexManager.isPackageSelectedToRunOob(info.packageName))) { + && DexManager.isPackageSelectedToRunOob(info.packageName))) { return "verify"; } @@ -539,43 +535,12 @@ public class PackageDexOptimizer { } /** - * Returns the compiler filter that should be used to optimize the package code. - * The target filter will be updated if the package code is used by other apps - * or if it has the safe mode flag set. + * Computes the dex flags that needs to be pass to installd for the given package and compiler + * filter. */ - private String getRealCompilerFilter(AndroidPackage pkg, String targetCompilerFilter, - boolean isUsedByOtherApps) { - // When an app or priv app is configured to run out of box, only verify it. - if (pkg.isEmbeddedDexUsed() - || (pkg.isPrivileged() - && DexManager.isPackageSelectedToRunOob(pkg.getPackageName()))) { - return "verify"; - } - - // We force vmSafeMode on debuggable apps as well: - // - the runtime ignores their compiled code - // - they generally have lots of methods that could make the compiler used run - // out of memory (b/130828957) - // Note that forcing the compiler filter here applies to all compilations (even if they - // are done via adb shell commands). That's ok because right now the runtime will ignore - // the compiled code anyway. The alternative would have been to update either - // PackageDexOptimizer#canOptimizePackage or PackageManagerService#getOptimizablePackages - // but that would have the downside of possibly producing a big odex files which would - // be ignored anyway. - boolean vmSafeModeOrDebuggable = ((pkg.getFlags() & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0) - || ((pkg.getFlags() & ApplicationInfo.FLAG_DEBUGGABLE) != 0); - - if (vmSafeModeOrDebuggable) { - return getSafeModeCompilerFilter(targetCompilerFilter); - } - - if (isProfileGuidedCompilerFilter(targetCompilerFilter) && isUsedByOtherApps) { - // If the dex files is used by other apps, apply the shared filter. - return PackageManagerServiceCompilerMapping.getCompilerFilterForReason( - PackageManagerService.REASON_SHARED); - } - - return targetCompilerFilter; + private int getDexFlags(PackageParser.Package pkg, String compilerFilter, + DexoptOptions options) { + return getDexFlags(pkg.applicationInfo, compilerFilter, options); } private boolean isAppImageEnabled() { @@ -583,24 +548,7 @@ public class PackageDexOptimizer { } private int getDexFlags(ApplicationInfo info, String compilerFilter, DexoptOptions options) { - return getDexFlags(info.flags, info.getHiddenApiEnforcementPolicy(), - info.splitDependencies, info.requestsIsolatedSplitLoading(), compilerFilter, - options); - } - private int getDexFlags(AndroidPackage pkg, String compilerFilter, - DexoptOptions options) { - return getDexFlags(pkg.getFlags(), pkg.getHiddenApiEnforcementPolicy(), - pkg.getSplitDependencies(), pkg.requestsIsolatedSplitLoading(), compilerFilter, - options); - } - - /** - * Computes the dex flags that needs to be pass to installd for the given package and compiler - * filter. - */ - private int getDexFlags(int flags, int hiddenApiEnforcementPolicy, - SparseArray<int[]> splitDependencies, boolean requestsIsolatedSplitLoading, - String compilerFilter, DexoptOptions options) { + int flags = info.flags; boolean debuggable = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; // Profile guide compiled oat files should not be public unles they are based // on profiles from dex metadata archives. @@ -612,9 +560,7 @@ public class PackageDexOptimizer { // Some apps are executed with restrictions on hidden API usage. If this app is one // of them, pass a flag to dexopt to enable the same restrictions during compilation. // TODO we should pass the actual flag value to dexopt, rather than assuming blacklist - // TODO(b/135203078): This flag is no longer set as part of AndroidPackage - // and may not be preserved - int hiddenApiFlag = hiddenApiEnforcementPolicy == HIDDEN_API_ENFORCEMENT_DISABLED + int hiddenApiFlag = info.getHiddenApiEnforcementPolicy() == HIDDEN_API_ENFORCEMENT_DISABLED ? 0 : DEXOPT_ENABLE_HIDDEN_API_CHECKS; // Avoid generating CompactDex for modes that are latency critical. @@ -632,8 +578,8 @@ public class PackageDexOptimizer { // declare inter-split dependencies, then all the splits will be loaded in the base // apk class loader (in the order of their definition, otherwise disable app images // because they are unsupported for multiple class loaders. b/7269679 - boolean generateAppImage = isProfileGuidedFilter && (splitDependencies == null || - !requestsIsolatedSplitLoading) && isAppImageEnabled(); + boolean generateAppImage = isProfileGuidedFilter && (info.splitDependencies == null || + !info.requestsIsolatedSplitLoading()) && isAppImageEnabled(); int dexFlags = (isPublic ? DEXOPT_PUBLIC : 0) | (debuggable ? DEXOPT_DEBUGGABLE : 0) @@ -671,7 +617,7 @@ public class PackageDexOptimizer { * current profile and the reference profile will be merged and subsequent calls * may return a different result. */ - private boolean isProfileUpdated(AndroidPackage pkg, int uid, String profileName, + private boolean isProfileUpdated(PackageParser.Package pkg, int uid, String profileName, String compilerFilter) { // Check if we are allowed to merge and if the compiler filter is profile guided. if (!isProfileGuidedCompilerFilter(compilerFilter)) { @@ -679,7 +625,7 @@ public class PackageDexOptimizer { } // Merge profiles. It returns whether or not there was an updated in the profile info. try { - return mInstaller.mergeProfiles(uid, pkg.getPackageName(), profileName); + return mInstaller.mergeProfiles(uid, pkg.packageName, profileName); } catch (InstallerException e) { Slog.w(TAG, "Failed to merge profiles", e); } @@ -699,11 +645,11 @@ public class PackageDexOptimizer { * not needed or unsupported for the package. */ @Nullable - private String getPackageOatDirIfSupported(AndroidPackage pkg) { + private String getPackageOatDirIfSupported(PackageParser.Package pkg) { if (!pkg.canHaveOatDir()) { return null; } - File codePath = new File(pkg.getCodePath()); + File codePath = new File(pkg.codePath); if (!codePath.isDirectory()) { return null; } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index a34ca914f548..b72029046067 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -66,7 +66,6 @@ import android.content.pm.PackageParser.ApkLite; import android.content.pm.PackageParser.PackageLite; import android.content.pm.PackageParser.PackageParserException; import android.content.pm.dex.DexMetadataHelper; -import android.content.pm.parsing.ApkLiteParseUtils; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Binder; @@ -1574,7 +1573,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { for (File addedFile : addedFiles) { final ApkLite apk; try { - apk = ApkLiteParseUtils.parseApkLite( + apk = PackageParser.parseApkLite( addedFile, PackageParser.PARSE_COLLECT_CERTIFICATES); } catch (PackageParserException e) { throw PackageManagerException.from(e); @@ -1673,7 +1672,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { ApplicationInfo appInfo = pkgInfo.applicationInfo; try { existing = PackageParser.parsePackageLite(new File(appInfo.getCodePath()), 0); - existingBase = ApkLiteParseUtils.parseApkLite(new File(appInfo.getBaseCodePath()), + existingBase = PackageParser.parseApkLite(new File(appInfo.getBaseCodePath()), PackageParser.PARSE_COLLECT_CERTIFICATES); } catch (PackageParserException e) { throw PackageManagerException.from(e); diff --git a/services/core/java/com/android/server/pm/PackageKeySetData.java b/services/core/java/com/android/server/pm/PackageKeySetData.java index 10685b06716f..031b5ce3d5b9 100644 --- a/services/core/java/com/android/server/pm/PackageKeySetData.java +++ b/services/core/java/com/android/server/pm/PackageKeySetData.java @@ -20,8 +20,6 @@ import android.util.ArrayMap; import com.android.internal.util.ArrayUtils; -import java.util.Map; - public class PackageKeySetData { static final long KEYSET_UNASSIGNED = -1; @@ -92,13 +90,16 @@ public class PackageKeySetData { /* * Replace defined keysets with new ones. */ - protected void setAliases(Map<String, Long> newAliases) { + protected void setAliases(ArrayMap<String, Long> newAliases) { /* remove old aliases */ removeAllDefinedKeySets(); /* add new ones */ - mKeySetAliases.putAll(newAliases); + final int newAliasSize = newAliases.size(); + for (int i = 0; i < newAliasSize; i++) { + mKeySetAliases.put(newAliases.keyAt(i), newAliases.valueAt(i));; + } } protected void addDefinedKeySet(long ks, String alias) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index f706dc3d3219..86340d40e3c9 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -34,6 +34,7 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; +import static android.content.pm.PackageManager.DELETE_KEEP_DATA; import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT; @@ -157,6 +158,7 @@ import android.content.pm.InstrumentationInfo; import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.KeySet; import android.content.pm.ModuleInfo; +import android.content.pm.PackageBackwardCompatibility; import android.content.pm.PackageInfo; import android.content.pm.PackageInfoLite; import android.content.pm.PackageInstaller; @@ -167,6 +169,7 @@ import android.content.pm.PackageManager.ModuleInfoFlags; import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManagerInternal.PackageListObserver; import android.content.pm.PackageParser; +import android.content.pm.PackageParser.ActivityIntentInfo; import android.content.pm.PackageParser.PackageLite; import android.content.pm.PackageParser.PackageParserException; import android.content.pm.PackageParser.ParseFlags; @@ -191,19 +194,6 @@ import android.content.pm.VersionedPackage; import android.content.pm.dex.ArtManager; import android.content.pm.dex.DexMetadataHelper; import android.content.pm.dex.IArtManager; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ApkParseUtils; -import android.content.pm.parsing.ComponentParseUtils.ParsedActivity; -import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo; -import android.content.pm.parsing.ComponentParseUtils.ParsedComponent; -import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermission; -import android.content.pm.parsing.ComponentParseUtils.ParsedProvider; -import android.content.pm.parsing.ComponentParseUtils.ParsedService; -import android.content.pm.parsing.PackageImpl; -import android.content.pm.parsing.PackageInfoUtils; -import android.content.pm.parsing.ParsedPackage; -import android.content.pm.parsing.library.PackageBackwardCompatibility; import android.content.res.Resources; import android.content.rollback.IRollbackManager; import android.database.ContentObserver; @@ -381,7 +371,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BiConsumer; import java.util.function.Consumer; -import java.util.function.Predicate; /** * Keep track of all those APKs everywhere. @@ -470,19 +459,20 @@ public class PackageManagerService extends IPackageManager.Stub static final int SCAN_REQUIRE_KNOWN = 1 << 7; static final int SCAN_MOVE = 1 << 8; static final int SCAN_INITIAL = 1 << 9; - static final int SCAN_DONT_KILL_APP = 1 << 10; - static final int SCAN_IGNORE_FROZEN = 1 << 11; - static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1 << 12; - static final int SCAN_AS_INSTANT_APP = 1 << 13; - static final int SCAN_AS_FULL_APP = 1 << 14; - static final int SCAN_AS_VIRTUAL_PRELOAD = 1 << 15; - static final int SCAN_AS_SYSTEM = 1 << 16; - static final int SCAN_AS_PRIVILEGED = 1 << 17; - static final int SCAN_AS_OEM = 1 << 18; - static final int SCAN_AS_VENDOR = 1 << 19; - static final int SCAN_AS_PRODUCT = 1 << 20; - static final int SCAN_AS_SYSTEM_EXT = 1 << 21; - static final int SCAN_AS_ODM = 1 << 22; + static final int SCAN_CHECK_ONLY = 1 << 10; + static final int SCAN_DONT_KILL_APP = 1 << 11; + static final int SCAN_IGNORE_FROZEN = 1 << 12; + static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1 << 13; + static final int SCAN_AS_INSTANT_APP = 1 << 14; + static final int SCAN_AS_FULL_APP = 1 << 15; + static final int SCAN_AS_VIRTUAL_PRELOAD = 1 << 16; + static final int SCAN_AS_SYSTEM = 1 << 17; + static final int SCAN_AS_PRIVILEGED = 1 << 18; + static final int SCAN_AS_OEM = 1 << 19; + static final int SCAN_AS_VENDOR = 1 << 20; + static final int SCAN_AS_PRODUCT = 1 << 21; + static final int SCAN_AS_SYSTEM_EXT = 1 << 22; + static final int SCAN_AS_ODM = 1 << 23; @IntDef(flag = true, prefix = { "SCAN_" }, value = { SCAN_NO_DEX, @@ -493,6 +483,7 @@ public class PackageManagerService extends IPackageManager.Stub SCAN_REQUIRE_KNOWN, SCAN_MOVE, SCAN_INITIAL, + SCAN_CHECK_ONLY, SCAN_DONT_KILL_APP, SCAN_IGNORE_FROZEN, SCAN_FIRST_BOOT_OR_UPGRADE, @@ -611,19 +602,11 @@ public class PackageManagerService extends IPackageManager.Stub public static final int REASON_LAST = REASON_SHARED; /** - * The initial enabled state of the cache before other checks are done. + * Whether the package parser cache is enabled. */ private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true; /** - * Whether to skip all other checks and force the cache to be enabled. - * - * Setting this to true will cause the cache to be named "debug" to avoid eviction from - * build fingerprint changes. - */ - private static final boolean FORCE_PACKAGE_PARSED_CACHE_ENABLED = false; - - /** * Permissions required in order to receive instant application lifecycle broadcasts. */ private static final String[] INSTANT_APP_BROADCAST_PERMISSION = @@ -680,7 +663,7 @@ public class PackageManagerService extends IPackageManager.Stub // Keys are String (package name), values are Package. @GuardedBy("mLock") - final ArrayMap<String, AndroidPackage> mPackages = new ArrayMap<>(); + final ArrayMap<String, PackageParser.Package> mPackages = new ArrayMap<>(); // Keys are isolated uids and values are the uid of the application // that created the isolated proccess. @@ -993,17 +976,17 @@ public class PackageManagerService extends IPackageManager.Stub return PackageManagerService.this.hasSystemFeature(feature, 0); } - final List<AndroidPackage> getStaticOverlayPackages( - Collection<AndroidPackage> allPackages, String targetPackageName) { + final List<PackageParser.Package> getStaticOverlayPackages( + Collection<PackageParser.Package> allPackages, String targetPackageName) { if ("android".equals(targetPackageName)) { // Static RROs targeting to "android", ie framework-res.apk, are already applied by // native AssetManager. return null; } - List<AndroidPackage> overlayPackages = null; - for (AndroidPackage p : allPackages) { - if (targetPackageName.equals(p.getOverlayTarget()) && p.isOverlayIsStatic()) { + List<PackageParser.Package> overlayPackages = null; + for (PackageParser.Package p : allPackages) { + if (targetPackageName.equals(p.mOverlayTarget) && p.mOverlayIsStatic) { if (overlayPackages == null) { overlayPackages = new ArrayList<>(); } @@ -1011,25 +994,25 @@ public class PackageManagerService extends IPackageManager.Stub } } if (overlayPackages != null) { - Comparator<AndroidPackage> cmp = - Comparator.comparingInt(p -> p.getOverlayPriority()); + Comparator<PackageParser.Package> cmp = + Comparator.comparingInt(p -> p.mOverlayPriority); overlayPackages.sort(cmp); } return overlayPackages; } - final String[] getStaticOverlayPaths(List<AndroidPackage> overlayPackages, + final String[] getStaticOverlayPaths(List<PackageParser.Package> overlayPackages, String targetPath) { if (overlayPackages == null || overlayPackages.isEmpty()) { return null; } List<String> overlayPathList = null; - for (AndroidPackage overlayPackage : overlayPackages) { + for (PackageParser.Package overlayPackage : overlayPackages) { if (targetPath == null) { if (overlayPathList == null) { overlayPathList = new ArrayList<>(); } - overlayPathList.add(overlayPackage.getBaseCodePath()); + overlayPathList.add(overlayPackage.baseCodePath); continue; } @@ -1039,23 +1022,23 @@ public class PackageManagerService extends IPackageManager.Stub // // OverlayManagerService will update each of them with a correct gid from its // target package app id. - mInstaller.idmap(targetPath, overlayPackage.getBaseCodePath(), + mInstaller.idmap(targetPath, overlayPackage.baseCodePath, UserHandle.getSharedAppGid( UserHandle.getUserGid(UserHandle.USER_SYSTEM))); if (overlayPathList == null) { overlayPathList = new ArrayList<>(); } - overlayPathList.add(overlayPackage.getBaseCodePath()); + overlayPathList.add(overlayPackage.baseCodePath); } catch (InstallerException e) { Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " + - overlayPackage.getBaseCodePath()); + overlayPackage.baseCodePath); } } return overlayPathList == null ? null : overlayPathList.toArray(new String[0]); } String[] getStaticOverlayPaths(String targetPackageName, String targetPath) { - List<AndroidPackage> overlayPackages; + List<PackageParser.Package> overlayPackages; synchronized (mInstallLock) { synchronized (mLock) { overlayPackages = getStaticOverlayPackages( @@ -1078,12 +1061,12 @@ public class PackageManagerService extends IPackageManager.Stub } class ParallelPackageParserCallback extends PackageParserCallback { - List<AndroidPackage> mOverlayPackages = null; + List<PackageParser.Package> mOverlayPackages = null; void findStaticOverlayPackages() { synchronized (mLock) { - for (AndroidPackage p : mPackages.values()) { - if (p.isOverlayIsStatic()) { + for (PackageParser.Package p : mPackages.values()) { + if (p.mOverlayIsStatic) { if (mOverlayPackages == null) { mOverlayPackages = new ArrayList<>(); } @@ -1117,7 +1100,7 @@ public class PackageManagerService extends IPackageManager.Stub new ArrayMap<>(); // Mapping from instrumentation class names to info about them. - final ArrayMap<ComponentName, ParsedInstrumentation> mInstrumentation = + final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = new ArrayMap<>(); // Packages whose data we have transfered into another package, thus @@ -1166,13 +1149,13 @@ public class PackageManagerService extends IPackageManager.Stub final ActivityInfo mResolveActivity = new ActivityInfo(); final ResolveInfo mResolveInfo = new ResolveInfo(); ComponentName mResolveComponentName; - AndroidPackage mPlatformPackage; + PackageParser.Package mPlatformPackage; ComponentName mCustomResolverComponentName; boolean mResolverReplaced = false; private final @Nullable ComponentName mIntentFilterVerifierComponent; - private final @Nullable IntentFilterVerifier<ParsedActivityIntentInfo> mIntentFilterVerifier; + private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier; private int mIntentFilterVerificationToken = 0; @@ -1205,19 +1188,14 @@ public class PackageManagerService extends IPackageManager.Stub private Future<?> mPrepareAppDataFuture; private static class IFVerificationParams { - String packageName; - boolean hasDomainUrls; - List<ParsedActivity> activities; + PackageParser.Package pkg; boolean replacing; int userId; int verifierUid; - public IFVerificationParams(String packageName, boolean hasDomainUrls, - List<ParsedActivity> activities, boolean _replacing, + public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, int _userId, int _verifierUid) { - this.packageName = packageName; - this.hasDomainUrls = hasDomainUrls; - this.activities = activities; + pkg = _pkg; replacing = _replacing; userId = _userId; verifierUid = _verifierUid; @@ -1231,7 +1209,7 @@ public class PackageManagerService extends IPackageManager.Stub void receiveVerificationResponse(int verificationId); } - private class IntentVerifierProxy implements IntentFilterVerifier<ParsedActivityIntentInfo> { + private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { private Context mContext; private ComponentName mIntentFilterVerifierComponent; private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<>(); @@ -1256,11 +1234,11 @@ public class PackageManagerService extends IPackageManager.Stub String packageName = ivs.getPackageName(); - ArrayList<ParsedActivityIntentInfo> filters = ivs.getFilters(); + ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); final int filterCount = filters.size(); ArraySet<String> domainsSet = new ArraySet<>(); for (int m=0; m<filterCount; m++) { - ParsedActivityIntentInfo filter = filters.get(m); + PackageParser.ActivityIntentInfo filter = filters.get(m); domainsSet.addAll(filter.getHostsList()); } synchronized (mLock) { @@ -1312,14 +1290,14 @@ public class PackageManagerService extends IPackageManager.Stub final boolean verified = ivs.isVerified(); - ArrayList<ParsedActivityIntentInfo> filters = ivs.getFilters(); + ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); final int count = filters.size(); if (DEBUG_DOMAIN_VERIFICATION) { Slog.i(TAG, "Received verification response " + verificationId + " for " + count + " filters, verified=" + verified); } for (int n=0; n<count; n++) { - ParsedActivityIntentInfo filter = filters.get(n); + PackageParser.ActivityIntentInfo filter = filters.get(n); filter.setVerified(verified); if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() @@ -1432,7 +1410,7 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, - ParsedActivityIntentInfo filter, String packageName) { + ActivityIntentInfo filter, String packageName) { if (!hasValidDomains(filter)) { return false; } @@ -1461,7 +1439,7 @@ public class PackageManagerService extends IPackageManager.Stub } } - private static boolean hasValidDomains(ParsedActivityIntentInfo filter) { + private static boolean hasValidDomains(ActivityIntentInfo filter) { return filter.hasCategory(Intent.CATEGORY_BROWSABLE) && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); @@ -1726,7 +1704,7 @@ public class PackageManagerService extends IPackageManager.Stub final List<String> whitelistedRestrictedPermissions = ((args.installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0 && parentRes.pkg != null) - ? parentRes.pkg.getRequestedPermissions() + ? parentRes.pkg.requestedPermissions : args.whitelistedRestrictedPermissions; // Handle the parent package @@ -1872,8 +1850,8 @@ public class PackageManagerService extends IPackageManager.Stub } case START_INTENT_FILTER_VERIFICATIONS: { IFVerificationParams params = (IFVerificationParams) msg.obj; - verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, params.replacing, - params.packageName, params.hasDomainUrls, params.activities); + verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, + params.replacing, params.pkg); break; } case INTENT_FILTER_VERIFIED: { @@ -2023,11 +2001,20 @@ public class PackageManagerService extends IPackageManager.Stub ? res.removedInfo.installerPackageName : null; + // If this is the first time we have child packages for a disabled privileged + // app that had no children, we grant requested runtime permissions to the new + // children if the parent on the system image had them already granted. + if (res.pkg.parentPackage != null) { + final int callingUid = Binder.getCallingUid(); + mPermissionManager.grantRuntimePermissionsGrantedToDisabledPackage( + res.pkg, callingUid); + } + synchronized (mLock) { mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers); } - final String packageName = res.pkg.getAppInfoPackageName(); + final String packageName = res.pkg.applicationInfo.packageName; // Determine the set of users who are adding this package for // the first time vs. those who are seeing an update. @@ -2036,7 +2023,7 @@ public class PackageManagerService extends IPackageManager.Stub int[] updateUserIds = EMPTY_INT_ARRAY; int[] instantUserIds = EMPTY_INT_ARRAY; final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0; - final PackageSetting ps = getPackageSetting(res.pkg.getPackageName()); + final PackageSetting ps = (PackageSetting) res.pkg.mExtras; for (int newUser : res.newUsers) { final boolean isInstantApp = ps.getInstantApp(newUser); if (allNewUsers) { @@ -2070,14 +2057,13 @@ public class PackageManagerService extends IPackageManager.Stub } // Send installed broadcasts if the package is not a static shared lib. - if (res.pkg.getStaticSharedLibName() == null) { - mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash( - res.pkg.getBaseCodePath()); + if (res.pkg.staticSharedLibName == null) { + mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath); // Send added for users that see the package for the first time // sendPackageAddedForNewUsers also deals with system apps int appId = UserHandle.getAppId(res.uid); - boolean isSystem = res.pkg.isSystemApp(); + boolean isSystem = res.pkg.applicationInfo.isSystemApp(); sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload, virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds); @@ -2155,30 +2141,30 @@ public class PackageManagerService extends IPackageManager.Stub final StorageManager storage = mInjector.getStorageManager(); VolumeInfo volume = storage.findVolumeByUuid( - res.pkg.getStorageUuid().toString()); + res.pkg.applicationInfo.storageUuid.toString()); int packageExternalStorageType = getPackageExternalStorageType(volume, isExternal(res.pkg)); // If the package was installed externally, log it. if (packageExternalStorageType != StorageEnums.UNKNOWN) { StatsLog.write(StatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED, - packageExternalStorageType, res.pkg.getPackageName()); + packageExternalStorageType, res.pkg.packageName); } } if (DEBUG_INSTALL) { Slog.i(TAG, "upgrading pkg " + res.pkg + " is external"); } - final int[] uidArray = new int[]{res.pkg.getUid()}; + final int[] uidArray = new int[]{res.pkg.applicationInfo.uid}; ArrayList<String> pkgList = new ArrayList<>(1); pkgList.add(packageName); sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null); } } else if (!ArrayUtils.isEmpty(res.libraryConsumers)) { // if static shared lib for (int i = 0; i < res.libraryConsumers.size(); i++) { - AndroidPackage pkg = res.libraryConsumers.get(i); + PackageParser.Package pkg = res.libraryConsumers.get(i); // send broadcast that all consumers of the static shared library have changed - sendPackageChangedBroadcast(pkg.getPackageName(), false /*killFlag*/, - new ArrayList<>(Collections.singletonList(pkg.getPackageName())), - pkg.getUid()); + sendPackageChangedBroadcast(pkg.packageName, false /*killFlag*/, + new ArrayList<>(Collections.singletonList(pkg.packageName)), + pkg.applicationInfo.uid); } } @@ -2308,7 +2294,7 @@ public class PackageManagerService extends IPackageManager.Stub private void scheduleDeferredNoKillInstallObserver(PackageInstalledInfo info, IPackageInstallObserver2 observer) { - String packageName = info.pkg.getPackageName(); + String packageName = info.pkg.packageName; mNoKillInstallObservers.put(packageName, Pair.create(info, observer)); Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_INSTALL_OBSERVER, packageName); mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS); @@ -2846,11 +2832,11 @@ public class PackageManagerService extends IPackageManager.Stub final List<String> stubSystemApps = new ArrayList<>(); if (!mOnlyCore) { // do this first before mucking with mPackages for the "expecting better" case - final Iterator<AndroidPackage> pkgIterator = mPackages.values().iterator(); + final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator(); while (pkgIterator.hasNext()) { - final AndroidPackage pkg = pkgIterator.next(); - if (pkg.isStub()) { - stubSystemApps.add(pkg.getPackageName()); + final PackageParser.Package pkg = pkgIterator.next(); + if (pkg.isStub) { + stubSystemApps.add(pkg.packageName); } } @@ -2869,7 +2855,7 @@ public class PackageManagerService extends IPackageManager.Stub /* * If the package is scanned, it's not erased. */ - final AndroidPackage scannedPkg = mPackages.get(ps.name); + final PackageParser.Package scannedPkg = mPackages.get(ps.name); if (scannedPkg != null) { /* * If the system app is both scanned and in the @@ -2946,7 +2932,7 @@ public class PackageManagerService extends IPackageManager.Stub // app completely. Otherwise, revoke their system privileges. for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) { final String packageName = possiblyDeletedUpdatedSystemApps.get(i); - final AndroidPackage pkg = mPackages.get(packageName); + final PackageParser.Package pkg = mPackages.get(packageName); final String msg; // remove from the disabled system list; do this first so any future @@ -2972,7 +2958,7 @@ public class PackageManagerService extends IPackageManager.Stub // special privileges removePackageLI(pkg, true); try { - final File codePath = new File(pkg.getAppInfoCodePath()); + final File codePath = new File(pkg.applicationInfo.getCodePath()); scanPackageTracedLI(codePath, 0, scanFlags, 0, null); } catch (PackageManagerException e) { Slog.e(TAG, "Failed to parse updated, ex-system package: " @@ -3167,7 +3153,7 @@ public class PackageManagerService extends IPackageManager.Stub } int count = 0; for (String pkgName : deferPackages) { - AndroidPackage pkg = null; + PackageParser.Package pkg = null; synchronized (mLock) { PackageSetting ps = mSettings.getPackageLPr(pkgName); if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) { @@ -3267,12 +3253,12 @@ public class PackageManagerService extends IPackageManager.Stub // Initialize InstantAppRegistry's Instant App list for all users. final int[] userIds = UserManagerService.getInstance().getUserIds(); - for (AndroidPackage pkg : mPackages.values()) { + for (PackageParser.Package pkg : mPackages.values()) { if (pkg.isSystem()) { continue; } for (int userId : userIds) { - final PackageSetting ps = getPackageSetting(pkg.getPackageName()); + final PackageSetting ps = (PackageSetting) pkg.mExtras; if (ps == null || !ps.getInstantApp(userId) || !ps.getInstalled(userId)) { continue; } @@ -3359,7 +3345,7 @@ public class PackageManagerService extends IPackageManager.Stub continue; } // skip if the package isn't installed (?!); this should never happen - final AndroidPackage pkg = mPackages.get(packageName); + final PackageParser.Package pkg = mPackages.get(packageName); if (pkg == null) { systemStubPackageNames.remove(i); continue; @@ -3403,46 +3389,43 @@ public class PackageManagerService extends IPackageManager.Stub * APK will be installed and the package will be disabled. To recover from this situation, * the user will need to go into system settings and re-enable the package. */ - private boolean enableCompressedPackage(AndroidPackage stubPkg) { + private boolean enableCompressedPackage(PackageParser.Package stubPkg) { final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | PackageParser.PARSE_ENFORCE_CODE; synchronized (mInstallLock) { - final AndroidPackage pkg; + final PackageParser.Package pkg; try (PackageFreezer freezer = - freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) { + freezePackage(stubPkg.packageName, "setEnabledSetting")) { pkg = installStubPackageLI(stubPkg, parseFlags, 0 /*scanFlags*/); synchronized (mLock) { prepareAppDataAfterInstallLIF(pkg); try { - updateSharedLibrariesLocked(pkg, null, - Collections.unmodifiableMap(mPackages)); + updateSharedLibrariesLocked(pkg, null, mPackages); } catch (PackageManagerException e) { Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e); } - mPermissionManager.updatePermissions(pkg.getPackageName(), pkg); + mPermissionManager.updatePermissions(pkg.packageName, pkg); mSettings.writeLPr(); } } catch (PackageManagerException e) { // Whoops! Something went very wrong; roll back to the stub and disable the package try (PackageFreezer freezer = - freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) { + freezePackage(stubPkg.packageName, "setEnabledSetting")) { synchronized (mLock) { // NOTE: Ensure the system package is enabled; even for a compressed stub. // If we don't, installing the system package fails during scan enableSystemPackageLPw(stubPkg); } - installPackageFromSystemLIF(stubPkg.getCodePath(), + installPackageFromSystemLIF(stubPkg.codePath, null /*allUserHandles*/, null /*origUserHandles*/, null /*origPermissionsState*/, true /*writeSettings*/); } catch (PackageManagerException pme) { // Serious WTF; we have to be able to install the stub - Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.getPackageName(), - pme); + Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.packageName, pme); } finally { // Disable the package; the stub by itself is not runnable synchronized (mLock) { - final PackageSetting stubPs = mSettings.mPackages.get( - stubPkg.getPackageName()); + final PackageSetting stubPs = mSettings.mPackages.get(stubPkg.packageName); if (stubPs != null) { stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, UserHandle.USER_SYSTEM, "android"); @@ -3454,33 +3437,31 @@ public class PackageManagerService extends IPackageManager.Stub } clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); - mDexManager.notifyPackageUpdated(pkg.getPackageName(), - pkg.getBaseCodePath(), pkg.getSplitCodePaths()); + mDexManager.notifyPackageUpdated(pkg.packageName, + pkg.baseCodePath, pkg.splitCodePaths); } return true; } - private AndroidPackage installStubPackageLI(AndroidPackage stubPkg, + private PackageParser.Package installStubPackageLI(PackageParser.Package stubPkg, @ParseFlags int parseFlags, @ScanFlags int scanFlags) throws PackageManagerException { if (DEBUG_COMPRESSION) { - Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.getPackageName()); + Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.packageName); } // uncompress the binary to its eventual destination on /data - final File scanFile = decompressPackage(stubPkg.getPackageName(), stubPkg.getCodePath()); + final File scanFile = decompressPackage(stubPkg.packageName, stubPkg.codePath); if (scanFile == null) { - throw new PackageManagerException( - "Unable to decompress stub at " + stubPkg.getCodePath()); + throw new PackageManagerException("Unable to decompress stub at " + stubPkg.codePath); } synchronized (mLock) { - mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/); + mSettings.disableSystemPackageLPw(stubPkg.packageName, true /*replaced*/); } removePackageLI(stubPkg, true /*chatty*/); try { return scanPackageTracedLI(scanFile, parseFlags, scanFlags, 0, null); } catch (PackageManagerException e) { - Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(), - e); + Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.packageName, e); // Remove the failed install removeCodePathLI(scanFile); throw e; @@ -3563,20 +3544,18 @@ public class PackageManagerService extends IPackageManager.Stub } private static @Nullable File preparePackageParserCache() { - if (!FORCE_PACKAGE_PARSED_CACHE_ENABLED) { - if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) { - return null; - } + if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) { + return null; + } - // Disable package parsing on eng builds to allow for faster incremental development. - if (Build.IS_ENG) { - return null; - } + // Disable package parsing on eng builds to allow for faster incremental development. + if (Build.IS_ENG) { + return null; + } - if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) { - Slog.i(TAG, "Disabling package parser cache due to system property."); - return null; - } + if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) { + Slog.i(TAG, "Disabling package parser cache due to system property."); + return null; } // The base directory for the package parser cache lives under /data/system/. @@ -3588,12 +3567,10 @@ public class PackageManagerService extends IPackageManager.Stub // There are several items that need to be combined together to safely // identify cached items. In particular, changing the value of certain // feature flags should cause us to invalidate any caches. - final String cacheName = FORCE_PACKAGE_PARSED_CACHE_ENABLED ? "debug" - : SystemProperties.digestOf( - "ro.build.fingerprint", - StorageManager.PROP_ISOLATED_STORAGE, - StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT - ); + final String cacheName = SystemProperties.digestOf( + "ro.build.fingerprint", + StorageManager.PROP_ISOLATED_STORAGE, + StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT); // Reconcile cache directories, keeping only what we'd actually use. for (File cacheDir : FileUtils.listFilesOrEmpty(cacheBaseDir)) { @@ -3917,7 +3894,7 @@ public class PackageManagerService extends IPackageManager.Stub ArraySet<String> packages = systemConfig.getLinkedApps(); for (String packageName : packages) { - AndroidPackage pkg = mPackages.get(packageName); + PackageParser.Package pkg = mPackages.get(packageName); if (pkg != null) { if (!pkg.isSystem()) { Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); @@ -3925,15 +3902,13 @@ public class PackageManagerService extends IPackageManager.Stub } ArraySet<String> domains = null; - if (pkg.getActivities() != null) { - for (ParsedActivity a : pkg.getActivities()) { - for (ParsedActivityIntentInfo filter : a.intents) { - if (hasValidDomains(filter)) { - if (domains == null) { - domains = new ArraySet<>(); - } - domains.addAll(filter.getHostsList()); + for (PackageParser.Activity a : pkg.activities) { + for (ActivityIntentInfo filter : a.intents) { + if (hasValidDomains(filter)) { + if (domains == null) { + domains = new ArraySet<>(); } + domains.addAll(filter.getHostsList()); } } } @@ -4049,7 +4024,7 @@ public class PackageManagerService extends IPackageManager.Stub } final PackageUserState state = ps.readUserState(userId); - AndroidPackage p = ps.pkg; + PackageParser.Package p = ps.pkg; if (p != null) { final PermissionsState permissionsState = ps.getPermissionsState(); @@ -4057,10 +4032,10 @@ public class PackageManagerService extends IPackageManager.Stub final int[] gids = (flags & PackageManager.GET_GIDS) == 0 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); // Compute granted permissions only if package has requested permissions - final Set<String> permissions = ArrayUtils.isEmpty(p.getRequestedPermissions()) + final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions) ? Collections.emptySet() : permissionsState.getPermissions(userId); - PackageInfo packageInfo = PackageInfoUtils.generate(p, gids, flags, + PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags, ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); if (packageInfo == null) { @@ -4123,7 +4098,7 @@ public class PackageManagerService extends IPackageManager.Stub throw new SecurityException("Package " + packageName + " is currently frozen!"); } - if (!userKeyUnlocked && !ps.pkg.isEncryptionAware()) { + if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) { throw new SecurityException("Package " + packageName + " is not encryption aware!"); } } @@ -4136,9 +4111,9 @@ public class PackageManagerService extends IPackageManager.Stub mPermissionManager.enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/, false /*checkShell*/, "is package available"); synchronized (mLock) { - AndroidPackage p = mPackages.get(packageName); + PackageParser.Package p = mPackages.get(packageName); if (p != null) { - final PackageSetting ps = getPackageSetting(p.getPackageName()); + final PackageSetting ps = (PackageSetting) p.mExtras; if (shouldFilterApplicationLocked(ps, callingUid, userId)) { return false; } @@ -4203,22 +4178,21 @@ public class PackageManagerService extends IPackageManager.Stub } } - AndroidPackage p = mPackages.get(packageName); + PackageParser.Package p = mPackages.get(packageName); if (matchFactoryOnly && p != null && !isSystemApp(p)) { return null; } if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getPackageInfo " + packageName + ": " + p); if (p != null) { - final PackageSetting ps = getPackageSetting(p.getPackageName()); + final PackageSetting ps = (PackageSetting) p.mExtras; if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) { return null; } if (ps != null && shouldFilterApplicationLocked(ps, filterCallingUid, userId)) { return null; } - - return generatePackageInfo(ps, flags, userId); + return generatePackageInfo((PackageSetting)p.mExtras, flags, userId); } if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) { final PackageSetting ps = mSettings.mPackages.get(packageName); @@ -4254,34 +4228,34 @@ public class PackageManagerService extends IPackageManager.Stub private boolean isComponentVisibleToInstantApp( @Nullable ComponentName component, @ComponentType int type) { if (type == TYPE_ACTIVITY) { - final ParsedActivity activity = mComponentResolver.getActivity(component); + final PackageParser.Activity activity = mComponentResolver.getActivity(component); if (activity == null) { return false; } final boolean visibleToInstantApp = - (activity.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0; + (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0; final boolean explicitlyVisibleToInstantApp = - (activity.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0; + (activity.info.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0; return visibleToInstantApp && explicitlyVisibleToInstantApp; } else if (type == TYPE_RECEIVER) { - final ParsedActivity activity = mComponentResolver.getReceiver(component); + final PackageParser.Activity activity = mComponentResolver.getReceiver(component); if (activity == null) { return false; } final boolean visibleToInstantApp = - (activity.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0; + (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0; final boolean explicitlyVisibleToInstantApp = - (activity.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0; + (activity.info.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0; return visibleToInstantApp && !explicitlyVisibleToInstantApp; } else if (type == TYPE_SERVICE) { - final ParsedService service = mComponentResolver.getService(component); + final PackageParser.Service service = mComponentResolver.getService(component); return service != null - ? (service.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0 + ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0 : false; } else if (type == TYPE_PROVIDER) { - final ParsedProvider provider = mComponentResolver.getProvider(component); + final PackageParser.Provider provider = mComponentResolver.getProvider(component); return provider != null - ? (provider.getFlags() & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0 + ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0 : false; } else if (type == TYPE_UNKNOWN) { return isComponentVisibleToInstantApp(component); @@ -4325,16 +4299,16 @@ public class PackageManagerService extends IPackageManager.Stub // request for a specific component; if it hasn't been explicitly exposed through // property or instrumentation target, filter if (component != null) { - final ParsedInstrumentation instrumentation = + final PackageParser.Instrumentation instrumentation = mInstrumentation.get(component); if (instrumentation != null - && isCallerSameApp(instrumentation.getTargetPackage(), callingUid)) { + && isCallerSameApp(instrumentation.info.targetPackage, callingUid)) { return false; } return !isComponentVisibleToInstantApp(component, componentType); } // request for application; if no components have been explicitly exposed, filter - return !ps.pkg.isVisibleToInstantApps(); + return !ps.pkg.visibleToInstantApps; } if (ps.getInstantApp(userId)) { // caller can see all components of all instant applications, don't filter @@ -4383,12 +4357,12 @@ public class PackageManagerService extends IPackageManager.Stub } // No package means no static lib as it is always on internal storage - if (ps == null || ps.pkg == null || !ps.pkg.isStaticSharedLibrary()) { + if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) { return false; } - final SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr( - ps.pkg.getStaticSharedLibName(), ps.pkg.getStaticSharedLibVersion()); + final SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(ps.pkg.staticSharedLibName, + ps.pkg.staticSharedLibVersion); if (libraryInfo == null) { return false; } @@ -4410,8 +4384,7 @@ public class PackageManagerService extends IPackageManager.Stub if (index < 0) { continue; } - if (uidPs.pkg.getUsesStaticLibrariesVersions()[index] - == libraryInfo.getLongVersion()) { + if (uidPs.pkg.usesStaticLibrariesVersions[index] == libraryInfo.getLongVersion()) { return false; } } @@ -4485,13 +4458,13 @@ public class PackageManagerService extends IPackageManager.Stub // reader synchronized (mLock) { - final AndroidPackage p = mPackages.get(packageName); + final PackageParser.Package p = mPackages.get(packageName); if (p != null && p.isMatch(flags)) { - PackageSetting ps = getPackageSetting(p.getPackageName()); + PackageSetting ps = (PackageSetting) p.mExtras; if (shouldFilterApplicationLocked(ps, callingUid, userId)) { return -1; } - return UserHandle.getUid(userId, p.getUid()); + return UserHandle.getUid(userId, p.applicationInfo.uid); } if ((flags & MATCH_KNOWN_PACKAGES) != 0) { final PackageSetting ps = mSettings.mPackages.get(packageName); @@ -4515,9 +4488,9 @@ public class PackageManagerService extends IPackageManager.Stub // reader synchronized (mLock) { - final AndroidPackage p = mPackages.get(packageName); + final PackageParser.Package p = mPackages.get(packageName); if (p != null && p.isMatch(flags)) { - PackageSetting ps = getPackageSetting(p.getPackageName()); + PackageSetting ps = (PackageSetting) p.mExtras; if (shouldFilterApplicationLocked(ps, callingUid, userId)) { return null; } @@ -4567,7 +4540,7 @@ public class PackageManagerService extends IPackageManager.Stub } return null; } - ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(ps.pkg, flags, + ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags, ps.readUserState(userId), userId); if (ai != null) { ai.packageName = resolveExternalPackageNameLPr(ps.pkg); @@ -4605,7 +4578,7 @@ public class PackageManagerService extends IPackageManager.Stub packageName = resolveInternalPackageNameLPr(packageName, PackageManager.VERSION_CODE_HIGHEST); - AndroidPackage p = mPackages.get(packageName); + PackageParser.Package p = mPackages.get(packageName); if (DEBUG_PACKAGE_INFO) Log.v( TAG, "getApplicationInfo " + packageName + ": " + p); @@ -4619,7 +4592,7 @@ public class PackageManagerService extends IPackageManager.Stub return null; } // Note: isEnabledLP() does not apply here - always return info - ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo( + ApplicationInfo ai = PackageParser.generateApplicationInfo( p, flags, ps.readUserState(userId), userId); if (ai != null) { ai.packageName = resolveExternalPackageNameLPr(p); @@ -4995,19 +4968,17 @@ public class PackageManagerService extends IPackageManager.Stub } synchronized (mLock) { - ParsedActivity a = mComponentResolver.getActivity(component); + PackageParser.Activity a = mComponentResolver.getActivity(component); if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); - - AndroidPackage pkg = a == null ? null : mPackages.get(a.getPackageName()); - if (pkg != null && mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) { + if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); if (ps == null) return null; if (shouldFilterApplicationLocked( ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) { return null; } - return PackageInfoUtils.generateActivityInfo(pkg, + return PackageParser.generateActivityInfo( a, flags, ps.readUserState(userId), userId); } if (mResolveComponentName.equals(component)) { @@ -5044,7 +5015,7 @@ public class PackageManagerService extends IPackageManager.Stub } final int callingUid = Binder.getCallingUid(); final int callingUserId = UserHandle.getUserId(callingUid); - ParsedActivity a = mComponentResolver.getActivity(component); + PackageParser.Activity a = mComponentResolver.getActivity(component); if (a == null) { return false; } @@ -5074,27 +5045,17 @@ public class PackageManagerService extends IPackageManager.Stub mPermissionManager.enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */, false /* checkShell */, "get receiver info"); synchronized (mLock) { - ParsedActivity a = mComponentResolver.getReceiver(component); + PackageParser.Activity a = mComponentResolver.getReceiver(component); if (DEBUG_PACKAGE_INFO) Log.v( TAG, "getReceiverInfo " + component + ": " + a); - - if (a == null) { - return null; - } - - AndroidPackage pkg = mPackages.get(a.getPackageName()); - if (pkg == null) { - return null; - } - - if (mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) { + if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); if (ps == null) return null; if (shouldFilterApplicationLocked( ps, callingUid, component, TYPE_RECEIVER, userId)) { return null; } - return PackageInfoUtils.generateActivityInfo(pkg, + return PackageParser.generateActivityInfo( a, flags, ps.readUserState(userId), userId); } } @@ -5273,13 +5234,13 @@ public class PackageManagerService extends IPackageManager.Stub } // If the dependent is a static shared lib, use the public package name String dependentPackageName = ps.name; - if (ps.pkg != null && ps.pkg.isStaticSharedLibrary()) { - dependentPackageName = ps.pkg.getManifestPackageName(); + if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) { + dependentPackageName = ps.pkg.manifestPackageName; } versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode)); } else if (ps.pkg != null) { - if (ArrayUtils.contains(ps.pkg.getUsesLibraries(), libName) - || ArrayUtils.contains(ps.pkg.getUsesOptionalLibraries(), libName)) { + if (ArrayUtils.contains(ps.pkg.usesLibraries, libName) + || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) { if (versionedPackages == null) { versionedPackages = new ArrayList<>(); } @@ -5299,22 +5260,17 @@ public class PackageManagerService extends IPackageManager.Stub mPermissionManager.enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */, false /* checkShell */, "get service info"); synchronized (mLock) { - ParsedService s = mComponentResolver.getService(component); + PackageParser.Service s = mComponentResolver.getService(component); if (DEBUG_PACKAGE_INFO) Log.v( - TAG, "getServiceInfo " + component + ": " + s); - if (s == null) { - return null; - } - - AndroidPackage pkg = mPackages.get(s.getPackageName()); - if (mSettings.isEnabledAndMatchLPr(pkg, s, flags, userId)) { + TAG, "getServiceInfo " + component + ": " + s); + if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); if (ps == null) return null; if (shouldFilterApplicationLocked( ps, callingUid, component, TYPE_SERVICE, userId)) { return null; } - return PackageInfoUtils.generateServiceInfo(pkg, + return PackageParser.generateServiceInfo( s, flags, ps.readUserState(userId), userId); } } @@ -5329,27 +5285,18 @@ public class PackageManagerService extends IPackageManager.Stub mPermissionManager.enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */, false /* checkShell */, "get provider info"); synchronized (mLock) { - ParsedProvider p = mComponentResolver.getProvider(component); + PackageParser.Provider p = mComponentResolver.getProvider(component); if (DEBUG_PACKAGE_INFO) Log.v( - TAG, "getProviderInfo " + component + ": " + p); - if (p == null) { - return null; - } - - AndroidPackage pkg = mPackages.get(p.getPackageName()); - if (pkg == null) { - return null; - } - - if (mSettings.isEnabledAndMatchLPr(pkg, p, flags, userId)) { + TAG, "getProviderInfo " + component + ": " + p); + if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); if (ps == null) return null; if (shouldFilterApplicationLocked( ps, callingUid, component, TYPE_PROVIDER, userId)) { return null; } - PackageUserState state = ps.readUserState(userId); - return PackageInfoUtils.generateProviderInfo(pkg, p, flags, state, userId); + return PackageParser.generateProviderInfo( + p, flags, ps.readUserState(userId), userId); } } return null; @@ -5607,21 +5554,21 @@ public class PackageManagerService extends IPackageManager.Stub @Override public int checkSignatures(String pkg1, String pkg2) { synchronized (mLock) { - final AndroidPackage p1 = mPackages.get(pkg1); - final AndroidPackage p2 = mPackages.get(pkg2); - final PackageSetting ps1 = p1 == null ? null : getPackageSetting(p1.getPackageName()); - final PackageSetting ps2 = p2 == null ? null : getPackageSetting(p2.getPackageName()); - if (p1 == null || ps1 == null || p2 == null || ps2 == null) { + final PackageParser.Package p1 = mPackages.get(pkg1); + final PackageParser.Package p2 = mPackages.get(pkg2); + if (p1 == null || p1.mExtras == null + || p2 == null || p2.mExtras == null) { return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; } final int callingUid = Binder.getCallingUid(); final int callingUserId = UserHandle.getUserId(callingUid); + final PackageSetting ps1 = (PackageSetting) p1.mExtras; + final PackageSetting ps2 = (PackageSetting) p2.mExtras; if (shouldFilterApplicationLocked(ps1, callingUid, callingUserId) || shouldFilterApplicationLocked(ps2, callingUid, callingUserId)) { return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; } - return compareSignatures(p1.getSigningDetails().signatures, - p2.getSigningDetails().signatures); + return compareSignatures(p1.mSigningDetails.signatures, p2.mSigningDetails.signatures); } } @@ -5684,21 +5631,21 @@ public class PackageManagerService extends IPackageManager.Stub String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) { synchronized (mLock) { - final AndroidPackage p = mPackages.get(packageName); - final PackageSetting ps = getPackageSetting(p.getPackageName()); - if (p == null || ps == null) { + final PackageParser.Package p = mPackages.get(packageName); + if (p == null || p.mExtras == null) { return false; } final int callingUid = Binder.getCallingUid(); final int callingUserId = UserHandle.getUserId(callingUid); + final PackageSetting ps = (PackageSetting) p.mExtras; if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) { return false; } switch (type) { case CERT_INPUT_RAW_X509: - return p.getSigningDetails().hasCertificate(certificate); + return p.mSigningDetails.hasCertificate(certificate); case CERT_INPUT_SHA256: - return p.getSigningDetails().hasSha256Certificate(certificate); + return p.mSigningDetails.hasSha256Certificate(certificate); default: return false; } @@ -5751,16 +5698,16 @@ public class PackageManagerService extends IPackageManager.Stub * external storage) is less than the version where package signatures * were updated, return true. */ - private boolean isCompatSignatureUpdateNeeded(AndroidPackage pkg) { - return isCompatSignatureUpdateNeeded(getSettingsVersionForPackage(pkg)); + private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { + return isCompatSignatureUpdateNeeded(getSettingsVersionForPackage(scannedPkg)); } private static boolean isCompatSignatureUpdateNeeded(VersionInfo ver) { return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; } - private boolean isRecoverSignatureUpdateNeeded(AndroidPackage pkg) { - return isRecoverSignatureUpdateNeeded(getSettingsVersionForPackage(pkg)); + private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { + return isRecoverSignatureUpdateNeeded(getSettingsVersionForPackage(scannedPkg)); } private static boolean isRecoverSignatureUpdateNeeded(VersionInfo ver) { @@ -5779,23 +5726,24 @@ public class PackageManagerService extends IPackageManager.Stub final List<String> result = new ArrayList<>(); if (instantAppPkgName != null) { // caller is an instant application; filter unexposed applications - for (AndroidPackage pkg : mPackages.values()) { - if (!pkg.isVisibleToInstantApps()) { + for (PackageParser.Package pkg : mPackages.values()) { + if (!pkg.visibleToInstantApps) { continue; } - result.add(pkg.getPackageName()); + result.add(pkg.packageName); } } else { // caller is a normal application; filter instant applications - for (AndroidPackage pkg : mPackages.values()) { - final PackageSetting ps = getPackageSetting(pkg.getPackageName()); + for (PackageParser.Package pkg : mPackages.values()) { + final PackageSetting ps = + pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null; if (ps != null && ps.getInstantApp(callingUserId) && !mInstantAppRegistry.isInstantAccessGranted( callingUserId, UserHandle.getAppId(callingUid), ps.appId)) { continue; } - result.add(pkg.getPackageName()); + result.add(pkg.packageName); } } return result; @@ -6641,7 +6589,7 @@ public class PackageManagerService extends IPackageManager.Stub if (obj instanceof PackageSetting) { final PackageSetting ps = (PackageSetting) obj; final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid)); - return isInstantApp ? ps.pkg.getPackageName() : null; + return isInstantApp ? ps.pkg.packageName : null; } } return null; @@ -6713,11 +6661,9 @@ public class PackageManagerService extends IPackageManager.Stub list.add(ri); } } - - List<ResolveInfo> result = applyPostResolutionFilter( + return applyPostResolutionFilter( list, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart, userId, intent); - return result; } // reader @@ -6794,11 +6740,11 @@ public class PackageManagerService extends IPackageManager.Stub sortResult = true; } } else { - final AndroidPackage pkg = mPackages.get(pkgName); + final PackageParser.Package pkg = mPackages.get(pkgName); result = null; if (pkg != null) { result = filterIfNotSystemUser(mComponentResolver.queryActivities( - intent, resolvedType, flags, pkg.getActivities(), userId), userId); + intent, resolvedType, flags, pkg.activities, userId), userId); } if (result == null || result.size() == 0) { // the caller wants to resolve for a particular package; however, there @@ -7691,10 +7637,10 @@ public class PackageManagerService extends IPackageManager.Stub result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId, intent); } - final AndroidPackage pkg = mPackages.get(pkgName); + final PackageParser.Package pkg = mPackages.get(pkgName); if (pkg != null) { final List<ResolveInfo> result = mComponentResolver.queryReceivers( - intent, resolvedType, flags, pkg.getReceivers(), userId); + intent, resolvedType, flags, pkg.receivers, userId); return applyPostResolutionFilter( result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId, intent); @@ -7793,11 +7739,11 @@ public class PackageManagerService extends IPackageManager.Stub mComponentResolver.queryServices(intent, resolvedType, flags, userId), instantAppPkgName); } - final AndroidPackage pkg = mPackages.get(pkgName); + final PackageParser.Package pkg = mPackages.get(pkgName); if (pkg != null) { return applyPostServiceResolutionFilter( - mComponentResolver.queryServices(intent, resolvedType, flags, - pkg.getServices(), userId), + mComponentResolver.queryServices(intent, resolvedType, flags, pkg.services, + userId), instantAppPkgName); } return Collections.emptyList(); @@ -7911,11 +7857,11 @@ public class PackageManagerService extends IPackageManager.Stub mComponentResolver.queryProviders(intent, resolvedType, flags, userId), instantAppPkgName); } - final AndroidPackage pkg = mPackages.get(pkgName); + final PackageParser.Package pkg = mPackages.get(pkgName); if (pkg != null) { return applyPostContentProviderResolutionFilter( mComponentResolver.queryProviders(intent, resolvedType, flags, - pkg.getProviders(), userId), + pkg.providers, userId), instantAppPkgName); } return Collections.emptyList(); @@ -8000,15 +7946,16 @@ public class PackageManagerService extends IPackageManager.Stub } } else { list = new ArrayList<>(mPackages.size()); - for (AndroidPackage p : mPackages.values()) { - final PackageSetting ps = getPackageSetting(p.getPackageName()); + for (PackageParser.Package p : mPackages.values()) { + final PackageSetting ps = (PackageSetting) p.mExtras; if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) { continue; } if (shouldFilterApplicationLocked(ps, callingUid, userId)) { continue; } - final PackageInfo pi = generatePackageInfo(ps, flags, userId); + final PackageInfo pi = generatePackageInfo((PackageSetting) + p.mExtras, flags, userId); if (pi != null) { list.add(pi); } @@ -8087,8 +8034,8 @@ public class PackageManagerService extends IPackageManager.Stub userId); } } else { - for (AndroidPackage pkg : mPackages.values()) { - PackageSetting ps = getPackageSetting(pkg.getPackageName()); + for (PackageParser.Package pkg : mPackages.values()) { + PackageSetting ps = (PackageSetting)pkg.mExtras; if (ps != null) { addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); @@ -8141,7 +8088,7 @@ public class PackageManagerService extends IPackageManager.Stub if (shouldFilterApplicationLocked(ps, callingUid, userId)) { continue; } - ai = PackageInfoUtils.generateApplicationInfo(ps.pkg, effectiveFlags, + ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags, ps.readUserState(userId), userId); if (ai != null) { ai.packageName = resolveExternalPackageNameLPr(ps.pkg); @@ -8158,16 +8105,16 @@ public class PackageManagerService extends IPackageManager.Stub } } else { list = new ArrayList<>(mPackages.size()); - for (AndroidPackage p : mPackages.values()) { - final PackageSetting ps = getPackageSetting(p.getPackageName()); - if (ps != null) { + for (PackageParser.Package p : mPackages.values()) { + if (p.mExtras != null) { + PackageSetting ps = (PackageSetting) p.mExtras; if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) { continue; } if (shouldFilterApplicationLocked(ps, callingUid, userId)) { continue; } - ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags, + ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, ps.readUserState(userId), userId); if (ai != null) { ai.packageName = resolveExternalPackageNameLPr(p); @@ -8223,6 +8170,7 @@ public class PackageManagerService extends IPackageManager.Stub callingUid = mIsolatedOwners.get(callingUid); } final PackageSetting ps = mSettings.mPackages.get(packageName); + PackageParser.Package pkg = mPackages.get(packageName); final boolean returnAllowed = ps != null && (isCallerSameApp(packageName, callingUid) @@ -8293,9 +8241,9 @@ public class PackageManagerService extends IPackageManager.Stub } private boolean isCallerSameApp(String packageName, int uid) { - AndroidPackage pkg = mPackages.get(packageName); + PackageParser.Package pkg = mPackages.get(packageName); return pkg != null - && UserHandle.getAppId(uid) == pkg.getUid(); + && UserHandle.getAppId(uid) == pkg.applicationInfo.uid; } @Override @@ -8311,22 +8259,23 @@ public class PackageManagerService extends IPackageManager.Stub // reader synchronized (mLock) { - final Iterator<AndroidPackage> i = mPackages.values().iterator(); + final Iterator<PackageParser.Package> i = mPackages.values().iterator(); final int userId = UserHandle.getCallingUserId(); while (i.hasNext()) { - final AndroidPackage p = i.next(); + final PackageParser.Package p = i.next(); + if (p.applicationInfo == null) continue; final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) - && !p.isDirectBootAware(); + && !p.applicationInfo.isDirectBootAware(); final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) - && p.isDirectBootAware(); + && p.applicationInfo.isDirectBootAware(); - if ((p.getFlags() & ApplicationInfo.FLAG_PERSISTENT) != 0 + if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 && (!mSafeMode || isSystemApp(p)) && (matchesUnaware || matchesAware)) { - PackageSetting ps = mSettings.mPackages.get(p.getPackageName()); + PackageSetting ps = mSettings.mPackages.get(p.packageName); if (ps != null) { - ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags, + ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, ps.readUserState(userId), userId); if (ai != null) { finalList.add(ai); @@ -8348,8 +8297,7 @@ public class PackageManagerService extends IPackageManager.Stub if (!mUserManager.exists(userId)) return null; flags = updateFlagsForComponent(flags, userId, name); final int callingUid = Binder.getCallingUid(); - final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, callingUid, - userId); + final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, userId); if (providerInfo == null) { return null; } @@ -8431,8 +8379,8 @@ public class PackageManagerService extends IPackageManager.Stub ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) { return null; } - final ParsedInstrumentation i = mInstrumentation.get(component); - return PackageInfoUtils.generateInstrumentationInfo(i, flags); + final PackageParser.Instrumentation i = mInstrumentation.get(component); + return PackageParser.generateInstrumentationInfo(i, flags); } } @@ -8454,12 +8402,12 @@ public class PackageManagerService extends IPackageManager.Stub // reader synchronized (mLock) { - final Iterator<ParsedInstrumentation> i = mInstrumentation.values().iterator(); + final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); while (i.hasNext()) { - final ParsedInstrumentation p = i.next(); + final PackageParser.Instrumentation p = i.next(); if (targetPackage == null - || targetPackage.equals(p.getTargetPackage())) { - InstrumentationInfo ii = PackageInfoUtils.generateInstrumentationInfo(p, + || targetPackage.equals(p.info.targetPackage)) { + InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, flags); if (ii != null) { finalList.add(ii); @@ -8516,18 +8464,18 @@ public class PackageManagerService extends IPackageManager.Stub if (throwable == null) { // TODO(toddke): move lower in the scan chain // Static shared libraries have synthetic package names - if (parseResult.parsedPackage.isStaticSharedLibrary()) { - renameStaticSharedLibraryPackage(parseResult.parsedPackage); + if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) { + renameStaticSharedLibraryPackage(parseResult.pkg); } try { - addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags, + scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags, currentTime, null); } catch (PackageManagerException e) { errorCode = e.error; Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage()); } - } else if (throwable instanceof PackageParserException) { - PackageParserException e = (PackageParserException) + } else if (throwable instanceof PackageParser.PackageParserException) { + PackageParser.PackageParserException e = (PackageParser.PackageParserException) throwable; errorCode = e.error; Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage()); @@ -8551,16 +8499,15 @@ public class PackageManagerService extends IPackageManager.Stub logCriticalInfo(priority, msg); } - private void collectCertificatesLI(PackageSetting ps, ParsedPackage parsedPackage, + private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, boolean forceCollect, boolean skipVerify) throws PackageManagerException { // When upgrading from pre-N MR1, verify the package time stamp using the package // directory and not the APK file. final long lastModifiedTime = mIsPreNMR1Upgrade - ? new File(parsedPackage.getCodePath()).lastModified() - : getLastModifiedTime(parsedPackage); - final VersionInfo settingsVersionForPackage = getSettingsVersionForPackage(parsedPackage); + ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg); + final VersionInfo settingsVersionForPackage = getSettingsVersionForPackage(pkg); if (ps != null && !forceCollect - && ps.codePathString.equals(parsedPackage.getCodePath()) + && ps.codePathString.equals(pkg.codePath) && ps.timeStamp == lastModifiedTime && !isCompatSignatureUpdateNeeded(settingsVersionForPackage) && !isRecoverSignatureUpdateNeeded(settingsVersionForPackage)) { @@ -8570,21 +8517,21 @@ public class PackageManagerService extends IPackageManager.Stub != SignatureSchemeVersion.UNKNOWN) { // Optimization: reuse the existing cached signing data // if the package appears to be unchanged. - parsedPackage.setSigningDetails( - new PackageParser.SigningDetails(ps.signatures.mSigningDetails)); + pkg.mSigningDetails = + new PackageParser.SigningDetails(ps.signatures.mSigningDetails); return; } Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures. Collecting certs again to recover them."); } else { - Slog.i(TAG, parsedPackage.getCodePath() + " changed; collecting certs" + + Slog.i(TAG, pkg.codePath + " changed; collecting certs" + (forceCollect ? " (forced)" : "")); } try { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); - ApkParseUtils.collectCertificates(parsedPackage, skipVerify); + PackageParser.collectCertificates(pkg, skipVerify); } catch (PackageParserException e) { throw PackageManagerException.from(e); } finally { @@ -8598,20 +8545,20 @@ public class PackageManagerService extends IPackageManager.Stub */ private void maybeClearProfilesForUpgradesLI( @Nullable PackageSetting originalPkgSetting, - @NonNull AndroidPackage pkg) { + @NonNull PackageParser.Package currentPkg) { if (originalPkgSetting == null || !isDeviceUpgrading()) { return; } - if (originalPkgSetting.versionCode == pkg.getVersionCode()) { + if (originalPkgSetting.versionCode == currentPkg.mVersionCode) { return; } - clearAppProfilesLIF(pkg, UserHandle.USER_ALL); + clearAppProfilesLIF(currentPkg, UserHandle.USER_ALL); if (DEBUG_INSTALL) { Slog.d(TAG, originalPkgSetting.name + " clear profile due to version change " + originalPkgSetting.versionCode + " != " - + pkg.getVersionCode()); + + currentPkg.mVersionCode); } } @@ -8620,7 +8567,7 @@ public class PackageManagerService extends IPackageManager.Stub * @see #scanPackageLI(File, int, int, long, UserHandle) */ @GuardedBy({"mInstallLock", "mLock"}) - private AndroidPackage scanPackageTracedLI(File scanFile, final int parseFlags, + private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags, int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]"); try { @@ -8635,7 +8582,7 @@ public class PackageManagerService extends IPackageManager.Stub * Returns {@code null} in case of errors and the error code is stored in mLastScanError */ @GuardedBy({"mInstallLock", "mLock"}) - private AndroidPackage scanPackageLI(File scanFile, int parseFlags, int scanFlags, + private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); PackageParser pp = new PackageParser(); @@ -8645,9 +8592,9 @@ public class PackageManagerService extends IPackageManager.Stub pp.setCallback(mPackageParserCallback); Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); - final ParsedPackage parsedPackage; + final PackageParser.Package pkg; try { - parsedPackage = pp.parseParsedPackage(scanFile, parseFlags, false); + pkg = pp.parsePackage(scanFile, parseFlags); } catch (PackageParserException e) { throw PackageManagerException.from(e); } finally { @@ -8655,25 +8602,66 @@ public class PackageManagerService extends IPackageManager.Stub } // Static shared libraries have synthetic package names - if (parsedPackage.isStaticSharedLibrary()) { - renameStaticSharedLibraryPackage(parsedPackage); + if (pkg.applicationInfo.isStaticSharedLibrary()) { + renameStaticSharedLibraryPackage(pkg); } - return addForInitLI(parsedPackage, parseFlags, scanFlags, currentTime, user); + return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user); + } + + /** + * Scans a package and returns the newly parsed package. + * @throws PackageManagerException on a parse error. + */ + @GuardedBy({"mInstallLock", "mLock"}) + private PackageParser.Package scanPackageChildLI(PackageParser.Package pkg, + final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime, + @Nullable UserHandle user) + throws PackageManagerException { + // If the package has children and this is the first dive in the function + // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all + // packages (parent and children) would be successfully scanned before the + // actual scan since scanning mutates internal state and we want to atomically + // install the package and its children. + if ((scanFlags & SCAN_CHECK_ONLY) == 0) { + if (pkg.childPackages != null && pkg.childPackages.size() > 0) { + scanFlags |= SCAN_CHECK_ONLY; + } + } else { + scanFlags &= ~SCAN_CHECK_ONLY; + } + + // Scan the parent + PackageParser.Package scannedPkg = addForInitLI(pkg, parseFlags, + scanFlags, currentTime, user); + + // Scan the children + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + PackageParser.Package childPackage = pkg.childPackages.get(i); + addForInitLI(childPackage, parseFlags, scanFlags, + currentTime, user); + } + + + if ((scanFlags & SCAN_CHECK_ONLY) != 0) { + return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user); + } + + return scannedPkg; } /** * Returns if forced apk verification can be skipped for the whole package, including splits. */ - private boolean canSkipForcedPackageVerification(AndroidPackage pkg) { - if (!canSkipForcedApkVerification(pkg.getBaseCodePath())) { + private boolean canSkipForcedPackageVerification(PackageParser.Package pkg) { + if (!canSkipForcedApkVerification(pkg.baseCodePath)) { return false; } // TODO: Allow base and splits to be verified individually. - String[] splitCodePaths = pkg.getSplitCodePaths(); - if (!ArrayUtils.isEmpty(splitCodePaths)) { - for (int i = 0; i < splitCodePaths.length; i++) { - if (!canSkipForcedApkVerification(splitCodePaths[i])) { + if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { + for (int i = 0; i < pkg.splitCodePaths.length; i++) { + if (!canSkipForcedApkVerification(pkg.splitCodePaths[i])) { return false; } } @@ -8722,7 +8710,7 @@ public class PackageManagerService extends IPackageManager.Stub * <p>NOTE: The return value should be removed. It's the passed in package object. */ @GuardedBy({"mInstallLock", "mLock"}) - private AndroidPackage addForInitLI(ParsedPackage parsedPackage, + private PackageParser.Package addForInitLI(PackageParser.Package pkg, @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime, @Nullable UserHandle user) throws PackageManagerException { @@ -8738,27 +8726,25 @@ public class PackageManagerService extends IPackageManager.Stub // stack [such as scanPackageOnly()]. However, we verify the application // info prior to that [in scanPackageNew()] and thus have to setup // the application info early. - // TODO(b/135203078): Remove all of these application info calls - parsedPackage.setApplicationVolumeUuid(parsedPackage.getVolumeUuid()) - .setApplicationInfoCodePath(parsedPackage.getCodePath()) - .setApplicationInfoResourcePath(parsedPackage.getCodePath()) - .setApplicationInfoBaseResourcePath(parsedPackage.getBaseCodePath()) - .setApplicationInfoSplitResourcePaths(parsedPackage.getSplitCodePaths()); + pkg.setApplicationVolumeUuid(pkg.volumeUuid); + pkg.setApplicationInfoCodePath(pkg.codePath); + pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); + pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); + pkg.setApplicationInfoResourcePath(pkg.codePath); + pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); + pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); synchronized (mLock) { - renamedPkgName = mSettings.getRenamedPackageLPr(parsedPackage.getRealPackage()); - final String realPkgName = getRealPackageName(parsedPackage, renamedPkgName); + renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage); + final String realPkgName = getRealPackageName(pkg, renamedPkgName); if (realPkgName != null) { - ensurePackageRenamed(parsedPackage, renamedPkgName); + ensurePackageRenamed(pkg, renamedPkgName); } - final PackageSetting originalPkgSetting = getOriginalPackageLocked(parsedPackage, - renamedPkgName); - final PackageSetting installedPkgSetting = mSettings.getPackageLPr( - parsedPackage.getPackageName()); + final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName); + final PackageSetting installedPkgSetting = mSettings.getPackageLPr(pkg.packageName); pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting; pkgAlreadyExists = pkgSetting != null; - final String disabledPkgName = - pkgAlreadyExists ? pkgSetting.name : parsedPackage.getPackageName(); + final String disabledPkgName = pkgAlreadyExists ? pkgSetting.name : pkg.packageName; disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName); isSystemPkgUpdated = disabledPkgSetting != null; @@ -8766,29 +8752,49 @@ public class PackageManagerService extends IPackageManager.Stub Slog.d(TAG, "updatedPkg = " + disabledPkgSetting); } - final SharedUserSetting sharedUserSetting = (parsedPackage.getSharedUserId() != null) - ? mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(), + final SharedUserSetting sharedUserSetting = (pkg.mSharedUserId != null) + ? mSettings.getSharedUserLPw(pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true) : null; if (DEBUG_PACKAGE_SCANNING && (parseFlags & PackageParser.PARSE_CHATTY) != 0 && sharedUserSetting != null) { - Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId() + Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + sharedUserSetting.userId + "):" + " packages=" + sharedUserSetting.packages); } if (scanSystemPartition) { + // Potentially prune child packages. If the application on the /system + // partition has been updated via OTA, but, is still disabled by a + // version on /data, cycle through all of its children packages and + // remove children that are no longer defined. if (isSystemPkgUpdated) { + final int scannedChildCount = (pkg.childPackages != null) + ? pkg.childPackages.size() : 0; + final int disabledChildCount = disabledPkgSetting.childPackageNames != null + ? disabledPkgSetting.childPackageNames.size() : 0; + for (int i = 0; i < disabledChildCount; i++) { + String disabledChildPackageName = + disabledPkgSetting.childPackageNames.get(i); + boolean disabledPackageAvailable = false; + for (int j = 0; j < scannedChildCount; j++) { + PackageParser.Package childPkg = pkg.childPackages.get(j); + if (childPkg.packageName.equals(disabledChildPackageName)) { + disabledPackageAvailable = true; + break; + } + } + if (!disabledPackageAvailable) { + mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); + } + } // we're updating the disabled package, so, scan it as the package setting - boolean isPlatformPackage = mPlatformPackage != null - && Objects.equals(mPlatformPackage.getPackageName(), - parsedPackage.getPackageName()); - final ScanRequest request = new ScanRequest(parsedPackage, sharedUserSetting, - null, disabledPkgSetting /* pkgSetting */, - null /* disabledPkgSetting */, null /* originalPkgSetting */, - null, parseFlags, scanFlags, isPlatformPackage, user); - applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage); + final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, null, + disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */, + null /* originalPkgSetting */, null, parseFlags, scanFlags, + (pkg == mPlatformPackage), user); + applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage); final ScanResult scanResult = scanPackageOnlyLI(request, mInjector, mFactoryTest, -1L); if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) { @@ -8799,9 +8805,9 @@ public class PackageManagerService extends IPackageManager.Stub } final boolean newPkgChangedPaths = - pkgAlreadyExists && !pkgSetting.codePathString.equals(parsedPackage.getCodePath()); + pkgAlreadyExists && !pkgSetting.codePathString.equals(pkg.codePath); final boolean newPkgVersionGreater = - pkgAlreadyExists && parsedPackage.getLongVersionCode() > pkgSetting.versionCode; + pkgAlreadyExists && pkg.getLongVersionCode() > pkgSetting.versionCode; final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated && newPkgChangedPaths && newPkgVersionGreater; if (isSystemPkgBetter) { @@ -8817,13 +8823,12 @@ public class PackageManagerService extends IPackageManager.Stub logCriticalInfo(Log.WARN, "System package updated;" + " name: " + pkgSetting.name - + "; " + pkgSetting.versionCode + " --> " + parsedPackage.getLongVersionCode() - + "; " + pkgSetting.codePathString + " --> " + parsedPackage.getCodePath()); + + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode() + + "; " + pkgSetting.codePathString + " --> " + pkg.codePath); final InstallArgs args = createInstallArgsForExisting( pkgSetting.codePathString, - pkgSetting.resourcePathString, getAppDexInstructionSets( - pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString)); + pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting)); args.cleanUpResourcesLI(); synchronized (mLock) { mSettings.enableSystemPackageLPw(pkgSetting.name); @@ -8834,10 +8839,9 @@ public class PackageManagerService extends IPackageManager.Stub // The version of the application on the /system partition is less than or // equal to the version on the /data partition. Throw an exception and use // the application already installed on the /data partition. - throw new PackageManagerException(Log.WARN, "Package " + parsedPackage.getPackageName() - + " at " + parsedPackage.getCodePath() + " ignored: updated version " - + pkgSetting.versionCode + " better than this " - + parsedPackage.getLongVersionCode()); + throw new PackageManagerException(Log.WARN, "Package " + pkg.packageName + " at " + + pkg.codePath + " ignored: updated version " + pkgSetting.versionCode + + " better than this " + pkg.getLongVersionCode()); } // Verify certificates against what was last scanned. Force re-collecting certificate in two @@ -8848,18 +8852,18 @@ public class PackageManagerService extends IPackageManager.Stub final boolean forceCollect = scanSystemPartition ? mIsUpgrade : PackageManagerServiceUtils.isApkVerificationForced(pkgSetting); if (DEBUG_VERIFY && forceCollect) { - Slog.d(TAG, "Force collect certificate of " + parsedPackage.getPackageName()); + Slog.d(TAG, "Force collect certificate of " + pkg.packageName); } // Full APK verification can be skipped during certificate collection, only if the file is // in verified partition, or can be verified on access (when apk verity is enabled). In both // cases, only data in Signing Block is verified instead of the whole file. final boolean skipVerify = scanSystemPartition - || (forceCollect && canSkipForcedPackageVerification(parsedPackage)); - collectCertificatesLI(pkgSetting, parsedPackage, forceCollect, skipVerify); + || (forceCollect && canSkipForcedPackageVerification(pkg)); + collectCertificatesLI(pkgSetting, pkg, forceCollect, skipVerify); // Reset profile if the application version is changed - maybeClearProfilesForUpgradesLI(pkgSetting, parsedPackage); + maybeClearProfilesForUpgradesLI(pkgSetting, pkg); /* * A new system app appeared, but we already had a non-system one of the @@ -8871,20 +8875,17 @@ public class PackageManagerService extends IPackageManager.Stub if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists && !pkgSetting.isSystem()) { - if (!parsedPackage.getSigningDetails() - .checkCapability(pkgSetting.signatures.mSigningDetails, + if (!pkg.mSigningDetails.checkCapability(pkgSetting.signatures.mSigningDetails, PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA) && !pkgSetting.signatures.mSigningDetails.checkCapability( - parsedPackage.getSigningDetails(), + pkg.mSigningDetails, PackageParser.SigningDetails.CertCapabilities.ROLLBACK)) { logCriticalInfo(Log.WARN, "System package signature mismatch;" + " name: " + pkgSetting.name); - try (@SuppressWarnings("unused") PackageFreezer freezer = freezePackage( - parsedPackage.getPackageName(), + try (PackageFreezer freezer = freezePackage(pkg.packageName, "scanPackageInternalLI")) { - deletePackageLIF(parsedPackage.getPackageName(), null, true, null, 0, null, - false, null); + deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null); } pkgSetting = null; } else if (newPkgVersionGreater) { @@ -8893,15 +8894,12 @@ public class PackageManagerService extends IPackageManager.Stub // and replace it with the version on /system. logCriticalInfo(Log.WARN, "System package enabled;" - + " name: " + pkgSetting.name - + "; " + pkgSetting.versionCode + " --> " - + parsedPackage.getLongVersionCode() - + "; " + pkgSetting.codePathString + " --> " - + parsedPackage.getCodePath()); + + " name: " + pkgSetting.name + + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode() + + "; " + pkgSetting.codePathString + " --> " + pkg.codePath); InstallArgs args = createInstallArgsForExisting( pkgSetting.codePathString, - pkgSetting.resourcePathString, getAppDexInstructionSets( - pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString)); + pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting)); synchronized (mInstallLock) { args.cleanUpResourcesLI(); } @@ -8912,15 +8910,13 @@ public class PackageManagerService extends IPackageManager.Stub shouldHideSystemApp = true; logCriticalInfo(Log.INFO, "System package disabled;" - + " name: " + pkgSetting.name - + "; old: " + pkgSetting.codePathString + " @ " - + pkgSetting.versionCode - + "; new: " + parsedPackage.getCodePath() + " @ " - + parsedPackage.getCodePath()); + + " name: " + pkgSetting.name + + "; old: " + pkgSetting.codePathString + " @ " + pkgSetting.versionCode + + "; new: " + pkg.codePath + " @ " + pkg.codePath); } } - final ScanResult scanResult = scanPackageNewLI(parsedPackage, parseFlags, scanFlags + final ScanResult scanResult = scanPackageNewLI(pkg, parseFlags, scanFlags | SCAN_UPDATE_SIGNATURE, currentTime, user); if (scanResult.success) { synchronized (mLock) { @@ -8933,7 +8929,7 @@ public class PackageManagerService extends IPackageManager.Stub mSharedLibraries, mPackages, Collections.singletonMap( - pkgName, getSettingsVersionForPackage(parsedPackage)), + pkgName, getSettingsVersionForPackage(pkg)), Collections.singletonMap(pkgName, getSharedLibLatestVersionSetting(scanResult))), mSettings.mKeySetManagerService); @@ -8950,17 +8946,16 @@ public class PackageManagerService extends IPackageManager.Stub if (shouldHideSystemApp) { synchronized (mLock) { - mSettings.disableSystemPackageLPw(parsedPackage.getPackageName(), true); + mSettings.disableSystemPackageLPw(pkg.packageName, true); } } return scanResult.pkgSetting.pkg; } - // TODO:(b/135203078): Move to parsing - private static void renameStaticSharedLibraryPackage(ParsedPackage parsedPackage) { + private static void renameStaticSharedLibraryPackage(PackageParser.Package pkg) { // Derive the new package synthetic package name - parsedPackage.setPackageName(parsedPackage.getPackageName() + STATIC_SHARED_LIB_DELIMITER - + parsedPackage.getStaticSharedLibVersion()); + pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER + + pkg.staticSharedLibVersion); } static String fixProcessName(String defProcessName, String processName) { @@ -9061,7 +9056,7 @@ public class PackageManagerService extends IPackageManager.Stub return; } - List<AndroidPackage> pkgs; + List<PackageParser.Package> pkgs; synchronized (mLock) { pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); } @@ -9084,8 +9079,8 @@ public class PackageManagerService extends IPackageManager.Stub /* * Return the prebuilt profile path given a package base code path. */ - private static String getPrebuildProfilePath(AndroidPackage pkg) { - return pkg.getBaseCodePath() + ".prof"; + private static String getPrebuildProfilePath(PackageParser.Package pkg) { + return pkg.baseCodePath + ".prof"; } /** @@ -9094,7 +9089,7 @@ public class PackageManagerService extends IPackageManager.Stub * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped} * and {@code numberOfPackagesFailed}. */ - private int[] performDexOptUpgrade(List<AndroidPackage> pkgs, boolean showDialog, + private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog, final int compilationReason, boolean bootComplete) { int numberOfPackagesVisited = 0; @@ -9103,7 +9098,7 @@ public class PackageManagerService extends IPackageManager.Stub int numberOfPackagesFailed = 0; final int numberOfPackagesToDexopt = pkgs.size(); - for (AndroidPackage pkg : pkgs) { + for (PackageParser.Package pkg : pkgs) { numberOfPackagesVisited++; boolean useProfileForDexopt = false; @@ -9119,7 +9114,7 @@ public class PackageManagerService extends IPackageManager.Stub // PackageDexOptimizer to prevent this happening on first boot. The issue // is that we don't have a good way to say "do this only once". if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(), - pkg.getUid(), pkg.getPackageName(), + pkg.applicationInfo.uid, pkg.packageName, ArtManager.getProfileName(null))) { Log.e(TAG, "Installer failed to copy system profile!"); } else { @@ -9132,12 +9127,11 @@ public class PackageManagerService extends IPackageManager.Stub e); } } else { - PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr( - pkg.getPackageName()); + PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); // Handle compressed APKs in this path. Only do this for stubs with profiles to // minimize the number off apps being speed-profile compiled during first boot. // The other paths will not change the filter. - if (disabledPs != null && disabledPs.pkg.isStub()) { + if (disabledPs != null && disabledPs.pkg.isStub) { // The package is the stub one, remove the stub suffix to get the normal // package and APK names. String systemProfilePath = @@ -9156,7 +9150,7 @@ public class PackageManagerService extends IPackageManager.Stub // issue is that we don't have a good way to say "do this only // once". if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(), - pkg.getUid(), pkg.getPackageName(), + pkg.applicationInfo.uid, pkg.packageName, ArtManager.getProfileName(null))) { Log.e(TAG, "Failed to copy system profile for stub package!"); } else { @@ -9173,7 +9167,7 @@ public class PackageManagerService extends IPackageManager.Stub if (!PackageDexOptimizer.canOptimizePackage(pkg)) { if (DEBUG_DEXOPT) { - Log.i(TAG, "Skipping update of non-optimizable app " + pkg.getPackageName()); + Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName); } numberOfPackagesSkipped++; continue; @@ -9181,7 +9175,7 @@ public class PackageManagerService extends IPackageManager.Stub if (DEBUG_DEXOPT) { Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " + - numberOfPackagesToDexopt + ": " + pkg.getPackageName()); + numberOfPackagesToDexopt + ": " + pkg.packageName); } if (showDialog) { @@ -9218,7 +9212,7 @@ public class PackageManagerService extends IPackageManager.Stub dexoptFlags |= DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE; } int primaryDexOptStaus = performDexOptTraced(new DexoptOptions( - pkg.getPackageName(), + pkg.packageName, pkgCompilationReason, dexoptFlags)); @@ -9262,11 +9256,11 @@ public class PackageManagerService extends IPackageManager.Stub @GuardedBy("mLock") private void notifyPackageUseLocked(String packageName, int reason) { - final AndroidPackage p = mPackages.get(packageName); + final PackageParser.Package p = mPackages.get(packageName); if (p == null) { return; } - p.mutate().setLastPackageUsageTimeInMills(reason, System.currentTimeMillis()); + p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis(); } @Override @@ -9346,7 +9340,7 @@ public class PackageManagerService extends IPackageManager.Stub */ @Override public boolean compileLayouts(String packageName) { - AndroidPackage pkg; + PackageParser.Package pkg; synchronized (mLock) { pkg = mPackages.get(packageName); if (pkg == null) { @@ -9393,7 +9387,7 @@ public class PackageManagerService extends IPackageManager.Stub // Run dexopt on a given package. Returns true if dexopt did not fail, i.e. // if the package can now be considered up to date for the given filter. private int performDexOptInternal(DexoptOptions options) { - AndroidPackage p; + PackageParser.Package p; synchronized (mLock) { p = mPackages.get(options.getPackageName()); if (p == null) { @@ -9416,16 +9410,16 @@ public class PackageManagerService extends IPackageManager.Stub public ArraySet<String> getOptimizablePackages() { ArraySet<String> pkgs = new ArraySet<>(); synchronized (mLock) { - for (AndroidPackage p : mPackages.values()) { + for (PackageParser.Package p : mPackages.values()) { if (PackageDexOptimizer.canOptimizePackage(p)) { - pkgs.add(p.getPackageName()); + pkgs.add(p.packageName); } } } return pkgs; } - private int performDexOptInternalWithDependenciesLI(AndroidPackage p, + private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, DexoptOptions options) { // Select the dex optimizer based on the force parameter. // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to @@ -9442,15 +9436,14 @@ public class PackageManagerService extends IPackageManager.Stub // and the first package that uses the library will dexopt it. The // others will see that the compiled code for the library is up to date. Collection<SharedLibraryInfo> deps = findSharedLibraries(p); - final String[] instructionSets = getAppDexInstructionSets(p.getPrimaryCpuAbi(), - p.getSecondaryCpuAbi()); + final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo); if (!deps.isEmpty()) { DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(), options.getCompilationReason(), options.getCompilerFilter(), options.getSplitName(), options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY); for (SharedLibraryInfo info : deps) { - AndroidPackage depPackage = null; + PackageParser.Package depPackage = null; synchronized (mLock) { depPackage = mPackages.get(info.getPackageName()); } @@ -9458,7 +9451,7 @@ public class PackageManagerService extends IPackageManager.Stub // TODO: Analyze and investigate if we (should) profile libraries. pdo.performDexOpt(depPackage, instructionSets, getOrCreateCompilerPackageStats(depPackage), - mDexManager.getPackageUseInfoOrDefault(depPackage.getPackageName()), + mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions); } else { // TODO(ngeoffray): Support dexopting system shared libraries. @@ -9467,7 +9460,7 @@ public class PackageManagerService extends IPackageManager.Stub } return pdo.performDexOpt(p, instructionSets, getOrCreateCompilerPackageStats(p), - mDexManager.getPackageUseInfoOrDefault(p.getPackageName()), options); + mDexManager.getPackageUseInfoOrDefault(p.packageName), options); } /** @@ -9508,11 +9501,11 @@ public class PackageManagerService extends IPackageManager.Stub } } - private static List<SharedLibraryInfo> findSharedLibraries(AndroidPackage p) { - if (p.getUsesLibraryInfos() != null) { + private static List<SharedLibraryInfo> findSharedLibraries(PackageParser.Package p) { + if (p.usesLibraryInfos != null) { ArrayList<SharedLibraryInfo> retValue = new ArrayList<>(); Set<String> collectedNames = new HashSet<>(); - for (SharedLibraryInfo info : p.getUsesLibraryInfos()) { + for (SharedLibraryInfo info : p.usesLibraryInfos) { findSharedLibrariesRecursive(info, retValue, collectedNames); } return retValue; @@ -9535,13 +9528,13 @@ public class PackageManagerService extends IPackageManager.Stub } } - List<AndroidPackage> findSharedNonSystemLibraries(AndroidPackage pkg) { + List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package pkg) { List<SharedLibraryInfo> deps = findSharedLibraries(pkg); if (!deps.isEmpty()) { - ArrayList<AndroidPackage> retValue = new ArrayList<>(); + ArrayList<PackageParser.Package> retValue = new ArrayList<>(); synchronized (mLock) { for (SharedLibraryInfo info : deps) { - AndroidPackage depPackage = mPackages.get(info.getPackageName()); + PackageParser.Package depPackage = mPackages.get(info.getPackageName()); if (depPackage != null) { retValue.add(depPackage); } @@ -9579,9 +9572,9 @@ public class PackageManagerService extends IPackageManager.Stub return versionedLib.get(version); } - private SharedLibraryInfo getLatestSharedLibraVersionLPr(AndroidPackage pkg) { + private SharedLibraryInfo getLatestSharedLibraVersionLPr(PackageParser.Package pkg) { LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get( - pkg.getStaticSharedLibName()); + pkg.staticSharedLibName); if (versionedLib == null) { return null; } @@ -9589,7 +9582,7 @@ public class PackageManagerService extends IPackageManager.Stub final int versionCount = versionedLib.size(); for (int i = 0; i < versionCount; i++) { final long libVersion = versionedLib.keyAt(i); - if (libVersion < pkg.getStaticSharedLibVersion()) { + if (libVersion < pkg.staticSharedLibVersion) { previousLibVersion = Math.max(previousLibVersion, libVersion); } } @@ -9605,7 +9598,7 @@ public class PackageManagerService extends IPackageManager.Stub PackageSetting sharedLibPackage = null; synchronized (mLock) { final SharedLibraryInfo latestSharedLibraVersionLPr = - getLatestSharedLibraVersionLPr(scanResult.request.parsedPackage); + getLatestSharedLibraVersionLPr(scanResult.pkgSetting.pkg); if (latestSharedLibraVersionLPr != null) { sharedLibPackage = mSettings.getPackageLPr( latestSharedLibraVersionLPr.getPackageName()); @@ -9634,7 +9627,7 @@ public class PackageManagerService extends IPackageManager.Stub @Override public void dumpProfiles(String packageName) { - AndroidPackage pkg; + PackageParser.Package pkg; synchronized (mLock) { pkg = mPackages.get(packageName); if (pkg == null) { @@ -9645,7 +9638,7 @@ public class PackageManagerService extends IPackageManager.Stub int callingUid = Binder.getCallingUid(); if (callingUid != Process.SHELL_UID && callingUid != Process.ROOT_UID && - callingUid != pkg.getUid()) { + callingUid != pkg.applicationInfo.uid) { throw new SecurityException("dumpProfiles"); } @@ -9660,7 +9653,7 @@ public class PackageManagerService extends IPackageManager.Stub public void forceDexOpt(String packageName) { enforceSystemOrRoot("forceDexOpt"); - AndroidPackage pkg; + PackageParser.Package pkg; synchronized (mLock) { pkg = mPackages.get(packageName); if (pkg == null) { @@ -9687,15 +9680,15 @@ public class PackageManagerService extends IPackageManager.Stub } @GuardedBy("mLock") - private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg) { + private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { Slog.w(TAG, "Unable to update from " + oldPkg.name - + " to " + newPkg.getPackageName() + + " to " + newPkg.packageName + ": old package not in system partition"); return false; } else if (mPackages.get(oldPkg.name) != null) { Slog.w(TAG, "Unable to update from " + oldPkg.name - + " to " + newPkg.getPackageName() + + " to " + newPkg.packageName + ": old package still exists"); return false; } @@ -9719,86 +9712,122 @@ public class PackageManagerService extends IPackageManager.Stub return (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds() : new int[] { userId }; } - private void clearAppDataLIF(AndroidPackage pkg, int userId, int flags) { + private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) { if (pkg == null) { Slog.wtf(TAG, "Package was null!", new Throwable()); return; } clearAppDataLeafLIF(pkg, userId, flags); + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); + } if ((flags & Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES) == 0) { clearAppProfilesLIF(pkg, UserHandle.USER_ALL); } } - private void clearAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) { + private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { final PackageSetting ps; synchronized (mLock) { - ps = mSettings.mPackages.get(pkg.getPackageName()); + ps = mSettings.mPackages.get(pkg.packageName); } for (int realUserId : resolveUserIds(userId)) { final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; try { - mInstaller.clearAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId, - flags, ceDataInode); + mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, + ceDataInode); } catch (InstallerException e) { Slog.w(TAG, String.valueOf(e)); } } } - private void destroyAppDataLIF(AndroidPackage pkg, int userId, int flags) { + private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) { if (pkg == null) { Slog.wtf(TAG, "Package was null!", new Throwable()); return; } destroyAppDataLeafLIF(pkg, userId, flags); + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); + } } - private void destroyAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) { + private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { final PackageSetting ps; synchronized (mLock) { - ps = mSettings.mPackages.get(pkg.getPackageName()); + ps = mSettings.mPackages.get(pkg.packageName); } for (int realUserId : resolveUserIds(userId)) { final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; try { - mInstaller.destroyAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId, - flags, ceDataInode); + mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, + ceDataInode); } catch (InstallerException e) { Slog.w(TAG, String.valueOf(e)); } - mDexManager.notifyPackageDataDestroyed(pkg.getPackageName(), userId); + mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId); } } - private void destroyAppProfilesLIF(AndroidPackage pkg) { + private void destroyAppProfilesLIF(PackageParser.Package pkg) { if (pkg == null) { Slog.wtf(TAG, "Package was null!", new Throwable()); return; } destroyAppProfilesLeafLIF(pkg); + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + destroyAppProfilesLeafLIF(pkg.childPackages.get(i)); + } } - private void destroyAppProfilesLeafLIF(AndroidPackage pkg) { + private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) { try { - mInstaller.destroyAppProfiles(pkg.getPackageName()); + mInstaller.destroyAppProfiles(pkg.packageName); } catch (InstallerException e) { Slog.w(TAG, String.valueOf(e)); } } - private void clearAppProfilesLIF(AndroidPackage pkg, int userId) { + private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) { if (pkg == null) { Slog.wtf(TAG, "Package was null!", new Throwable()); return; } mArtManagerService.clearAppProfiles(pkg); + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + mArtManagerService.clearAppProfiles(pkg.childPackages.get(i)); + } + } + + private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, + long lastUpdateTime) { + // Set parent install/update time + PackageSetting ps = (PackageSetting) pkg.mExtras; + if (ps != null) { + ps.firstInstallTime = firstInstallTime; + ps.lastUpdateTime = lastUpdateTime; + } + // Set children install/update time + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + PackageParser.Package childPkg = pkg.childPackages.get(i); + ps = (PackageSetting) childPkg.mExtras; + if (ps != null) { + ps.firstInstallTime = firstInstallTime; + ps.lastUpdateTime = lastUpdateTime; + } + } } @GuardedBy("mLock") private void applyDefiningSharedLibraryUpdateLocked( - AndroidPackage pkg, SharedLibraryInfo libInfo, + PackageParser.Package pkg, SharedLibraryInfo libInfo, BiConsumer<SharedLibraryInfo, SharedLibraryInfo> action) { // Note that libraries defined by this package may be null if: // - Package manager was unable to create the shared library. The package still @@ -9807,14 +9836,14 @@ public class PackageManagerService extends IPackageManager.Stub // - Package manager is in a state where package isn't scanned yet. This will // get called again after scanning to fix the dependencies. if (pkg.isLibrary()) { - if (pkg.getStaticSharedLibName() != null) { + if (pkg.staticSharedLibName != null) { SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr( - pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion()); + pkg.staticSharedLibName, pkg.staticSharedLibVersion); if (definedLibrary != null) { action.accept(definedLibrary, libInfo); } } else { - for (String libraryName : pkg.getLibraryNames()) { + for (String libraryName : pkg.libraryNames) { SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr( libraryName, SharedLibraryInfo.VERSION_UNDEFINED); if (definedLibrary != null) { @@ -9826,19 +9855,19 @@ public class PackageManagerService extends IPackageManager.Stub } @GuardedBy("mLock") - private void addSharedLibraryLPr(AndroidPackage pkg, Set<String> usesLibraryFiles, - SharedLibraryInfo libInfo, AndroidPackage changingLib) { + private void addSharedLibraryLPr(PackageParser.Package pkg, Set<String> usesLibraryFiles, + SharedLibraryInfo libInfo, PackageParser.Package changingLib) { if (libInfo.getPath() != null) { usesLibraryFiles.add(libInfo.getPath()); return; } - AndroidPackage p = mPackages.get(libInfo.getPackageName()); - if (changingLib != null && changingLib.getPackageName().equals(libInfo.getPackageName())) { + PackageParser.Package p = mPackages.get(libInfo.getPackageName()); + if (changingLib != null && changingLib.packageName.equals(libInfo.getPackageName())) { // If we are doing this while in the middle of updating a library apk, // then we need to make sure to use that new apk for determining the // dependencies here. (We haven't yet finished committing the new apk // to the package manager state.) - if (p == null || p.getPackageName().equals(changingLib.getPackageName())) { + if (p == null || p.packageName.equals(changingLib.packageName)) { p = changingLib; } } @@ -9848,23 +9877,23 @@ public class PackageManagerService extends IPackageManager.Stub applyDefiningSharedLibraryUpdateLocked(pkg, libInfo, (definingLibrary, dependency) -> { definingLibrary.addDependency(dependency); }); - if (p.getUsesLibraryFiles() != null) { - Collections.addAll(usesLibraryFiles, p.getUsesLibraryFiles()); + if (p.usesLibraryFiles != null) { + Collections.addAll(usesLibraryFiles, p.usesLibraryFiles); } } } @GuardedBy("mLock") - private void updateSharedLibrariesLocked(AndroidPackage pkg, - AndroidPackage changingLib, Map<String, AndroidPackage> availablePackages) + private void updateSharedLibrariesLocked(PackageParser.Package pkg, + PackageParser.Package changingLib, Map<String, PackageParser.Package> availablePackages) throws PackageManagerException { final ArrayList<SharedLibraryInfo> sharedLibraryInfos = collectSharedLibraryInfos(pkg, availablePackages, mSharedLibraries, null); executeSharedLibrariesUpdateLPr(pkg, changingLib, sharedLibraryInfos); } - private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(AndroidPackage pkg, - Map<String, AndroidPackage> availablePackages, + private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(PackageParser.Package pkg, + Map<String, PackageParser.Package> availablePackages, @NonNull final Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries, @Nullable final Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries) throws PackageManagerException { @@ -9875,45 +9904,44 @@ public class PackageManagerService extends IPackageManager.Stub // that libraries are searched in the correct order) and must have no // duplicates. ArrayList<SharedLibraryInfo> usesLibraryInfos = null; - if (pkg.getUsesLibraries() != null) { - usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesLibraries(), null, null, - pkg.getPackageName(), true, pkg.getTargetSdkVersion(), null, + if (pkg.usesLibraries != null) { + usesLibraryInfos = collectSharedLibraryInfos(pkg.usesLibraries, null, null, + pkg.packageName, true, pkg.applicationInfo.targetSdkVersion, null, availablePackages, existingLibraries, newLibraries); } - if (pkg.getUsesStaticLibraries() != null) { - usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesStaticLibraries(), - pkg.getUsesStaticLibrariesVersions(), pkg.getUsesStaticLibrariesCertDigests(), - pkg.getPackageName(), true, pkg.getTargetSdkVersion(), usesLibraryInfos, + if (pkg.usesStaticLibraries != null) { + usesLibraryInfos = collectSharedLibraryInfos(pkg.usesStaticLibraries, + pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests, + pkg.packageName, true, pkg.applicationInfo.targetSdkVersion, usesLibraryInfos, availablePackages, existingLibraries, newLibraries); } - if (pkg.getUsesOptionalLibraries() != null) { - usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalLibraries(), - null, null, pkg.getPackageName(), false, pkg.getTargetSdkVersion(), + if (pkg.usesOptionalLibraries != null) { + usesLibraryInfos = collectSharedLibraryInfos(pkg.usesOptionalLibraries, + null, null, pkg.packageName, false, pkg.applicationInfo.targetSdkVersion, usesLibraryInfos, availablePackages, existingLibraries, newLibraries); } return usesLibraryInfos; } - private void executeSharedLibrariesUpdateLPr(AndroidPackage pkg, - AndroidPackage changingLib, ArrayList<SharedLibraryInfo> usesLibraryInfos) { + private void executeSharedLibrariesUpdateLPr(PackageParser.Package pkg, + PackageParser.Package changingLib, ArrayList<SharedLibraryInfo> usesLibraryInfos) { // If the package provides libraries, clear their old dependencies. // This method will set them up again. applyDefiningSharedLibraryUpdateLocked(pkg, null, (definingLibrary, dependency) -> { definingLibrary.clearDependencies(); }); if (usesLibraryInfos != null) { - pkg.mutate().setUsesLibraryInfos(usesLibraryInfos); + pkg.usesLibraryInfos = usesLibraryInfos; // Use LinkedHashSet to preserve the order of files added to // usesLibraryFiles while eliminating duplicates. Set<String> usesLibraryFiles = new LinkedHashSet<>(); for (SharedLibraryInfo libInfo : usesLibraryInfos) { addSharedLibraryLPr(pkg, usesLibraryFiles, libInfo, changingLib); } - pkg.mutate().setUsesLibraryFiles(usesLibraryFiles.toArray( - new String[usesLibraryFiles.size()])); + pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]); } else { - pkg.mutate().setUsesLibraryInfos(null) - .setUsesLibraryFiles(null); + pkg.usesLibraryInfos = null; + pkg.usesLibraryFiles = null; } } @@ -9923,7 +9951,7 @@ public class PackageManagerService extends IPackageManager.Stub @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests, @NonNull String packageName, boolean required, int targetSdk, @Nullable ArrayList<SharedLibraryInfo> outUsedLibraries, - @NonNull final Map<String, AndroidPackage> availablePackages, + @NonNull final Map<String, PackageParser.Package> availablePackages, @NonNull final Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries, @Nullable final Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries) throws PackageManagerException { @@ -9952,8 +9980,8 @@ public class PackageManagerService extends IPackageManager.Stub + " library " + libName + " version " + libraryInfo.getLongVersion() + "; failing!"); } - AndroidPackage pkg = availablePackages.get(libraryInfo.getPackageName()); - SigningDetails libPkg = pkg == null ? null : pkg.getSigningDetails(); + PackageParser.Package libPkg = + availablePackages.get(libraryInfo.getPackageName()); if (libPkg == null) { throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, "Package " + packageName + " requires unavailable static shared" @@ -9964,9 +9992,9 @@ public class PackageManagerService extends IPackageManager.Stub // For apps targeting O MR1 we require explicit enumeration of all certs. final String[] libCertDigests = (targetSdk >= Build.VERSION_CODES.O_MR1) ? PackageUtils.computeSignaturesSha256Digests( - libPkg.signatures) + libPkg.mSigningDetails.signatures) : PackageUtils.computeSignaturesSha256Digests( - new Signature[]{libPkg.signatures[0]}); + new Signature[]{libPkg.mSigningDetails.signatures[0]}); // Take a shortcut if sizes don't match. Note that if an app doesn't // target O we don't parse the "additional-certificate" tags similarly @@ -9996,7 +10024,7 @@ public class PackageManagerService extends IPackageManager.Stub // if the new one has been blessed by the old byte[] digestBytes = HexEncoding.decode( expectedCertDigests[0], false /* allowSingleChar */); - if (!libPkg.hasSha256Certificate(digestBytes)) { + if (!libPkg.mSigningDetails.hasSha256Certificate(digestBytes)) { throw new PackageManagerException( INSTALL_FAILED_MISSING_SHARED_LIBRARY, "Package " + packageName + " requires differently signed" + @@ -10028,28 +10056,28 @@ public class PackageManagerService extends IPackageManager.Stub } @GuardedBy("mLock") - private ArrayList<AndroidPackage> updateAllSharedLibrariesLocked( - AndroidPackage updatedPkg, - Map<String, AndroidPackage> availablePackages) { - ArrayList<AndroidPackage> resultList = null; + private ArrayList<PackageParser.Package> updateAllSharedLibrariesLocked( + PackageParser.Package updatedPkg, + Map<String, PackageParser.Package> availablePackages) { + ArrayList<PackageParser.Package> resultList = null; // Set of all descendants of a library; used to eliminate cycles ArraySet<String> descendants = null; // The current list of packages that need updating - ArrayList<AndroidPackage> needsUpdating = null; + ArrayList<PackageParser.Package> needsUpdating = null; if (updatedPkg != null) { needsUpdating = new ArrayList<>(1); needsUpdating.add(updatedPkg); } do { - final AndroidPackage changingPkg = + final PackageParser.Package changingPkg = (needsUpdating == null) ? null : needsUpdating.remove(0); for (int i = mPackages.size() - 1; i >= 0; --i) { - final AndroidPackage pkg = mPackages.valueAt(i); + final PackageParser.Package pkg = mPackages.valueAt(i); if (changingPkg != null - && !hasString(pkg.getUsesLibraries(), changingPkg.getLibraryNames()) - && !hasString(pkg.getUsesOptionalLibraries(), changingPkg.getLibraryNames()) - && !ArrayUtils.contains(pkg.getUsesStaticLibraries(), - changingPkg.getStaticSharedLibName())) { + && !hasString(pkg.usesLibraries, changingPkg.libraryNames) + && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames) + && !ArrayUtils.contains(pkg.usesStaticLibraries, + changingPkg.staticSharedLibName)) { continue; } if (resultList == null) { @@ -10061,8 +10089,8 @@ public class PackageManagerService extends IPackageManager.Stub if (descendants == null) { descendants = new ArraySet<>(); } - if (!descendants.contains(pkg.getPackageName())) { - descendants.add(pkg.getPackageName()); + if (!descendants.contains(pkg.packageName)) { + descendants.add(pkg.packageName); needsUpdating.add(pkg); } } @@ -10077,9 +10105,8 @@ public class PackageManagerService extends IPackageManager.Stub if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) { final int flags = pkg.isUpdatedSystemApp() ? PackageManager.DELETE_KEEP_DATA : 0; - deletePackageLIF(pkg.getPackageName(), null, true, - mUserManager.getUserIds(), flags, null, - true, null); + deletePackageLIF(pkg.packageName, null, true, mUserManager.getUserIds(), + flags , null, true, null); } Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); } @@ -10089,15 +10116,43 @@ public class PackageManagerService extends IPackageManager.Stub } @GuardedBy({"mInstallLock", "mLock"}) - private ScanResult scanPackageTracedLI(ParsedPackage parsedPackage, + private List<ScanResult> scanPackageTracedLI(PackageParser.Package pkg, final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime, @Nullable UserHandle user) throws PackageManagerException { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); + // If the package has children and this is the first dive in the function + // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see + // whether all packages (parent and children) would be successfully scanned + // before the actual scan since scanning mutates internal state and we want + // to atomically install the package and its children. + if ((scanFlags & SCAN_CHECK_ONLY) == 0) { + if (pkg.childPackages != null && pkg.childPackages.size() > 0) { + scanFlags |= SCAN_CHECK_ONLY; + } + } else { + scanFlags &= ~SCAN_CHECK_ONLY; + } + + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + final List<ScanResult> scanResults = new ArrayList<>(1 + childCount); try { - return scanPackageNewLI(parsedPackage, parseFlags, scanFlags, currentTime, user); + // Scan the parent + scanResults.add(scanPackageNewLI(pkg, parseFlags, scanFlags, currentTime, user)); + // Scan the children + for (int i = 0; i < childCount; i++) { + PackageParser.Package childPkg = pkg.childPackages.get(i); + scanResults.add(scanPackageNewLI(childPkg, parseFlags, + scanFlags, currentTime, user)); + } } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } + + if ((scanFlags & SCAN_CHECK_ONLY) != 0) { + return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user); + } + + return scanResults; } /** The result of a package scan. */ @@ -10144,9 +10199,9 @@ public class PackageManagerService extends IPackageManager.Stub @VisibleForTesting static class ScanRequest { /** The parsed package */ - @NonNull public final ParsedPackage parsedPackage; + @NonNull public final PackageParser.Package pkg; /** The package this package replaces */ - @Nullable public final AndroidPackage oldPkg; + @Nullable public final PackageParser.Package oldPkg; /** Shared user settings, if the package has a shared user */ @Nullable public final SharedUserSetting sharedUserSetting; /** @@ -10170,9 +10225,9 @@ public class PackageManagerService extends IPackageManager.Stub /** Whether or not the platform package is being scanned */ public final boolean isPlatformPackage; public ScanRequest( - @NonNull ParsedPackage parsedPackage, + @NonNull PackageParser.Package pkg, @Nullable SharedUserSetting sharedUserSetting, - @Nullable AndroidPackage oldPkg, + @Nullable PackageParser.Package oldPkg, @Nullable PackageSetting pkgSetting, @Nullable PackageSetting disabledPkgSetting, @Nullable PackageSetting originalPkgSetting, @@ -10181,7 +10236,7 @@ public class PackageManagerService extends IPackageManager.Stub @ScanFlags int scanFlags, boolean isPlatformPackage, @Nullable UserHandle user) { - this.parsedPackage = parsedPackage; + this.pkg = pkg; this.oldPkg = oldPkg; this.pkgSetting = pkgSetting; this.sharedUserSetting = sharedUserSetting; @@ -10214,7 +10269,7 @@ public class PackageManagerService extends IPackageManager.Stub */ private @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags, PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user, - AndroidPackage pkg) { + PackageParser.Package pkg) { // TODO(patb): Do away entirely with disabledPkgSetting here. PkgSetting will always contain // the correct isSystem value now that we don't disable system packages before scan. @@ -10266,14 +10321,12 @@ public class PackageManagerService extends IPackageManager.Stub && SystemProperties.getInt("ro.vndk.version", 28) < 28; if (((scanFlags & SCAN_AS_PRIVILEGED) == 0) && !pkg.isPrivileged() - && (pkg.getSharedUserId() != null) + && (pkg.mSharedUserId != null) && !skipVendorPrivilegeScan) { SharedUserSetting sharedUserSetting = null; try { - sharedUserSetting = mSettings.getSharedUserLPw(pkg.getSharedUserId(), 0, - 0, false); - } catch (PackageManagerException ignore) { - } + sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false); + } catch (PackageManagerException ignore) {} if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) { // Exempt SharedUsers signed with the platform key. // TODO(b/72378145) Fix this exemption. Force signature apps @@ -10282,8 +10335,7 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mLock) { PackageSetting platformPkgSetting = mSettings.mPackages.get("android"); if ((compareSignatures(platformPkgSetting.signatures.mSigningDetails.signatures, - pkg.getSigningDetails().signatures) - != PackageManager.SIGNATURE_MATCH)) { + pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH)) { scanFlags |= SCAN_AS_PRIVILEGED; } } @@ -10298,50 +10350,46 @@ public class PackageManagerService extends IPackageManager.Stub // method. Also, we need to solve the problem of potentially creating a new shared user // setting. That can probably be done later and patch things up after the fact. @GuardedBy({"mInstallLock", "mLock"}) - private ScanResult scanPackageNewLI(@NonNull ParsedPackage parsedPackage, + private ScanResult scanPackageNewLI(@NonNull PackageParser.Package pkg, final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime, @Nullable UserHandle user) throws PackageManagerException { - final String renamedPkgName = mSettings.getRenamedPackageLPr( - parsedPackage.getRealPackage()); - final String realPkgName = getRealPackageName(parsedPackage, renamedPkgName); + final String renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage); + final String realPkgName = getRealPackageName(pkg, renamedPkgName); if (realPkgName != null) { - ensurePackageRenamed(parsedPackage, renamedPkgName); + ensurePackageRenamed(pkg, renamedPkgName); } - final PackageSetting originalPkgSetting = getOriginalPackageLocked(parsedPackage, - renamedPkgName); - final PackageSetting pkgSetting = mSettings.getPackageLPr(parsedPackage.getPackageName()); + final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName); + final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.packageName); final PackageSetting disabledPkgSetting = - mSettings.getDisabledSystemPkgLPr(parsedPackage.getPackageName()); + mSettings.getDisabledSystemPkgLPr(pkg.packageName); - if (mTransferedPackages.contains(parsedPackage.getPackageName())) { - Slog.w(TAG, "Package " + parsedPackage.getPackageName() + if (mTransferedPackages.contains(pkg.packageName)) { + Slog.w(TAG, "Package " + pkg.packageName + " was transferred to another, but its .apk remains"); } - scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, parsedPackage); + scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, pkg); synchronized (mLock) { - applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage); - assertPackageIsValid(parsedPackage, parseFlags, scanFlags); + applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage); + assertPackageIsValid(pkg, parseFlags, scanFlags); SharedUserSetting sharedUserSetting = null; - if (parsedPackage.getSharedUserId() != null) { + if (pkg.mSharedUserId != null) { // SIDE EFFECTS; may potentially allocate a new shared user - sharedUserSetting = mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(), - 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/); + sharedUserSetting = mSettings.getSharedUserLPw( + pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/); if (DEBUG_PACKAGE_SCANNING) { if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) - Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId() + Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + sharedUserSetting.userId + "):" + " packages=" + sharedUserSetting.packages); } } - String platformPackageName = mPlatformPackage == null - ? null : mPlatformPackage.getPackageName(); - final ScanRequest request = new ScanRequest(parsedPackage, sharedUserSetting, + final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting, originalPkgSetting, realPkgName, parseFlags, scanFlags, - Objects.equals(parsedPackage.getPackageName(), platformPackageName), user); + (pkg == mPlatformPackage), user); return scanPackageOnlyLI(request, mInjector, mFactoryTest, currentTime); } } @@ -10384,18 +10432,11 @@ public class PackageManagerService extends IPackageManager.Stub * possible and the system is not left in an inconsistent state. */ @GuardedBy({"mLock", "mInstallLock"}) - private AndroidPackage commitReconciledScanResultLocked( - @NonNull ReconciledPackage reconciledPkg) { + private void commitReconciledScanResultLocked(@NonNull ReconciledPackage reconciledPkg) { final ScanResult result = reconciledPkg.scanResult; final ScanRequest request = result.request; - // TODO(b/135203078): Move this even further away - ParsedPackage parsedPackage = request.parsedPackage; - if ("android".equals(parsedPackage.getPackageName())) { - // TODO(b/135203078): Move this to initial parse - parsedPackage.setVersionCode(mSdkVersion) - .setVersionCodeMajor(0); - } - final AndroidPackage oldPkg = request.oldPkg; + final PackageParser.Package pkg = request.pkg; + final PackageParser.Package oldPkg = request.oldPkg; final @ParseFlags int parseFlags = request.parseFlags; final @ScanFlags int scanFlags = request.scanFlags; final PackageSetting oldPkgSetting = request.oldPkgSetting; @@ -10412,11 +10453,13 @@ public class PackageManagerService extends IPackageManager.Stub if (result.existingSettingCopied) { pkgSetting = request.pkgSetting; pkgSetting.updateFrom(result.pkgSetting); + pkg.mExtras = pkgSetting; } else { pkgSetting = result.pkgSetting; if (originalPkgSetting != null) { - mSettings.addRenamedPackageLPw(parsedPackage.getPackageName(), - originalPkgSetting.name); + mSettings.addRenamedPackageLPw(pkg.packageName, originalPkgSetting.name); + } + if (originalPkgSetting != null && (scanFlags & SCAN_CHECK_ONLY) == 0) { mTransferedPackages.add(originalPkgSetting.name); } } @@ -10429,13 +10472,12 @@ public class PackageManagerService extends IPackageManager.Stub // We need to have this here because addUserToSettingLPw() is sometimes responsible // for creating the application ID. If we did this earlier, we would be saving the // correct ID. - parsedPackage.setUid(pkgSetting.appId); - final AndroidPackage pkg = parsedPackage.hideAsFinal(); + pkg.applicationInfo.uid = pkgSetting.appId; mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting); - if (realPkgName != null) { - mTransferedPackages.add(pkg.getPackageName()); + if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realPkgName != null) { + mTransferedPackages.add(pkg.packageName); } if (reconciledPkg.collectedSharedLibraryInfos != null) { @@ -10444,7 +10486,7 @@ public class PackageManagerService extends IPackageManager.Stub final KeySetManagerService ksms = mSettings.mKeySetManagerService; if (reconciledPkg.removeAppKeySetData) { - ksms.removeAppKeySetDataLPw(pkg.getPackageName()); + ksms.removeAppKeySetDataLPw(pkg.packageName); } if (reconciledPkg.sharedUserSignaturesChanged) { pkgSetting.sharedUser.signaturesChanged = Boolean.TRUE; @@ -10452,17 +10494,17 @@ public class PackageManagerService extends IPackageManager.Stub } pkgSetting.signatures.mSigningDetails = reconciledPkg.signingDetails; - if (pkg.getAdoptPermissions() != null) { + if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { // This package wants to adopt ownership of permissions from // another package. - for (int i = pkg.getAdoptPermissions().size() - 1; i >= 0; i--) { - final String origName = pkg.getAdoptPermissions().get(i); + for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { + final String origName = pkg.mAdoptPermissions.get(i); final PackageSetting orig = mSettings.getPackageLPr(origName); if (orig != null) { if (verifyPackageUpdateLPr(orig, pkg)) { Slog.i(TAG, "Adopting permissions from " + origName + " to " - + pkg.getPackageName()); - mSettings.mPermissions.transferPermissions(origName, pkg.getPackageName()); + + pkg.packageName); + mSettings.mPermissions.transferPermissions(origName, pkg.packageName); } } } @@ -10479,15 +10521,21 @@ public class PackageManagerService extends IPackageManager.Stub } } - final int userId = user == null ? 0 : user.getIdentifier(); - // Modify state for the given package setting - commitPackageSettings(pkg, oldPkg, pkgSetting, scanFlags, - (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg); - if (pkgSetting.getInstantApp(userId)) { - mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId); + if ((scanFlags & SCAN_CHECK_ONLY) != 0) { + if (oldPkgSetting != null) { + synchronized (mLock) { + mSettings.mPackages.put(oldPkgSetting.name, oldPkgSetting); + } + } + } else { + final int userId = user == null ? 0 : user.getIdentifier(); + // Modify state for the given package setting + commitPackageSettings(pkg, oldPkg, pkgSetting, scanFlags, + (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg); + if (pkgSetting.getInstantApp(userId)) { + mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId); + } } - - return pkg; } /** @@ -10495,19 +10543,18 @@ public class PackageManagerService extends IPackageManager.Stub * <p>This may differ from the package's actual name if the application has already * been installed under one of this package's original names. */ - private static @Nullable String getRealPackageName(@NonNull AndroidPackage pkg, + private static @Nullable String getRealPackageName(@NonNull PackageParser.Package pkg, @Nullable String renamedPkgName) { if (isPackageRenamed(pkg, renamedPkgName)) { - return pkg.getRealPackage(); + return pkg.mRealPackage; } return null; } /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */ - private static boolean isPackageRenamed(@NonNull AndroidPackage pkg, + private static boolean isPackageRenamed(@NonNull PackageParser.Package pkg, @Nullable String renamedPkgName) { - return pkg.getOriginalPackages() != null - && pkg.getOriginalPackages().contains(renamedPkgName); + return pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(renamedPkgName); } /** @@ -10518,14 +10565,14 @@ public class PackageManagerService extends IPackageManager.Stub * shared user [if any]. */ @GuardedBy("mLock") - private @Nullable PackageSetting getOriginalPackageLocked(@NonNull AndroidPackage pkg, + private @Nullable PackageSetting getOriginalPackageLocked(@NonNull PackageParser.Package pkg, @Nullable String renamedPkgName) { if (!isPackageRenamed(pkg, renamedPkgName)) { return null; } - for (int i = ArrayUtils.size(pkg.getOriginalPackages()) - 1; i >= 0; --i) { + for (int i = pkg.mOriginalPackages.size() - 1; i >= 0; --i) { final PackageSetting originalPs = - mSettings.getPackageLPr(pkg.getOriginalPackages().get(i)); + mSettings.getPackageLPr(pkg.mOriginalPackages.get(i)); if (originalPs != null) { // the package is already installed under its original name... // but, should we use it? @@ -10533,18 +10580,18 @@ public class PackageManagerService extends IPackageManager.Stub // the new package is incompatible with the original continue; } else if (originalPs.sharedUser != null) { - if (!originalPs.sharedUser.name.equals(pkg.getSharedUserId())) { + if (!originalPs.sharedUser.name.equals(pkg.mSharedUserId)) { // the shared user id is incompatible with the original Slog.w(TAG, "Unable to migrate data from " + originalPs.name - + " to " + pkg.getPackageName() + ": old uid " + + " to " + pkg.packageName + ": old uid " + originalPs.sharedUser.name - + " differs from " + pkg.getSharedUserId()); + + " differs from " + pkg.mSharedUserId); continue; } // TODO: Add case when shared user id is added [b/28144775] } else { if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " - + pkg.getPackageName() + " to old name " + originalPs.name); + + pkg.packageName + " to old name " + originalPs.name); } return originalPs; } @@ -10557,19 +10604,19 @@ public class PackageManagerService extends IPackageManager.Stub * <p>When we've already installed the package under an original name, update * the new package so we can continue to have the old name. */ - private static void ensurePackageRenamed(@NonNull ParsedPackage parsedPackage, + private static void ensurePackageRenamed(@NonNull PackageParser.Package pkg, @NonNull String renamedPackageName) { - if (parsedPackage.getOriginalPackages() == null - || !parsedPackage.getOriginalPackages().contains(renamedPackageName) - || parsedPackage.getPackageName().equals(renamedPackageName)) { + if (pkg.mOriginalPackages == null + || !pkg.mOriginalPackages.contains(renamedPackageName) + || pkg.packageName.equals(renamedPackageName)) { return; } - parsedPackage.setPackageName(renamedPackageName); + pkg.setPackageName(renamedPackageName); } /** * Applies the adjusted ABI calculated by - * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(Set, AndroidPackage)} to all + * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(Set, PackageParser.Package)} to all * relevant packages and settings. * @param sharedUserSetting The {@code SharedUserSetting} to adjust * @param scannedPackage the package being scanned or null @@ -10577,20 +10624,22 @@ public class PackageManagerService extends IPackageManager.Stub * @return the list of code paths that belong to packages that had their ABIs adjusted. */ private static List<String> applyAdjustedAbiToSharedUser(SharedUserSetting sharedUserSetting, - ParsedPackage scannedPackage, String adjustedAbi) { + PackageParser.Package scannedPackage, String adjustedAbi) { if (scannedPackage != null) { - scannedPackage.setPrimaryCpuAbi(adjustedAbi); + scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; } List<String> changedAbiCodePath = null; for (PackageSetting ps : sharedUserSetting.packages) { - if (scannedPackage == null || !scannedPackage.getPackageName().equals(ps.name)) { + if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { if (ps.primaryCpuAbiString != null) { continue; } ps.primaryCpuAbiString = adjustedAbi; - if (ps.pkg != null && !TextUtils.equals(adjustedAbi, ps.pkg.getPrimaryCpuAbi())) { - ps.pkg.mutate().setPrimaryCpuAbi(adjustedAbi); + if (ps.pkg != null && ps.pkg.applicationInfo != null + && !TextUtils.equals( + adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { + ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; if (DEBUG_ABI_SELECTION) { Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi @@ -10630,7 +10679,7 @@ public class PackageManagerService extends IPackageManager.Stub throws PackageManagerException { final PackageAbiHelper packageAbiHelper = injector.getAbiHelper(); final UserManagerInternal userManager = injector.getUserManagerInternal(); - ParsedPackage parsedPackage = request.parsedPackage; + final PackageParser.Package pkg = request.pkg; PackageSetting pkgSetting = request.pkgSetting; final PackageSetting disabledPkgSetting = request.disabledPkgSetting; final PackageSetting originalPkgSetting = request.originalPkgSetting; @@ -10645,12 +10694,13 @@ public class PackageManagerService extends IPackageManager.Stub if (DEBUG_PACKAGE_SCANNING) { if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) - Log.d(TAG, "Scanning package " + parsedPackage.getPackageName()); + Log.d(TAG, "Scanning package " + pkg.packageName); } // Initialize package source and resource directories - final File destCodeFile = new File(parsedPackage.getAppInfoCodePath()); - final File destResourceFile = new File(parsedPackage.getAppInfoResourcePath()); + final File scanFile = new File(pkg.codePath); + final File destCodeFile = new File(pkg.applicationInfo.getCodePath()); + final File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); // We keep references to the derived CPU Abis from settings in oder to reuse // them in the case where we're not upgrading or booting for the first time. @@ -10669,7 +10719,7 @@ public class PackageManagerService extends IPackageManager.Stub if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) { PackageManagerService.reportSettingsProblem(Log.WARN, - "Package " + parsedPackage.getPackageName() + " shared user changed from " + "Package " + pkg.packageName + " shared user changed from " + (pkgSetting.sharedUser != null ? pkgSetting.sharedUser.name : "<nothing>") + " to " @@ -10679,28 +10729,30 @@ public class PackageManagerService extends IPackageManager.Stub } String[] usesStaticLibraries = null; - if (parsedPackage.getUsesStaticLibraries() != null) { - usesStaticLibraries = new String[parsedPackage.getUsesStaticLibraries().size()]; - parsedPackage.getUsesStaticLibraries().toArray(usesStaticLibraries); + if (pkg.usesStaticLibraries != null) { + usesStaticLibraries = new String[pkg.usesStaticLibraries.size()]; + pkg.usesStaticLibraries.toArray(usesStaticLibraries); } final boolean createNewPackage = (pkgSetting == null); if (createNewPackage) { + final String parentPackageName = (pkg.parentPackage != null) + ? pkg.parentPackage.packageName : null; final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0; // REMOVE SharedUserSetting from method; update in a separate call - pkgSetting = Settings.createNewSetting(parsedPackage.getPackageName(), - originalPkgSetting, disabledPkgSetting, realPkgName, sharedUserSetting, - destCodeFile, destResourceFile, parsedPackage.getNativeLibraryRootDir(), - parsedPackage.getPrimaryCpuAbi(), parsedPackage.getSecondaryCpuAbi(), - parsedPackage.getVersionCode(), parsedPackage.getFlags(), - parsedPackage.getPrivateFlags(), user, true /*allowInstall*/, instantApp, - virtualPreload, UserManagerService.getInstance(), usesStaticLibraries, - parsedPackage.getUsesStaticLibrariesVersions()); + pkgSetting = Settings.createNewSetting(pkg.packageName, originalPkgSetting, + disabledPkgSetting, realPkgName, sharedUserSetting, destCodeFile, + destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, + pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi, + pkg.mVersionCode, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, + user, true /*allowInstall*/, instantApp, virtualPreload, + parentPackageName, pkg.getChildPackageNames(), + UserManagerService.getInstance(), usesStaticLibraries, + pkg.usesStaticLibrariesVersions); } else { // make a deep copy to avoid modifying any existing system state. pkgSetting = new PackageSetting(pkgSetting); - // TODO(b/135203078): Remove entirely. Set package directly. - parsedPackage.setPackageSettingCallback(pkgSetting); + pkgSetting.pkg = pkg; // REMOVE SharedUserSetting from method; update in a separate call. // @@ -10708,18 +10760,18 @@ public class PackageManagerService extends IPackageManager.Stub // secondaryCpuAbi are not known at this point so we always update them // to null here, only to reset them at a later point. Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting, - destCodeFile, destResourceFile, parsedPackage.getNativeLibraryDir(), - parsedPackage.getPrimaryCpuAbi(), parsedPackage.getSecondaryCpuAbi(), - parsedPackage.getFlags(), parsedPackage.getPrivateFlags(), - UserManagerService.getInstance(), - usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions()); + destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryDir, + pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi, + pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, + pkg.getChildPackageNames(), UserManagerService.getInstance(), + usesStaticLibraries, pkg.usesStaticLibrariesVersions); } if (createNewPackage && originalPkgSetting != null) { // This is the initial transition from the original package, so, // fix up the new package's name now. We must do this after looking // up the package under its new name, so getPackageLP takes care of // fiddling things correctly. - parsedPackage.setPackageName(originalPkgSetting.name); + pkg.setPackageName(originalPkgSetting.name); // File a report about this. String msg = "New package " + pkgSetting.realName @@ -10738,7 +10790,7 @@ public class PackageManagerService extends IPackageManager.Stub if (disabledPkgSetting != null || (0 != (scanFlags & SCAN_NEW_INSTALL) && pkgSetting != null && pkgSetting.isSystem())) { - parsedPackage.mutate().setUpdatedSystemApp(true); + pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; } // Apps which share a sharedUserId must be placed in the same selinux domain. If this @@ -10750,72 +10802,68 @@ public class PackageManagerService extends IPackageManager.Stub // will NOT be modified until next boot, even if a lower targetSdkVersion is used. This // ensures that all packages continue to run in the same selinux domain. final int targetSdkVersion = - ((sharedUserSetting != null) && (sharedUserSetting.packages.size() != 0)) ? - sharedUserSetting.seInfoTargetSdkVersion - : parsedPackage.getTargetSdkVersion(); + ((sharedUserSetting != null) && (sharedUserSetting.packages.size() != 0)) ? + sharedUserSetting.seInfoTargetSdkVersion : pkg.applicationInfo.targetSdkVersion; // TODO(b/71593002): isPrivileged for sharedUser and appInfo should never be out of sync. // They currently can be if the sharedUser apps are signed with the platform key. final boolean isPrivileged = (sharedUserSetting != null) ? - sharedUserSetting.isPrivileged() | parsedPackage.isPrivileged() - : parsedPackage.isPrivileged(); - - parsedPackage.setSeInfo( - SELinuxMMAC.getSeInfo(parsedPackage, isPrivileged, targetSdkVersion)) - .setSeInfoUser( - SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState( - userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId))) - .setProcessName(fixProcessName( - parsedPackage.getPackageName(), - parsedPackage.getProcessName())); + sharedUserSetting.isPrivileged() | pkg.isPrivileged() : pkg.isPrivileged(); + + pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo(pkg, isPrivileged, + targetSdkVersion); + pkg.applicationInfo.seInfoUser = SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState( + userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId)); + + pkg.mExtras = pkgSetting; + pkg.applicationInfo.processName = fixProcessName( + pkg.applicationInfo.packageName, + pkg.applicationInfo.processName); if (!isPlatformPackage) { // Get all of our default paths setup - parsedPackage.initForUser(UserHandle.USER_SYSTEM); + pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); } - final String cpuAbiOverride = deriveAbiOverride(parsedPackage.getCpuAbiOverride(), - pkgSetting); + final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); if ((scanFlags & SCAN_NEW_INSTALL) == 0) { if (needToDeriveAbi) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi"); - final boolean extractNativeLibs = !parsedPackage.isLibrary(); + final boolean extractNativeLibs = !pkg.isLibrary(); final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> derivedAbi = - packageAbiHelper.derivePackageAbi(parsedPackage, cpuAbiOverride, - extractNativeLibs); - derivedAbi.first.applyTo(parsedPackage); - derivedAbi.second.applyTo(parsedPackage); + packageAbiHelper.derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs); + derivedAbi.first.applyTo(pkg); + derivedAbi.second.applyTo(pkg); Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); // Some system apps still use directory structure for native libraries // in which case we might end up not detecting abi solely based on apk // structure. Try to detect abi based on directory structure. - if (isSystemApp(parsedPackage) && !parsedPackage.isUpdatedSystemApp() && - parsedPackage.getPrimaryCpuAbi() == null) { + if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && + pkg.applicationInfo.primaryCpuAbi == null) { final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis( - parsedPackage); - abis.applyTo(parsedPackage); + pkg); + abis.applyTo(pkg); abis.applyTo(pkgSetting); final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths = - packageAbiHelper.getNativeLibraryPaths(parsedPackage, - sAppLib32InstallDir); - nativeLibraryPaths.applyTo(parsedPackage); + packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir); + nativeLibraryPaths.applyTo(pkg); } } else { // This is not a first boot or an upgrade, don't bother deriving the // ABI during the scan. Instead, trust the value that was stored in the // package setting. - parsedPackage.setPrimaryCpuAbi(primaryCpuAbiFromSettings) - .setSecondaryCpuAbi(secondaryCpuAbiFromSettings); + pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings; + pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings; final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths = - packageAbiHelper.getNativeLibraryPaths(parsedPackage, sAppLib32InstallDir); - nativeLibraryPaths.applyTo(parsedPackage); + packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir); + nativeLibraryPaths.applyTo(pkg); if (DEBUG_ABI_SELECTION) { Slog.i(TAG, "Using ABIS and native lib paths from settings : " + - parsedPackage.getPackageName() + " " + parsedPackage.getPrimaryCpuAbi() - + ", " + parsedPackage.getSecondaryCpuAbi()); + pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " + + pkg.applicationInfo.secondaryCpuAbi); } } } else { @@ -10823,8 +10871,8 @@ public class PackageManagerService extends IPackageManager.Stub // We haven't run dex-opt for this move (since we've moved the compiled output too) // but we already have this packages package info in the PackageSetting. We just // use that and derive the native library path based on the new codepath. - parsedPackage.setPrimaryCpuAbi(pkgSetting.primaryCpuAbiString) - .setSecondaryCpuAbi(pkgSetting.secondaryCpuAbiString); + pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; + pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; } // Set native library paths again. For moves, the path will be updated based on the @@ -10832,8 +10880,8 @@ public class PackageManagerService extends IPackageManager.Stub // ABIs we determined during compilation, but the path will depend on the final // package path (after the rename away from the stage path). final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths = - packageAbiHelper.getNativeLibraryPaths(parsedPackage, sAppLib32InstallDir); - nativeLibraryPaths.applyTo(parsedPackage); + packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir); + nativeLibraryPaths.applyTo(pkg); } // This is a special case for the "system" package, where the ABI is @@ -10841,8 +10889,8 @@ public class PackageManagerService extends IPackageManager.Stub // of this ABI so that we can deal with "normal" applications that run under // the same UID correctly. if (isPlatformPackage) { - parsedPackage.setPrimaryCpuAbi(VMRuntime.getRuntime().is64Bit() ? - Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]); + pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? + Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; } // If there's a mismatch between the abi-override in the package setting @@ -10850,34 +10898,34 @@ public class PackageManagerService extends IPackageManager.Stub // would've already compiled the app without taking the package setting into // account. if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { - if (cpuAbiOverride == null && parsedPackage.getPackageName() != null) { + if (cpuAbiOverride == null && pkg.packageName != null) { Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + - " for package " + parsedPackage.getPackageName()); + " for package " + pkg.packageName); } } - pkgSetting.primaryCpuAbiString = parsedPackage.getPrimaryCpuAbi(); - pkgSetting.secondaryCpuAbiString = parsedPackage.getSecondaryCpuAbi(); + pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; + pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; pkgSetting.cpuAbiOverrideString = cpuAbiOverride; // Copy the derived override back to the parsed package, so that we can // update the package settings accordingly. - parsedPackage.setCpuAbiOverride(cpuAbiOverride); + pkg.cpuAbiOverride = cpuAbiOverride; if (DEBUG_ABI_SELECTION) { - Slog.d(TAG, "Resolved nativeLibraryRoot for " + parsedPackage.getPackageName() - + " to root=" + parsedPackage.getNativeLibraryRootDir() + ", isa=" - + parsedPackage.isNativeLibraryRootRequiresIsa()); + Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.packageName + + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" + + pkg.applicationInfo.nativeLibraryRootRequiresIsa); } // Push the derived path down into PackageSettings so we know what to // clean up at uninstall time. - pkgSetting.legacyNativeLibraryPathString = parsedPackage.getNativeLibraryRootDir(); + pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; if (DEBUG_ABI_SELECTION) { - Log.d(TAG, "Abis for package[" + parsedPackage.getPackageName() + "] are" + - " primary=" + parsedPackage.getPrimaryCpuAbi() + - " secondary=" + parsedPackage.getSecondaryCpuAbi()); + Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + + " primary=" + pkg.applicationInfo.primaryCpuAbi + + " secondary=" + pkg.applicationInfo.secondaryCpuAbi); } if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { @@ -10887,20 +10935,22 @@ public class PackageManagerService extends IPackageManager.Stub // We also do this *before* we perform dexopt on this package, so that // we can avoid redundant dexopts, and also to make sure we've got the // code and package path correct. - changedAbiCodePath = applyAdjustedAbiToSharedUser(pkgSetting.sharedUser, parsedPackage, + changedAbiCodePath = applyAdjustedAbiToSharedUser(pkgSetting.sharedUser, pkg, packageAbiHelper.getAdjustedAbiForSharedUser( - pkgSetting.sharedUser.packages, parsedPackage)); + pkgSetting.sharedUser.packages, pkg)); } - parsedPackage.setFactoryTest(isUnderFactoryTest && parsedPackage.getRequestedPermissions() - .contains(android.Manifest.permission.FACTORY_TEST)); + if (isUnderFactoryTest && pkg.requestedPermissions.contains( + android.Manifest.permission.FACTORY_TEST)) { + pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; + } - if (isSystemApp(parsedPackage)) { + if (isSystemApp(pkg)) { pkgSetting.isOrphaned = true; } // Take care of first install / last update times. - final long scanFileTime = getLastModifiedTime(parsedPackage); + final long scanFileTime = getLastModifiedTime(pkg); if (currentTime != 0) { if (pkgSetting.firstInstallTime == 0) { pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; @@ -10918,33 +10968,32 @@ public class PackageManagerService extends IPackageManager.Stub } } pkgSetting.setTimeStamp(scanFileTime); - // TODO(b/135203078): Remove, move to constructor - parsedPackage.setPackageSettingCallback(pkgSetting); - pkgSetting.pkgFlags = parsedPackage.getFlags(); - if (parsedPackage.getLongVersionCode() != pkgSetting.versionCode) { - pkgSetting.versionCode = parsedPackage.getLongVersionCode(); + + pkgSetting.pkg = pkg; + pkgSetting.pkgFlags = pkg.applicationInfo.flags; + if (pkg.getLongVersionCode() != pkgSetting.versionCode) { + pkgSetting.versionCode = pkg.getLongVersionCode(); } // Update volume if needed - final String volumeUuid = parsedPackage.getApplicationInfoVolumeUuid(); + final String volumeUuid = pkg.applicationInfo.volumeUuid; if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) { Slog.i(PackageManagerService.TAG, "Update" + (pkgSetting.isSystem() ? " system" : "") - + " package " + parsedPackage.getPackageName() + + " package " + pkg.packageName + " volume from " + pkgSetting.volumeUuid + " to " + volumeUuid); pkgSetting.volumeUuid = volumeUuid; } SharedLibraryInfo staticSharedLibraryInfo = null; - if (!TextUtils.isEmpty(parsedPackage.getStaticSharedLibName())) { - staticSharedLibraryInfo = SharedLibraryInfo.createForStatic(parsedPackage); + if (!TextUtils.isEmpty(pkg.staticSharedLibName)) { + staticSharedLibraryInfo = SharedLibraryInfo.createForStatic(pkg); } List<SharedLibraryInfo> dynamicSharedLibraryInfos = null; - if (!ArrayUtils.isEmpty(parsedPackage.getLibraryNames())) { - dynamicSharedLibraryInfos = new ArrayList<>(parsedPackage.getLibraryNames().size()); - for (String name : parsedPackage.getLibraryNames()) { - dynamicSharedLibraryInfos.add( - SharedLibraryInfo.createForDynamic(parsedPackage, name)); + if (!ArrayUtils.isEmpty(pkg.libraryNames)) { + dynamicSharedLibraryInfos = new ArrayList<>(pkg.libraryNames.size()); + for (String name : pkg.libraryNames) { + dynamicSharedLibraryInfos.add(SharedLibraryInfo.createForDynamic(pkg, name)); } } @@ -10980,21 +11029,22 @@ public class PackageManagerService extends IPackageManager.Stub * * @throws PackageManagerException If bytecode could not be found when it should exist */ - private static void assertCodePolicy(AndroidPackage pkg) + private static void assertCodePolicy(PackageParser.Package pkg) throws PackageManagerException { - final boolean shouldHaveCode = (pkg.getFlags() & ApplicationInfo.FLAG_HAS_CODE) != 0; - if (shouldHaveCode && !apkHasCode(pkg.getBaseCodePath())) { + final boolean shouldHaveCode = + (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0; + if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, - "Package " + pkg.getBaseCodePath() + " code is missing"); + "Package " + pkg.baseCodePath + " code is missing"); } - if (!ArrayUtils.isEmpty(pkg.getSplitCodePaths())) { - for (int i = 0; i < pkg.getSplitCodePaths().length; i++) { + if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { + for (int i = 0; i < pkg.splitCodePaths.length; i++) { final boolean splitShouldHaveCode = - (pkg.getSplitFlags()[i] & ApplicationInfo.FLAG_HAS_CODE) != 0; - if (splitShouldHaveCode && !apkHasCode(pkg.getSplitCodePaths()[i])) { + (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0; + if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, - "Package " + pkg.getSplitCodePaths()[i] + " code is missing"); + "Package " + pkg.splitCodePaths[i] + " code is missing"); } } } @@ -11007,59 +11057,118 @@ public class PackageManagerService extends IPackageManager.Stub * Implementation detail: This method must NOT have any side effect. It would * ideally be static, but, it requires locks to read system state. */ - private static void applyPolicy(ParsedPackage parsedPackage, final @ParseFlags int parseFlags, - final @ScanFlags int scanFlags, AndroidPackage platformPkg) { + private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags, + final @ScanFlags int scanFlags, PackageParser.Package platformPkg) { if ((scanFlags & SCAN_AS_SYSTEM) != 0) { - parsedPackage.setSystem(true); - // TODO(b/135203078): Can this be done in PackageParser? Or just inferred when the flag - // is set during parse. - if (parsedPackage.isDirectBootAware()) { - parsedPackage.setAllComponentsDirectBootAware(true); + pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; + if (pkg.applicationInfo.isDirectBootAware()) { + // we're direct boot aware; set for all components + for (PackageParser.Service s : pkg.services) { + s.info.directBootAware = true; + } + for (PackageParser.Provider p : pkg.providers) { + p.info.directBootAware = true; + } + for (PackageParser.Activity a : pkg.activities) { + a.info.directBootAware = true; + } + for (PackageParser.Activity r : pkg.receivers) { + r.info.directBootAware = true; + } } - if (compressedFileExists(parsedPackage.getCodePath())) { - parsedPackage.setIsStub(true); + if (compressedFileExists(pkg.codePath)) { + pkg.isStub = true; } } else { - parsedPackage - // non system apps can't be flagged as core - .setCoreApp(false) - // clear flags not applicable to regular apps - .setPersistent(false) - .setDefaultToDeviceProtectedStorage(false) - .setDirectBootAware(false) - // non system apps can't have permission priority - .capPermissionPriorities(); + // non system apps can't be flagged as core + pkg.coreApp = false; + // clear flags not applicable to regular apps + pkg.applicationInfo.flags &= + ~ApplicationInfo.FLAG_PERSISTENT; + pkg.applicationInfo.privateFlags &= + ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; + pkg.applicationInfo.privateFlags &= + ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; + // cap permission priorities + if (pkg.permissionGroups != null && pkg.permissionGroups.size() > 0) { + for (int i = pkg.permissionGroups.size() - 1; i >= 0; --i) { + pkg.permissionGroups.get(i).info.priority = 0; + } + } } if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) { - parsedPackage - .clearProtectedBroadcasts() - .markNotActivitiesAsNotExportedIfSingleUser(); + // clear protected broadcasts + pkg.protectedBroadcasts = null; + // ignore export request for single user receivers + if (pkg.receivers != null) { + for (int i = pkg.receivers.size() - 1; i >= 0; --i) { + final PackageParser.Activity receiver = pkg.receivers.get(i); + if ((receiver.info.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) { + receiver.info.exported = false; + } + } + } + // ignore export request for single user services + if (pkg.services != null) { + for (int i = pkg.services.size() - 1; i >= 0; --i) { + final PackageParser.Service service = pkg.services.get(i); + if ((service.info.flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { + service.info.exported = false; + } + } + } + // ignore export request for single user providers + if (pkg.providers != null) { + for (int i = pkg.providers.size() - 1; i >= 0; --i) { + final PackageParser.Provider provider = pkg.providers.get(i); + if ((provider.info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0) { + provider.info.exported = false; + } + } + } + } + + if ((scanFlags & SCAN_AS_PRIVILEGED) != 0) { + pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; + } + + if ((scanFlags & SCAN_AS_OEM) != 0) { + pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM; + } + + if ((scanFlags & SCAN_AS_VENDOR) != 0) { + pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR; + } + + if ((scanFlags & SCAN_AS_PRODUCT) != 0) { + pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT; + } + + if ((scanFlags & SCAN_AS_SYSTEM_EXT) != 0) { + pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT; } - parsedPackage.setPrivileged((scanFlags & SCAN_AS_PRIVILEGED) != 0) - .setOem((scanFlags & SCAN_AS_OEM) != 0) - .setVendor((scanFlags & SCAN_AS_VENDOR) != 0) - .setProduct((scanFlags & SCAN_AS_PRODUCT) != 0) - .setSystemExt((scanFlags & SCAN_AS_SYSTEM_EXT) != 0) - .setOdm((scanFlags & SCAN_AS_ODM) != 0); + if ((scanFlags & SCAN_AS_ODM) != 0) { + pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ODM; + } // Check if the package is signed with the same key as the platform package. - parsedPackage.setSignedWithPlatformKey( - (PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName()) - || (platformPkg != null && compareSignatures( - platformPkg.getSigningDetails().signatures, - parsedPackage.getSigningDetails().signatures - ) == PackageManager.SIGNATURE_MATCH)) - ); - - if (!isSystemApp(parsedPackage)) { + if (PLATFORM_PACKAGE_NAME.equals(pkg.packageName) || + (platformPkg != null && compareSignatures( + platformPkg.mSigningDetails.signatures, + pkg.mSigningDetails.signatures) == PackageManager.SIGNATURE_MATCH)) { + pkg.applicationInfo.privateFlags |= + ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY; + } + + if (!isSystemApp(pkg)) { // Only system apps can use these features. - parsedPackage.clearOriginalPackages() - .setRealPackage(null) - .clearAdoptPermissions(); + pkg.mOriginalPackages = null; + pkg.mRealPackage = null; + pkg.mAdoptPermissions = null; } - PackageBackwardCompatibility.modifySharedLibraries(parsedPackage); + PackageBackwardCompatibility.modifySharedLibraries(pkg); } private static @NonNull <T> T assertNotNull(@Nullable T object, String message) @@ -11079,15 +11188,15 @@ public class PackageManagerService extends IPackageManager.Stub * * @throws PackageManagerException If the package fails any of the validation checks */ - private void assertPackageIsValid(AndroidPackage pkg, final @ParseFlags int parseFlags, + private void assertPackageIsValid(PackageParser.Package pkg, final @ParseFlags int parseFlags, final @ScanFlags int scanFlags) throws PackageManagerException { if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) { assertCodePolicy(pkg); } - if (pkg.getAppInfoCodePath() == null || - pkg.getAppInfoResourcePath() == null) { + if (pkg.applicationInfo.getCodePath() == null || + pkg.applicationInfo.getResourcePath() == null) { // Bail out. The resource and code paths haven't been set. throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "Code and resource paths haven't been set correctly"); @@ -11098,10 +11207,9 @@ public class PackageManagerService extends IPackageManager.Stub final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0; final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0; if ((isUserInstall || isFirstBootOrUpgrade) - && mApexManager.isApexPackage(pkg.getPackageName())) { + && mApexManager.isApexPackage(pkg.packageName)) { throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, - pkg.getPackageName() - + " is an APEX package and can't be installed as an APK."); + pkg.packageName + " is an APEX package and can't be installed as an APK."); } // Make sure we're not adding any bogus keyset info @@ -11110,11 +11218,11 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mLock) { // The special "android" package can only be defined once - if (pkg.getPackageName().equals("android")) { + if (pkg.packageName.equals("android")) { if (mAndroidApplication != null) { Slog.w(TAG, "*************************************************"); Slog.w(TAG, "Core android package being redefined. Skipping."); - Slog.w(TAG, " codePath=" + pkg.getCodePath()); + Slog.w(TAG, " codePath=" + pkg.codePath); Slog.w(TAG, "*************************************************"); throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, "Core android package being redefined. Skipping."); @@ -11122,24 +11230,23 @@ public class PackageManagerService extends IPackageManager.Stub } // A package name must be unique; don't allow duplicates - if ((scanFlags & SCAN_NEW_INSTALL) == 0 - && mPackages.containsKey(pkg.getPackageName())) { + if ((scanFlags & SCAN_NEW_INSTALL) == 0 && mPackages.containsKey(pkg.packageName)) { throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, - "Application package " + pkg.getPackageName() + "Application package " + pkg.packageName + " already installed. Skipping duplicate."); } - if (pkg.isStaticSharedLibrary()) { + if (pkg.applicationInfo.isStaticSharedLibrary()) { // Static libs have a synthetic package name containing the version // but we still want the base name to be unique. if ((scanFlags & SCAN_NEW_INSTALL) == 0 - && mPackages.containsKey(pkg.getManifestPackageName())) { + && mPackages.containsKey(pkg.manifestPackageName)) { throw new PackageManagerException( "Duplicate static shared lib provider package"); } // Static shared libraries should have at least O target SDK - if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) { + if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) { throw new PackageManagerException( "Packages declaring static-shared libs must target O SDK or higher"); } @@ -11152,67 +11259,73 @@ public class PackageManagerService extends IPackageManager.Stub // Package declaring static a shared lib cannot be renamed since the package // name is synthetic and apps can't code around package manager internals. - if (!ArrayUtils.isEmpty(pkg.getOriginalPackages())) { + if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) { throw new PackageManagerException( "Packages declaring static-shared libs cannot be renamed"); } + // Package declaring static a shared lib cannot declare child packages + if (!ArrayUtils.isEmpty(pkg.childPackages)) { + throw new PackageManagerException( + "Packages declaring static-shared libs cannot have child packages"); + } + // Package declaring static a shared lib cannot declare dynamic libs - if (!ArrayUtils.isEmpty(pkg.getLibraryNames())) { + if (!ArrayUtils.isEmpty(pkg.libraryNames)) { throw new PackageManagerException( "Packages declaring static-shared libs cannot declare dynamic libs"); } // Package declaring static a shared lib cannot declare shared users - if (pkg.getSharedUserId() != null) { + if (pkg.mSharedUserId != null) { throw new PackageManagerException( "Packages declaring static-shared libs cannot declare shared users"); } // Static shared libs cannot declare activities - if (pkg.getActivities() != null && !pkg.getActivities().isEmpty()) { + if (!pkg.activities.isEmpty()) { throw new PackageManagerException( "Static shared libs cannot declare activities"); } // Static shared libs cannot declare services - if (pkg.getServices() != null && !pkg.getServices().isEmpty()) { + if (!pkg.services.isEmpty()) { throw new PackageManagerException( "Static shared libs cannot declare services"); } // Static shared libs cannot declare providers - if (pkg.getProviders() != null && !pkg.getProviders().isEmpty()) { + if (!pkg.providers.isEmpty()) { throw new PackageManagerException( "Static shared libs cannot declare content providers"); } // Static shared libs cannot declare receivers - if (pkg.getReceivers() != null && !pkg.getReceivers().isEmpty()) { + if (!pkg.receivers.isEmpty()) { throw new PackageManagerException( "Static shared libs cannot declare broadcast receivers"); } // Static shared libs cannot declare permission groups - if (pkg.getPermissionGroups() != null && !pkg.getPermissionGroups().isEmpty()) { + if (!pkg.permissionGroups.isEmpty()) { throw new PackageManagerException( "Static shared libs cannot declare permission groups"); } // Static shared libs cannot declare permissions - if (pkg.getPermissions() != null && !pkg.getPermissions().isEmpty()) { + if (!pkg.permissions.isEmpty()) { throw new PackageManagerException( "Static shared libs cannot declare permissions"); } // Static shared libs cannot declare protected broadcasts - if (pkg.getProtectedBroadcasts() != null) { + if (pkg.protectedBroadcasts != null) { throw new PackageManagerException( "Static shared libs cannot declare protected broadcasts"); } // Static shared libs cannot be overlay targets - if (pkg.getOverlayTarget() != null) { + if (pkg.mOverlayTarget != null) { throw new PackageManagerException( "Static shared libs cannot be overlay targets"); } @@ -11222,17 +11335,16 @@ public class PackageManagerService extends IPackageManager.Stub long maxVersionCode = Long.MAX_VALUE; LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get( - pkg.getStaticSharedLibName()); + pkg.staticSharedLibName); if (versionedLib != null) { final int versionCount = versionedLib.size(); for (int i = 0; i < versionCount; i++) { SharedLibraryInfo libInfo = versionedLib.valueAt(i); final long libVersionCode = libInfo.getDeclaringPackage() .getLongVersionCode(); - if (libInfo.getLongVersion() < pkg.getStaticSharedLibVersion()) { + if (libInfo.getLongVersion() < pkg.staticSharedLibVersion) { minVersionCode = Math.max(minVersionCode, libVersionCode + 1); - } else if (libInfo.getLongVersion() - > pkg.getStaticSharedLibVersion()) { + } else if (libInfo.getLongVersion() > pkg.staticSharedLibVersion) { maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1); } else { minVersionCode = maxVersionCode = libVersionCode; @@ -11247,6 +11359,23 @@ public class PackageManagerService extends IPackageManager.Stub } } + // Only privileged apps and updated privileged apps can add child packages. + if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { + if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) { + throw new PackageManagerException("Only privileged apps can add child " + + "packages. Ignoring package " + pkg.packageName); + } + final int childCount = pkg.childPackages.size(); + for (int i = 0; i < childCount; i++) { + PackageParser.Package childPkg = pkg.childPackages.get(i); + if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, + childPkg.packageName)) { + throw new PackageManagerException("Can't override child of " + + "another disabled app. Ignoring package " + pkg.packageName); + } + } + } + // If we're only installing presumed-existing packages, require that the // scanned APK is both already known and at the path previously established // for it. Previously unknown packages we pick up normally, but if we have an @@ -11256,30 +11385,29 @@ public class PackageManagerService extends IPackageManager.Stub // to the user-installed location. If we don't allow this change, any newer, // user-installed version of the application will be ignored. if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { - if (mExpectingBetter.containsKey(pkg.getPackageName())) { + if (mExpectingBetter.containsKey(pkg.packageName)) { logCriticalInfo(Log.WARN, - "Relax SCAN_REQUIRE_KNOWN requirement for package " - + pkg.getPackageName()); + "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); } else { - PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName()); + PackageSetting known = mSettings.getPackageLPr(pkg.packageName); if (known != null) { if (DEBUG_PACKAGE_SCANNING) { - Log.d(TAG, "Examining " + pkg.getCodePath() + Log.d(TAG, "Examining " + pkg.codePath + " and requiring known paths " + known.codePathString + " & " + known.resourcePathString); } - if (!pkg.getAppInfoCodePath().equals(known.codePathString) - || !pkg.getAppInfoResourcePath().equals( + if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) + || !pkg.applicationInfo.getResourcePath().equals( known.resourcePathString)) { throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, - "Application package " + pkg.getPackageName() - + " found at " + pkg.getAppInfoCodePath() + "Application package " + pkg.packageName + + " found at " + pkg.applicationInfo.getCodePath() + " but expected at " + known.codePathString + "; ignoring."); } } else { throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION, - "Application package " + pkg.getPackageName() + "Application package " + pkg.packageName + " not found; ignoring."); } } @@ -11294,13 +11422,11 @@ public class PackageManagerService extends IPackageManager.Stub } // Verify that packages sharing a user with a privileged app are marked as privileged. - if (!pkg.isPrivileged() && (pkg.getSharedUserId() != null)) { + if (!pkg.isPrivileged() && (pkg.mSharedUserId != null)) { SharedUserSetting sharedUserSetting = null; try { - sharedUserSetting = mSettings.getSharedUserLPw(pkg.getSharedUserId(), - 0, 0, false); - } catch (PackageManagerException ignore) { - } + sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false); + } catch (PackageManagerException ignore) {} if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) { // Exempt SharedUsers signed with the platform key. PackageSetting platformPkgSetting = mSettings.mPackages.get("android"); @@ -11308,18 +11434,18 @@ public class PackageManagerService extends IPackageManager.Stub != PackageParser.SigningDetails.UNKNOWN) && (compareSignatures( platformPkgSetting.signatures.mSigningDetails.signatures, - pkg.getSigningDetails().signatures) + pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH)) { throw new PackageManagerException("Apps that share a user with a " + "privileged app must themselves be marked as privileged. " + - pkg.getPackageName() + " shares privileged user " + - pkg.getSharedUserId() + "."); + pkg.packageName + " shares privileged user " + + pkg.mSharedUserId + "."); } } } // Apply policies specific for runtime resource overlays (RROs). - if (pkg.getOverlayTarget() != null) { + if (pkg.mOverlayTarget != null) { // System overlays have some restrictions on their use of the 'static' state. if ((scanFlags & SCAN_AS_SYSTEM) != 0) { // We are scanning a system overlay. This can be the first scan of the @@ -11327,62 +11453,54 @@ public class PackageManagerService extends IPackageManager.Stub if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { // This must be an update to a system overlay. final PackageSetting previousPkg = assertNotNull( - mSettings.getPackageLPr(pkg.getPackageName()), + mSettings.getPackageLPr(pkg.packageName), "previous package state not present"); // previousPkg.pkg may be null: the package will be not be scanned if the // package manager knows there is a newer version on /data. // TODO[b/79435695]: Find a better way to keep track of the "static" // property for RROs instead of having to parse packages on /system - AndroidPackage ppkg = previousPkg.pkg; + PackageParser.Package ppkg = previousPkg.pkg; if (ppkg == null) { try { final PackageParser pp = new PackageParser(); - // TODO(b/135203078): Do we really need to parse here? Maybe use - // a shortened path? - ppkg = pp.parseParsedPackage(previousPkg.codePath, - parseFlags | PackageParser.PARSE_IS_SYSTEM_DIR, - false) - .hideAsFinal(); + ppkg = pp.parsePackage(previousPkg.codePath, + parseFlags | PackageParser.PARSE_IS_SYSTEM_DIR); } catch (PackageParserException e) { Slog.w(TAG, "failed to parse " + previousPkg.codePath, e); } } // Static overlays cannot be updated. - if (ppkg != null && ppkg.isOverlayIsStatic()) { - throw new PackageManagerException("Overlay " - + pkg.getPackageName() - + " is static and cannot be upgraded."); + if (ppkg != null && ppkg.mOverlayIsStatic) { + throw new PackageManagerException("Overlay " + pkg.packageName + + " is static and cannot be upgraded."); // Non-static overlays cannot be converted to static overlays. - } else if (pkg.isOverlayIsStatic()) { - throw new PackageManagerException("Overlay " - + pkg.getPackageName() - + " cannot be upgraded into a static overlay."); + } else if (pkg.mOverlayIsStatic) { + throw new PackageManagerException("Overlay " + pkg.packageName + + " cannot be upgraded into a static overlay."); } } } else { // The overlay is a non-system overlay. Non-system overlays cannot be static. - if (pkg.isOverlayIsStatic()) { - throw new PackageManagerException("Overlay " - + pkg.getPackageName() - + " is static but not pre-installed."); + if (pkg.mOverlayIsStatic) { + throw new PackageManagerException("Overlay " + pkg.packageName + + " is static but not pre-installed."); } // A non-preloaded overlay packages must have targetSdkVersion >= Q, or be // signed with the platform certificate. Check this in increasing order of // computational cost. - if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) { + if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.Q) { final PackageSetting platformPkgSetting = mSettings.getPackageLPr("android"); if ((platformPkgSetting.signatures.mSigningDetails != PackageParser.SigningDetails.UNKNOWN) && (compareSignatures( platformPkgSetting.signatures.mSigningDetails.signatures, - pkg.getSigningDetails().signatures) + pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH)) { - throw new PackageManagerException("Overlay " - + pkg.getPackageName() + throw new PackageManagerException("Overlay " + pkg.packageName + " must target Q or later, " + "or be signed with the platform certificate"); } @@ -11392,19 +11510,18 @@ public class PackageManagerService extends IPackageManager.Stub // only be used if it is signed with the same certificate as its target. If the // target is already installed, check this here to augment the last line of // defence which is OMS. - if (pkg.getOverlayTargetName() == null) { + if (pkg.mOverlayTargetName == null) { final PackageSetting targetPkgSetting = - mSettings.getPackageLPr(pkg.getOverlayTarget()); + mSettings.getPackageLPr(pkg.mOverlayTarget); if (targetPkgSetting != null) { if ((targetPkgSetting.signatures.mSigningDetails != PackageParser.SigningDetails.UNKNOWN) && (compareSignatures( targetPkgSetting.signatures.mSigningDetails.signatures, - pkg.getSigningDetails().signatures) + pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH)) { - throw new PackageManagerException("Overlay " - + pkg.getPackageName() + " and target " - + pkg.getOverlayTarget() + " signed with" + throw new PackageManagerException("Overlay " + pkg.packageName + + " and target " + pkg.mOverlayTarget + " signed with" + " different certificates, and the overlay lacks" + " <overlay android:targetName>"); } @@ -11484,67 +11601,71 @@ public class PackageManagerService extends IPackageManager.Stub * Adds a scanned package to the system. When this method is finished, the package will * be available for query, resolution, etc... */ - private void commitPackageSettings(AndroidPackage pkg, - @Nullable AndroidPackage oldPkg, PackageSetting pkgSetting, + private void commitPackageSettings(PackageParser.Package pkg, + @Nullable PackageParser.Package oldPkg, PackageSetting pkgSetting, final @ScanFlags int scanFlags, boolean chatty, ReconciledPackage reconciledPkg) { - final String pkgName = pkg.getPackageName(); + final String pkgName = pkg.packageName; if (mCustomResolverComponentName != null && - mCustomResolverComponentName.getPackageName().equals(pkg.getPackageName())) { + mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { setUpCustomResolverActivity(pkg); } - if (pkg.getPackageName().equals("android")) { + if (pkg.packageName.equals("android")) { synchronized (mLock) { - // Set up information for our fall-back user intent resolution activity. - mPlatformPackage = pkg; - mAndroidApplication = pkg.toAppInfo(); - if (!mResolverReplaced) { - mResolveActivity.applicationInfo = mAndroidApplication; - mResolveActivity.name = ResolverActivity.class.getName(); - mResolveActivity.packageName = mAndroidApplication.packageName; - mResolveActivity.processName = "system:ui"; - mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; - mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; - mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; - mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert; - mResolveActivity.exported = true; - mResolveActivity.enabled = true; - mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; - mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE - | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE - | ActivityInfo.CONFIG_SCREEN_LAYOUT - | ActivityInfo.CONFIG_ORIENTATION - | ActivityInfo.CONFIG_KEYBOARD - | ActivityInfo.CONFIG_KEYBOARD_HIDDEN; - mResolveInfo.activityInfo = mResolveActivity; - mResolveInfo.priority = 0; - mResolveInfo.preferredOrder = 0; - mResolveInfo.match = 0; - mResolveComponentName = new ComponentName( - mAndroidApplication.packageName, mResolveActivity.name); - } - } - } - - ArrayList<AndroidPackage> clientLibPkgs = null; + if ((scanFlags & SCAN_CHECK_ONLY) == 0) { + // Set up information for our fall-back user intent resolution activity. + mPlatformPackage = pkg; + pkg.mVersionCode = mSdkVersion; + pkg.mVersionCodeMajor = 0; + mAndroidApplication = pkg.applicationInfo; + if (!mResolverReplaced) { + mResolveActivity.applicationInfo = mAndroidApplication; + mResolveActivity.name = ResolverActivity.class.getName(); + mResolveActivity.packageName = mAndroidApplication.packageName; + mResolveActivity.processName = "system:ui"; + mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; + mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; + mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; + mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert; + mResolveActivity.exported = true; + mResolveActivity.enabled = true; + mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; + mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE + | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE + | ActivityInfo.CONFIG_SCREEN_LAYOUT + | ActivityInfo.CONFIG_ORIENTATION + | ActivityInfo.CONFIG_KEYBOARD + | ActivityInfo.CONFIG_KEYBOARD_HIDDEN; + mResolveInfo.activityInfo = mResolveActivity; + mResolveInfo.priority = 0; + mResolveInfo.preferredOrder = 0; + mResolveInfo.match = 0; + mResolveComponentName = new ComponentName( + mAndroidApplication.packageName, mResolveActivity.name); + } + } + } + } + + ArrayList<PackageParser.Package> clientLibPkgs = null; // writer synchronized (mLock) { if (!ArrayUtils.isEmpty(reconciledPkg.allowedSharedLibraryInfos)) { for (SharedLibraryInfo info : reconciledPkg.allowedSharedLibraryInfos) { commitSharedLibraryInfoLocked(info); } - final Map<String, AndroidPackage> combinedSigningDetails = - reconciledPkg.getCombinedAvailablePackages(); + final Map<String, PackageParser.Package> combinedPackages = + reconciledPkg.getCombinedPackages(); try { // Shared libraries for the package need to be updated. - updateSharedLibrariesLocked(pkg, null, combinedSigningDetails); + updateSharedLibrariesLocked(pkg, null, combinedPackages); } catch (PackageManagerException e) { Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e); } // Update all applications that use this library. Skip when booting // since this will be done after all packages are scaned. if ((scanFlags & SCAN_BOOTING) == 0) { - clientLibPkgs = updateAllSharedLibrariesLocked(pkg, combinedSigningDetails); + clientLibPkgs = updateAllSharedLibrariesLocked(pkg, combinedPackages); } } } @@ -11568,9 +11689,9 @@ public class PackageManagerService extends IPackageManager.Stub // Also need to kill any apps that are dependent on the library. if (clientLibPkgs != null) { for (int i=0; i<clientLibPkgs.size(); i++) { - AndroidPackage clientPkg = clientLibPkgs.get(i); - killApplication(clientPkg.getAppInfoPackageName(), - clientPkg.getUid(), "update lib"); + PackageParser.Package clientPkg = clientLibPkgs.get(i); + killApplication(clientPkg.applicationInfo.packageName, + clientPkg.applicationInfo.uid, "update lib"); } } @@ -11583,7 +11704,7 @@ public class PackageManagerService extends IPackageManager.Stub // Add the new setting to mSettings mSettings.insertPackageSettingLPw(pkgSetting, pkg); // Add the new setting to mPackages - mPackages.put(pkg.getAppInfoPackageName(), pkg); + mPackages.put(pkg.applicationInfo.packageName, pkg); // Add the package's KeySets to the global KeySetManagerService KeySetManagerService ksms = mSettings.mKeySetManagerService; @@ -11594,7 +11715,7 @@ public class PackageManagerService extends IPackageManager.Stub // Don't allow ephemeral applications to define new permissions groups. if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { - Slog.w(TAG, "Permission groups from package " + pkg.getPackageName() + Slog.w(TAG, "Permission groups from package " + pkg.packageName + " ignored: instant apps cannot define new permission groups."); } else { mPermissionManager.addAllPermissionGroups(pkg, chatty); @@ -11602,31 +11723,31 @@ public class PackageManagerService extends IPackageManager.Stub // Don't allow ephemeral applications to define new permissions. if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { - Slog.w(TAG, "Permissions from package " + pkg.getPackageName() + Slog.w(TAG, "Permissions from package " + pkg.packageName + " ignored: instant apps cannot define new permissions."); } else { mPermissionManager.addAllPermissions(pkg, chatty); } - int collectionSize = ArrayUtils.size(pkg.getInstrumentations()); + int collectionSize = pkg.instrumentation.size(); StringBuilder r = null; int i; for (i = 0; i < collectionSize; i++) { - ParsedInstrumentation a = pkg.getInstrumentations().get(i); - a.setPackageName(pkg.getAppInfoPackageName()); - a.sourceDir = pkg.getBaseCodePath(); - a.publicSourceDir = pkg.getPublicSourceDir(); - a.splitNames = pkg.getSplitNames(); - a.splitSourceDirs = pkg.getSplitCodePaths(); - a.splitPublicSourceDirs = pkg.getSplitPublicSourceDirs(); - a.splitDependencies = pkg.getSplitDependencies(); - a.dataDir = pkg.getDataDir(); - a.deviceProtectedDataDir = pkg.getDeviceProtectedDataDir(); - a.credentialProtectedDataDir = pkg.getCredentialProtectedDataDir(); - a.primaryCpuAbi = pkg.getPrimaryCpuAbi(); - a.secondaryCpuAbi = pkg.getSecondaryCpuAbi(); - a.nativeLibraryDir = pkg.getNativeLibraryDir(); - a.secondaryNativeLibraryDir = pkg.getSecondaryNativeLibraryDir(); + PackageParser.Instrumentation a = pkg.instrumentation.get(i); + a.info.packageName = pkg.applicationInfo.packageName; + a.info.sourceDir = pkg.applicationInfo.sourceDir; + a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; + a.info.splitNames = pkg.splitNames; + a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; + a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; + a.info.splitDependencies = pkg.applicationInfo.splitDependencies; + a.info.dataDir = pkg.applicationInfo.dataDir; + a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir; + a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir; + a.info.primaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; + a.info.secondaryCpuAbi = pkg.applicationInfo.secondaryCpuAbi; + a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; + a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir; mInstrumentation.put(a.getComponentName(), a); if (chatty) { if (r == null) { @@ -11634,16 +11755,19 @@ public class PackageManagerService extends IPackageManager.Stub } else { r.append(' '); } - r.append(a.getName()); + r.append(a.info.name); } } if (r != null) { if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); } - if (pkg.getProtectedBroadcasts() != null) { + if (pkg.protectedBroadcasts != null) { + collectionSize = pkg.protectedBroadcasts.size(); synchronized (mProtectedBroadcasts) { - mProtectedBroadcasts.addAll(pkg.getProtectedBroadcasts()); + for (i = 0; i < collectionSize; i++) { + mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); + } } } @@ -11667,14 +11791,14 @@ public class PackageManagerService extends IPackageManager.Stub Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } - private void setUpCustomResolverActivity(AndroidPackage pkg) { + private void setUpCustomResolverActivity(PackageParser.Package pkg) { synchronized (mLock) { mResolverReplaced = true; // Set up information for custom user intent resolution activity. - mResolveActivity.applicationInfo = pkg.toAppInfo(); + mResolveActivity.applicationInfo = pkg.applicationInfo; mResolveActivity.name = mCustomResolverComponentName.getClassName(); - mResolveActivity.packageName = pkg.getAppInfoPackageName(); - mResolveActivity.processName = pkg.getAppInfoProcessName(); + mResolveActivity.packageName = pkg.applicationInfo.packageName; + mResolveActivity.processName = pkg.applicationInfo.packageName; mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; @@ -11741,13 +11865,22 @@ public class PackageManagerService extends IPackageManager.Stub } } - private void removePackageLI(AndroidPackage pkg, boolean chatty) { + private void removePackageLI(PackageParser.Package pkg, boolean chatty) { // Remove the parent package setting - PackageSetting ps = getPackageSetting(pkg.getPackageName()); + PackageSetting ps = (PackageSetting) pkg.mExtras; if (ps != null) { removePackageLI(ps.name, chatty); } else if (DEBUG_REMOVE && chatty) { - Log.d(TAG, "Not removing package " + pkg.getPackageName() + "; mExtras == null"); + Log.d(TAG, "Not removing package " + pkg.packageName + "; mExtras == null"); + } + // Remove the child package setting + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + PackageParser.Package childPkg = pkg.childPackages.get(i); + ps = (PackageSetting) childPkg.mExtras; + if (ps != null) { + removePackageLI(ps.name, chatty); + } } } @@ -11759,23 +11892,45 @@ public class PackageManagerService extends IPackageManager.Stub // writer synchronized (mLock) { - final AndroidPackage removedPackage = mPackages.remove(packageName); + final PackageParser.Package removedPackage = mPackages.remove(packageName); if (removedPackage != null) { cleanPackageDataStructuresLILPw(removedPackage, chatty); } } } - void cleanPackageDataStructuresLILPw(AndroidPackage pkg, boolean chatty) { + void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { + if (DEBUG_INSTALL) { + if (chatty) + Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); + } + + // writer + synchronized (mLock) { + // Remove the parent package + mPackages.remove(pkg.applicationInfo.packageName); + cleanPackageDataStructuresLILPw(pkg, chatty); + + // Remove the child packages + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + PackageParser.Package childPkg = pkg.childPackages.get(i); + mPackages.remove(childPkg.applicationInfo.packageName); + cleanPackageDataStructuresLILPw(childPkg, chatty); + } + } + } + + void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { mComponentResolver.removeAllComponents(pkg, chatty); - mAppsFilter.removePackage(pkg.getPackageName()); + mAppsFilter.removePackage(pkg.packageName); mPermissionManager.removeAllPermissions(pkg, chatty); - final int instrumentationSize = ArrayUtils.size(pkg.getInstrumentations()); + final int instrumentationSize = pkg.instrumentation.size(); StringBuilder r = null; int i; for (i = 0; i < instrumentationSize; i++) { - ParsedInstrumentation a = pkg.getInstrumentations().get(i); + PackageParser.Instrumentation a = pkg.instrumentation.get(i); mInstrumentation.remove(a.getComponentName()); if (DEBUG_REMOVE && chatty) { if (r == null) { @@ -11783,7 +11938,7 @@ public class PackageManagerService extends IPackageManager.Stub } else { r.append(' '); } - r.append(a.getName()); + r.append(a.info.name); } } if (r != null) { @@ -11791,12 +11946,12 @@ public class PackageManagerService extends IPackageManager.Stub } r = null; - if ((pkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0) { + if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { // Only system apps can hold shared libraries. - if (pkg.getLibraryNames() != null) { - final int libraryNamesSize = pkg.getLibraryNames().size(); + if (pkg.libraryNames != null) { + final int libraryNamesSize = pkg.libraryNames.size(); for (i = 0; i < libraryNamesSize; i++) { - String name = pkg.getLibraryNames().get(i); + String name = pkg.libraryNames.get(i); if (removeSharedLibraryLPw(name, 0)) { if (DEBUG_REMOVE && chatty) { if (r == null) { @@ -11814,16 +11969,15 @@ public class PackageManagerService extends IPackageManager.Stub r = null; // Any package can hold static shared libraries. - if (pkg.getStaticSharedLibName() != null) { - if (removeSharedLibraryLPw(pkg.getStaticSharedLibName(), - pkg.getStaticSharedLibVersion())) { + if (pkg.staticSharedLibName != null) { + if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) { if (DEBUG_REMOVE && chatty) { if (r == null) { r = new StringBuilder(256); } else { r.append(' '); } - r.append(pkg.getStaticSharedLibName()); + r.append(pkg.staticSharedLibName); } } } @@ -12164,11 +12318,11 @@ public class PackageManagerService extends IPackageManager.Stub // Cannot hide static shared libs as they are considered // a part of the using app (emulating static linking). Also // static libs are installed always on internal storage. - AndroidPackage pkg = mPackages.get(packageName); - if (pkg != null && pkg.getStaticSharedLibName() != null) { + PackageParser.Package pkg = mPackages.get(packageName); + if (pkg != null && pkg.staticSharedLibName != null) { Slog.w(TAG, "Cannot hide package: " + packageName + " providing static shared library: " - + pkg.getStaticSharedLibName()); + + pkg.staticSharedLibName); return false; } // Only allow protected packages to hide themselves. @@ -12214,17 +12368,17 @@ public class PackageManagerService extends IPackageManager.Stub if (pkgSetting == null || !pkgSetting.isSystem()) { return; } - AndroidPackage pkg = pkgSetting.pkg; - if (pkg != null) { - pkg.mutate().setHiddenUntilInstalled(hidden); + PackageParser.Package pkg = pkgSetting.pkg; + if (pkg != null && pkg.applicationInfo != null) { + pkg.applicationInfo.hiddenUntilInstalled = hidden; } final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(packageName); if (disabledPs == null) { return; } pkg = disabledPs.pkg; - if (pkg != null) { - pkg.mutate().setHiddenUntilInstalled(hidden); + if (pkg != null && pkg.applicationInfo != null) { + pkg.applicationInfo.hiddenUntilInstalled = hidden; } } } @@ -12293,14 +12447,10 @@ public class PackageManagerService extends IPackageManager.Stub } private void sendPackagesSuspendedForUser(String[] pkgList, int[] uidList, int userId, - boolean suspended, PersistableBundle launcherExtras) { + boolean suspended) { final Bundle extras = new Bundle(3); extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList); - if (launcherExtras != null) { - extras.putBundle(Intent.EXTRA_LAUNCHER_EXTRAS, - new Bundle(launcherExtras.deepCopy())); - } sendPackageBroadcast( suspended ? Intent.ACTION_PACKAGES_SUSPENDED : Intent.ACTION_PACKAGES_UNSUSPENDED, @@ -12420,7 +12570,7 @@ public class PackageManagerService extends IPackageManager.Stub if (installed) { if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0 && pkgSetting.pkg != null) { - whiteListedPermissions = pkgSetting.pkg.getRequestedPermissions(); + whiteListedPermissions = pkgSetting.pkg.requestedPermissions; } mPermissionManager.setWhitelistedRestrictedPermissions(packageName, whiteListedPermissions, FLAG_PERMISSION_WHITELIST_INSTALLER, userId); @@ -12565,8 +12715,6 @@ public class PackageManagerService extends IPackageManager.Stub if (ownerUid == callingUid) { return; } - throw new UnsupportedOperationException("Cannot suspend/unsuspend packages. User " - + userId + " has an active DO or PO"); } mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS, @@ -12574,6 +12722,7 @@ public class PackageManagerService extends IPackageManager.Stub final int packageUid = getPackageUid(callingPackage, 0, userId); final boolean allowedPackageUid = packageUid == callingUid; + // TODO(b/139383163): remove special casing for shell and enforce INTERACT_ACROSS_USERS_FULL final boolean allowedShell = callingUid == SHELL_UID && UserHandle.isSameApp(packageUid, callingUid); @@ -12624,20 +12773,27 @@ public class PackageManagerService extends IPackageManager.Stub unactionedPackages.add(packageName); continue; } + boolean packageUnsuspended; synchronized (mLock) { - pkgSetting.setSuspended(suspended, callingPackage, dialogInfo, appExtras, - launcherExtras, userId); + if (suspended) { + pkgSetting.addOrUpdateSuspension(callingPackage, dialogInfo, appExtras, + launcherExtras, userId); + } else { + pkgSetting.removeSuspension(callingPackage, userId); + } + packageUnsuspended = !suspended && !pkgSetting.getSuspended(userId); + } + if (suspended || packageUnsuspended) { + changedPackagesList.add(packageName); + changedUids.add(UserHandle.getUid(userId, pkgSetting.appId)); } - changedPackagesList.add(packageName); - changedUids.add(UserHandle.getUid(userId, pkgSetting.appId)); } if (!changedPackagesList.isEmpty()) { final String[] changedPackages = changedPackagesList.toArray( new String[changedPackagesList.size()]); - sendPackagesSuspendedForUser( - changedPackages, changedUids.toArray(), userId, suspended, launcherExtras); - sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, appExtras, userId); + sendPackagesSuspendedForUser(changedPackages, changedUids.toArray(), userId, suspended); + sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, userId); synchronized (mLock) { scheduleWritePackageRestrictionsLocked(userId); } @@ -12646,38 +12802,40 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public PersistableBundle getSuspendedPackageAppExtras(String packageName, int userId) { + public Bundle getSuspendedPackageAppExtras(String packageName, int userId) { final int callingUid = Binder.getCallingUid(); if (getPackageUid(packageName, 0, userId) != callingUid) { throw new SecurityException("Calling package " + packageName + " does not belong to calling uid " + callingUid); } + return getSuspendedPackageAppExtrasInternal(packageName, userId); + } + + private Bundle getSuspendedPackageAppExtrasInternal(String packageName, int userId) { synchronized (mLock) { final PackageSetting ps = mSettings.mPackages.get(packageName); - if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) { + if (ps == null) { throw new IllegalArgumentException("Unknown target package: " + packageName); } - final PackageUserState packageUserState = ps.readUserState(userId); - if (packageUserState.suspended) { - return packageUserState.suspendedAppExtras; + final PackageUserState pus = ps.readUserState(userId); + final Bundle allExtras = new Bundle(); + if (pus.suspended) { + for (int i = 0; i < pus.suspendParams.size(); i++) { + final PackageUserState.SuspendParams params = pus.suspendParams.valueAt(i); + if (params != null && params.appExtras != null) { + allExtras.putAll(params.appExtras); + } + } } - return null; + return (allExtras.size() > 0) ? allExtras : null; } } private void sendMyPackageSuspendedOrUnsuspended(String[] affectedPackages, boolean suspended, - PersistableBundle appExtras, int userId) { - final String action; - final Bundle intentExtras = new Bundle(); - if (suspended) { - action = Intent.ACTION_MY_PACKAGE_SUSPENDED; - if (appExtras != null) { - final Bundle bundledAppExtras = new Bundle(appExtras.deepCopy()); - intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, bundledAppExtras); - } - } else { - action = Intent.ACTION_MY_PACKAGE_UNSUSPENDED; - } + int userId) { + final String action = suspended + ? Intent.ACTION_MY_PACKAGE_SUSPENDED + : Intent.ACTION_MY_PACKAGE_UNSUSPENDED; mHandler.post(() -> { try { final IActivityManager am = ActivityManager.getService(); @@ -12688,6 +12846,16 @@ public class PackageManagerService extends IPackageManager.Stub } final int[] targetUserIds = new int[] {userId}; for (String packageName : affectedPackages) { + final Bundle appExtras = suspended + ? getSuspendedPackageAppExtrasInternal(packageName, userId) + : null; + final Bundle intentExtras; + if (appExtras != null) { + intentExtras = new Bundle(1); + intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, appExtras); + } else { + intentExtras = null; + } doSendBroadcast(am, action, null, intentExtras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName, null, targetUserIds, false); @@ -12720,57 +12888,32 @@ public class PackageManagerService extends IPackageManager.Stub * <p><b>Should not be used on a frequent code path</b> as it flushes state to disk * synchronously * - * @param packageName The package holding {@link Manifest.permission#SUSPEND_APPS} permission - * @param affectedUser The user for which the changes are taking place. - */ - void unsuspendForSuspendingPackage(final String packageName, int affectedUser) { - final int[] userIds = (affectedUser == UserHandle.USER_ALL) ? mUserManager.getUserIds() - : new int[] {affectedUser}; - for (int userId : userIds) { - unsuspendForSuspendingPackages(packageName::equals, userId); - } - } - - /** - * Immediately unsuspends any packages in the given users not suspended by the platform or root. - * To be called when a profile owner or a device owner is added. - * - * <p><b>Should not be used on a frequent code path</b> as it flushes state to disk - * synchronously - * - * @param userIds The users for which to unsuspend packages + * @param suspendingPackage The suspending package + * @param userId The user for which the changes are taking place. */ - void unsuspendForNonSystemSuspendingPackages(ArraySet<Integer> userIds) { - final int sz = userIds.size(); - for (int i = 0; i < sz; i++) { - unsuspendForSuspendingPackages( - (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage), - userIds.valueAt(i)); - } - } - - private void unsuspendForSuspendingPackages(Predicate<String> packagePredicate, int userId) { - final List<String> affectedPackages = new ArrayList<>(); - final IntArray affectedUids = new IntArray(); + private void unsuspendForSuspendingPackage(String suspendingPackage, int userId) { + final List<String> unsuspendedPackages = new ArrayList<>(); + final IntArray unsuspendedUids = new IntArray(); synchronized (mLock) { for (PackageSetting ps : mSettings.mPackages.values()) { final PackageUserState pus = ps.readUserState(userId); - if (pus.suspended && packagePredicate.test(pus.suspendingPackage)) { - ps.setSuspended(false, null, null, null, null, userId); - affectedPackages.add(ps.name); - affectedUids.add(UserHandle.getUid(userId, ps.getAppId())); + if (pus.suspended) { + ps.removeSuspension(suspendingPackage, userId); + if (!ps.getSuspended(userId)) { + unsuspendedPackages.add(ps.name); + unsuspendedUids.add(UserHandle.getUid(userId, ps.getAppId())); + } } } } - if (!affectedPackages.isEmpty()) { - final String[] packageArray = affectedPackages.toArray( - new String[affectedPackages.size()]); - sendMyPackageSuspendedOrUnsuspended(packageArray, false, null, userId); - sendPackagesSuspendedForUser( - packageArray, affectedUids.toArray(), userId, false, null); - // Write package restrictions immediately to avoid an inconsistent state. - mSettings.writePackageRestrictionsLPr(userId); + if (!unsuspendedPackages.isEmpty()) { + final String[] packageArray = unsuspendedPackages.toArray( + new String[unsuspendedPackages.size()]); + sendMyPackageSuspendedOrUnsuspended(packageArray, false, userId); + sendPackagesSuspendedForUser(packageArray, unsuspendedUids.toArray(), userId, false); } + // Write package restrictions immediately to avoid an inconsistent state. + mSettings.writePackageRestrictionsLPr(userId); } @Override @@ -12857,11 +13000,11 @@ public class PackageManagerService extends IPackageManager.Stub // Cannot suspend static shared libs as they are considered // a part of the using app (emulating static linking). Also // static libs are installed always on internal storage. - AndroidPackage pkg = mPackages.get(packageName); - if (pkg != null && pkg.isStaticSharedLibrary()) { + PackageParser.Package pkg = mPackages.get(packageName); + if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) { Slog.w(TAG, "Cannot suspend package: " + packageName + " providing static shared library: " - + pkg.getStaticSharedLibName()); + + pkg.staticSharedLibName); continue; } } @@ -13006,10 +13149,10 @@ public class PackageManagerService extends IPackageManager.Stub private int getUidForVerifier(VerifierInfo verifierInfo) { synchronized (mLock) { - final AndroidPackage pkg = mPackages.get(verifierInfo.packageName); + final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); if (pkg == null) { return -1; - } else if (pkg.getSigningDetails().signatures.length != 1) { + } else if (pkg.mSigningDetails.signatures.length != 1) { Slog.i(TAG, "Verifier package " + verifierInfo.packageName + " has more than one signature; ignoring"); return -1; @@ -13023,7 +13166,7 @@ public class PackageManagerService extends IPackageManager.Stub final byte[] expectedPublicKey; try { - final Signature verifierSig = pkg.getSigningDetails().signatures[0]; + final Signature verifierSig = pkg.mSigningDetails.signatures[0]; final PublicKey publicKey = verifierSig.getPublicKey(); expectedPublicKey = publicKey.getEncoded(); } catch (CertificateException e) { @@ -13038,7 +13181,7 @@ public class PackageManagerService extends IPackageManager.Stub return -1; } - return pkg.getUid(); + return pkg.applicationInfo.uid; } } @@ -13226,33 +13369,26 @@ public class PackageManagerService extends IPackageManager.Stub final int callingUid = Binder.getCallingUid(); final int callingUserId = UserHandle.getUserId(callingUid); synchronized (mLock) { - AndroidPackage pkg = mPackages.get(packageName); - if (pkg == null || ArrayUtils.isEmpty(pkg.getActivities())) { + PackageParser.Package pkg = mPackages.get(packageName); + if (pkg == null || pkg.activities == null) { return ParceledListSlice.emptyList(); } - final PackageSetting ps = getPackageSetting(pkg.getPackageName()); - if (ps == null) { + if (pkg.mExtras == null) { return ParceledListSlice.emptyList(); } + final PackageSetting ps = (PackageSetting) pkg.mExtras; if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) { return ParceledListSlice.emptyList(); } - final int count = ArrayUtils.size(pkg.getActivities()); + final int count = pkg.activities.size(); ArrayList<IntentFilter> result = new ArrayList<>(); for (int n=0; n<count; n++) { - ParsedActivity activity = pkg.getActivities().get(n); + PackageParser.Activity activity = pkg.activities.get(n); if (activity.intents != null && activity.intents.size() > 0) { result.addAll(activity.intents); } } - return new ParceledListSlice<IntentFilter>(result) { - @Override - protected void writeElement(IntentFilter parcelable, Parcel dest, int callFlags) { - // IntentFilter has final Parcelable methods, so redirect to the subclass - ((ParsedActivityIntentInfo) parcelable).writeIntentInfoToParcel(dest, - callFlags); - } - }; + return new ParceledListSlice<>(result); } } @@ -13433,7 +13569,7 @@ public class PackageManagerService extends IPackageManager.Stub // package has not opted out of backup participation. final boolean update = res.removedInfo != null && res.removedInfo.removedPackage != null; - final int flags = (res.pkg == null) ? 0 : res.pkg.getFlags(); + final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; boolean doRestore = !update && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); @@ -13471,7 +13607,7 @@ public class PackageManagerService extends IPackageManager.Stub try { if (bm.isBackupServiceActive(userId)) { bm.restoreAtInstallForUser( - userId, res.pkg.getAppInfoPackageName(), token); + userId, res.pkg.applicationInfo.packageName, token); } else { doRestore = false; } @@ -13496,8 +13632,8 @@ public class PackageManagerService extends IPackageManager.Stub IRollbackManager rm = IRollbackManager.Stub.asInterface( ServiceManager.getService(Context.ROLLBACK_SERVICE)); - final String packageName = res.pkg.getAppInfoPackageName(); - final String seInfo = res.pkg.getSeInfo(); + final String packageName = res.pkg.applicationInfo.packageName; + final String seInfo = res.pkg.applicationInfo.seInfo; final int[] allUsers = mUserManager.getUserIds(); final int[] installedUsers; @@ -13566,7 +13702,7 @@ public class PackageManagerService extends IPackageManager.Stub if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) { continue; } - if (packageName.equals(data.res.pkg.getAppInfoPackageName())) { + if (packageName.equals(data.res.pkg.applicationInfo.packageName)) { // right package; but is it for the right user? for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) { if (userId == data.res.newUsers[uIndex]) { @@ -13908,12 +14044,12 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mLock) { // Currently installed package which the new package is attempting to replace or // null if no such package is installed. - AndroidPackage installedPkg = mPackages.get(packageName); + PackageParser.Package installedPkg = mPackages.get(packageName); // Package which currently owns the data which the new package will own if installed. // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg // will be null whereas dataOwnerPkg will contain information about the package // which was uninstalled while keeping its data. - AndroidPackage dataOwnerPkg = installedPkg; + PackageParser.Package dataOwnerPkg = installedPkg; if (dataOwnerPkg == null) { PackageSetting ps = mSettings.mPackages.get(packageName); if (ps != null) { @@ -13940,7 +14076,7 @@ public class PackageManagerService extends IPackageManager.Stub if (dataOwnerPkg != null) { if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags, - dataOwnerPkg.getFlags())) { + dataOwnerPkg.applicationInfo.flags)) { try { checkDowngrade(dataOwnerPkg, pkgLite); } catch (PackageManagerException e) { @@ -13953,7 +14089,7 @@ public class PackageManagerService extends IPackageManager.Stub if (installedPkg != null) { if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { // Check for updated system application. - if ((installedPkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0) { + if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { return PackageHelper.RECOMMEND_INSTALL_INTERNAL; } else { // If current upgrade specifies particular preference @@ -14416,7 +14552,7 @@ public class PackageManagerService extends IPackageManager.Stub * Rename package into final resting place. All paths on the given * scanned package should be updated to reflect the rename. */ - abstract boolean doRename(int status, ParsedPackage parsedPackage); + abstract boolean doRename(int status, PackageParser.Package pkg); abstract int doPostInstall(int status, int uid); /** @see PackageSettingBase#codePathString */ @@ -14564,8 +14700,7 @@ public class PackageManagerService extends IPackageManager.Stub return status; } - @Override - boolean doRename(int status, ParsedPackage parsedPackage) { + boolean doRename(int status, PackageParser.Package pkg) { if (status != PackageManager.INSTALL_SUCCEEDED) { cleanUp(); return false; @@ -14573,7 +14708,7 @@ public class PackageManagerService extends IPackageManager.Stub final File targetDir = codeFile.getParentFile(); final File beforeCodeFile = codeFile; - final File afterCodeFile = getNextCodePath(targetDir, parsedPackage.getPackageName()); + final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); try { @@ -14594,23 +14729,24 @@ public class PackageManagerService extends IPackageManager.Stub // Reflect the rename in scanned details try { - parsedPackage.setCodePath(afterCodeFile.getCanonicalPath()); + pkg.setCodePath(afterCodeFile.getCanonicalPath()); } catch (IOException e) { Slog.e(TAG, "Failed to get path: " + afterCodeFile, e); return false; } - parsedPackage.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, - afterCodeFile, parsedPackage.getBaseCodePath())); - parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, - afterCodeFile, parsedPackage.getSplitCodePaths())); + pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, + afterCodeFile, pkg.baseCodePath)); + pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, + afterCodeFile, pkg.splitCodePaths)); // Reflect the rename in app info - // TODO(b/135203078): Remove all of these application info calls - parsedPackage.setApplicationVolumeUuid(parsedPackage.getVolumeUuid()) - .setApplicationInfoCodePath(parsedPackage.getCodePath()) - .setApplicationInfoResourcePath(parsedPackage.getCodePath()) - .setApplicationInfoBaseResourcePath(parsedPackage.getBaseCodePath()) - .setApplicationInfoSplitResourcePaths(parsedPackage.getSplitCodePaths()); + pkg.setApplicationVolumeUuid(pkg.volumeUuid); + pkg.setApplicationInfoCodePath(pkg.codePath); + pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); + pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); + pkg.setApplicationInfoResourcePath(pkg.codePath); + pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); + pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); return true; } @@ -14713,20 +14849,20 @@ public class PackageManagerService extends IPackageManager.Stub return status; } - @Override - boolean doRename(int status, ParsedPackage parsedPackage) { + boolean doRename(int status, PackageParser.Package pkg) { if (status != PackageManager.INSTALL_SUCCEEDED) { cleanUp(move.toUuid); return false; } // Reflect the move in app info - // TODO(b/135203078): Remove all of these application info calls - parsedPackage.setApplicationVolumeUuid(parsedPackage.getVolumeUuid()) - .setApplicationInfoCodePath(parsedPackage.getCodePath()) - .setApplicationInfoResourcePath(parsedPackage.getCodePath()) - .setApplicationInfoBaseResourcePath(parsedPackage.getBaseCodePath()) - .setApplicationInfoSplitResourcePaths(parsedPackage.getSplitCodePaths()); + pkg.setApplicationVolumeUuid(pkg.volumeUuid); + pkg.setApplicationInfoCodePath(pkg.codePath); + pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); + pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); + pkg.setApplicationInfoResourcePath(pkg.codePath); + pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); + pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); return true; } @@ -14802,14 +14938,14 @@ public class PackageManagerService extends IPackageManager.Stub int[] origUsers; // The set of users that now have this package installed. int[] newUsers; - AndroidPackage pkg; + PackageParser.Package pkg; int returnCode; String returnMsg; String installerPackageName; PackageRemovedInfo removedInfo; ArrayMap<String, PackageInstalledInfo> addedChildPackages; // The set of packages consuming this shared library or null if no consumers exist. - ArrayList<AndroidPackage> libraryConsumers; + ArrayList<PackageParser.Package> libraryConsumers; public void setError(int code, String msg) { setReturnCode(code); @@ -14865,39 +15001,123 @@ public class PackageManagerService extends IPackageManager.Stub } } + /** + * Checks whether the parent or any of the child packages have a change shared + * user. For a package to be a valid update the shred users of the parent and + * the children should match. We may later support changing child shared users. + * @param oldPkg The updated package. + * @param newPkg The update package. + * @return The shared user that change between the versions. + */ + private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, + PackageParser.Package newPkg) { + // Check parent shared user + if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { + return newPkg.packageName; + } + // Check child shared users + final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; + final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; + for (int i = 0; i < newChildCount; i++) { + PackageParser.Package newChildPkg = newPkg.childPackages.get(i); + // If this child was present, did it have the same shared user? + for (int j = 0; j < oldChildCount; j++) { + PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); + if (newChildPkg.packageName.equals(oldChildPkg.packageName) + && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { + return newChildPkg.packageName; + } + } + } + return null; + } + private void removeNativeBinariesLI(PackageSetting ps) { + // Remove the lib path for the parent package if (ps != null) { NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); + // Remove the lib path for the child packages + final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; + for (int i = 0; i < childCount; i++) { + PackageSetting childPs = null; + synchronized (mLock) { + childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i)); + } + if (childPs != null) { + NativeLibraryHelper.removeNativeBinariesLI(childPs + .legacyNativeLibraryPathString); + } + } } } @GuardedBy("mLock") - private void enableSystemPackageLPw(AndroidPackage pkg) { - mSettings.enableSystemPackageLPw(pkg.getPackageName()); + private void enableSystemPackageLPw(PackageParser.Package pkg) { + // Enable the parent package + mSettings.enableSystemPackageLPw(pkg.packageName); + // Enable the child packages + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + PackageParser.Package childPkg = pkg.childPackages.get(i); + mSettings.enableSystemPackageLPw(childPkg.packageName); + } } @GuardedBy("mLock") - private boolean disableSystemPackageLPw(AndroidPackage oldPkg) { - return mSettings.disableSystemPackageLPw(oldPkg.getPackageName(), true); + private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, + PackageParser.Package newPkg) { + // Disable the parent package (parent always replaced) + boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); + // Disable the child packages + final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + PackageParser.Package childPkg = oldPkg.childPackages.get(i); + final boolean replace = newPkg.hasChildPackage(childPkg.packageName); + disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); + } + return disabled; } - private void updateSettingsLI(AndroidPackage newPackage, String installerPackageName, + @GuardedBy("mLock") + private void setInstallerPackageNameLPw(PackageParser.Package pkg, + String installerPackageName) { + // Enable the parent package + mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); + // Enable the child packages + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + PackageParser.Package childPkg = pkg.childPackages.get(i); + mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); + } + } + + private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) { + // Update the parent package setting updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, res, user, installReason); + // Update the child packages setting + final int childCount = (newPackage.childPackages != null) + ? newPackage.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + PackageParser.Package childPackage = newPackage.childPackages.get(i); + PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); + updateSettingsInternalLI(childPackage, installerPackageName, allUsers, + childRes.origUsers, childRes, user, installReason); + } } - private void updateSettingsInternalLI(AndroidPackage pkg, + private void updateSettingsInternalLI(PackageParser.Package pkg, String installerPackageName, int[] allUsers, int[] installedForUsers, PackageInstalledInfo res, UserHandle user, int installReason) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); - final String pkgName = pkg.getPackageName(); + final String pkgName = pkg.packageName; - if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getCodePath()); + if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath); synchronized (mLock) { // NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions - mPermissionManager.updatePermissions(pkg.getPackageName(), pkg); + mPermissionManager.updatePermissions(pkg.packageName, pkg); // For system-bundled packages, we assume that installing an upgraded version // of the package implies that the user actually wants to run that new code, // so we enable the package. @@ -14964,7 +15184,7 @@ public class PackageManagerService extends IPackageManager.Stub mSettings.writeKernelMappingLPr(ps); } res.name = pkgName; - res.uid = pkg.getUid(); + res.uid = pkg.applicationInfo.uid; res.pkg = pkg; mSettings.setInstallerPackageName(pkgName, installerPackageName); res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); @@ -15022,7 +15242,7 @@ public class PackageManagerService extends IPackageManager.Stub private static class ReconcileRequest { public final Map<String, ScanResult> scannedPackages; - public final Map<String, AndroidPackage> allPackages; + public final Map<String, PackageParser.Package> allPackages; public final Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource; public final Map<String, InstallArgs> installArgs; public final Map<String, PackageInstalledInfo> installResults; @@ -15035,7 +15255,7 @@ public class PackageManagerService extends IPackageManager.Stub Map<String, PackageInstalledInfo> installResults, Map<String, PrepareResult> preparedPackages, Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource, - Map<String, AndroidPackage> allPackages, + Map<String, PackageParser.Package> allPackages, Map<String, VersionInfo> versionInfos, Map<String, PackageSetting> lastStaticSharedLibSettings) { this.scannedPackages = scannedPackages; @@ -15050,7 +15270,7 @@ public class PackageManagerService extends IPackageManager.Stub private ReconcileRequest(Map<String, ScanResult> scannedPackages, Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource, - Map<String, AndroidPackage> allPackages, + Map<String, PackageParser.Package> allPackages, Map<String, VersionInfo> versionInfos, Map<String, PackageSetting> lastStaticSharedLibSettings) { this(scannedPackages, Collections.emptyMap(), Collections.emptyMap(), @@ -15118,17 +15338,15 @@ public class PackageManagerService extends IPackageManager.Stub * with the package(s) currently being installed. The to-be installed packages take * precedence and may shadow already installed packages. */ - private Map<String, AndroidPackage> getCombinedAvailablePackages() { - final ArrayMap<String, AndroidPackage> combined = + private Map<String, PackageParser.Package> getCombinedPackages() { + final ArrayMap<String, PackageParser.Package> combinedPackages = new ArrayMap<>(request.allPackages.size() + request.scannedPackages.size()); - combined.putAll(request.allPackages); - + combinedPackages.putAll(request.allPackages); for (ScanResult scanResult : request.scannedPackages.values()) { - combined.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage); + combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.pkg); } - - return combined; + return combinedPackages; } } @@ -15141,9 +15359,8 @@ public class PackageManagerService extends IPackageManager.Stub final Map<String, ReconciledPackage> result = new ArrayMap<>(scannedPackages.size()); // make a copy of the existing set of packages so we can combine them with incoming packages - final ArrayMap<String, AndroidPackage> combinedPackages = + final ArrayMap<String, PackageParser.Package> combinedPackages = new ArrayMap<>(request.allPackages.size() + scannedPackages.size()); - combinedPackages.putAll(request.allPackages); final Map<String, LongSparseArray<SharedLibraryInfo>> incomingSharedLibraries = @@ -15153,7 +15370,7 @@ public class PackageManagerService extends IPackageManager.Stub final ScanResult scanResult = scannedPackages.get(installPackageName); // add / replace existing with incoming packages - combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage); + combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.pkg); // in the first pass, we'll build up the set of incoming shared libraries final List<SharedLibraryInfo> allowedSharedLibInfos = @@ -15186,7 +15403,7 @@ public class PackageManagerService extends IPackageManager.Stub | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); deletePackageAction = mayDeletePackageLocked(res.removedInfo, prepareResult.originalPs, prepareResult.disabledPs, - deleteFlags, null /* all users */); + prepareResult.childPackageSettings, deleteFlags, null /* all users */); if (deletePackageAction == null) { throw new ReconcileFailure( PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE, @@ -15198,7 +15415,7 @@ public class PackageManagerService extends IPackageManager.Stub final int scanFlags = scanResult.request.scanFlags; final int parseFlags = scanResult.request.parseFlags; - final ParsedPackage parsedPackage = scanResult.request.parsedPackage; + final PackageParser.Package pkg = scanResult.request.pkg; final PackageSetting disabledPkgSetting = scanResult.request.disabledPkgSetting; final PackageSetting lastStaticSharedLibSetting = @@ -15211,37 +15428,35 @@ public class PackageManagerService extends IPackageManager.Stub boolean sharedUserSignaturesChanged = false; SigningDetails signingDetails = null; if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) { - if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) { + if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) { // We just determined the app is signed correctly, so bring // over the latest parsed certs. } else { if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { throw new ReconcileFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, - "Package " + parsedPackage.getPackageName() - + " upgrade keys do not match the previously installed" - + " version"); + "Package " + pkg.packageName + " upgrade keys do not match the " + + "previously installed version"); } else { - String msg = "System package " + parsedPackage.getPackageName() + String msg = "System package " + pkg.packageName + " signature changed; retaining data."; reportSettingsProblem(Log.WARN, msg); } } - signingDetails = parsedPackage.getSigningDetails(); + signingDetails = pkg.mSigningDetails; } else { try { final VersionInfo versionInfo = request.versionInfos.get(installPackageName); final boolean compareCompat = isCompatSignatureUpdateNeeded(versionInfo); final boolean compareRecover = isRecoverSignatureUpdateNeeded(versionInfo); final boolean compatMatch = verifySignatures(signatureCheckPs, - disabledPkgSetting, parsedPackage.getSigningDetails(), compareCompat, - compareRecover); + disabledPkgSetting, pkg.mSigningDetails, compareCompat, compareRecover); // The new KeySets will be re-added later in the scanning process. if (compatMatch) { removeAppKeySetData = true; } // We just determined the app is signed correctly, so bring // over the latest parsed certs. - signingDetails = parsedPackage.getSigningDetails(); + signingDetails = pkg.mSigningDetails; // if this is is a sharedUser, check to see if the new package is signed by a @@ -15249,10 +15464,10 @@ public class PackageManagerService extends IPackageManager.Stub // signing certificate than the existing one, and if so, copy over the new // details if (signatureCheckPs.sharedUser != null) { - if (parsedPackage.getSigningDetails().hasAncestor( + if (pkg.mSigningDetails.hasAncestor( signatureCheckPs.sharedUser.signatures.mSigningDetails)) { signatureCheckPs.sharedUser.signatures.mSigningDetails = - parsedPackage.getSigningDetails(); + pkg.mSigningDetails; } if (signatureCheckPs.sharedUser.signaturesChanged == null) { signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE; @@ -15262,7 +15477,7 @@ public class PackageManagerService extends IPackageManager.Stub if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { throw new ReconcileFailure(e); } - signingDetails = parsedPackage.getSigningDetails(); + signingDetails = pkg.mSigningDetails; // If the system app is part of a shared user we allow that shared user to // change @@ -15277,7 +15492,7 @@ public class PackageManagerService extends IPackageManager.Stub signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures; if (signatureCheckPs.sharedUser.signaturesChanged != null && compareSignatures(sharedUserSignatures, - parsedPackage.getSigningDetails().signatures) + pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) { if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 29) { // Mismatched signatures is an error and silently skipping system @@ -15297,19 +15512,18 @@ public class PackageManagerService extends IPackageManager.Stub // whichever package happened to be scanned later. throw new IllegalStateException( "Signature mismatch on system package " - + parsedPackage.getPackageName() - + " for shared user " + + pkg.packageName + " for shared user " + scanResult.pkgSetting.sharedUser); } } sharedUserSignaturesChanged = true; signatureCheckPs.sharedUser.signatures.mSigningDetails = - parsedPackage.getSigningDetails(); + pkg.mSigningDetails; signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE; } // File a report about this. - String msg = "System package " + parsedPackage.getPackageName() + String msg = "System package " + pkg.packageName + " signature changed; retaining data."; reportSettingsProblem(Log.WARN, msg); } catch (IllegalArgumentException e) { @@ -15343,9 +15557,8 @@ public class PackageManagerService extends IPackageManager.Stub } try { result.get(installPackageName).collectedSharedLibraryInfos = - collectSharedLibraryInfos(scanResult.request.parsedPackage, - combinedPackages, request.sharedLibrarySource, - incomingSharedLibraries); + collectSharedLibraryInfos(scanResult.request.pkg, combinedPackages, + request.sharedLibrarySource, incomingSharedLibraries); } catch (PackageManagerException e) { throw new ReconcileFailure(e.error, e.getMessage()); @@ -15363,7 +15576,7 @@ public class PackageManagerService extends IPackageManager.Stub ScanResult scanResult, Map<String, LongSparseArray<SharedLibraryInfo>> existingSharedLibraries) { // Let's used the parsed package as scanResult.pkgSetting may be null - final ParsedPackage parsedPackage = scanResult.request.parsedPackage; + final PackageParser.Package pkg = scanResult.request.pkg; if (scanResult.staticSharedLibraryInfo == null && scanResult.dynamicSharedLibraryInfos == null) { return null; @@ -15374,12 +15587,12 @@ public class PackageManagerService extends IPackageManager.Stub return Collections.singletonList(scanResult.staticSharedLibraryInfo); } final boolean hasDynamicLibraries = - (parsedPackage.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0 + (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 && scanResult.dynamicSharedLibraryInfos != null; if (!hasDynamicLibraries) { return null; } - final boolean isUpdatedSystemApp = parsedPackage.isUpdatedSystemApp(); + final boolean isUpdatedSystemApp = pkg.isUpdatedSystemApp(); // We may not yet have disabled the updated package yet, so be sure to grab the // current setting if that's the case. final PackageSetting updatedSystemPs = isUpdatedSystemApp @@ -15388,9 +15601,9 @@ public class PackageManagerService extends IPackageManager.Stub : scanResult.request.disabledPkgSetting : null; if (isUpdatedSystemApp && (updatedSystemPs.pkg == null - || updatedSystemPs.pkg.getLibraryNames() == null)) { - Slog.w(TAG, "Package " + parsedPackage.getPackageName() - + " declares libraries that are not declared on the system image; skipping"); + || updatedSystemPs.pkg.libraryNames == null)) { + Slog.w(TAG, "Package " + pkg.packageName + " declares libraries that are not " + + "declared on the system image; skipping"); return null; } final ArrayList<SharedLibraryInfo> infos = @@ -15408,17 +15621,16 @@ public class PackageManagerService extends IPackageManager.Stub // with it. Better to just have the restriction here, be // conservative, and create many fewer cases that can negatively // impact the user experience. - if (!updatedSystemPs.pkg.getLibraryNames().contains(name)) { - Slog.w(TAG, "Package " + parsedPackage.getPackageName() - + " declares library " + name + if (!updatedSystemPs.pkg.libraryNames.contains(name)) { + Slog.w(TAG, "Package " + pkg.packageName + " declares library " + name + " that is not declared on system image; skipping"); continue; } } if (sharedLibExists( name, SharedLibraryInfo.VERSION_UNDEFINED, existingSharedLibraries)) { - Slog.w(TAG, "Package " + parsedPackage.getPackageName() + " declares library " - + name + " that already exists; skipping"); + Slog.w(TAG, "Package " + pkg.packageName + " declares library " + name + + " that already exists; skipping"); continue; } infos.add(info); @@ -15456,38 +15668,68 @@ public class PackageManagerService extends IPackageManager.Stub for (ReconciledPackage reconciledPkg : request.reconciledPackages.values()) { final ScanResult scanResult = reconciledPkg.scanResult; final ScanRequest scanRequest = scanResult.request; - final ParsedPackage parsedPackage = scanRequest.parsedPackage; - final String packageName = parsedPackage.getPackageName(); + final PackageParser.Package pkg = scanRequest.pkg; + final String packageName = pkg.packageName; final PackageInstalledInfo res = reconciledPkg.installResult; if (reconciledPkg.prepareResult.replace) { - AndroidPackage oldPackage = mPackages.get(packageName); + PackageParser.Package oldPackage = mPackages.get(packageName); // Set the update and install times - PackageSetting deletedPkgSetting = getPackageSetting(oldPackage.getPackageName()); - reconciledPkg.pkgSetting.firstInstallTime = deletedPkgSetting.firstInstallTime; - reconciledPkg.pkgSetting.lastUpdateTime = System.currentTimeMillis(); + PackageSetting deletedPkgSetting = (PackageSetting) oldPackage.mExtras; + setInstallAndUpdateTime(pkg, deletedPkgSetting.firstInstallTime, + System.currentTimeMillis()); if (reconciledPkg.prepareResult.system) { // Remove existing system package removePackageLI(oldPackage, true); - if (!disableSystemPackageLPw(oldPackage)) { + if (!disableSystemPackageLPw(oldPackage, pkg)) { // We didn't need to disable the .apk as a current system package, // which means we are replacing another update that is already // installed. We need to make sure to delete the older one's .apk. res.removedInfo.args = createInstallArgsForExisting( - oldPackage.getAppInfoCodePath(), - oldPackage.getAppInfoResourcePath(), - getAppDexInstructionSets(oldPackage.getPrimaryCpuAbi(), - oldPackage.getSecondaryCpuAbi())); + oldPackage.applicationInfo.getCodePath(), + oldPackage.applicationInfo.getResourcePath(), + getAppDexInstructionSets(oldPackage.applicationInfo)); } else { res.removedInfo.args = null; } + + // Update the package dynamic state if succeeded + // Now that the install succeeded make sure we remove data + // directories for any child package the update removed. + final int deletedChildCount = (oldPackage.childPackages != null) + ? oldPackage.childPackages.size() : 0; + final int newChildCount = (pkg.childPackages != null) + ? pkg.childPackages.size() : 0; + for (int i = 0; i < deletedChildCount; i++) { + PackageParser.Package deletedChildPkg = oldPackage.childPackages.get(i); + boolean childPackageDeleted = true; + for (int j = 0; j < newChildCount; j++) { + PackageParser.Package newChildPkg = pkg.childPackages.get(j); + if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { + childPackageDeleted = false; + break; + } + } + if (childPackageDeleted) { + PackageSetting ps1 = mSettings.getDisabledSystemPkgLPr( + deletedChildPkg.packageName); + if (ps1 != null && res.removedInfo.removedChildPackages != null) { + PackageRemovedInfo removedChildRes = res.removedInfo + .removedChildPackages.get(deletedChildPkg.packageName); + removePackageDataLIF(ps1, request.mAllUsers, removedChildRes, 0, + false); + removedChildRes.removedForAllUsers = mPackages.get(ps1.name) + == null; + } + } + } } else { try { // Settings will be written during the call to updateSettingsLI(). executeDeletePackageLIF(reconciledPkg.deletePackageAction, packageName, - true, request.mAllUsers, false, parsedPackage); + true, request.mAllUsers, false, pkg); } catch (SystemDeleteException e) { if (Build.IS_ENG) { throw new RuntimeException("Unexpected failure", e); @@ -15503,40 +15745,62 @@ public class PackageManagerService extends IPackageManager.Stub Slog.i(TAG, "upgrading pkg " + oldPackage + " is ASEC-hosted -> UNAVAILABLE"); } - final int[] uidArray = new int[]{oldPackage.getUid()}; + final int[] uidArray = new int[]{oldPackage.applicationInfo.uid}; final ArrayList<String> pkgList = new ArrayList<>(1); - pkgList.add(oldPackage.getAppInfoPackageName()); + pkgList.add(oldPackage.applicationInfo.packageName); sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); } // Update the in-memory copy of the previous code paths. PackageSetting ps1 = mSettings.mPackages.get( - reconciledPkg.prepareResult.existingPackage.getPackageName()); + reconciledPkg.prepareResult.existingPackage.packageName); if ((reconciledPkg.installArgs.installFlags & PackageManager.DONT_KILL_APP) == 0) { if (ps1.mOldCodePaths == null) { ps1.mOldCodePaths = new ArraySet<>(); } - Collections.addAll(ps1.mOldCodePaths, oldPackage.getBaseCodePath()); - if (oldPackage.getSplitCodePaths() != null) { - Collections.addAll(ps1.mOldCodePaths, oldPackage.getSplitCodePaths()); + Collections.addAll(ps1.mOldCodePaths, oldPackage.baseCodePath); + if (oldPackage.splitCodePaths != null) { + Collections.addAll(ps1.mOldCodePaths, oldPackage.splitCodePaths); } } else { ps1.mOldCodePaths = null; } + if (ps1.childPackageNames != null) { + for (int i = ps1.childPackageNames.size() - 1; i >= 0; --i) { + final String childPkgName = ps1.childPackageNames.get(i); + final PackageSetting childPs = mSettings.mPackages.get(childPkgName); + childPs.mOldCodePaths = ps1.mOldCodePaths; + } + } if (reconciledPkg.installResult.returnCode == PackageManager.INSTALL_SUCCEEDED) { - PackageSetting ps2 = mSettings.getPackageLPr( - parsedPackage.getPackageName()); + PackageSetting ps2 = mSettings.getPackageLPr(pkg.packageName); if (ps2 != null) { res.removedInfo.removedForAllUsers = mPackages.get(ps2.name) == null; + if (res.removedInfo.removedChildPackages != null) { + final int childCount1 = res.removedInfo.removedChildPackages.size(); + // Iterate in reverse as we may modify the collection + for (int i = childCount1 - 1; i >= 0; i--) { + String childPackageName = + res.removedInfo.removedChildPackages.keyAt(i); + if (res.addedChildPackages.containsKey(childPackageName)) { + res.removedInfo.removedChildPackages.removeAt(i); + } else { + PackageRemovedInfo childInfo = res.removedInfo + .removedChildPackages.valueAt(i); + childInfo.removedForAllUsers = mPackages.get( + childInfo.removedPackage) == null; + } + } + } } } } } - AndroidPackage pkg = commitReconciledScanResultLocked(reconciledPkg); + commitReconciledScanResultLocked(reconciledPkg); updateSettingsLI(pkg, reconciledPkg.installArgs.installerPackageName, request.mAllUsers, res, reconciledPkg.installArgs.user, reconciledPkg.installArgs.installReason); @@ -15545,6 +15809,17 @@ public class PackageManagerService extends IPackageManager.Stub res.newUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true); ps.setUpdateAvailable(false /*updateAvailable*/); } + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + PackageParser.Package childPkg = pkg.childPackages.get(i); + PackageInstalledInfo childRes = res.addedChildPackages.get( + childPkg.packageName); + PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); + if (childPs != null) { + childRes.newUsers = childPs.queryInstalledUsers( + mUserManager.getUserIds(), true); + } + } if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { updateSequenceNumberLP(ps, res.newUsers); updateInstantAppInstallerLocked(packageName); @@ -15604,31 +15879,33 @@ public class PackageManagerService extends IPackageManager.Stub request.installResult.setReturnCode(PackageManager.INSTALL_SUCCEEDED); request.installResult.installerPackageName = request.args.installerPackageName; - final String packageName = prepareResult.packageToScan.getPackageName(); + final String packageName = prepareResult.packageToScan.packageName; prepareResults.put(packageName, prepareResult); installResults.put(packageName, request.installResult); installArgs.put(packageName, request.args); try { - final ScanResult result = scanPackageTracedLI( + final List<ScanResult> scanResults = scanPackageTracedLI( prepareResult.packageToScan, prepareResult.parseFlags, prepareResult.scanFlags, System.currentTimeMillis(), request.args.user); - if (null != preparedScans.put(result.pkgSetting.pkg.getPackageName(), result)) { - request.installResult.setError( - PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE, - "Duplicate package " + result.pkgSetting.pkg.getPackageName() - + " in multi-package install request."); - return; - } - createdAppId.put(packageName, optimisticallyRegisterAppId(result)); - versionInfos.put(result.pkgSetting.pkg.getPackageName(), - getSettingsVersionForPackage(result.pkgSetting.pkg)); - if (result.staticSharedLibraryInfo != null) { - final PackageSetting sharedLibLatestVersionSetting = - getSharedLibLatestVersionSetting(result); - if (sharedLibLatestVersionSetting != null) { - lastStaticSharedLibSettings.put(result.pkgSetting.pkg.getPackageName(), - sharedLibLatestVersionSetting); + for (ScanResult result : scanResults) { + if (null != preparedScans.put(result.pkgSetting.pkg.packageName, result)) { + request.installResult.setError( + PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE, + "Duplicate package " + result.pkgSetting.pkg.packageName + + " in multi-package install request."); + return; + } + createdAppId.put(packageName, optimisticallyRegisterAppId(result)); + versionInfos.put(result.pkgSetting.pkg.packageName, + getSettingsVersionForPackage(result.pkgSetting.pkg)); + if (result.staticSharedLibraryInfo != null) { + final PackageSetting sharedLibLatestVersionSetting = + getSharedLibLatestVersionSetting(result); + if (sharedLibLatestVersionSetting != null) { + lastStaticSharedLibSettings.put(result.pkgSetting.pkg.packageName, + sharedLibLatestVersionSetting); + } } } } catch (PackageManagerException e) { @@ -15671,8 +15948,7 @@ public class PackageManagerService extends IPackageManager.Stub } finally { if (!success) { for (ScanResult result : preparedScans.values()) { - if (createdAppId.getOrDefault(result.request.parsedPackage.getPackageName(), - false)) { + if (createdAppId.getOrDefault(result.request.pkg.packageName, false)) { cleanUpAppIdCreation(result); } } @@ -15702,16 +15978,16 @@ public class PackageManagerService extends IPackageManager.Stub for (ReconciledPackage reconciledPkg : commitRequest.reconciledPackages.values()) { final boolean instantApp = ((reconciledPkg.scanResult.request.scanFlags & PackageManagerService.SCAN_AS_INSTANT_APP) != 0); - final AndroidPackage pkg = reconciledPkg.pkgSetting.pkg; - final String packageName = pkg.getPackageName(); + final PackageParser.Package pkg = reconciledPkg.pkgSetting.pkg; + final String packageName = pkg.packageName; prepareAppDataAfterInstallLIF(pkg); if (reconciledPkg.prepareResult.clearCodeCache) { clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); } if (reconciledPkg.prepareResult.replace) { - mDexManager.notifyPackageUpdated(pkg.getPackageName(), - pkg.getBaseCodePath(), pkg.getSplitCodePaths()); + mDexManager.notifyPackageUpdated(pkg.packageName, + pkg.baseCodePath, pkg.splitCodePaths); } // Prepare the application profiles for the new code paths. @@ -15725,7 +16001,7 @@ public class PackageManagerService extends IPackageManager.Stub // Check whether we need to dexopt the app. // // NOTE: it is IMPORTANT to call dexopt: - // - after doRename which will sync the package data from AndroidPackage and + // - after doRename which will sync the package data from PackageParser.Package and // its corresponding ApplicationInfo. // - after installNewPackageLIF or replacePackageLIF which will update result with the // uid of the application (pkg.applicationInfo.uid). @@ -15744,7 +16020,7 @@ public class PackageManagerService extends IPackageManager.Stub final boolean performDexopt = (!instantApp || Global.getInt(mContext.getContentResolver(), Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0) - && ((pkg.getFlags() & ApplicationInfo.FLAG_DEBUGGABLE) == 0); + && ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0); if (performDexopt) { // Compile the layout resources. @@ -15792,8 +16068,8 @@ public class PackageManagerService extends IPackageManager.Stub public final int scanFlags; public final int parseFlags; @Nullable /* The original Package if it is being replaced, otherwise {@code null} */ - public final AndroidPackage existingPackage; - public final ParsedPackage packageToScan; + public final PackageParser.Package existingPackage; + public final PackageParser.Package packageToScan; public final boolean clearCodeCache; public final boolean system; /* The original package name if it was changed during an update, otherwise {@code null}. */ @@ -15802,13 +16078,14 @@ public class PackageManagerService extends IPackageManager.Stub public final PackageFreezer freezer; public final PackageSetting originalPs; public final PackageSetting disabledPs; + public final PackageSetting[] childPackageSettings; private PrepareResult(int installReason, String volumeUuid, String installerPackageName, UserHandle user, boolean replace, int scanFlags, - int parseFlags, AndroidPackage existingPackage, - ParsedPackage packageToScan, boolean clearCodeCache, boolean system, + int parseFlags, PackageParser.Package existingPackage, + PackageParser.Package packageToScan, boolean clearCodeCache, boolean system, String renamedPackage, PackageFreezer freezer, PackageSetting originalPs, - PackageSetting disabledPs) { + PackageSetting disabledPs, PackageSetting[] childPackageSettings) { this.installReason = installReason; this.volumeUuid = volumeUuid; this.installerPackageName = installerPackageName; @@ -15824,6 +16101,7 @@ public class PackageManagerService extends IPackageManager.Stub this.freezer = freezer; this.originalPs = originalPs; this.disabledPs = disabledPs; + this.childPackageSettings = childPackageSettings; } } @@ -15904,10 +16182,10 @@ public class PackageManagerService extends IPackageManager.Stub pp.setCallback(mPackageParserCallback); Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); - ParsedPackage parsedPackage; + final PackageParser.Package pkg; try { - parsedPackage = pp.parseParsedPackage(tmpPackageFile, parseFlags, false); - DexMetadataHelper.validatePackageDexMetadata(parsedPackage); + pkg = pp.parsePackage(tmpPackageFile, parseFlags); + DexMetadataHelper.validatePackageDexMetadata(pkg); } catch (PackageParserException e) { throw new PrepareFailure("Failed parse during installPackageLI", e); } finally { @@ -15916,23 +16194,23 @@ public class PackageManagerService extends IPackageManager.Stub // Instant apps have several additional install-time checks. if (instantApp) { - if (parsedPackage.getTargetSdkVersion() < Build.VERSION_CODES.O) { - Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName() - + " does not target at least O"); + if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) { + Slog.w(TAG, + "Instant app package " + pkg.packageName + " does not target at least O"); throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID, "Instant app package must target at least O"); } - if (parsedPackage.getSharedUserId() != null) { - Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName() + if (pkg.mSharedUserId != null) { + Slog.w(TAG, "Instant app package " + pkg.packageName + " may not declare sharedUserId."); throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID, "Instant app package may not declare a sharedUserId"); } } - if (parsedPackage.isStaticSharedLibrary()) { + if (pkg.applicationInfo.isStaticSharedLibrary()) { // Static shared libraries have synthetic package names - renameStaticSharedLibraryPackage(parsedPackage); + renameStaticSharedLibraryPackage(pkg); // No static shared libs on external storage if (onExternal) { @@ -15942,16 +16220,42 @@ public class PackageManagerService extends IPackageManager.Stub } } + // If we are installing a clustered package add results for the children + if (pkg.childPackages != null) { + synchronized (mLock) { + final int childCount = pkg.childPackages.size(); + for (int i = 0; i < childCount; i++) { + PackageParser.Package childPkg = pkg.childPackages.get(i); + PackageInstalledInfo childRes = new PackageInstalledInfo(); + childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); + childRes.pkg = childPkg; + childRes.name = childPkg.packageName; + PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); + if (childPs != null) { + childRes.origUsers = childPs.queryInstalledUsers( + mUserManager.getUserIds(), true); + } + if ((mPackages.containsKey(childPkg.packageName))) { + childRes.removedInfo = new PackageRemovedInfo(this); + childRes.removedInfo.removedPackage = childPkg.packageName; + childRes.removedInfo.installerPackageName = childPs.installerPackageName; + } + if (res.addedChildPackages == null) { + res.addedChildPackages = new ArrayMap<>(); + } + res.addedChildPackages.put(childPkg.packageName, childRes); + } + } + } + // If package doesn't declare API override, mark that we have an install // time CPU ABI override. - // TODO(b/135203078): Isn't this always true because cpuAbiOverride isn't assigned during - // parsing? - if (TextUtils.isEmpty(parsedPackage.getCpuAbiOverride())) { - parsedPackage.setCpuAbiOverride(args.abiOverride); + if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { + pkg.cpuAbiOverride = args.abiOverride; } - String pkgName = res.name = parsedPackage.getPackageName(); - if ((parsedPackage.getFlags() & ApplicationInfo.FLAG_TEST_ONLY) != 0) { + String pkgName = res.name = pkg.packageName; + if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_TEST_ONLY) != 0) { if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { throw new PrepareFailure(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); } @@ -15960,17 +16264,17 @@ public class PackageManagerService extends IPackageManager.Stub try { // either use what we've been given or parse directly from the APK if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) { - parsedPackage.setSigningDetails(args.signingDetails); + pkg.setSigningDetails(args.signingDetails); } else { - ApkParseUtils.collectCertificates(parsedPackage, false /* skipVerify */); + PackageParser.collectCertificates(pkg, false /* skipVerify */); } } catch (PackageParserException e) { throw new PrepareFailure("Failed collect during installPackageLI", e); } - if (instantApp && parsedPackage.getSigningDetails().signatureSchemeVersion + if (instantApp && pkg.mSigningDetails.signatureSchemeVersion < SignatureSchemeVersion.SIGNING_BLOCK_V2) { - Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName() + Slog.w(TAG, "Instant app package " + pkg.packageName + " is not signed with at least APK Signature Scheme v2"); throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID, "Instant app package must be signed with APK Signature Scheme v2 or greater"); @@ -15984,15 +16288,15 @@ public class PackageManagerService extends IPackageManager.Stub // Check if installing already existing package if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { String oldName = mSettings.getRenamedPackageLPr(pkgName); - if (parsedPackage.getOriginalPackages() != null - && parsedPackage.getOriginalPackages().contains(oldName) + if (pkg.mOriginalPackages != null + && pkg.mOriginalPackages.contains(oldName) && mPackages.containsKey(oldName)) { // This package is derived from an original package, // and this device has been updating from that original // name. We must continue using the original name, so // rename the new package here. - parsedPackage.setPackageName(oldName); - pkgName = parsedPackage.getPackageName(); + pkg.setPackageName(oldName); + pkgName = pkg.packageName; replace = true; if (DEBUG_INSTALL) { Slog.d(TAG, "Replacing existing renamed package: oldName=" @@ -16005,27 +16309,43 @@ public class PackageManagerService extends IPackageManager.Stub if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); } + // Child packages are installed through the parent package + if (pkg.parentPackage != null) { + throw new PrepareFailure( + PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, + "Package " + pkg.packageName + " is child of package " + + pkg.parentPackage.parentPackage + ". Child packages " + + "can be updated only through the parent package."); + } + if (replace) { // Prevent apps opting out from runtime permissions - AndroidPackage oldPackage = mPackages.get(pkgName); - final int oldTargetSdk = oldPackage.getTargetSdkVersion(); - final int newTargetSdk = parsedPackage.getTargetSdkVersion(); + PackageParser.Package oldPackage = mPackages.get(pkgName); + final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; + final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { throw new PrepareFailure( PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, - "Package " + parsedPackage.getPackageName() - + " new target SDK " + newTargetSdk + "Package " + pkg.packageName + " new target SDK " + newTargetSdk + " doesn't support runtime permissions but the old" + " target SDK " + oldTargetSdk + " does."); } // Prevent persistent apps from being updated - if (((oldPackage.getFlags() & ApplicationInfo.FLAG_PERSISTENT) != 0) + if (((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0) && ((installFlags & PackageManager.INSTALL_STAGED) == 0)) { throw new PrepareFailure(PackageManager.INSTALL_FAILED_INVALID_APK, - "Package " + oldPackage.getPackageName() + " is a persistent app. " + "Package " + oldPackage.packageName + " is a persistent app. " + "Persistent apps are not updateable."); } + // Prevent installing of child packages + if (oldPackage.parentPackage != null) { + throw new PrepareFailure( + PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, + "Package " + pkg.packageName + " is child of package " + + oldPackage.parentPackage + ". Child packages " + + "can be updated only through the parent package."); + } } } @@ -16038,8 +16358,8 @@ public class PackageManagerService extends IPackageManager.Stub // of the same package, therefore we need to compare signatures against // the package setting for the latest library version. PackageSetting signatureCheckPs = ps; - if (parsedPackage.isStaticSharedLibrary()) { - SharedLibraryInfo libraryInfo = getLatestSharedLibraVersionLPr(parsedPackage); + if (pkg.applicationInfo.isStaticSharedLibrary()) { + SharedLibraryInfo libraryInfo = getLatestSharedLibraVersionLPr(pkg); if (libraryInfo != null) { signatureCheckPs = mSettings.getPackageLPr(libraryInfo.getPackageName()); } @@ -16050,23 +16370,23 @@ public class PackageManagerService extends IPackageManager.Stub // bail early here before tripping over redefined permissions. final KeySetManagerService ksms = mSettings.mKeySetManagerService; if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) { - if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) { + if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) { throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " - + parsedPackage.getPackageName() + " upgrade keys do not match the " + + pkg.packageName + " upgrade keys do not match the " + "previously installed version"); } } else { try { - final boolean compareCompat = isCompatSignatureUpdateNeeded(parsedPackage); - final boolean compareRecover = isRecoverSignatureUpdateNeeded( - parsedPackage); + final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg); + final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg); // We don't care about disabledPkgSetting on install for now. - final boolean compatMatch = verifySignatures(signatureCheckPs, null, - parsedPackage.getSigningDetails(), compareCompat, compareRecover); + final boolean compatMatch = verifySignatures( + signatureCheckPs, null, pkg.mSigningDetails, compareCompat, + compareRecover); // The new KeySets will be re-added later in the scanning process. if (compatMatch) { synchronized (mLock) { - ksms.removeAppKeySetDataLPw(parsedPackage.getPackageName()); + ksms.removeAppKeySetDataLPw(pkg.packageName); } } } catch (PackageManagerException e) { @@ -16074,25 +16394,27 @@ public class PackageManagerService extends IPackageManager.Stub } } - if (ps.pkg != null) { - systemApp = (ps.pkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0; + if (ps.pkg != null && ps.pkg.applicationInfo != null) { + systemApp = (ps.pkg.applicationInfo.flags & + ApplicationInfo.FLAG_SYSTEM) != 0; } res.origUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true); } - int N = ArrayUtils.size(parsedPackage.getPermissions()); + int N = pkg.permissions.size(); for (int i = N - 1; i >= 0; i--) { - final ParsedPermission perm = parsedPackage.getPermissions().get(i); - final BasePermission bp = mPermissionManager.getPermissionTEMP(perm.getName()); + final PackageParser.Permission perm = pkg.permissions.get(i); + final BasePermission bp = + (BasePermission) mPermissionManager.getPermissionTEMP(perm.info.name); // Don't allow anyone but the system to define ephemeral permissions. - if ((perm.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0 + if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0 && !systemApp) { - Slog.w(TAG, "Non-System package " + parsedPackage.getPackageName() + Slog.w(TAG, "Non-System package " + pkg.packageName + " attempting to delcare ephemeral permission " - + perm.getName() + "; Removing ephemeral."); - perm.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT; + + perm.info.name + "; Removing ephemeral."); + perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT; } // Check whether the newly-scanned package wants to define an already-defined perm @@ -16104,27 +16426,26 @@ public class PackageManagerService extends IPackageManager.Stub final String sourcePackageName = bp.getSourcePackageName(); final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting(); final KeySetManagerService ksms = mSettings.mKeySetManagerService; - if (sourcePackageName.equals(parsedPackage.getPackageName()) + if (sourcePackageName.equals(pkg.packageName) && (ksms.shouldCheckUpgradeKeySetLocked( sourcePackageSetting, scanFlags))) { - sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, parsedPackage); + sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, pkg); } else { // in the event of signing certificate rotation, we need to see if the // package's certificate has rotated from the current one, or if it is an // older certificate with which the current is ok with sharing permissions if (sourcePackageSetting.signatures.mSigningDetails.checkCapability( - parsedPackage.getSigningDetails(), + pkg.mSigningDetails, PackageParser.SigningDetails.CertCapabilities.PERMISSION)) { sigsOk = true; - } else if (parsedPackage.getSigningDetails().checkCapability( + } else if (pkg.mSigningDetails.checkCapability( sourcePackageSetting.signatures.mSigningDetails, PackageParser.SigningDetails.CertCapabilities.PERMISSION)) { // the scanned package checks out, has signing certificate rotation // history, and is newer; bring it over - sourcePackageSetting.signatures.mSigningDetails = - parsedPackage.getSigningDetails(); + sourcePackageSetting.signatures.mSigningDetails = pkg.mSigningDetails; sigsOk = true; } else { sigsOk = false; @@ -16136,31 +16457,30 @@ public class PackageManagerService extends IPackageManager.Stub // redefinitions. if (!sourcePackageName.equals("android")) { throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " - + parsedPackage.getPackageName() + + pkg.packageName + " attempting to redeclare permission " - + perm.getName() + " already owned by " + + perm.info.name + " already owned by " + sourcePackageName) - .conflictsWithExistingPermission(perm.getName(), + .conflictsWithExistingPermission(perm.info.name, sourcePackageName); } else { - Slog.w(TAG, "Package " + parsedPackage.getPackageName() + Slog.w(TAG, "Package " + pkg.packageName + " attempting to redeclare system permission " - + perm.getName() + "; ignoring new declaration"); - parsedPackage.removePermission(i); + + perm.info.name + "; ignoring new declaration"); + pkg.permissions.remove(i); } - } else if (!PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())) { + } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) { // Prevent apps to change protection level to dangerous from any other // type as this would allow a privilege escalation where an app adds a // normal/signature permission in other app's group and later redefines // it as dangerous leading to the group auto-grant. - if ((perm.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) + if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) == PermissionInfo.PROTECTION_DANGEROUS) { if (bp != null && !bp.isRuntime()) { - Slog.w(TAG, "Package " + parsedPackage.getPackageName() - + " trying to change a non-runtime permission " - + perm.getName() + Slog.w(TAG, "Package " + pkg.packageName + " trying to change a " + + "non-runtime permission " + perm.info.name + " to runtime; keeping old protection level"); - perm.protectionLevel = bp.getProtectionLevel(); + perm.info.protectionLevel = bp.getProtectionLevel(); } } } @@ -16194,8 +16514,8 @@ public class PackageManagerService extends IPackageManager.Stub // We moved the entire application as-is, so bring over the // previously derived ABI information. - parsedPackage.setPrimaryCpuAbi(ps.primaryCpuAbiString) - .setSecondaryCpuAbi(ps.secondaryCpuAbiString); + pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; + pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; } } else { @@ -16203,14 +16523,14 @@ public class PackageManagerService extends IPackageManager.Stub scanFlags |= SCAN_NO_DEX; try { - String abiOverride = (TextUtils.isEmpty(parsedPackage.getCpuAbiOverride()) - ? args.abiOverride : parsedPackage.getCpuAbiOverride()); - final boolean extractNativeLibs = !parsedPackage.isLibrary(); + String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? + args.abiOverride : pkg.cpuAbiOverride); + final boolean extractNativeLibs = !pkg.isLibrary(); final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> derivedAbi = mInjector.getAbiHelper().derivePackageAbi( - parsedPackage, abiOverride, extractNativeLibs); - derivedAbi.first.applyTo(parsedPackage); - derivedAbi.second.applyTo(parsedPackage); + pkg, abiOverride, extractNativeLibs); + derivedAbi.first.applyTo(pkg); + derivedAbi.second.applyTo(pkg); } catch (PackageManagerException pme) { Slog.e(TAG, "Error deriving application ABI", pme); throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR, @@ -16218,19 +16538,19 @@ public class PackageManagerService extends IPackageManager.Stub } } - if (!args.doRename(res.returnCode, parsedPackage)) { + if (!args.doRename(res.returnCode, pkg)) { throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); } try { - setUpFsVerityIfPossible(parsedPackage); + setUpFsVerityIfPossible(pkg); } catch (InstallerException | IOException | DigestException | NoSuchAlgorithmException e) { throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR, "Failed to set up verity: " + e); } if (!instantApp) { - startIntentFilterVerifications(args.user.getIdentifier(), replace, parsedPackage); + startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); } else { if (DEBUG_DOMAIN_VERIFICATION) { Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName); @@ -16240,7 +16560,7 @@ public class PackageManagerService extends IPackageManager.Stub freezePackageForInstall(pkgName, installFlags, "installPackageLI"); boolean shouldCloseFreezerBeforeReturn = true; try { - final AndroidPackage existingPackage; + final PackageParser.Package existingPackage; String renamedPackage = null; boolean sysPkg = false; String targetVolumeUuid = volumeUuid; @@ -16251,15 +16571,14 @@ public class PackageManagerService extends IPackageManager.Stub final PackageSetting[] childPackages; if (replace) { targetVolumeUuid = null; - if (parsedPackage.isStaticSharedLibrary()) { + if (pkg.applicationInfo.isStaticSharedLibrary()) { // Static libs have a synthetic package name containing the version // and cannot be updated as an update would get a new package name, // unless this is the exact same version code which is useful for // development. - AndroidPackage existingPkg = mPackages.get(parsedPackage.getPackageName()); + PackageParser.Package existingPkg = mPackages.get(pkg.packageName); if (existingPkg != null - && existingPkg.getLongVersionCode() - != parsedPackage.getLongVersionCode()) { + && existingPkg.getLongVersionCode() != pkg.getLongVersionCode()) { throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring " + "static-shared libs cannot be updated"); @@ -16268,8 +16587,8 @@ public class PackageManagerService extends IPackageManager.Stub final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; - final AndroidPackage oldPackage; - final String pkgName11 = parsedPackage.getPackageName(); + final PackageParser.Package oldPackage; + final String pkgName11 = pkg.packageName; final int[] allUsers; final int[] installedUsers; @@ -16277,9 +16596,8 @@ public class PackageManagerService extends IPackageManager.Stub oldPackage = mPackages.get(pkgName11); existingPackage = oldPackage; if (DEBUG_INSTALL) { - // TODO(b/135203078): PackageImpl.toString() Slog.d(TAG, - "replacePackageLI: new=" + parsedPackage + ", old=" + oldPackage); + "replacePackageLI: new=" + pkg + ", old=" + oldPackage); } ps = mSettings.mPackages.get(pkgName11); @@ -16288,18 +16606,17 @@ public class PackageManagerService extends IPackageManager.Stub // verify signatures are valid final KeySetManagerService ksms = mSettings.mKeySetManagerService; if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) { - if (!ksms.checkUpgradeKeySetLocked(ps, parsedPackage)) { + if (!ksms.checkUpgradeKeySetLocked(ps, pkg)) { throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "New package not signed by keys specified by upgrade-keysets: " + pkgName11); } } else { // default to original signature matching - if (!parsedPackage.getSigningDetails().checkCapability( - oldPackage.getSigningDetails(), + if (!pkg.mSigningDetails.checkCapability(oldPackage.mSigningDetails, SigningDetails.CertCapabilities.INSTALLED_DATA) - && !oldPackage.getSigningDetails().checkCapability( - parsedPackage.getSigningDetails(), + && !oldPackage.mSigningDetails.checkCapability( + pkg.mSigningDetails, SigningDetails.CertCapabilities.ROLLBACK)) { throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "New package has a different signature: " + pkgName11); @@ -16307,13 +16624,13 @@ public class PackageManagerService extends IPackageManager.Stub } // don't allow a system upgrade unless the upgrade hash matches - if (oldPackage.getRestrictUpdateHash() != null && oldPackage.isSystem()) { + if (oldPackage.restrictUpdateHash != null && oldPackage.isSystem()) { final byte[] digestBytes; try { final MessageDigest digest = MessageDigest.getInstance("SHA-512"); - updateDigest(digest, new File(parsedPackage.getBaseCodePath())); - if (!ArrayUtils.isEmpty(parsedPackage.getSplitCodePaths())) { - for (String path : parsedPackage.getSplitCodePaths()) { + updateDigest(digest, new File(pkg.baseCodePath)); + if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { + for (String path : pkg.splitCodePaths) { updateDigest(digest, new File(path)); } } @@ -16322,25 +16639,21 @@ public class PackageManagerService extends IPackageManager.Stub throw new PrepareFailure(INSTALL_FAILED_INVALID_APK, "Could not compute hash: " + pkgName11); } - if (!Arrays.equals(oldPackage.getRestrictUpdateHash(), digestBytes)) { + if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) { throw new PrepareFailure(INSTALL_FAILED_INVALID_APK, "New package fails restrict-update check: " + pkgName11); } // retain upgrade restriction - parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash()); + pkg.restrictUpdateHash = oldPackage.restrictUpdateHash; } // Check for shared user id changes - String invalidPackageName = null; - if (!Objects.equals(oldPackage.getSharedUserId(), - parsedPackage.getSharedUserId())) { - invalidPackageName = parsedPackage.getPackageName(); - } - + String invalidPackageName = + getParentOrChildPackageChangedSharedUser(oldPackage, pkg); if (invalidPackageName != null) { throw new PrepareFailure(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, "Package " + invalidPackageName + " tried to change user " - + oldPackage.getSharedUserId()); + + oldPackage.mSharedUserId); } // In case of rollback, remember per-user/profile install state @@ -16373,10 +16686,10 @@ public class PackageManagerService extends IPackageManager.Stub // Update what is removed res.removedInfo = new PackageRemovedInfo(this); - res.removedInfo.uid = oldPackage.getUid(); - res.removedInfo.removedPackage = oldPackage.getPackageName(); + res.removedInfo.uid = oldPackage.applicationInfo.uid; + res.removedInfo.removedPackage = oldPackage.packageName; res.removedInfo.installerPackageName = ps.installerPackageName; - res.removedInfo.isStaticSharedLib = parsedPackage.getStaticSharedLibName() != null; + res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null; res.removedInfo.isUpdate = true; res.removedInfo.origUsers = installedUsers; res.removedInfo.installReasons = new SparseArray<>(installedUsers.length); @@ -16385,6 +16698,52 @@ public class PackageManagerService extends IPackageManager.Stub res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId)); } + childPackages = mSettings.getChildSettingsLPr(ps); + if (childPackages != null) { + for (PackageSetting childPs : childPackages) { + boolean childPackageUpdated = false; + PackageParser.Package childPkg = (childPs == null) ? null : childPs.pkg; + if (res.addedChildPackages != null) { + PackageInstalledInfo childRes = res.addedChildPackages.get( + childPkg.packageName); + if (childRes != null) { + childRes.removedInfo.uid = childPkg.applicationInfo.uid; + childRes.removedInfo.removedPackage = childPkg.packageName; + if (childPs != null) { + childRes.removedInfo.installerPackageName = + childPs.installerPackageName; + } + childRes.removedInfo.isUpdate = true; + childRes.removedInfo.installReasons = + res.removedInfo.installReasons; + childPackageUpdated = true; + } + } + if (!childPackageUpdated) { + PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this); + childRemovedRes.removedPackage = childPkg.packageName; + if (childPs != null) { + childRemovedRes.installerPackageName = childPs.installerPackageName; + } + childRemovedRes.isUpdate = false; + childRemovedRes.dataRemoved = true; + synchronized (mLock) { + if (childPs != null) { + childRemovedRes.origUsers = childPs.queryInstalledUsers( + allUsers, + true); + } + } + if (res.removedInfo.removedChildPackages == null) { + res.removedInfo.removedChildPackages = new ArrayMap<>(); + } + res.removedInfo.removedChildPackages.put(childPkg.packageName, + childRemovedRes); + } + } + } + + sysPkg = (isSystemApp(oldPackage)); if (sysPkg) { // Set the system/privileged/oem/vendor/product flags as needed @@ -16403,30 +16762,41 @@ public class PackageManagerService extends IPackageManager.Stub | (odm ? SCAN_AS_ODM : 0); if (DEBUG_INSTALL) { - Slog.d(TAG, "replaceSystemPackageLI: new=" + parsedPackage + Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg + ", old=" + oldPackage); } res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); - parsedPackage.setUpdatedSystemApp(true); + pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, + ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); targetParseFlags = systemParseFlags; targetScanFlags = systemScanFlags; } else { // non system replace replace = true; if (DEBUG_INSTALL) { Slog.d(TAG, - "replaceNonSystemPackageLI: new=" + parsedPackage + ", old=" + "replaceNonSystemPackageLI: new=" + pkg + ", old=" + oldPackage); } + + String pkgName1 = oldPackage.packageName; + boolean deletedPkg = true; + boolean addedPkg = false; + boolean updatedSettings = false; + + final long origUpdateTime = (pkg.mExtras != null) + ? ((PackageSetting) pkg.mExtras).lastUpdateTime : 0; + } } else { // new package install ps = null; + childPackages = null; disabledPs = null; replace = false; existingPackage = null; // Remember this for later, in case we need to rollback this install - String pkgName1 = parsedPackage.getPackageName(); + String pkgName1 = pkg.packageName; - if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + parsedPackage); + if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); // TODO(patb): MOVE TO RECONCILE synchronized (mLock) { @@ -16453,9 +16823,9 @@ public class PackageManagerService extends IPackageManager.Stub shouldCloseFreezerBeforeReturn = false; return new PrepareResult(args.installReason, targetVolumeUuid, installerPackageName, - args.user, replace, targetScanFlags, targetParseFlags, existingPackage, - parsedPackage, replace /* clearCodeCache */, sysPkg, renamedPackage, freezer, - ps, disabledPs); + args.user, replace, targetScanFlags, targetParseFlags, existingPackage, pkg, + replace /* clearCodeCache */, sysPkg, renamedPackage, freezer, + ps, disabledPs, childPackages); } finally { if (shouldCloseFreezerBeforeReturn) { freezer.close(); @@ -16470,7 +16840,7 @@ public class PackageManagerService extends IPackageManager.Stub * <p>When the feature flag is set to legacy mode, only APK is supported (with some experimental * kernel patches). In normal mode, all file format can be supported. */ - private void setUpFsVerityIfPossible(AndroidPackage pkg) throws InstallerException, + private void setUpFsVerityIfPossible(PackageParser.Package pkg) throws InstallerException, PrepareFailure, IOException, DigestException, NoSuchAlgorithmException { final boolean standardMode = PackageManagerServiceUtils.isApkVerityEnabled(); final boolean legacyMode = PackageManagerServiceUtils.isLegacyApkVerityEnabled(); @@ -16482,11 +16852,11 @@ public class PackageManagerService extends IPackageManager.Stub ArrayMap<String, String> fsverityCandidates = new ArrayMap<>(); if (legacyMode) { synchronized (mLock) { - final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName()); + final PackageSetting ps = mSettings.mPackages.get(pkg.packageName); if (ps != null && ps.isPrivileged()) { - fsverityCandidates.put(pkg.getBaseCodePath(), null); - if (pkg.getSplitCodePaths() != null) { - for (String splitPath : pkg.getSplitCodePaths()) { + fsverityCandidates.put(pkg.baseCodePath, null); + if (pkg.splitCodePaths != null) { + for (String splitPath : pkg.splitCodePaths) { fsverityCandidates.put(splitPath, null); } } @@ -16495,17 +16865,16 @@ public class PackageManagerService extends IPackageManager.Stub } else { // NB: These files will become only accessible if the signing key is loaded in kernel's // .fs-verity keyring. - fsverityCandidates.put(pkg.getBaseCodePath(), - VerityUtils.getFsveritySignatureFilePath(pkg.getBaseCodePath())); + fsverityCandidates.put(pkg.baseCodePath, + VerityUtils.getFsveritySignatureFilePath(pkg.baseCodePath)); - final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk( - pkg.getBaseCodePath()); + final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk(pkg.baseCodePath); if (new File(dmPath).exists()) { fsverityCandidates.put(dmPath, VerityUtils.getFsveritySignatureFilePath(dmPath)); } - if (pkg.getSplitCodePaths() != null) { - for (String path : pkg.getSplitCodePaths()) { + if (pkg.splitCodePaths != null) { + for (String path : pkg.splitCodePaths) { fsverityCandidates.put(path, VerityUtils.getFsveritySignatureFilePath(path)); final String splitDmPath = DexMetadataHelper.buildDexMetadataPathForApk(path); @@ -16559,7 +16928,8 @@ public class PackageManagerService extends IPackageManager.Stub } } - private void startIntentFilterVerifications(int userId, boolean replacing, AndroidPackage pkg) { + private void startIntentFilterVerifications(int userId, boolean replacing, + PackageParser.Package pkg) { if (mIntentFilterVerifierComponent == null) { Slog.w(TAG, "No IntentFilter verification will not be done as " + "there is no IntentFilterVerifier available!"); @@ -16572,29 +16942,29 @@ public class PackageManagerService extends IPackageManager.Stub (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); - msg.obj = new IFVerificationParams( - pkg.getPackageName(), - hasDomainURLs(pkg), - pkg.getActivities(), - replacing, - userId, - verifierUid - ); + msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); mHandler.sendMessage(msg); + + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + PackageParser.Package childPkg = pkg.childPackages.get(i); + msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); + msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); + mHandler.sendMessage(msg); + } } private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, - String packageName, - boolean hasDomainUrls, - List<ParsedActivity> activities) { - int size = activities.size(); + PackageParser.Package pkg) { + int size = pkg.activities.size(); if (size == 0) { if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "No activity, so no need to verify any IntentFilter!"); return; } - if (!hasDomainUrls) { + final boolean hasDomainURLs = hasDomainURLs(pkg); + if (!hasDomainURLs) { if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "No domain URLs, so no need to verify any IntentFilter!"); return; @@ -16605,6 +16975,7 @@ public class PackageManagerService extends IPackageManager.Stub + " Activities needs verification ..."); int count = 0; + final String packageName = pkg.packageName; synchronized (mLock) { // If this is a new install and we see that we've already run verification for this @@ -16623,8 +16994,8 @@ public class PackageManagerService extends IPackageManager.Stub // If any filters need to be verified, then all need to be. boolean needToVerify = false; - for (ParsedActivity a : activities) { - for (ParsedActivityIntentInfo filter : a.intents) { + for (PackageParser.Activity a : pkg.activities) { + for (ActivityIntentInfo filter : a.intents) { if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) { Slog.d(TAG, @@ -16638,8 +17009,8 @@ public class PackageManagerService extends IPackageManager.Stub if (needToVerify) { final int verificationId = mIntentFilterVerificationToken++; - for (ParsedActivity a : activities) { - for (ParsedActivityIntentInfo filter : a.intents) { + for (PackageParser.Activity a : pkg.activities) { + for (ActivityIntentInfo filter : a.intents) { if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString()); @@ -16665,8 +17036,9 @@ public class PackageManagerService extends IPackageManager.Stub } @GuardedBy("mLock") - private boolean needsNetworkVerificationLPr(ParsedActivityIntentInfo filter) { - final String packageName = filter.getPackageName(); + private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { + final ComponentName cn = filter.activity.getComponentName(); + final String packageName = cn.getPackageName(); IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( packageName); @@ -16686,45 +17058,45 @@ public class PackageManagerService extends IPackageManager.Stub } } - private static boolean isExternal(AndroidPackage pkg) { - return (pkg.getFlags() & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; + private static boolean isExternal(PackageParser.Package pkg) { + return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; } private static boolean isExternal(PackageSetting ps) { return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; } - static boolean isSystemApp(AndroidPackage pkg) { - return (pkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0; + static boolean isSystemApp(PackageParser.Package pkg) { + return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; } - private static boolean isPrivilegedApp(AndroidPackage pkg) { - return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; + private static boolean isPrivilegedApp(PackageParser.Package pkg) { + return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; } - private static boolean isOemApp(AndroidPackage pkg) { - return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_OEM) != 0; + private static boolean isOemApp(PackageParser.Package pkg) { + return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0; } - private static boolean isVendorApp(AndroidPackage pkg) { - return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0; + private static boolean isVendorApp(PackageParser.Package pkg) { + return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0; } - private static boolean isProductApp(AndroidPackage pkg) { - return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0; + private static boolean isProductApp(PackageParser.Package pkg) { + return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0; } - private static boolean isSystemExtApp(AndroidPackage pkg) { - return (pkg.getPrivateFlags() + private static boolean isSystemExtApp(PackageParser.Package pkg) { + return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0; } - private static boolean isOdmApp(AndroidPackage pkg) { - return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_ODM) != 0; + private static boolean isOdmApp(PackageParser.Package pkg) { + return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_ODM) != 0; } - private static boolean hasDomainURLs(AndroidPackage pkg) { - return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; + private static boolean hasDomainURLs(PackageParser.Package pkg) { + return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; } private static boolean isSystemApp(PackageSetting ps) { @@ -16735,12 +17107,12 @@ public class PackageManagerService extends IPackageManager.Stub return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; } - private VersionInfo getSettingsVersionForPackage(AndroidPackage pkg) { + private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { if (isExternal(pkg)) { - if (TextUtils.isEmpty(pkg.getVolumeUuid())) { + if (TextUtils.isEmpty(pkg.volumeUuid)) { return mSettings.getExternalVersion(); } else { - return mSettings.findOrCreateVersion(pkg.getVolumeUuid()); + return mSettings.findOrCreateVersion(pkg.volumeUuid); } } else { return mSettings.getInternalVersion(); @@ -16748,7 +17120,6 @@ public class PackageManagerService extends IPackageManager.Stub } private void deleteTempPackageFiles() { - // TODO: Is this used? final FilenameFilter filter = (dir, name) -> name.startsWith("vmdl") && name.endsWith(".tmp"); } @@ -16882,11 +17253,11 @@ public class PackageManagerService extends IPackageManager.Stub }); } - private String resolveExternalPackageNameLPr(AndroidPackage pkg) { - if (pkg.getStaticSharedLibName() != null) { - return pkg.getManifestPackageName(); + private String resolveExternalPackageNameLPr(PackageParser.Package pkg) { + if (pkg.staticSharedLibName != null) { + return pkg.manifestPackageName; } - return pkg.getPackageName(); + return pkg.packageName; } @GuardedBy("mLock") @@ -17093,7 +17464,7 @@ public class PackageManagerService extends IPackageManager.Stub final PackageSetting uninstalledPs; final PackageSetting disabledSystemPs; - final AndroidPackage pkg; + final PackageParser.Package pkg; // for the uninstall-updates case and restricted profiles, remember the per- // user handle installed state @@ -17125,9 +17496,9 @@ public class PackageManagerService extends IPackageManager.Stub allUsers = mUserManager.getUserIds(); - if (pkg != null && pkg.getStaticSharedLibName() != null) { - SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr( - pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion()); + if (pkg != null && pkg.staticSharedLibName != null) { + SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(pkg.staticSharedLibName, + pkg.staticSharedLibVersion); if (libraryInfo != null) { for (int currUserId : allUsers) { if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) { @@ -17136,7 +17507,7 @@ public class PackageManagerService extends IPackageManager.Stub List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr( libraryInfo, 0, currUserId); if (!ArrayUtils.isEmpty(libClientPackages)) { - Slog.w(TAG, "Not removing package " + pkg.getManifestPackageName() + Slog.w(TAG, "Not removing package " + pkg.manifestPackageName + " hosting lib " + libraryInfo.getName() + " version " + libraryInfo.getLongVersion() + " used by " + libClientPackages + " for user " + currUserId); @@ -17191,13 +17562,13 @@ public class PackageManagerService extends IPackageManager.Stub if (info.args != null) { info.args.doPostDeleteLI(true); } - final AndroidPackage stubPkg = + final PackageParser.Package stubPkg = (disabledSystemPs == null) ? null : disabledSystemPs.pkg; - if (stubPkg != null && stubPkg.isStub()) { + if (stubPkg != null && stubPkg.isStub) { synchronized (mLock) { // restore the enabled state of the stub; the state is overwritten when // the stub is uninstalled - final PackageSetting stubPs = mSettings.mPackages.get(stubPkg.getPackageName()); + final PackageSetting stubPs = mSettings.mPackages.get(stubPkg.packageName); if (stubPs != null) { stubPs.setEnabled(origEnabledState, userId, "android"); } @@ -17206,7 +17577,7 @@ public class PackageManagerService extends IPackageManager.Stub || origEnabledState == COMPONENT_ENABLED_STATE_ENABLED) { if (DEBUG_COMPRESSION) { Slog.i(TAG, "Enabling system stub after removal; pkg: " - + stubPkg.getPackageName()); + + stubPkg.packageName); } enableCompressedPackage(stubPkg); } @@ -17234,6 +17605,7 @@ public class PackageManagerService extends IPackageManager.Stub boolean isStaticSharedLib; // Clean up resources deleted packages. InstallArgs args = null; + ArrayMap<String, PackageRemovedInfo> removedChildPackages; ArrayMap<String, PackageInstalledInfo> appearedChildPackages; PackageRemovedInfo(PackageSender packageSender) { @@ -17242,11 +17614,24 @@ public class PackageManagerService extends IPackageManager.Stub void sendPackageRemovedBroadcasts(boolean killApp) { sendPackageRemovedBroadcastInternal(killApp); + final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); + childInfo.sendPackageRemovedBroadcastInternal(killApp); + } } void sendSystemPackageUpdatedBroadcasts() { if (isRemovedPackageSystemUpdate) { sendSystemPackageUpdatedBroadcastsInternal(); + final int childCount = (removedChildPackages != null) + ? removedChildPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); + if (childInfo.isRemovedPackageSystemUpdate) { + childInfo.sendSystemPackageUpdatedBroadcastsInternal(); + } + } } } @@ -17358,12 +17743,12 @@ public class PackageManagerService extends IPackageManager.Stub String packageName = deletedPs.name; if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + deletedPs); // Retrieve object to delete permissions for shared user later on - final AndroidPackage deletedPkg = deletedPs.pkg; + final PackageParser.Package deletedPkg = deletedPs.pkg; if (outInfo != null) { outInfo.removedPackage = packageName; outInfo.installerPackageName = deletedPs.installerPackageName; outInfo.isStaticSharedLib = deletedPkg != null - && deletedPkg.getStaticSharedLibName() != null; + && deletedPkg.staticSharedLibName != null; outInfo.populateUsers(deletedPs == null ? null : deletedPs.queryInstalledUsers(mUserManager.getUserIds(), true), deletedPs); } @@ -17371,14 +17756,14 @@ public class PackageManagerService extends IPackageManager.Stub removePackageLI(deletedPs.name, (flags & PackageManager.DELETE_CHATTY) != 0); if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { - final AndroidPackage resolvedPkg; + final PackageParser.Package resolvedPkg; if (deletedPkg != null) { resolvedPkg = deletedPkg; } else { // We don't have a parsed package when it lives on an ejected // adopted storage device, so fake something together - resolvedPkg = PackageImpl.buildFakeForDeletion(deletedPs.name, - deletedPs.volumeUuid); + resolvedPkg = new PackageParser.Package(deletedPs.name); + resolvedPkg.setVolumeUuid(deletedPs.volumeUuid); } destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL); @@ -17490,13 +17875,13 @@ public class PackageManagerService extends IPackageManager.Stub throws SystemDeleteException { final boolean applyUserRestrictions = (allUserHandles != null) && outInfo != null && (outInfo.origUsers != null); - final AndroidPackage deletedPkg = deletedPs.pkg; + final PackageParser.Package deletedPkg = deletedPs.pkg; // Confirm if the system package has been updated // An updated system app can be deleted. This will also have to restore // the system pkg from system partition // reader final PackageSetting disabledPs = action.disabledPs; - if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.getPackageName() + if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName + " disabledPs=" + disabledPs); Slog.d(TAG, "Deleting system pkg from data partition"); @@ -17513,6 +17898,21 @@ public class PackageManagerService extends IPackageManager.Stub if (outInfo != null) { // Delete the updated package outInfo.isRemovedPackageSystemUpdate = true; + if (outInfo.removedChildPackages != null) { + final int childCount = (deletedPs.childPackageNames != null) + ? deletedPs.childPackageNames.size() : 0; + for (int i = 0; i < childCount; i++) { + String childPackageName = deletedPs.childPackageNames.get(i); + if (disabledPs.childPackageNames != null && disabledPs.childPackageNames + .contains(childPackageName)) { + PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( + childPackageName); + if (childInfo != null) { + childInfo.isRemovedPackageSystemUpdate = true; + } + } + } + } } if (disabledPs.versionCode < deletedPs.versionCode) { @@ -17524,7 +17924,7 @@ public class PackageManagerService extends IPackageManager.Stub } deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, - outInfo, writeSettings); + outInfo, writeSettings, disabledPs.pkg); // writer synchronized (mLock) { @@ -17545,16 +17945,16 @@ public class PackageManagerService extends IPackageManager.Stub outInfo == null ? null : outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings); } catch (PackageManagerException e) { - Slog.w(TAG, "Failed to restore system package:" + deletedPkg.getPackageName() + ": " + Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " + e.getMessage()); // TODO(patb): can we avoid this; throw would come from scan... throw new SystemDeleteException(e); } finally { - if (disabledPs.pkg.isStub()) { + if (disabledPs.pkg.isStub) { // We've re-installed the stub; make sure it's disabled here. If package was // originally enabled, we'll install the compressed version of the application // and re-enable it afterward. - final PackageSetting stubPs = mSettings.mPackages.get(deletedPkg.getPackageName()); + final PackageSetting stubPs = mSettings.mPackages.get(deletedPkg.packageName); if (stubPs != null) { stubPs.setEnabled( COMPONENT_ENABLED_STATE_DISABLED, UserHandle.USER_SYSTEM, "android"); @@ -17566,7 +17966,7 @@ public class PackageManagerService extends IPackageManager.Stub /** * Installs a package that's already on the system partition. */ - private AndroidPackage installPackageFromSystemLIF(@NonNull String codePathString, + private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles, @Nullable PermissionsState origPermissionState, boolean writeSettings) throws PackageManagerException { @@ -17587,7 +17987,7 @@ public class PackageManagerService extends IPackageManager.Stub } final File codePath = new File(codePathString); - final AndroidPackage pkg = + final PackageParser.Package pkg = scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null); try { @@ -17601,7 +18001,7 @@ public class PackageManagerService extends IPackageManager.Stub // writer synchronized (mLock) { - PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName()); + PackageSetting ps = mSettings.mPackages.get(pkg.packageName); // Propagate the permissions state as we do not want to drop on the floor // runtime permissions. The update permissions method below will take @@ -17609,7 +18009,7 @@ public class PackageManagerService extends IPackageManager.Stub if (origPermissionState != null) { ps.getPermissionsState().copyFrom(origPermissionState); } - mPermissionManager.updatePermissions(pkg.getPackageName(), pkg); + mPermissionManager.updatePermissions(pkg.packageName, pkg); final boolean applyUserRestrictions = (allUserHandles != null) && (origUserHandles != null); @@ -17647,22 +18047,58 @@ public class PackageManagerService extends IPackageManager.Stub private void deleteInstalledPackageLIF(PackageSetting ps, boolean deleteCodeAndResources, int flags, int[] allUserHandles, - PackageRemovedInfo outInfo, boolean writeSettings) { + PackageRemovedInfo outInfo, boolean writeSettings, + PackageParser.Package replacingPackage) { synchronized (mLock) { if (outInfo != null) { outInfo.uid = ps.appId; } + + if (outInfo != null && outInfo.removedChildPackages != null) { + final int childCount = (ps.childPackageNames != null) + ? ps.childPackageNames.size() : 0; + for (int i = 0; i < childCount; i++) { + String childPackageName = ps.childPackageNames.get(i); + PackageSetting childPs = mSettings.mPackages.get(childPackageName); + PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( + childPackageName); + if (childInfo != null) { + childInfo.uid = childPs.appId; + } + } + } } // Delete package data from internal structures and also remove data if flag is set removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings); + // Delete the child packages data + final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; + for (int i = 0; i < childCount; i++) { + PackageSetting childPs; + synchronized (mLock) { + childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i)); + } + if (childPs != null) { + PackageRemovedInfo childOutInfo = (outInfo != null + && outInfo.removedChildPackages != null) + ? outInfo.removedChildPackages.get(childPs.name) : null; + final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 + && (replacingPackage != null + && !replacingPackage.hasChildPackage(childPs.name)) + ? flags & ~DELETE_KEEP_DATA : flags; + removePackageDataLIF(childPs, allUserHandles, childOutInfo, + deleteFlags, writeSettings); + } + } + // Delete application code and resources only for parent packages - if (deleteCodeAndResources && (outInfo != null)) { - outInfo.args = createInstallArgsForExisting( - ps.codePathString, ps.resourcePathString, getAppDexInstructionSets( - ps.primaryCpuAbiString, ps.secondaryCpuAbiString)); - if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); + if (ps.parentPackageName == null) { + if (deleteCodeAndResources && (outInfo != null)) { + outInfo.args = createInstallArgsForExisting( + ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); + if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); + } } } @@ -17675,10 +18111,10 @@ public class PackageManagerService extends IPackageManager.Stub // Cannot block uninstall of static shared libs as they are // considered a part of the using app (emulating static linking). // Also static libs are installed always on internal storage. - AndroidPackage pkg = mPackages.get(packageName); - if (pkg != null && pkg.getStaticSharedLibName() != null) { + PackageParser.Package pkg = mPackages.get(packageName); + if (pkg != null && pkg.staticSharedLibName != null) { Slog.w(TAG, "Cannot block uninstall of package: " + packageName - + " providing static shared library: " + pkg.getStaticSharedLibName()); + + " providing static shared library: " + pkg.staticSharedLibName); return false; } mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall); @@ -17742,22 +18178,40 @@ public class PackageManagerService extends IPackageManager.Stub @GuardedBy("mLock") private static DeletePackageAction mayDeletePackageLocked( PackageRemovedInfo outInfo, PackageSetting ps, @Nullable PackageSetting disabledPs, - int flags, UserHandle user) { + @Nullable PackageSetting[] children, int flags, UserHandle user) { if (ps == null) { return null; } if (isSystemApp(ps)) { + if (ps.parentPackageName != null) { + Slog.w(TAG, "Attempt to delete child system package " + ps.pkg.packageName); + return null; + } + final boolean deleteSystem = (flags & PackageManager.DELETE_SYSTEM_APP) != 0; final boolean deleteAllUsers = user == null || user.getIdentifier() == UserHandle.USER_ALL; if ((!deleteSystem || deleteAllUsers) && disabledPs == null) { - Slog.w(TAG, "Attempt to delete unknown system package " + ps.pkg.getPackageName()); + Slog.w(TAG, "Attempt to delete unknown system package " + ps.pkg.packageName); return null; } // Confirmed if the system package has been updated // An updated system app can be deleted. This will also have to restore // the system pkg from system partition reader } + final int parentReferenceCount = + (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; + final int childCount = children != null ? children.length : 0; + if (childCount != parentReferenceCount) { + return null; + } + if (childCount != 0 && outInfo != null && outInfo.removedChildPackages != null) { + for (PackageSetting child : children) { + if (child == null || !ps.childPackageNames.contains(child.name)) { + return null; + } + } + } return new DeletePackageAction(ps, disabledPs, outInfo, flags, user); } @@ -17767,12 +18221,13 @@ public class PackageManagerService extends IPackageManager.Stub private boolean deletePackageLIF(@NonNull String packageName, UserHandle user, boolean deleteCodeAndResources, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, boolean writeSettings, - ParsedPackage replacingPackage) { + PackageParser.Package replacingPackage) { final DeletePackageAction action; synchronized (mLock) { final PackageSetting ps = mSettings.mPackages.get(packageName); final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps); - action = mayDeletePackageLocked(outInfo, ps, disabledPs, flags, user); + PackageSetting[] children = mSettings.getChildSettingsLPr(ps); + action = mayDeletePackageLocked(outInfo, ps, disabledPs, children, flags, user); } if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); if (null == action) { @@ -17803,13 +18258,30 @@ public class PackageManagerService extends IPackageManager.Stub private void executeDeletePackageLIF(DeletePackageAction action, String packageName, boolean deleteCodeAndResources, int[] allUserHandles, boolean writeSettings, - ParsedPackage replacingPackage) throws SystemDeleteException { + PackageParser.Package replacingPackage) throws SystemDeleteException { final PackageSetting ps = action.deletingPs; final PackageRemovedInfo outInfo = action.outInfo; final UserHandle user = action.user; final int flags = action.flags; final boolean systemApp = isSystemApp(ps); + if (ps.parentPackageName != null + && (!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { + if (DEBUG_REMOVE) { + Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" + + ((user == null) ? UserHandle.USER_ALL : user)); + } + final int removedUserId = (user != null) ? user.getIdentifier() + : UserHandle.USER_ALL; + + clearPackageStateForUserLIF(ps, removedUserId, outInfo, flags); + synchronized (mLock) { + markPackageUninstalledForUserLPw(ps, user); + scheduleWritePackageRestrictionsLocked(user); + } + return; + } + final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier(); if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS, userId)) { unsuspendForSuspendingPackage(packageName, userId); @@ -17859,6 +18331,26 @@ public class PackageManagerService extends IPackageManager.Stub } } + // If we are deleting a composite package for all users, keep track + // of result for each child. + if (ps.childPackageNames != null && outInfo != null) { + synchronized (mLock) { + final int childCount = ps.childPackageNames.size(); + outInfo.removedChildPackages = new ArrayMap<>(childCount); + for (int i = 0; i < childCount; i++) { + String childPackageName = ps.childPackageNames.get(i); + PackageRemovedInfo childInfo = new PackageRemovedInfo(this); + childInfo.removedPackage = childPackageName; + childInfo.installerPackageName = ps.installerPackageName; + outInfo.removedChildPackages.put(childPackageName, childInfo); + PackageSetting childPs = mSettings.getPackageLPr(childPackageName); + if (childPs != null) { + childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); + } + } + } + } + // TODO(b/109941548): break reasons for ret = false out into mayDelete method if (systemApp) { if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); @@ -17868,12 +18360,53 @@ public class PackageManagerService extends IPackageManager.Stub } else { if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles, - outInfo, writeSettings); + outInfo, writeSettings, replacingPackage); } // Take a note whether we deleted the package for all users if (outInfo != null) { outInfo.removedForAllUsers = mPackages.get(ps.name) == null; + if (outInfo.removedChildPackages != null) { + synchronized (mLock) { + final int childCount = outInfo.removedChildPackages.size(); + for (int i = 0; i < childCount; i++) { + PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); + if (childInfo != null) { + childInfo.removedForAllUsers = mPackages.get( + childInfo.removedPackage) == null; + } + } + } + } + // If we uninstalled an update to a system app there may be some + // child packages that appeared as they are declared in the system + // app but were not declared in the update. + if (systemApp) { + synchronized (mLock) { + PackageSetting updatedPs = mSettings.getPackageLPr(ps.name); + final int childCount = (updatedPs.childPackageNames != null) + ? updatedPs.childPackageNames.size() : 0; + for (int i = 0; i < childCount; i++) { + String childPackageName = updatedPs.childPackageNames.get(i); + if (outInfo.removedChildPackages == null + || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { + PackageSetting childPs = mSettings.getPackageLPr(childPackageName); + if (childPs == null) { + continue; + } + PackageInstalledInfo installRes = new PackageInstalledInfo(); + installRes.name = childPackageName; + installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); + installRes.pkg = mPackages.get(childPackageName); + installRes.uid = childPs.pkg.applicationInfo.uid; + if (outInfo.appearedChildPackages == null) { + outInfo.appearedChildPackages = new ArrayMap<>(); + } + outInfo.appearedChildPackages.put(childPackageName, installRes); + } + } + } + } } } @@ -17892,10 +18425,7 @@ public class PackageManagerService extends IPackageManager.Stub false /*hidden*/, 0 /*distractionFlags*/, false /*suspended*/, - null /*suspendingPackage*/, - null /*dialogInfo*/, - null /*suspendedAppExtras*/, - null /*suspendedLauncherExtras*/, + null /*suspendParams*/, false /*instantApp*/, false /*virtualPreload*/, null /*lastDisableAppCaller*/, @@ -17910,7 +18440,7 @@ public class PackageManagerService extends IPackageManager.Stub private void clearPackageStateForUserLIF(PackageSetting ps, int userId, PackageRemovedInfo outInfo, int flags) { - final AndroidPackage pkg; + final PackageParser.Package pkg; synchronized (mLock) { pkg = mPackages.get(ps.name); } @@ -17952,7 +18482,7 @@ public class PackageManagerService extends IPackageManager.Stub if (outInfo != null) { outInfo.removedPackage = ps.name; outInfo.installerPackageName = ps.installerPackageName; - outInfo.isStaticSharedLib = pkg != null && pkg.getStaticSharedLibName() != null; + outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null; outInfo.removedAppId = ps.appId; outInfo.removedUsers = userIds; outInfo.broadcastUsers = userIds; @@ -17963,7 +18493,7 @@ public class PackageManagerService extends IPackageManager.Stub public void clearApplicationProfileData(String packageName) { enforceSystemOrRoot("Only the system can clear all profile data"); - final AndroidPackage pkg; + final PackageParser.Package pkg; synchronized (mLock) { pkg = mPackages.get(packageName); } @@ -18041,7 +18571,7 @@ public class PackageManagerService extends IPackageManager.Stub } // Try finding details about the requested package - AndroidPackage pkg; + PackageParser.Package pkg; synchronized (mLock) { pkg = mPackages.get(packageName); if (pkg == null) { @@ -18060,7 +18590,7 @@ public class PackageManagerService extends IPackageManager.Stub clearAppDataLIF(pkg, userId, FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL); - final int appId = UserHandle.getAppId(pkg.getUid()); + final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), userId, appId); UserManagerInternal umInternal = mInjector.getUserManagerInternal(); @@ -18137,14 +18667,14 @@ public class PackageManagerService extends IPackageManager.Stub final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission( android.Manifest.permission.ACCESS_INSTANT_APPS); - final AndroidPackage pkg; + final PackageParser.Package pkg; synchronized (mLock) { pkg = mPackages.get(packageName); } // Queue up an async operation since the package deletion may take a little while. mHandler.post(() -> { - final PackageSetting ps = pkg == null ? null : getPackageSetting(pkg.getPackageName()); + final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras; boolean doClearData = true; if (ps != null) { final boolean targetIsInstantApp = @@ -18224,7 +18754,7 @@ public class PackageManagerService extends IPackageManager.Stub while (it.hasNext()) { final PackageSetting ps = it.next(); if (ps.pkg != null) { - int v = ps.pkg.getTargetSdkVersion(); + int v = ps.pkg.applicationInfo.targetSdkVersion; if (v < vers) vers = v; } } @@ -18232,7 +18762,7 @@ public class PackageManagerService extends IPackageManager.Stub } else if (obj instanceof PackageSetting) { final PackageSetting ps = (PackageSetting) obj; if (ps.pkg != null) { - return ps.pkg.getTargetSdkVersion(); + return ps.pkg.applicationInfo.targetSdkVersion; } } return Build.VERSION_CODES.CUR_DEVELOPMENT; @@ -18240,9 +18770,9 @@ public class PackageManagerService extends IPackageManager.Stub @GuardedBy("mLock") private int getPackageTargetSdkVersionLockedLPr(String packageName) { - final AndroidPackage p = mPackages.get(packageName); + final PackageParser.Package p = mPackages.get(packageName); if (p != null) { - return p.getTargetSdkVersion(); + return p.applicationInfo.targetSdkVersion; } return Build.VERSION_CODES.CUR_DEVELOPMENT; } @@ -18411,7 +18941,7 @@ public class PackageManagerService extends IPackageManager.Stub } // writer synchronized (mLock) { - AndroidPackage pkg = mPackages.get(packageName); + PackageParser.Package pkg = mPackages.get(packageName); if (pkg == null || !isCallerSameApp(packageName, callingUid)) { if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.SET_PREFERRED_APPLICATIONS) @@ -18485,8 +19015,8 @@ public class PackageManagerService extends IPackageManager.Stub private void clearIntentFilterVerificationsLPw(int userId) { final int packageCount = mPackages.size(); for (int i = 0; i < packageCount; i++) { - AndroidPackage pkg = mPackages.valueAt(i); - clearIntentFilterVerificationsLPw(pkg.getPackageName(), userId); + PackageParser.Package pkg = mPackages.valueAt(i); + clearIntentFilterVerificationsLPw(pkg.packageName, userId); } } @@ -19393,8 +19923,8 @@ public class PackageManagerService extends IPackageManager.Stub // If we're enabling a system stub, there's a little more work to do. // Prior to enabling the package, we need to decompress the APK(s) to the // data partition and then replace the version on the system partition. - final AndroidPackage deletedPkg = pkgSetting.pkg; - final boolean isSystemStub = deletedPkg.isStub() + final PackageParser.Package deletedPkg = pkgSetting.pkg; + final boolean isSystemStub = deletedPkg.isStub && deletedPkg.isSystem(); if (isSystemStub && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT @@ -19415,10 +19945,10 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mLock) { // We're dealing with a component level state change // First, verify that this is a valid class name. - AndroidPackage pkg = pkgSetting.pkg; + PackageParser.Package pkg = pkgSetting.pkg; if (pkg == null || !pkg.hasComponentClassName(className)) { if (pkg != null && - pkg.getTargetSdkVersion() >= + pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) { throw new IllegalArgumentException("Component class " + className + " does not exist in " + packageName); @@ -19450,7 +19980,11 @@ public class PackageManagerService extends IPackageManager.Stub } } synchronized (mLock) { - scheduleWritePackageRestrictionsLocked(userId); + if ((flags & PackageManager.SYNCHRONOUS) != 0) { + flushPackageRestrictionsAsUserInternalLocked(userId); + } else { + scheduleWritePackageRestrictionsLocked(userId); + } updateSequenceNumberLP(pkgSetting, new int[] { userId }); final long callingId = Binder.clearCallingIdentity(); try { @@ -19511,11 +20045,16 @@ public class PackageManagerService extends IPackageManager.Stub mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, false /* checkShell */, "flushPackageRestrictions"); synchronized (mLock) { - mSettings.writePackageRestrictionsLPr(userId); - mDirtyUsers.remove(userId); - if (mDirtyUsers.isEmpty()) { - mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); - } + flushPackageRestrictionsAsUserInternalLocked(userId); + } + } + + @GuardedBy("mLock") + private void flushPackageRestrictionsAsUserInternalLocked(int userId) { + mSettings.writePackageRestrictionsLPr(userId); + mDirtyUsers.remove(userId); + if (mDirtyUsers.isEmpty()) { + mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); } } @@ -19725,7 +20264,7 @@ public class PackageManagerService extends IPackageManager.Stub mInjector.getPermissionPolicyInternal(); permissionPolicyInternal.setOnInitializedCallback(userId -> { // The SDK updated case is already handled when we run during the ctor. - synchronized (mPackages) { + synchronized (mLock) { mPermissionManager.updateAllPermissions( StorageManager.UUID_PRIVATE_INTERNAL, false); } @@ -20358,7 +20897,7 @@ public class PackageManagerService extends IPackageManager.Stub if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS) && packageName == null) { - mComponentResolver.dumpServicePermissions(pw, dumpState); + mComponentResolver.dumpServicePermissions(pw, dumpState, packageName); } if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) { @@ -20501,9 +21040,9 @@ public class PackageManagerService extends IPackageManager.Stub ipw.println(); ipw.println("Dexopt state:"); ipw.increaseIndent(); - Collection<AndroidPackage> packages; + Collection<PackageParser.Package> packages; if (packageName != null) { - AndroidPackage targetPackage = mPackages.get(packageName); + PackageParser.Package targetPackage = mPackages.get(packageName); if (targetPackage != null) { packages = Collections.singletonList(targetPackage); } else { @@ -20514,11 +21053,11 @@ public class PackageManagerService extends IPackageManager.Stub packages = mPackages.values(); } - for (AndroidPackage pkg : packages) { - ipw.println("[" + pkg.getPackageName() + "]"); + for (PackageParser.Package pkg : packages) { + ipw.println("[" + pkg.packageName + "]"); ipw.increaseIndent(); mPackageDexOptimizer.dumpDexoptState(ipw, pkg, - mDexManager.getPackageUseInfoOrDefault(pkg.getPackageName())); + mDexManager.getPackageUseInfoOrDefault(pkg.packageName)); ipw.decreaseIndent(); } } @@ -20530,9 +21069,9 @@ public class PackageManagerService extends IPackageManager.Stub ipw.println(); ipw.println("Compiler stats:"); ipw.increaseIndent(); - Collection<AndroidPackage> packages; + Collection<PackageParser.Package> packages; if (packageName != null) { - AndroidPackage targetPackage = mPackages.get(packageName); + PackageParser.Package targetPackage = mPackages.get(packageName); if (targetPackage != null) { packages = Collections.singletonList(targetPackage); } else { @@ -20543,11 +21082,11 @@ public class PackageManagerService extends IPackageManager.Stub packages = mPackages.values(); } - for (AndroidPackage pkg : packages) { - ipw.println("[" + pkg.getPackageName() + "]"); + for (PackageParser.Package pkg : packages) { + ipw.println("[" + pkg.packageName + "]"); ipw.increaseIndent(); - CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.getPackageName()); + CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName); if (stats == null) { ipw.println("(No recorded stats)"); } else { @@ -20618,14 +21157,14 @@ public class PackageManagerService extends IPackageManager.Stub } private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, - ArrayList<AndroidPackage> packages, IIntentReceiver finishedReceiver) { - final int size = packages.size(); + ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { + final int size = infos.size(); final String[] packageNames = new String[size]; final int[] packageUids = new int[size]; for (int i = 0; i < size; i++) { - final AndroidPackage pkg = packages.get(i); - packageNames[i] = pkg.getAppInfoPackageName(); - packageUids[i] = pkg.getUid(); + final ApplicationInfo info = infos.get(i); + packageNames[i] = info.packageName; + packageUids[i] = info.uid; } sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, finishedReceiver); @@ -20668,7 +21207,7 @@ public class PackageManagerService extends IPackageManager.Stub } final ArrayList<PackageFreezer> freezers = new ArrayList<>(); - final ArrayList<AndroidPackage> loaded = new ArrayList<>(); + final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; final VersionInfo ver; @@ -20681,10 +21220,10 @@ public class PackageManagerService extends IPackageManager.Stub for (PackageSetting ps : packages) { freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner")); synchronized (mInstallLock) { - final AndroidPackage pkg; + final PackageParser.Package pkg; try { pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); - loaded.add(pkg); + loaded.add(pkg.applicationInfo); } catch (PackageManagerException e) { Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); @@ -20756,14 +21295,14 @@ public class PackageManagerService extends IPackageManager.Stub return; } - final ArrayList<AndroidPackage> unloaded = new ArrayList<>(); + final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); synchronized (mInstallLock) { synchronized (mLock) { final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); for (PackageSetting ps : packages) { if (ps.pkg == null) continue; - final AndroidPackage pkg = ps.pkg; + final ApplicationInfo info = ps.pkg.applicationInfo; final int deleteFlags = PackageManager.DELETE_KEEP_DATA; final PackageRemovedInfo outInfo = new PackageRemovedInfo(this); @@ -20771,7 +21310,7 @@ public class PackageManagerService extends IPackageManager.Stub "unloadPrivatePackagesInner")) { if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo, false, null)) { - unloaded.add(pkg); + unloaded.add(info); } else { Slog.w(TAG, "Failed to unload " + ps.codePath); } @@ -20986,7 +21525,7 @@ public class PackageManagerService extends IPackageManager.Stub continue; } // Skip non-core apps if requested - if (onlyCoreApps && !ps.pkg.isCoreApp()) { + if (onlyCoreApps && !ps.pkg.coreApp) { result.add(packageName); continue; } @@ -21013,10 +21552,10 @@ public class PackageManagerService extends IPackageManager.Stub * <p> * <em>Note: To avoid a deadlock, do not call this method with {@code mLock} lock held</em> */ - private void prepareAppDataAfterInstallLIF(AndroidPackage pkg) { + private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) { final PackageSetting ps; synchronized (mLock) { - ps = mSettings.mPackages.get(pkg.getPackageName()); + ps = mSettings.mPackages.get(pkg.packageName); mSettings.writeKernelMappingLPr(ps); } @@ -21046,15 +21585,19 @@ public class PackageManagerService extends IPackageManager.Stub * will try recovering system apps by wiping data; third-party app data is * left intact. */ - private void prepareAppDataLIF(AndroidPackage pkg, int userId, int flags) { + private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) { if (pkg == null) { Slog.wtf(TAG, "Package was null!", new Throwable()); return; } prepareAppDataLeafLIF(pkg, userId, flags); + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); + } } - private void prepareAppDataAndMigrateLIF(AndroidPackage pkg, int userId, int flags, + private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags, boolean maybeMigrateAppData) { prepareAppDataLIF(pkg, userId, flags); @@ -21065,37 +21608,43 @@ public class PackageManagerService extends IPackageManager.Stub } } - private void prepareAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) { + private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { if (DEBUG_APP_DATA) { - Slog.v(TAG, "prepareAppData for " + pkg.getPackageName() + " u" + userId + " 0x" + Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" + Integer.toHexString(flags)); } final PackageSetting ps; synchronized (mLock) { - ps = mSettings.mPackages.get(pkg.getPackageName()); + ps = mSettings.mPackages.get(pkg.packageName); + } + final String volumeUuid = pkg.volumeUuid; + final String packageName = pkg.packageName; + + ApplicationInfo app = (ps == null) + ? pkg.applicationInfo + : PackageParser.generateApplicationInfo(pkg, 0, ps.readUserState(userId), userId); + if (app == null) { + app = pkg.applicationInfo; } - final String volumeUuid = pkg.getVolumeUuid(); - final String packageName = pkg.getPackageName(); - final int appId = UserHandle.getAppId(pkg.getUid()); + final int appId = UserHandle.getAppId(app.uid); - Preconditions.checkNotNull(pkg.getSeInfo()); + Preconditions.checkNotNull(app.seInfo); - final String seInfo = - pkg.getSeInfo() + (pkg.getSeInfoUser() != null ? pkg.getSeInfoUser() : ""); + final String seInfo = app.seInfo + (app.seInfoUser != null ? app.seInfoUser : ""); long ceDataInode = -1; try { ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags, - appId, seInfo, pkg.getTargetSdkVersion()); + appId, seInfo, app.targetSdkVersion); } catch (InstallerException e) { - if (pkg.isSystemApp()) { + if (app.isSystemApp()) { logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName + ", but trying to recover: " + e); destroyAppDataLeafLIF(pkg, userId, flags); try { ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags, - appId, seInfo, pkg.getTargetSdkVersion()); + appId, seInfo, app.targetSdkVersion); logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); } catch (InstallerException e2) { logCriticalInfo(Log.DEBUG, "Recovery failed!"); @@ -21137,24 +21686,29 @@ public class PackageManagerService extends IPackageManager.Stub prepareAppDataContentsLeafLIF(pkg, userId, flags); } - private void prepareAppDataContentsLIF(AndroidPackage pkg, int userId, int flags) { + private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) { if (pkg == null) { Slog.wtf(TAG, "Package was null!", new Throwable()); return; } prepareAppDataContentsLeafLIF(pkg, userId, flags); + final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; + for (int i = 0; i < childCount; i++) { + prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags); + } } - private void prepareAppDataContentsLeafLIF(AndroidPackage pkg, int userId, int flags) { - final String volumeUuid = pkg.getVolumeUuid(); - final String packageName = pkg.getPackageName(); + private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) { + final String volumeUuid = pkg.volumeUuid; + final String packageName = pkg.packageName; + final ApplicationInfo app = pkg.applicationInfo; if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { // Create a native library symlink only if we have native libraries // and if the native libraries are 32 bit libraries. We do not provide // this symlink for 64 bit libraries. - if (pkg.getPrimaryCpuAbi() != null && !VMRuntime.is64BitAbi(pkg.getPrimaryCpuAbi())) { - final String nativeLibPath = pkg.getNativeLibraryDir(); + if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { + final String nativeLibPath = app.nativeLibraryDir; try { mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, nativeLibPath, userId); @@ -21170,17 +21724,17 @@ public class PackageManagerService extends IPackageManager.Stub * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag * requested by the app. */ - private boolean maybeMigrateAppDataLIF(AndroidPackage pkg, int userId) { + private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) { if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated() && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { - final int storageTarget = pkg.isDefaultToDeviceProtectedStorage() + final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage() ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; try { - mInstaller.migrateAppData(pkg.getVolumeUuid(), pkg.getPackageName(), userId, + mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId, storageTarget); } catch (InstallerException e) { logCriticalInfo(Log.WARN, - "Failed to migrate " + pkg.getPackageName() + ": " + e.getMessage()); + "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); } return true; } else { @@ -21231,6 +21785,7 @@ public class PackageManagerService extends IPackageManager.Stub */ private class PackageFreezer implements AutoCloseable { private final String mPackageName; + private final PackageFreezer[] mChildren; private final boolean mWeFroze; @@ -21245,6 +21800,7 @@ public class PackageManagerService extends IPackageManager.Stub */ public PackageFreezer() { mPackageName = null; + mChildren = null; mWeFroze = false; mCloseGuard.open("close"); } @@ -21258,6 +21814,18 @@ public class PackageManagerService extends IPackageManager.Stub if (ps != null) { killApplication(ps.name, ps.appId, userId, killReason); } + + final PackageParser.Package p = mPackages.get(packageName); + if (p != null && p.childPackages != null) { + final int N = p.childPackages.size(); + mChildren = new PackageFreezer[N]; + for (int i = 0; i < N; i++) { + mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName, + userId, killReason); + } + } else { + mChildren = null; + } } mCloseGuard.open("close"); } @@ -21280,6 +21848,12 @@ public class PackageManagerService extends IPackageManager.Stub if (mWeFroze) { mFrozenPackages.remove(mPackageName); } + + if (mChildren != null) { + for (PackageFreezer freezer : mChildren) { + freezer.close(); + } + } } } } @@ -21334,14 +21908,14 @@ public class PackageManagerService extends IPackageManager.Stub // reader synchronized (mLock) { - final AndroidPackage pkg = mPackages.get(packageName); + final PackageParser.Package pkg = mPackages.get(packageName); final PackageSetting ps = mSettings.mPackages.get(packageName); if (pkg == null || ps == null || shouldFilterApplicationLocked(ps, callingUid, user.getIdentifier())) { throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); } - if (pkg.isSystemApp()) { + if (pkg.applicationInfo.isSystemApp()) { throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, "Cannot move system application"); } @@ -21356,7 +21930,7 @@ public class PackageManagerService extends IPackageManager.Stub currentVolumeUuid = ps.volumeUuid; - final File probe = new File(pkg.getCodePath()); + final File probe = new File(pkg.codePath); final File probeOat = new File(probe, "oat"); if (!probe.isDirectory() || !probeOat.isDirectory()) { throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, @@ -21367,7 +21941,7 @@ public class PackageManagerService extends IPackageManager.Stub throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Package already moved to " + volumeUuid); } - if (pkg.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { + if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, "Device admin cannot be moved"); } @@ -21378,13 +21952,13 @@ public class PackageManagerService extends IPackageManager.Stub } isCurrentLocationExternal = isExternal(pkg); - codeFile = new File(pkg.getCodePath()); + codeFile = new File(pkg.codePath); installerPackageName = ps.installerPackageName; packageAbiOverride = ps.cpuAbiOverrideString; - appId = UserHandle.getAppId(pkg.getUid()); - seinfo = pkg.getSeInfo(); - label = String.valueOf(pm.getApplicationLabel(pkg.toAppInfo())); - targetSdkVersion = pkg.getTargetSdkVersion(); + appId = UserHandle.getAppId(pkg.applicationInfo.uid); + seinfo = pkg.applicationInfo.seInfo; + label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); + targetSdkVersion = pkg.applicationInfo.targetSdkVersion; freezer = freezePackage(packageName, "movePackageInternal"); installedUserIds = ps.queryInstalledUsers(mUserManager.getUserIds(), true); } @@ -21545,7 +22119,7 @@ public class PackageManagerService extends IPackageManager.Stub * @param packageName The package that was moved. */ private void logAppMovedStorage(String packageName, boolean isPreviousLocationExternal) { - final AndroidPackage pkg; + final PackageParser.Package pkg; synchronized (mLock) { pkg = mPackages.get(packageName); } @@ -21553,8 +22127,8 @@ public class PackageManagerService extends IPackageManager.Stub return; } - final StorageManager storage = mInjector.getStorageManager();; - VolumeInfo volume = storage.findVolumeByUuid(pkg.getStorageUuid().toString()); + final StorageManager storage = mInjector.getStorageManager(); + VolumeInfo volume = storage.findVolumeByUuid(pkg.applicationInfo.storageUuid.toString()); int packageExternalStorageType = getPackageExternalStorageType(volume, isExternal(pkg)); if (!isPreviousLocationExternal && isExternal(pkg)) { @@ -21668,7 +22242,7 @@ public class PackageManagerService extends IPackageManager.Stub if (ps.pkg == null) { continue; } - final String packageName = ps.pkg.getPackageName(); + final String packageName = ps.pkg.packageName; // Skip over if system app if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { continue; @@ -21797,13 +22371,13 @@ public class PackageManagerService extends IPackageManager.Stub if (packageName == null || alias == null) { return null; } - synchronized(mLock) { - final AndroidPackage pkg = mPackages.get(packageName); + synchronized (mLock) { + final PackageParser.Package pkg = mPackages.get(packageName); if (pkg == null) { Slog.w(TAG, "KeySet requested for unknown package: " + packageName); throw new IllegalArgumentException("Unknown package: " + packageName); } - final PackageSetting ps = getPackageSetting(pkg.getPackageName()); + final PackageSetting ps = (PackageSetting) pkg.mExtras; if (shouldFilterApplicationLocked( ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) { Slog.w(TAG, "KeySet requested for filtered package: " + packageName); @@ -21822,19 +22396,19 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mLock) { final int callingUid = Binder.getCallingUid(); final int callingUserId = UserHandle.getUserId(callingUid); - final AndroidPackage pkg = mPackages.get(packageName); + final PackageParser.Package pkg = mPackages.get(packageName); if (pkg == null) { Slog.w(TAG, "KeySet requested for unknown package: " + packageName); throw new IllegalArgumentException("Unknown package: " + packageName); } - final PackageSetting ps = getPackageSetting(pkg.getPackageName()); + final PackageSetting ps = (PackageSetting) pkg.mExtras; if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) { // filter and pretend the package doesn't exist Slog.w(TAG, "KeySet requested for filtered package: " + packageName + ", uid:" + callingUid); throw new IllegalArgumentException("Unknown package: " + packageName); } - if (pkg.getUid() != callingUid + if (pkg.applicationInfo.uid != callingUid && Process.SYSTEM_UID != callingUid) { throw new SecurityException("May not access signing KeySet of other apps."); } @@ -21852,11 +22426,11 @@ public class PackageManagerService extends IPackageManager.Stub if (packageName == null || ks == null) { return false; } - synchronized(mLock) { - final AndroidPackage pkg = mPackages.get(packageName); + synchronized (mLock) { + final PackageParser.Package pkg = mPackages.get(packageName); if (pkg == null - || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()), - callingUid, UserHandle.getUserId(callingUid))) { + || shouldFilterApplicationLocked((PackageSetting) pkg.mExtras, callingUid, + UserHandle.getUserId(callingUid))) { Slog.w(TAG, "KeySet requested for unknown package: " + packageName); throw new IllegalArgumentException("Unknown package: " + packageName); } @@ -21879,10 +22453,10 @@ public class PackageManagerService extends IPackageManager.Stub return false; } synchronized (mLock) { - final AndroidPackage pkg = mPackages.get(packageName); + final PackageParser.Package pkg = mPackages.get(packageName); if (pkg == null - || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()), - callingUid, UserHandle.getUserId(callingUid))) { + || shouldFilterApplicationLocked((PackageSetting) pkg.mExtras, callingUid, + UserHandle.getUserId(callingUid))) { Slog.w(TAG, "KeySet requested for unknown package: " + packageName); throw new IllegalArgumentException("Unknown package: " + packageName); } @@ -21914,29 +22488,29 @@ public class PackageManagerService extends IPackageManager.Stub * Check and throw if the given before/after packages would be considered a * downgrade. */ - private static void checkDowngrade(AndroidPackage before, PackageInfoLite after) + private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) throws PackageManagerException { if (after.getLongVersionCode() < before.getLongVersionCode()) { throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, "Update version code " + after.versionCode + " is older than current " + before.getLongVersionCode()); } else if (after.getLongVersionCode() == before.getLongVersionCode()) { - if (after.baseRevisionCode < before.getBaseRevisionCode()) { + if (after.baseRevisionCode < before.baseRevisionCode) { throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, "Update base revision code " + after.baseRevisionCode - + " is older than current " + before.getBaseRevisionCode()); + + " is older than current " + before.baseRevisionCode); } if (!ArrayUtils.isEmpty(after.splitNames)) { for (int i = 0; i < after.splitNames.length; i++) { final String splitName = after.splitNames[i]; - final int j = ArrayUtils.indexOf(before.getSplitNames(), splitName); + final int j = ArrayUtils.indexOf(before.splitNames, splitName); if (j != -1) { - if (after.splitRevisionCodes[i] < before.getSplitRevisionCodes()[j]) { + if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, "Update split " + splitName + " revision code " + after.splitRevisionCodes[i] + " is older than current " - + before.getSplitRevisionCodes()[j]); + + before.splitRevisionCodes[j]); } } } @@ -22126,13 +22700,13 @@ public class PackageManagerService extends IPackageManager.Stub if (packageSetting == null) { return false; } - AndroidPackage pkg = packageSetting.pkg; + PackageParser.Package pkg = packageSetting.pkg; if (pkg == null) { // May happen if package in on a removable sd card return false; } - return pkg.getSigningDetails().hasAncestorOrSelf(mPlatformPackage.getSigningDetails()) - || mPlatformPackage.getSigningDetails().checkCapability(pkg.getSigningDetails(), + return pkg.mSigningDetails.hasAncestorOrSelf(mPlatformPackage.mSigningDetails) + || mPlatformPackage.mSigningDetails.checkCapability(pkg.mSigningDetails, PackageParser.SigningDetails.CertCapabilities.PERMISSION); } @@ -22168,11 +22742,11 @@ public class PackageManagerService extends IPackageManager.Stub private SigningDetails getSigningDetails(@NonNull String packageName) { synchronized (mLock) { - AndroidPackage p = mPackages.get(packageName); + PackageParser.Package p = mPackages.get(packageName); if (p == null) { return null; } - return p.getSigningDetails(); + return p.mSigningDetails; } } @@ -22203,25 +22777,28 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) { + public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) { synchronized (mLock) { - PackageSetting ps = getPackageSetting(pkg.getPackageName()); - return PackageManagerService.this.shouldFilterApplicationLocked(ps, callingUid, - userId); + return PackageManagerService.this.shouldFilterApplicationLocked( + (PackageSetting) pkg.mExtras, callingUid, userId); } } @Override public boolean filterAppAccess(String packageName, int callingUid, int userId) { synchronized (mLock) { - PackageSetting ps = getPackageSetting(packageName); - return PackageManagerService.this.shouldFilterApplicationLocked(ps, callingUid, - userId); + final PackageParser.Package pkg = mPackages.get(packageName); + if (pkg == null) { + return false; + } + return PackageManagerService.this + .shouldFilterApplicationLocked( + (PackageSetting) pkg.mExtras, callingUid, userId); } } @Override - public AndroidPackage getPackage(String packageName) { + public PackageParser.Package getPackage(String packageName) { synchronized (mLock) { packageName = resolveInternalPackageNameLPr( packageName, PackageManager.VERSION_CODE_HIGHEST); @@ -22230,10 +22807,10 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public AndroidPackage getPackage(int uid) { + public PackageParser.Package getPackage(int uid) { synchronized (mLock) { final String[] packageNames = getPackagesForUid(uid); - AndroidPackage pkg = null; + PackageParser.Package pkg = null; final int numPackages = packageNames == null ? 0 : packageNames.length; for (int i = 0; pkg == null && i < numPackages; i++) { pkg = mPackages.get(packageNames[i]); @@ -22242,12 +22819,6 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Nullable - @Override - public PackageSetting getPackageSetting(String packageName) { - return PackageManagerService.this.getPackageSetting(packageName); - } - @Override public PackageList getPackageList(PackageListObserver observer) { synchronized (mLock) { @@ -22272,19 +22843,17 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public Object getDisabledSystemPackage(@NonNull String packageName) { + public PackageParser.Package getDisabledSystemPackage(String packageName) { synchronized (mLock) { - return mSettings.getDisabledSystemPkgLPr(packageName); + final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName); + return (ps != null) ? ps.pkg : null; } } @Override - public @Nullable - String getDisabledSystemPackageName(@NonNull String packageName) { - PackageSetting disabledPkgSetting = (PackageSetting) getDisabledSystemPackage( - packageName); - AndroidPackage disabledPkg = disabledPkgSetting == null ? null : disabledPkgSetting.pkg; - return disabledPkg == null ? null : disabledPkg.getPackageName(); + public @Nullable String getDisabledSystemPackageName(@NonNull String packageName) { + PackageParser.Package pkg = getDisabledSystemPackage(packageName); + return pkg == null ? null : pkg.packageName; } @Override @@ -22355,7 +22924,7 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean isPermissionsReviewRequired(String packageName, int userId) { synchronized (mLock) { - final AndroidPackage pkg = mPackages.get(packageName); + final PackageParser.Package pkg = mPackages.get(packageName); if (pkg == null) { return false; } @@ -22376,11 +22945,21 @@ public class PackageManagerService extends IPackageManager.Stub public Bundle getSuspendedPackageLauncherExtras(String packageName, int userId) { synchronized (mLock) { final PackageSetting ps = mSettings.mPackages.get(packageName); - PersistableBundle launcherExtras = null; + final Bundle allExtras = new Bundle(); if (ps != null) { - launcherExtras = ps.readUserState(userId).suspendedLauncherExtras; + final PackageUserState pus = ps.readUserState(userId); + if (pus.suspended) { + for (int i = 0; i < pus.suspendParams.size(); i++) { + final PackageUserState.SuspendParams params = + pus.suspendParams.valueAt(i); + if (params != null && params.launcherExtras != null) { + allExtras.putAll(params.launcherExtras); + } + } + } + } - return (launcherExtras != null) ? new Bundle(launcherExtras.deepCopy()) : null; + return (allExtras.size() > 0) ? allExtras : null; } } @@ -22396,16 +22975,38 @@ public class PackageManagerService extends IPackageManager.Stub public String getSuspendingPackage(String suspendedPackage, int userId) { synchronized (mLock) { final PackageSetting ps = mSettings.mPackages.get(suspendedPackage); - return (ps != null) ? ps.readUserState(userId).suspendingPackage : null; + if (ps != null) { + final PackageUserState pus = ps.readUserState(userId); + if (pus.suspended) { + String suspendingPackage = null; + for (int i = 0; i < pus.suspendParams.size(); i++) { + suspendingPackage = pus.suspendParams.keyAt(i); + if (PLATFORM_PACKAGE_NAME.equals(suspendingPackage)) { + return suspendingPackage; + } + } + return suspendingPackage; + } + } + return null; } } @Override - public SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage, int userId) { + public SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage, + String suspendingPackage, int userId) { synchronized (mLock) { final PackageSetting ps = mSettings.mPackages.get(suspendedPackage); - return (ps != null) ? ps.readUserState(userId).dialogInfo : null; + if (ps != null) { + final PackageUserState pus = ps.readUserState(userId); + if (pus.suspended) { + final PackageUserState.SuspendParams suspendParams = + pus.suspendParams.get(suspendingPackage); + return (suspendParams != null) ? suspendParams.dialogInfo : null; + } + } } + return null; } @Override @@ -22482,7 +23083,6 @@ public class PackageManagerService extends IPackageManager.Stub usersWithPoOrDo.add(profileOwnerPackages.keyAt(i)); } } - unsuspendForNonSystemSuspendingPackages(usersWithPoOrDo); } @Override @@ -22511,10 +23111,9 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public boolean isEnabledAndMatches(ParsedComponent component, int flags, int userId) { + public boolean isEnabledAndMatches(ComponentInfo info, int flags, int userId) { synchronized (mLock) { - AndroidPackage pkg = getPackage(component.getPackageName()); - return mSettings.isEnabledAndMatchLPr(pkg, component, flags, userId); + return mSettings.isEnabledAndMatchLPr(info, flags, userId); } } @@ -22531,10 +23130,10 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public boolean setInstalled(AndroidPackage pkg, @UserIdInt int userId, + public boolean setInstalled(PackageParser.Package pkg, @UserIdInt int userId, boolean installed) { synchronized (mLock) { - final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName()); + final PackageSetting ps = mSettings.mPackages.get(pkg.packageName); if (ps.getInstalled(userId) != installed) { ps.setInstalled(installed, userId); return true; @@ -22556,21 +23155,21 @@ public class PackageManagerService extends IPackageManager.Stub public void grantImplicitAccess(int userId, Intent intent, int callingUid, int targetAppId) { synchronized (mLock) { - final AndroidPackage callingPackage = getPackage(callingUid); - final AndroidPackage targetPackage = + final PackageParser.Package callingPackage = getPackage(callingUid); + final PackageParser.Package targetPackage = getPackage(UserHandle.getUid(userId, targetAppId)); if (callingPackage == null || targetPackage == null) { return; } - final boolean instantApp = isInstantAppInternal(callingPackage.getPackageName(), - userId, callingUid); + final boolean instantApp = isInstantAppInternal(callingPackage.packageName, userId, + callingUid); if (instantApp) { mInstantAppRegistry.grantInstantAccessLPw(userId, intent, UserHandle.getAppId(callingUid), targetAppId); } else { - mAppsFilter.grantImplicitAccess(callingPackage.getPackageName(), - targetPackage.getPackageName(), userId); + mAppsFilter.grantImplicitAccess( + callingPackage.packageName, targetPackage.packageName, userId); } } } @@ -22602,9 +23201,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean isPackagePersistent(String packageName) { synchronized (mLock) { - AndroidPackage pkg = mPackages.get(packageName); + PackageParser.Package pkg = mPackages.get(packageName); return pkg != null - ? ((pkg.getFlags() & (ApplicationInfo.FLAG_SYSTEM + ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT)) == (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT)) : false; @@ -22612,9 +23211,9 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public boolean isLegacySystemApp(AndroidPackage pkg) { + public boolean isLegacySystemApp(PackageParser.Package pkg) { synchronized (mLock) { - final PackageSetting ps = getPackageSetting(pkg.getPackageName()); + final PackageSetting ps = (PackageSetting) pkg.mExtras; return mPromoteSystemApps && ps.isSystem() && mExistingSystemPackages.contains(ps.name); @@ -22625,10 +23224,9 @@ public class PackageManagerService extends IPackageManager.Stub public List<PackageInfo> getOverlayPackages(int userId) { final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>(); synchronized (mLock) { - for (AndroidPackage p : mPackages.values()) { - if (p.getOverlayTarget() != null) { - PackageInfo pkg = generatePackageInfo(getPackageSetting(p.getPackageName()), - 0, userId); + for (PackageParser.Package p : mPackages.values()) { + if (p.mOverlayTarget != null) { + PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId); if (pkg != null) { overlayPackages.add(pkg); } @@ -22642,9 +23240,9 @@ public class PackageManagerService extends IPackageManager.Stub public List<String> getTargetPackageNames(int userId) { List<String> targetPackages = new ArrayList<>(); synchronized (mLock) { - for (AndroidPackage p : mPackages.values()) { - if (p.getOverlayTarget() == null) { - targetPackages.add(p.getPackageName()); + for (PackageParser.Package p : mPackages.values()) { + if (p.mOverlayTarget == null) { + targetPackages.add(p.packageName); } } } @@ -22665,12 +23263,12 @@ public class PackageManagerService extends IPackageManager.Stub overlayPaths = new ArrayList<>(N); for (int i = 0; i < N; i++) { final String packageName = overlayPackageNames.get(i); - final AndroidPackage pkg = mPackages.get(packageName); + final PackageParser.Package pkg = mPackages.get(packageName); if (pkg == null) { Slog.e(TAG, "failed to find package " + packageName); return false; } - overlayPaths.add(pkg.getBaseCodePath()); + overlayPaths.add(pkg.baseCodePath); } } @@ -22788,12 +23386,12 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public void forEachPackage(Consumer<AndroidPackage> actionLocked) { + public void forEachPackage(Consumer<PackageParser.Package> actionLocked) { PackageManagerService.this.forEachPackage(actionLocked); } @Override - public void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked, + public void forEachInstalledPackage(@NonNull Consumer<PackageParser.Package> actionLocked, @UserIdInt int userId) { PackageManagerService.this.forEachInstalledPackage(actionLocked, userId); } @@ -22842,7 +23440,7 @@ public class PackageManagerService extends IPackageManager.Stub */ @Override public boolean compileLayouts(String packageName) { - AndroidPackage pkg; + PackageParser.Package pkg; synchronized (mLock) { pkg = mPackages.get(packageName); if (pkg == null) { @@ -22949,12 +23547,12 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean isCallerInstallerOfRecord( - @NonNull AndroidPackage pkg, int callingUid) { + @NonNull PackageParser.Package pkg, int callingUid) { synchronized (mLock) { if (pkg == null) { return false; } - final PackageSetting packageSetting = getPackageSetting(pkg.getPackageName()); + final PackageSetting packageSetting = (PackageSetting) pkg.mExtras; if (packageSetting == null) { return false; } @@ -23051,16 +23649,7 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Nullable - public PackageSetting getPackageSetting(String packageName) { - synchronized (mPackages) { - packageName = resolveInternalPackageNameLPr( - packageName, PackageManager.VERSION_CODE_HIGHEST); - return mSettings.mPackages.get(packageName); - } - } - - void forEachPackage(Consumer<AndroidPackage> actionLocked) { + void forEachPackage(Consumer<PackageParser.Package> actionLocked) { synchronized (mLock) { int numPackages = mPackages.size(); for (int i = 0; i < numPackages; i++) { @@ -23069,13 +23658,13 @@ public class PackageManagerService extends IPackageManager.Stub } } - void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked, + void forEachInstalledPackage(@NonNull Consumer<PackageParser.Package> actionLocked, @UserIdInt int userId) { synchronized (mLock) { int numPackages = mPackages.size(); for (int i = 0; i < numPackages; i++) { - AndroidPackage pkg = mPackages.valueAt(i); - PackageSetting setting = mSettings.getPackageLPr(pkg.getPackageName()); + PackageParser.Package pkg = mPackages.valueAt(i); + PackageSetting setting = mSettings.getPackageLPr(pkg.packageName); if (setting == null || !setting.getInstalled(userId)) { continue; } @@ -23092,7 +23681,7 @@ public class PackageManagerService extends IPackageManager.Stub * Return a <b>copy</b> of the collection of packages known to the package manager. * @return A copy of the values of mPackages. */ - Collection<AndroidPackage> getPackages() { + Collection<PackageParser.Package> getPackages() { synchronized (mLock) { return new ArrayList<>(mPackages.values()); } @@ -23128,8 +23717,8 @@ public class PackageManagerService extends IPackageManager.Stub return mCompilerStats.getPackageStats(pkgName); } - public CompilerStats.PackageStats getOrCreateCompilerPackageStats(AndroidPackage pkg) { - return getOrCreateCompilerPackageStats(pkg.getPackageName()); + public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) { + return getOrCreateCompilerPackageStats(pkg.packageName); } public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) { @@ -23239,7 +23828,7 @@ public class PackageManagerService extends IPackageManager.Stub boolean canHaveOatDir(String packageName) { synchronized (mLock) { - AndroidPackage p = mPackages.get(packageName); + PackageParser.Package p = mPackages.get(packageName); if (p == null) { return false; } @@ -23247,11 +23836,11 @@ public class PackageManagerService extends IPackageManager.Stub } } - private String getOatDir(AndroidPackage pkg) { + private String getOatDir(PackageParser.Package pkg) { if (!pkg.canHaveOatDir()) { return null; } - File codePath = new File(pkg.getCodePath()); + File codePath = new File(pkg.codePath); if (codePath.isDirectory()) { return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath(); } @@ -23262,12 +23851,11 @@ public class PackageManagerService extends IPackageManager.Stub final String[] instructionSets; final List<String> codePaths; final String oatDir; - final AndroidPackage pkg; + final PackageParser.Package pkg; synchronized (mLock) { pkg = mPackages.get(packageName); } - instructionSets = getAppDexInstructionSets(pkg.getPrimaryCpuAbi(), - pkg.getSecondaryCpuAbi()); + instructionSets = getAppDexInstructionSets(pkg.applicationInfo); codePaths = pkg.getAllCodePaths(); oatDir = getOatDir(pkg); @@ -23286,19 +23874,19 @@ public class PackageManagerService extends IPackageManager.Stub Set<String> unusedPackages = new HashSet<>(); long currentTimeInMillis = System.currentTimeMillis(); synchronized (mLock) { - for (AndroidPackage pkg : mPackages.values()) { - PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName()); + for (PackageParser.Package pkg : mPackages.values()) { + PackageSetting ps = mSettings.mPackages.get(pkg.packageName); if (ps == null) { continue; } PackageDexUsage.PackageUseInfo packageUseInfo = - getDexManager().getPackageUseInfoOrDefault(pkg.getPackageName()); + getDexManager().getPackageUseInfoOrDefault(pkg.packageName); if (PackageManagerServiceUtils .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis, downgradeTimeThresholdMillis, packageUseInfo, pkg.getLatestPackageUseTimeInMills(), pkg.getLatestForegroundPackageUseTimeInMills())) { - unusedPackages.add(pkg.getPackageName()); + unusedPackages.add(pkg.packageName); } } } diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java index ded9a9c58c5e..ef47410ded8c 100644 --- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java @@ -35,13 +35,10 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfoLite; import android.content.pm.PackageManager; -import android.content.pm.PackageManagerInternal; import android.content.pm.PackageParser; import android.content.pm.PackageParser.PackageParserException; import android.content.pm.ResolveInfo; import android.content.pm.Signature; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ApkParseUtils; import android.os.Build; import android.os.Debug; import android.os.Environment; @@ -123,7 +120,7 @@ public class PackageManagerServiceUtils { // Sort a list of apps by their last usage, most recently used apps first. The order of // packages without usage data is undefined (but they will be sorted after the packages // that do have usage data). - public static void sortPackagesByUsageDate(List<AndroidPackage> pkgs, + public static void sortPackagesByUsageDate(List<PackageParser.Package> pkgs, PackageManagerService packageManagerService) { if (!packageManagerService.isHistoricalPackageUsageAvailable()) { return; @@ -138,12 +135,12 @@ public class PackageManagerServiceUtils { // package will be removed from {@code packages} and added to {@code result} with its // dependencies. If usage data is available, the positive packages will be sorted by usage // data (with {@code sortTemp} as temporary storage). - private static void applyPackageFilter(Predicate<AndroidPackage> filter, - Collection<AndroidPackage> result, - Collection<AndroidPackage> packages, - @NonNull List<AndroidPackage> sortTemp, + private static void applyPackageFilter(Predicate<PackageParser.Package> filter, + Collection<PackageParser.Package> result, + Collection<PackageParser.Package> packages, + @NonNull List<PackageParser.Package> sortTemp, PackageManagerService packageManagerService) { - for (AndroidPackage pkg : packages) { + for (PackageParser.Package pkg : packages) { if (filter.test(pkg)) { sortTemp.add(pkg); } @@ -152,10 +149,10 @@ public class PackageManagerServiceUtils { sortPackagesByUsageDate(sortTemp, packageManagerService); packages.removeAll(sortTemp); - for (AndroidPackage pkg : sortTemp) { + for (PackageParser.Package pkg : sortTemp) { result.add(pkg); - Collection<AndroidPackage> deps = + Collection<PackageParser.Package> deps = packageManagerService.findSharedNonSystemLibraries(pkg); if (!deps.isEmpty()) { deps.removeAll(result); @@ -169,51 +166,50 @@ public class PackageManagerServiceUtils { // Sort apps by importance for dexopt ordering. Important apps are given // more priority in case the device runs out of space. - public static List<AndroidPackage> getPackagesForDexopt( - Collection<AndroidPackage> packages, + public static List<PackageParser.Package> getPackagesForDexopt( + Collection<PackageParser.Package> packages, PackageManagerService packageManagerService) { return getPackagesForDexopt(packages, packageManagerService, DEBUG_DEXOPT); } - public static List<AndroidPackage> getPackagesForDexopt( - Collection<AndroidPackage> packages, + public static List<PackageParser.Package> getPackagesForDexopt( + Collection<PackageParser.Package> packages, PackageManagerService packageManagerService, boolean debug) { - ArrayList<AndroidPackage> remainingPkgs = new ArrayList<>(packages); - LinkedList<AndroidPackage> result = new LinkedList<>(); - ArrayList<AndroidPackage> sortTemp = new ArrayList<>(remainingPkgs.size()); + ArrayList<PackageParser.Package> remainingPkgs = new ArrayList<>(packages); + LinkedList<PackageParser.Package> result = new LinkedList<>(); + ArrayList<PackageParser.Package> sortTemp = new ArrayList<>(remainingPkgs.size()); // Give priority to core apps. - applyPackageFilter((pkg) -> pkg.isCoreApp(), result, remainingPkgs, sortTemp, + applyPackageFilter((pkg) -> pkg.coreApp, result, remainingPkgs, sortTemp, packageManagerService); // Give priority to system apps that listen for pre boot complete. Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); final ArraySet<String> pkgNames = getPackageNamesForIntent(intent, UserHandle.USER_SYSTEM); - applyPackageFilter((pkg) -> pkgNames.contains(pkg.getPackageName()), result, remainingPkgs, + applyPackageFilter((pkg) -> pkgNames.contains(pkg.packageName), result, remainingPkgs, sortTemp, packageManagerService); // Give priority to apps used by other apps. DexManager dexManager = packageManagerService.getDexManager(); applyPackageFilter((pkg) -> - dexManager.getPackageUseInfoOrDefault(pkg.getPackageName()) + dexManager.getPackageUseInfoOrDefault(pkg.packageName) .isAnyCodePathUsedByOtherApps(), result, remainingPkgs, sortTemp, packageManagerService); // Filter out packages that aren't recently used, add all remaining apps. // TODO: add a property to control this? - Predicate<AndroidPackage> remainingPredicate; + Predicate<PackageParser.Package> remainingPredicate; if (!remainingPkgs.isEmpty() && packageManagerService.isHistoricalPackageUsageAvailable()) { if (debug) { Log.i(TAG, "Looking at historical package use"); } // Get the package that was used last. - AndroidPackage lastUsed = Collections.max(remainingPkgs, (pkg1, pkg2) -> + PackageParser.Package lastUsed = Collections.max(remainingPkgs, (pkg1, pkg2) -> Long.compare(pkg1.getLatestForegroundPackageUseTimeInMills(), pkg2.getLatestForegroundPackageUseTimeInMills())); if (debug) { - Log.i(TAG, "Taking package " + lastUsed.getPackageName() - + " as reference in time use"); + Log.i(TAG, "Taking package " + lastUsed.packageName + " as reference in time use"); } long estimatedPreviousSystemUseTime = lastUsed.getLatestForegroundPackageUseTimeInMills(); @@ -289,13 +285,13 @@ public class PackageManagerServiceUtils { } } - public static String packagesToString(Collection<AndroidPackage> c) { + public static String packagesToString(Collection<PackageParser.Package> c) { StringBuilder sb = new StringBuilder(); - for (AndroidPackage pkg : c) { + for (PackageParser.Package pkg : c) { if (sb.length() > 0) { sb.append(", "); } - sb.append(pkg.getPackageName()); + sb.append(pkg.packageName); } return sb.toString(); } @@ -313,16 +309,16 @@ public class PackageManagerServiceUtils { return false; } - public static long getLastModifiedTime(AndroidPackage pkg) { - final File srcFile = new File(pkg.getCodePath()); + public static long getLastModifiedTime(PackageParser.Package pkg) { + final File srcFile = new File(pkg.codePath); if (!srcFile.isDirectory()) { return srcFile.lastModified(); } - final File baseFile = new File(pkg.getBaseCodePath()); + final File baseFile = new File(pkg.baseCodePath); long maxModifiedTime = baseFile.lastModified(); - if (pkg.getSplitCodePaths() != null) { - for (int i = pkg.getSplitCodePaths().length - 1; i >=0; --i) { - final File splitFile = new File(pkg.getSplitCodePaths()[i]); + if (pkg.splitCodePaths != null) { + for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) { + final File splitFile = new File(pkg.splitCodePaths[i]); maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified()); } } @@ -543,7 +539,7 @@ public class PackageManagerServiceUtils { private static boolean matchSignatureInSystem(PackageSetting pkgSetting, PackageSetting disabledPkgSetting) { try { - ApkParseUtils.collectCertificates(disabledPkgSetting.pkg, true /* skipVerify */); + PackageParser.collectCertificates(disabledPkgSetting.pkg, true /* skipVerify */); if (pkgSetting.signatures.mSigningDetails.checkCapability( disabledPkgSetting.signatures.mSigningDetails, PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA) @@ -909,10 +905,8 @@ public class PackageManagerServiceUtils { * Returns the {@link PermissionsState} for the given package. If the {@link PermissionsState} * could not be found, {@code null} will be returned. */ - public static PermissionsState getPermissionsState( - PackageManagerInternal packageManagerInternal, AndroidPackage pkg) { - final PackageSetting packageSetting = - (PackageSetting) packageManagerInternal.getPackageSetting(pkg.getPackageName()); + public static PermissionsState getPermissionsState(PackageParser.Package pkg) { + final PackageSetting packageSetting = (PackageSetting) pkg.mExtras; if (packageSetting == null) { return null; } diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 121d709cc037..6435d9b410a9 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -48,6 +48,7 @@ import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManagerInternal; +import android.content.pm.PackageParser; import android.content.pm.PackageParser.ApkLite; import android.content.pm.PackageParser.PackageLite; import android.content.pm.PackageParser.PackageParserException; @@ -61,7 +62,6 @@ import android.content.pm.VersionedPackage; import android.content.pm.dex.ArtManager; import android.content.pm.dex.DexMetadataHelper; import android.content.pm.dex.ISnapshotRuntimeProfileCallback; -import android.content.pm.parsing.ApkLiteParseUtils; import android.content.res.AssetManager; import android.content.res.Resources; import android.content.rollback.IRollbackManager; @@ -446,7 +446,7 @@ class PackageManagerShellCommand extends ShellCommand { throw new IllegalArgumentException("Error: Can't open file: " + inPath); } try { - ApkLite baseApk = ApkLiteParseUtils.parseApkLite(fd.getFileDescriptor(), inPath, 0); + ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0); PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null, null, null); params.sessionParams.setSize(PackageHelper.calculateInstalledSize( @@ -751,7 +751,7 @@ class PackageManagerShellCommand extends ShellCommand { (!listThirdParty || !isSystem) && (!listApexOnly || isApex)) { pw.print("package:"); - if (showSourceDir && !isApex) { + if (showSourceDir) { pw.print(info.applicationInfo.sourceDir); pw.print("="); } @@ -2068,7 +2068,9 @@ class PackageManagerShellCommand extends ShellCommand { userId = UserHandle.USER_SYSTEM; } mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState, - appExtras, launcherExtras, info, callingPackage, userId); + ((appExtras.size() > 0) ? appExtras : null), + ((launcherExtras.size() > 0) ? launcherExtras : null), + info, callingPackage, userId); pw.println("Package " + packageName + " new suspended state: " + mInterface.isPackageSuspendedForUser(packageName, userId)); return 0; diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java index 44928fbd48c0..4ea8a30fa206 100644 --- a/services/core/java/com/android/server/pm/PackageSetting.java +++ b/services/core/java/com/android/server/pm/PackageSetting.java @@ -18,9 +18,8 @@ package com.android.server.pm; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageParser; import android.content.pm.UserInfo; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ParsedPackage; import android.service.pm.PackageProto; import android.util.proto.ProtoOutputStream; @@ -32,11 +31,9 @@ import java.util.List; /** * Settings data for a particular package we know about. */ -public final class PackageSetting extends PackageSettingBase implements - ParsedPackage.PackageSettingCallback { +public final class PackageSetting extends PackageSettingBase { int appId; - - public AndroidPackage pkg; + PackageParser.Package pkg; /** * WARNING. The object reference is important. We perform integer equality and NOT * object equality to check whether shared user settings are the same. @@ -53,12 +50,12 @@ public final class PackageSetting extends PackageSettingBase implements PackageSetting(String name, String realName, File codePath, File resourcePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, String cpuAbiOverrideString, - long pVersionCode, int pkgFlags, int privateFlags, - int sharedUserId, String[] usesStaticLibraries, + long pVersionCode, int pkgFlags, int privateFlags, String parentPackageName, + List<String> childPackageNames, int sharedUserId, String[] usesStaticLibraries, long[] usesStaticLibrariesVersions) { super(name, realName, codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString, - pVersionCode, pkgFlags, privateFlags, + pVersionCode, pkgFlags, privateFlags, parentPackageName, childPackageNames, usesStaticLibraries, usesStaticLibrariesVersions); this.sharedUserId = sharedUserId; } @@ -119,6 +116,10 @@ public final class PackageSetting extends PackageSettingBase implements : super.getPermissionsState(); } + public PackageParser.Package getPackage() { + return pkg; + } + public int getAppId() { return appId; } @@ -131,7 +132,6 @@ public final class PackageSetting extends PackageSettingBase implements return installPermissionsFixed; } - // TODO(b/135203078): Remove these in favor of reading from the package directly public boolean isPrivileged() { return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; } @@ -176,6 +176,10 @@ public final class PackageSetting extends PackageSettingBase implements return true; } + public boolean hasChildPackages() { + return childPackageNames != null && !childPackageNames.isEmpty(); + } + public void writeToProto(ProtoOutputStream proto, long fieldId, List<UserInfo> users) { final long packageToken = proto.start(fieldId); proto.write(PackageProto.NAME, (realName != null ? realName : name)); @@ -186,19 +190,18 @@ public final class PackageSetting extends PackageSettingBase implements proto.write(PackageProto.INSTALLER_NAME, installerPackageName); if (pkg != null) { - proto.write(PackageProto.VERSION_STRING, pkg.getVersionName()); + proto.write(PackageProto.VERSION_STRING, pkg.mVersionName); long splitToken = proto.start(PackageProto.SPLITS); proto.write(PackageProto.SplitProto.NAME, "base"); - proto.write(PackageProto.SplitProto.REVISION_CODE, pkg.getBaseRevisionCode()); + proto.write(PackageProto.SplitProto.REVISION_CODE, pkg.baseRevisionCode); proto.end(splitToken); - if (pkg.getSplitNames() != null) { - for (int i = 0; i < pkg.getSplitNames().length; i++) { + if (pkg.splitNames != null) { + for (int i = 0; i < pkg.splitNames.length; i++) { splitToken = proto.start(PackageProto.SPLITS); - proto.write(PackageProto.SplitProto.NAME, pkg.getSplitNames()[i]); - proto.write(PackageProto.SplitProto.REVISION_CODE, - pkg.getSplitRevisionCodes()[i]); + proto.write(PackageProto.SplitProto.NAME, pkg.splitNames[i]); + proto.write(PackageProto.SplitProto.REVISION_CODE, pkg.splitRevisionCodes[i]); proto.end(splitToken); } } @@ -215,10 +218,4 @@ public final class PackageSetting extends PackageSettingBase implements sharedUserId = other.sharedUserId; sharedUser = other.sharedUser; } - - // TODO(b/135203078): Move to constructor - @Override - public void setAndroidPackage(AndroidPackage pkg) { - this.pkg = pkg; - } } diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index 09c1789cf445..0da6b549f296 100644 --- a/services/core/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java @@ -29,6 +29,7 @@ import android.content.pm.Signature; import android.content.pm.SuspendDialogInfo; import android.os.PersistableBundle; import android.service.pm.PackageProto; +import android.util.ArrayMap; import android.util.ArraySet; import android.util.SparseArray; import android.util.proto.ProtoOutputStream; @@ -36,6 +37,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; import java.io.File; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; @@ -50,6 +52,9 @@ public abstract class PackageSettingBase extends SettingBase { public final String name; final String realName; + String parentPackageName; + List<String> childPackageNames; + /** * Path where this package was found on disk. For monolithic packages * this is path to single base APK file; for cluster packages this is @@ -133,10 +138,14 @@ public abstract class PackageSettingBase extends SettingBase { String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, String cpuAbiOverrideString, long pVersionCode, int pkgFlags, int pkgPrivateFlags, + String parentPackageName, List<String> childPackageNames, String[] usesStaticLibraries, long[] usesStaticLibrariesVersions) { super(pkgFlags, pkgPrivateFlags); this.name = name; this.realName = realName; + this.parentPackageName = parentPackageName; + this.childPackageNames = (childPackageNames != null) + ? new ArrayList<>(childPackageNames) : null; this.usesStaticLibraries = usesStaticLibraries; this.usesStaticLibrariesVersions = usesStaticLibrariesVersions; init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString, @@ -224,6 +233,8 @@ public abstract class PackageSettingBase extends SettingBase { } private void doCopy(PackageSettingBase orig) { + childPackageNames = (orig.childPackageNames != null) + ? new ArrayList<>(orig.childPackageNames) : null; codePath = orig.codePath; codePathString = orig.codePathString; cpuAbiOverrideString = orig.cpuAbiOverrideString; @@ -235,6 +246,7 @@ public abstract class PackageSettingBase extends SettingBase { lastUpdateTime = orig.lastUpdateTime; legacyNativeLibraryPathString = orig.legacyNativeLibraryPathString; // Intentionally skip mOldCodePaths; it's not relevant for copies + parentPackageName = orig.parentPackageName; primaryCpuAbiString = orig.primaryCpuAbiString; resourcePath = orig.resourcePath; resourcePathString = orig.resourcePathString; @@ -394,14 +406,28 @@ public abstract class PackageSettingBase extends SettingBase { return readUserState(userId).suspended; } - void setSuspended(boolean suspended, String suspendingPackage, SuspendDialogInfo dialogInfo, + void addOrUpdateSuspension(String suspendingPackage, SuspendDialogInfo dialogInfo, PersistableBundle appExtras, PersistableBundle launcherExtras, int userId) { final PackageUserState existingUserState = modifyUserState(userId); - existingUserState.suspended = suspended; - existingUserState.suspendingPackage = suspended ? suspendingPackage : null; - existingUserState.dialogInfo = suspended ? dialogInfo : null; - existingUserState.suspendedAppExtras = suspended ? appExtras : null; - existingUserState.suspendedLauncherExtras = suspended ? launcherExtras : null; + final PackageUserState.SuspendParams newSuspendParams = + PackageUserState.SuspendParams.getInstanceOrNull(dialogInfo, appExtras, + launcherExtras); + if (existingUserState.suspendParams == null) { + existingUserState.suspendParams = new ArrayMap<>(); + } + existingUserState.suspendParams.put(suspendingPackage, newSuspendParams); + existingUserState.suspended = true; + } + + void removeSuspension(String suspendingPackage, int userId) { + final PackageUserState existingUserState = modifyUserState(userId); + if (existingUserState.suspendParams != null) { + existingUserState.suspendParams.remove(suspendingPackage); + if (existingUserState.suspendParams.size() == 0) { + existingUserState.suspendParams = null; + } + } + existingUserState.suspended = (existingUserState.suspendParams != null); } public boolean getInstantApp(int userId) { @@ -422,9 +448,7 @@ public abstract class PackageSettingBase extends SettingBase { void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped, boolean notLaunched, boolean hidden, int distractionFlags, boolean suspended, - String suspendingPackage, - SuspendDialogInfo dialogInfo, PersistableBundle suspendedAppExtras, - PersistableBundle suspendedLauncherExtras, boolean instantApp, + ArrayMap<String, PackageUserState.SuspendParams> suspendParams, boolean instantApp, boolean virtualPreload, String lastDisableAppCaller, ArraySet<String> enabledComponents, ArraySet<String> disabledComponents, int domainVerifState, int linkGeneration, int installReason, @@ -438,10 +462,7 @@ public abstract class PackageSettingBase extends SettingBase { state.hidden = hidden; state.distractionFlags = distractionFlags; state.suspended = suspended; - state.suspendingPackage = suspendingPackage; - state.dialogInfo = dialogInfo; - state.suspendedAppExtras = suspendedAppExtras; - state.suspendedLauncherExtras = suspendedLauncherExtras; + state.suspendParams = suspendParams; state.lastDisableAppCaller = lastDisableAppCaller; state.enabledComponents = enabledComponents; state.disabledComponents = disabledComponents; @@ -456,9 +477,8 @@ public abstract class PackageSettingBase extends SettingBase { void setUserState(int userId, PackageUserState otherState) { setUserState(userId, otherState.ceDataInode, otherState.enabled, otherState.installed, otherState.stopped, otherState.notLaunched, otherState.hidden, - otherState.distractionFlags, otherState.suspended, otherState.suspendingPackage, - otherState.dialogInfo, otherState.suspendedAppExtras, - otherState.suspendedLauncherExtras, otherState.instantApp, + otherState.distractionFlags, otherState.suspended, otherState.suspendParams, + otherState.instantApp, otherState.virtualPreload, otherState.lastDisableAppCaller, otherState.enabledComponents, otherState.disabledComponents, otherState.domainVerificationStatus, otherState.appLinkGeneration, @@ -622,7 +642,10 @@ public abstract class PackageSettingBase extends SettingBase { proto.write(PackageProto.UserInfoProto.DISTRACTION_FLAGS, state.distractionFlags); proto.write(PackageProto.UserInfoProto.IS_SUSPENDED, state.suspended); if (state.suspended) { - proto.write(PackageProto.UserInfoProto.SUSPENDING_PACKAGE, state.suspendingPackage); + for (int j = 0; j < state.suspendParams.size(); j++) { + proto.write(PackageProto.UserInfoProto.SUSPENDING_PACKAGE, + state.suspendParams.keyAt(j)); + } } proto.write(PackageProto.UserInfoProto.IS_STOPPED, state.stopped); proto.write(PackageProto.UserInfoProto.IS_LAUNCHED, !state.notLaunched); @@ -646,6 +669,8 @@ public abstract class PackageSettingBase extends SettingBase { protected PackageSettingBase updateFrom(PackageSettingBase other) { super.copyFrom(other); + this.parentPackageName = other.parentPackageName; + this.childPackageNames = other.childPackageNames; this.codePath = other.codePath; this.codePathString = other.codePathString; this.resourcePath = other.resourcePath; diff --git a/services/core/java/com/android/server/pm/PackageUsage.java b/services/core/java/com/android/server/pm/PackageUsage.java index ce2c9e767d5e..ac1f739cd9f8 100644 --- a/services/core/java/com/android/server/pm/PackageUsage.java +++ b/services/core/java/com/android/server/pm/PackageUsage.java @@ -20,7 +20,7 @@ import static android.os.Process.PACKAGE_INFO_GID; import static android.os.Process.SYSTEM_UID; import android.content.pm.PackageManager; -import android.content.pm.parsing.AndroidPackage; +import android.content.pm.PackageParser; import android.os.FileUtils; import android.util.AtomicFile; import android.util.Log; @@ -36,7 +36,7 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Map; -class PackageUsage extends AbstractStatsBase<Map<String, AndroidPackage>> { +class PackageUsage extends AbstractStatsBase<Map<String, PackageParser.Package>> { private static final String USAGE_FILE_MAGIC = "PACKAGE_USAGE__VERSION_"; private static final String USAGE_FILE_MAGIC_VERSION_1 = USAGE_FILE_MAGIC + "1"; @@ -52,7 +52,7 @@ class PackageUsage extends AbstractStatsBase<Map<String, AndroidPackage>> { } @Override - protected void writeInternal(Map<String, AndroidPackage> packages) { + protected void writeInternal(Map<String, PackageParser.Package> packages) { AtomicFile file = getFile(); FileOutputStream f = null; try { @@ -66,13 +66,13 @@ class PackageUsage extends AbstractStatsBase<Map<String, AndroidPackage>> { sb.append('\n'); out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); - for (AndroidPackage pkg : packages.values()) { + for (PackageParser.Package pkg : packages.values()) { if (pkg.getLatestPackageUseTimeInMills() == 0L) { continue; } sb.setLength(0); - sb.append(pkg.getPackageName()); - for (long usageTimeInMillis : pkg.getLastPackageUsageTimeInMills()) { + sb.append(pkg.packageName); + for (long usageTimeInMillis : pkg.mLastPackageUsageTimeInMills) { sb.append(' '); sb.append(usageTimeInMillis); } @@ -90,7 +90,7 @@ class PackageUsage extends AbstractStatsBase<Map<String, AndroidPackage>> { } @Override - protected void readInternal(Map<String, AndroidPackage> packages) { + protected void readInternal(Map<String, PackageParser.Package> packages) { AtomicFile file = getFile(); BufferedInputStream in = null; try { @@ -114,7 +114,7 @@ class PackageUsage extends AbstractStatsBase<Map<String, AndroidPackage>> { } } - private void readVersion0LP(Map<String, AndroidPackage> packages, InputStream in, + private void readVersion0LP(Map<String, PackageParser.Package> packages, InputStream in, StringBuffer sb, String firstLine) throws IOException { // Initial version of the file had no version number and stored one @@ -128,7 +128,7 @@ class PackageUsage extends AbstractStatsBase<Map<String, AndroidPackage>> { } String packageName = tokens[0]; - AndroidPackage pkg = packages.get(packageName); + PackageParser.Package pkg = packages.get(packageName); if (pkg == null) { continue; } @@ -137,12 +137,12 @@ class PackageUsage extends AbstractStatsBase<Map<String, AndroidPackage>> { for (int reason = 0; reason < PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT; reason++) { - pkg.mutate().setLastPackageUsageTimeInMills(reason, timestamp); + pkg.mLastPackageUsageTimeInMills[reason] = timestamp; } } } - private void readVersion1LP(Map<String, AndroidPackage> packages, InputStream in, + private void readVersion1LP(Map<String, PackageParser.Package> packages, InputStream in, StringBuffer sb) throws IOException { // Version 1 of the file started with the corresponding version // number and then stored a package name and eight timestamps per line. @@ -154,7 +154,7 @@ class PackageUsage extends AbstractStatsBase<Map<String, AndroidPackage>> { } String packageName = tokens[0]; - AndroidPackage pkg = packages.get(packageName); + PackageParser.Package pkg = packages.get(packageName); if (pkg == null) { continue; } @@ -162,8 +162,7 @@ class PackageUsage extends AbstractStatsBase<Map<String, AndroidPackage>> { for (int reason = 0; reason < PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT; reason++) { - pkg.mutate().setLastPackageUsageTimeInMills(reason, - parseAsLong(tokens[reason + 1])); + pkg.mLastPackageUsageTimeInMills[reason] = parseAsLong(tokens[reason + 1]); } } } @@ -197,4 +196,4 @@ class PackageUsage extends AbstractStatsBase<Map<String, AndroidPackage>> { sb.append((char)ch); } } -} +}
\ No newline at end of file diff --git a/services/core/java/com/android/server/pm/ParallelPackageParser.java b/services/core/java/com/android/server/pm/ParallelPackageParser.java index a5065145cafd..4ff3e1218b53 100644 --- a/services/core/java/com/android/server/pm/ParallelPackageParser.java +++ b/services/core/java/com/android/server/pm/ParallelPackageParser.java @@ -16,10 +16,7 @@ package com.android.server.pm; -import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; - import android.content.pm.PackageParser; -import android.content.pm.parsing.ParsedPackage; import android.os.Process; import android.os.Trace; import android.util.DisplayMetrics; @@ -33,6 +30,8 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; +import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; + /** * Helper class for parallel parsing of packages using {@link PackageParser}. * <p>Parsing requests are processed by a thread-pool of {@link #MAX_THREADS}. @@ -66,14 +65,14 @@ class ParallelPackageParser implements AutoCloseable { static class ParseResult { - ParsedPackage parsedPackage; // Parsed package + PackageParser.Package pkg; // Parsed package File scanFile; // File that was parsed Throwable throwable; // Set if an error occurs during parsing @Override public String toString() { return "ParseResult{" + - "parsedPackage=" + parsedPackage + + "pkg=" + pkg + ", scanFile=" + scanFile + ", throwable=" + throwable + '}'; @@ -101,7 +100,7 @@ class ParallelPackageParser implements AutoCloseable { /** * Submits the file for parsing * @param scanFile file to scan - * @param parseFlags parse flags + * @param parseFlags parse falgs */ public void submit(File scanFile, int parseFlags) { mService.submit(() -> { @@ -115,7 +114,7 @@ class ParallelPackageParser implements AutoCloseable { pp.setCacheDir(mCacheDir); pp.setCallback(mPackageParserCallback); pr.scanFile = scanFile; - pr.parsedPackage = parsePackage(pp, scanFile, parseFlags); + pr.pkg = parsePackage(pp, scanFile, parseFlags); } catch (Throwable e) { pr.throwable = e; } finally { @@ -134,9 +133,9 @@ class ParallelPackageParser implements AutoCloseable { } @VisibleForTesting - protected ParsedPackage parsePackage(PackageParser packageParser, File scanFile, + protected PackageParser.Package parsePackage(PackageParser packageParser, File scanFile, int parseFlags) throws PackageParser.PackageParserException { - return packageParser.parseParsedPackage(scanFile, parseFlags, true); + return packageParser.parsePackage(scanFile, parseFlags, true /* useCaches */); } @Override diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java index c404dad075cf..b464988d5871 100644 --- a/services/core/java/com/android/server/pm/SELinuxMMAC.java +++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java @@ -16,9 +16,9 @@ package com.android.server.pm; +import android.content.pm.PackageParser; import android.content.pm.PackageParser.SigningDetails; import android.content.pm.Signature; -import android.content.pm.parsing.AndroidPackage; import android.os.Environment; import android.util.Slog; import android.util.Xml; @@ -332,7 +332,7 @@ public final class SELinuxMMAC { * MINIMUM_TARGETSDKVERSION. * @return String representing the resulting seinfo. */ - public static String getSeInfo(AndroidPackage pkg, boolean isPrivileged, + public static String getSeInfo(PackageParser.Package pkg, boolean isPrivileged, int targetSdkVersion) { String seInfo = null; synchronized (sPolicies) { @@ -361,8 +361,8 @@ public final class SELinuxMMAC { seInfo += TARGETSDKVERSION_STR + targetSdkVersion; if (DEBUG_POLICY_INSTALL) { - Slog.i(TAG, "package (" + pkg.getPackageName() + ") labeled with " - + "seinfo=" + seInfo); + Slog.i(TAG, "package (" + pkg.packageName + ") labeled with " + + "seinfo=" + seInfo); } return seInfo; } @@ -371,7 +371,7 @@ public final class SELinuxMMAC { /** * Holds valid policy representations of individual stanzas from a mac_permissions.xml * file. Each instance can further be used to assign seinfo values to apks using the - * {@link Policy#getMatchedSeInfo(AndroidPackage)} method. To create an instance of this use the + * {@link Policy#getMatchedSeinfo} method. To create an instance of this use the * {@link PolicyBuilder} pattern class, where each instance is validated against a set * of invariants before being built and returned. Each instance can be guaranteed to * hold one valid policy stanza as outlined in the system/sepolicy/mac_permissions.xml @@ -498,21 +498,21 @@ final class Policy { * @return A string representing the seinfo matched during policy lookup. * A value of null can also be returned if no match occured. */ - public String getMatchedSeInfo(AndroidPackage pkg) { + public String getMatchedSeInfo(PackageParser.Package pkg) { // Check for exact signature matches across all certs. Signature[] certs = mCerts.toArray(new Signature[0]); - if (pkg.getSigningDetails() != SigningDetails.UNKNOWN - && !Signature.areExactMatch(certs, pkg.getSigningDetails().signatures)) { + if (pkg.mSigningDetails != SigningDetails.UNKNOWN + && !Signature.areExactMatch(certs, pkg.mSigningDetails.signatures)) { // certs aren't exact match, but the package may have rotated from the known system cert - if (certs.length > 1 || !pkg.getSigningDetails().hasCertificate(certs[0])) { + if (certs.length > 1 || !pkg.mSigningDetails.hasCertificate(certs[0])) { return null; } } // Check for inner package name matches given that the // signature checks already passed. - String seinfoValue = mPkgMap.get(pkg.getPackageName()); + String seinfoValue = mPkgMap.get(pkg.packageName); if (seinfoValue != null) { return seinfoValue; } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 7d6c4824a520..0db6e79ba2ed 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -42,6 +42,7 @@ import android.content.pm.ComponentInfo; import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; +import android.content.pm.PackageParser; import android.content.pm.PackageUserState; import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; @@ -49,10 +50,6 @@ import android.content.pm.Signature; import android.content.pm.SuspendDialogInfo; import android.content.pm.UserInfo; import android.content.pm.VerifierDeviceIdentity; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ComponentParseUtils; -import android.content.pm.parsing.ComponentParseUtils.ParsedComponent; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermission; import android.net.Uri; import android.os.Binder; import android.os.Build; @@ -208,9 +205,22 @@ public final class Settings { private static final String TAG_DEFAULT_BROWSER = "default-browser"; private static final String TAG_DEFAULT_DIALER = "default-dialer"; private static final String TAG_VERSION = "version"; + /** + * @deprecated Moved to {@link android.content.pm.PackageUserState.SuspendParams} + */ + @Deprecated private static final String TAG_SUSPENDED_DIALOG_INFO = "suspended-dialog-info"; + /** + * @deprecated Moved to {@link android.content.pm.PackageUserState.SuspendParams} + */ + @Deprecated private static final String TAG_SUSPENDED_APP_EXTRAS = "suspended-app-extras"; + /** + * @deprecated Moved to {@link android.content.pm.PackageUserState.SuspendParams} + */ + @Deprecated private static final String TAG_SUSPENDED_LAUNCHER_EXTRAS = "suspended-launcher-extras"; + private static final String TAG_SUSPEND_PARAMS = "suspend-params"; public static final String ATTR_NAME = "name"; public static final String ATTR_PACKAGE = "package"; @@ -469,8 +479,8 @@ public final class Settings { final PackageSetting dp = mDisabledSysPackages.get(name); // always make sure the system package code and resource paths dont change if (dp == null && p.pkg != null && p.pkg.isSystem() && !p.pkg.isUpdatedSystemApp()) { - if(p.pkg != null) { - p.pkg.mutate().setUpdatedSystemApp(true); + if((p.pkg != null) && (p.pkg.applicationInfo != null)) { + p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; } final PackageSetting disabled; if (replaced) { @@ -496,14 +506,14 @@ public final class Settings { return null; } // Reset flag in ApplicationInfo object - if(p.pkg != null) { - p.pkg.mutate().setUpdatedSystemApp(false); + if((p.pkg != null) && (p.pkg.applicationInfo != null)) { + p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; } PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath, p.legacyNativeLibraryPathString, p.primaryCpuAbiString, p.secondaryCpuAbiString, p.cpuAbiOverrideString, p.appId, p.versionCode, p.pkgFlags, p.pkgPrivateFlags, - p.usesStaticLibraries, + p.parentPackageName, p.childPackageNames, p.usesStaticLibraries, p.usesStaticLibrariesVersions); mDisabledSysPackages.remove(name); return ret; @@ -520,7 +530,8 @@ public final class Settings { PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, String cpuAbiOverrideString, int uid, long vc, int - pkgFlags, int pkgPrivateFlags, String[] usesStaticLibraries, + pkgFlags, int pkgPrivateFlags, String parentPackageName, + List<String> childPackageNames, String[] usesStaticLibraries, long[] usesStaticLibraryNames) { PackageSetting p = mPackages.get(name); if (p != null) { @@ -533,8 +544,8 @@ public final class Settings { } p = new PackageSetting(name, realName, codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString, - cpuAbiOverrideString, vc, pkgFlags, pkgPrivateFlags, - 0 /*userId*/, usesStaticLibraries, usesStaticLibraryNames); + cpuAbiOverrideString, vc, pkgFlags, pkgPrivateFlags, parentPackageName, + childPackageNames, 0 /*userId*/, usesStaticLibraries, usesStaticLibraryNames); p.appId = uid; if (registerExistingAppIdLPw(uid, p, name)) { mPackages.put(name, p); @@ -600,15 +611,19 @@ public final class Settings { File codePath, File resourcePath, String legacyNativeLibraryPath, String primaryCpuAbi, String secondaryCpuAbi, long versionCode, int pkgFlags, int pkgPrivateFlags, UserHandle installUser, boolean allowInstall, boolean instantApp, - boolean virtualPreload, UserManagerService userManager, + boolean virtualPreload, String parentPkgName, List<String> childPkgNames, + UserManagerService userManager, String[] usesStaticLibraries, long[] usesStaticLibrariesVersions) { final PackageSetting pkgSetting; if (originalPkg != null) { if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package " + pkgName + " is adopting original package " + originalPkg.name); pkgSetting = new PackageSetting(originalPkg, pkgName /*realPkgName*/); + pkgSetting.childPackageNames = + (childPkgNames != null) ? new ArrayList<>(childPkgNames) : null; pkgSetting.codePath = codePath; pkgSetting.legacyNativeLibraryPathString = legacyNativeLibraryPath; + pkgSetting.parentPackageName = parentPkgName; pkgSetting.pkgFlags = pkgFlags; pkgSetting.pkgPrivateFlags = pkgPrivateFlags; pkgSetting.primaryCpuAbiString = primaryCpuAbi; @@ -626,7 +641,7 @@ public final class Settings { pkgSetting = new PackageSetting(pkgName, realPkgName, codePath, resourcePath, legacyNativeLibraryPath, primaryCpuAbi, secondaryCpuAbi, null /*cpuAbiOverrideString*/, versionCode, pkgFlags, pkgPrivateFlags, - 0 /*sharedUserId*/, usesStaticLibraries, + parentPkgName, childPkgNames, 0 /*sharedUserId*/, usesStaticLibraries, usesStaticLibrariesVersions); pkgSetting.setTimeStamp(codePath.lastModified()); pkgSetting.sharedUser = sharedUser; @@ -658,10 +673,7 @@ public final class Settings { false /*hidden*/, 0 /*distractionFlags*/, false /*suspended*/, - null /*suspendingPackage*/, - null /*dialogInfo*/, - null /*suspendedAppExtras*/, - null /*suspendedLauncherExtras*/, + null /*suspendParams*/, instantApp, virtualPreload, null /*lastDisableAppCaller*/, @@ -713,7 +725,7 @@ public final class Settings { @NonNull File codePath, File resourcePath, @Nullable String legacyNativeLibraryPath, @Nullable String primaryCpuAbi, @Nullable String secondaryCpuAbi, int pkgFlags, int pkgPrivateFlags, - @NonNull UserManagerService userManager, + @Nullable List<String> childPkgNames, @NonNull UserManagerService userManager, @Nullable String[] usesStaticLibraries, @Nullable long[] usesStaticLibrariesVersions) throws PackageManagerException { final String pkgName = pkgSetting.name; @@ -791,6 +803,9 @@ public final class Settings { pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_ODM; pkgSetting.primaryCpuAbiString = primaryCpuAbi; pkgSetting.secondaryCpuAbiString = secondaryCpuAbi; + if (childPkgNames != null) { + pkgSetting.childPackageNames = new ArrayList<>(childPkgNames); + } // Update static shared library dependencies if needed if (usesStaticLibraries != null && usesStaticLibrariesVersions != null && usesStaticLibraries.length == usesStaticLibrariesVersions.length) { @@ -859,15 +874,15 @@ public final class Settings { // TODO: Move to scanPackageOnlyLI() after verifying signatures are setup correctly // by that time. - void insertPackageSettingLPw(PackageSetting p, AndroidPackage pkg) { + void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) { // Update signatures if needed. if (p.signatures.mSigningDetails.signatures == null) { - p.signatures.mSigningDetails = pkg.getSigningDetails(); + p.signatures.mSigningDetails = pkg.mSigningDetails; } // If this app defines a shared user id initialize // the shared user signatures as well. if (p.sharedUser != null && p.sharedUser.signatures.mSigningDetails.signatures == null) { - p.sharedUser.signatures.mSigningDetails = pkg.getSigningDetails(); + p.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails; } addPackageSettingLPw(p, p.sharedUser); } @@ -944,7 +959,7 @@ public final class Settings { int affectedUserId = UserHandle.USER_NULL; // Update permissions - for (String eachPerm : deletedPs.pkg.getRequestedPermissions()) { + for (String eachPerm : deletedPs.pkg.requestedPermissions) { BasePermission bp = mPermissions.getPermission(eachPerm); if (bp == null) { continue; @@ -954,8 +969,8 @@ public final class Settings { boolean used = false; for (PackageSetting pkg : sus.packages) { if (pkg.pkg != null - && !pkg.pkg.getPackageName().equals(deletedPs.pkg.getPackageName()) - && pkg.pkg.getRequestedPermissions().contains(eachPerm)) { + && !pkg.pkg.packageName.equals(deletedPs.pkg.packageName) + && pkg.pkg.requestedPermissions.contains(eachPerm)) { used = true; break; } @@ -965,13 +980,13 @@ public final class Settings { } PermissionsState permissionsState = sus.getPermissionsState(); - PackageSetting disabledPs = getDisabledSystemPkgLPr(deletedPs.pkg.getPackageName()); + PackageSetting disabledPs = getDisabledSystemPkgLPr(deletedPs.pkg.packageName); // If the package is shadowing is a disabled system package, // do not drop permissions that the shadowed package requests. if (disabledPs != null) { boolean reqByDisabledSysPkg = false; - for (String permission : disabledPs.pkg.getRequestedPermissions()) { + for (String permission : disabledPs.pkg.requestedPermissions) { if (permission.equals(eachPerm)) { reqByDisabledSysPkg = true; break; @@ -1545,10 +1560,7 @@ public final class Settings { false /*hidden*/, 0 /*distractionFlags*/, false /*suspended*/, - null /*suspendingPackage*/, - null /*dialogInfo*/, - null /*suspendedAppExtras*/, - null /*suspendedLauncherExtras*/, + null /*suspendParams*/, false /*instantApp*/, false /*virtualPreload*/, null /*lastDisableAppCaller*/, @@ -1623,12 +1635,12 @@ public final class Settings { ATTR_DISTRACTION_FLAGS, 0); final boolean suspended = XmlUtils.readBooleanAttribute(parser, ATTR_SUSPENDED, false); - String suspendingPackage = parser.getAttributeValue(null, + String oldSuspendingPackage = parser.getAttributeValue(null, ATTR_SUSPENDING_PACKAGE); final String dialogMessage = parser.getAttributeValue(null, ATTR_SUSPEND_DIALOG_MESSAGE); - if (suspended && suspendingPackage == null) { - suspendingPackage = PLATFORM_PACKAGE_NAME; + if (suspended && oldSuspendingPackage == null) { + oldSuspendingPackage = PLATFORM_PACKAGE_NAME; } final boolean blockUninstall = XmlUtils.readBooleanAttribute(parser, @@ -1658,9 +1670,10 @@ public final class Settings { ArraySet<String> disabledComponents = null; PersistableBundle suspendedAppExtras = null; PersistableBundle suspendedLauncherExtras = null; - SuspendDialogInfo suspendDialogInfo = null; + SuspendDialogInfo oldSuspendDialogInfo = null; int packageDepth = parser.getDepth(); + ArrayMap<String, PackageUserState.SuspendParams> suspendParamsMap = null; while ((type=parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > packageDepth)) { @@ -1682,26 +1695,48 @@ public final class Settings { suspendedLauncherExtras = PersistableBundle.restoreFromXml(parser); break; case TAG_SUSPENDED_DIALOG_INFO: - suspendDialogInfo = SuspendDialogInfo.restoreFromXml(parser); + oldSuspendDialogInfo = SuspendDialogInfo.restoreFromXml(parser); + break; + case TAG_SUSPEND_PARAMS: + final String suspendingPackage = parser.getAttributeValue(null, + ATTR_SUSPENDING_PACKAGE); + if (suspendingPackage == null) { + Slog.wtf(TAG, "No suspendingPackage found inside tag " + + TAG_SUSPEND_PARAMS); + continue; + } + if (suspendParamsMap == null) { + suspendParamsMap = new ArrayMap<>(); + } + suspendParamsMap.put(suspendingPackage, + PackageUserState.SuspendParams.restoreFromXml(parser)); break; default: Slog.wtf(TAG, "Unknown tag " + parser.getName() + " under tag " + TAG_PACKAGE); } } - if (suspendDialogInfo == null && !TextUtils.isEmpty(dialogMessage)) { - suspendDialogInfo = new SuspendDialogInfo.Builder() + if (oldSuspendDialogInfo == null && !TextUtils.isEmpty(dialogMessage)) { + oldSuspendDialogInfo = new SuspendDialogInfo.Builder() .setMessage(dialogMessage) .build(); } + if (suspended && suspendParamsMap == null) { + final PackageUserState.SuspendParams suspendParams = + PackageUserState.SuspendParams.getInstanceOrNull( + oldSuspendDialogInfo, + suspendedAppExtras, + suspendedLauncherExtras); + suspendParamsMap = new ArrayMap<>(); + suspendParamsMap.put(oldSuspendingPackage, suspendParams); + } if (blockUninstall) { setBlockUninstallLPw(userId, name, true); } ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched, - hidden, distractionFlags, suspended, suspendingPackage, - suspendDialogInfo, - suspendedAppExtras, suspendedLauncherExtras, instantApp, virtualPreload, + hidden, distractionFlags, suspended, suspendParamsMap, + instantApp, virtualPreload, enabledCaller, enabledComponents, disabledComponents, verifState, linkGeneration, installReason, harmfulAppWarning); } else if (tagName.equals("preferred-activities")) { @@ -2001,35 +2036,6 @@ public final class Settings { } if (ustate.suspended) { serializer.attribute(null, ATTR_SUSPENDED, "true"); - if (ustate.suspendingPackage != null) { - serializer.attribute(null, ATTR_SUSPENDING_PACKAGE, - ustate.suspendingPackage); - } - if (ustate.dialogInfo != null) { - serializer.startTag(null, TAG_SUSPENDED_DIALOG_INFO); - ustate.dialogInfo.saveToXml(serializer); - serializer.endTag(null, TAG_SUSPENDED_DIALOG_INFO); - } - if (ustate.suspendedAppExtras != null) { - serializer.startTag(null, TAG_SUSPENDED_APP_EXTRAS); - try { - ustate.suspendedAppExtras.saveToXml(serializer); - } catch (XmlPullParserException xmle) { - Slog.wtf(TAG, "Exception while trying to write suspendedAppExtras for " - + pkg + ". Will be lost on reboot", xmle); - } - serializer.endTag(null, TAG_SUSPENDED_APP_EXTRAS); - } - if (ustate.suspendedLauncherExtras != null) { - serializer.startTag(null, TAG_SUSPENDED_LAUNCHER_EXTRAS); - try { - ustate.suspendedLauncherExtras.saveToXml(serializer); - } catch (XmlPullParserException xmle) { - Slog.wtf(TAG, "Exception while trying to write suspendedLauncherExtras" - + " for " + pkg + ". Will be lost on reboot", xmle); - } - serializer.endTag(null, TAG_SUSPENDED_LAUNCHER_EXTRAS); - } } if (ustate.instantApp) { serializer.attribute(null, ATTR_INSTANT_APP, "true"); @@ -2062,6 +2068,19 @@ public final class Settings { serializer.attribute(null, ATTR_HARMFUL_APP_WARNING, ustate.harmfulAppWarning); } + if (ustate.suspended) { + for (int i = 0; i < ustate.suspendParams.size(); i++) { + final String suspendingPackage = ustate.suspendParams.keyAt(i); + serializer.startTag(null, TAG_SUSPEND_PARAMS); + serializer.attribute(null, ATTR_SUSPENDING_PACKAGE, suspendingPackage); + final PackageUserState.SuspendParams params = + ustate.suspendParams.valueAt(i); + if (params != null) { + params.saveToXml(serializer); + } + serializer.endTag(null, TAG_SUSPEND_PARAMS); + } + } if (!ArrayUtils.isEmpty(ustate.enabledComponents)) { serializer.startTag(null, TAG_ENABLED_COMPONENTS); for (final String name : ustate.enabledComponents) { @@ -2202,6 +2221,20 @@ public final class Settings { serializer.endTag(null, TAG_PERMISSIONS); } + void writeChildPackagesLPw(XmlSerializer serializer, List<String> childPackageNames) + throws IOException { + if (childPackageNames == null) { + return; + } + final int childCount = childPackageNames.size(); + for (int i = 0; i < childCount; i++) { + String childPackageName = childPackageNames.get(i); + serializer.startTag(null, TAG_CHILD_PACKAGE); + serializer.attribute(null, ATTR_NAME, childPackageName); + serializer.endTag(null, TAG_CHILD_PACKAGE); + } + } + void readUsesStaticLibLPw(XmlPullParser parser, PackageSetting outPs) throws IOException, XmlPullParserException { int outerDepth = parser.getDepth(); @@ -2655,15 +2688,17 @@ public final class Settings { StringBuilder sb = new StringBuilder(); for (final PackageSetting pkg : mPackages.values()) { - if (pkg.pkg == null || pkg.pkg.getDataDir() == null) { + if (pkg.pkg == null || pkg.pkg.applicationInfo == null + || pkg.pkg.applicationInfo.dataDir == null) { if (!"android".equals(pkg.name)) { Slog.w(TAG, "Skipping " + pkg + " due to missing metadata"); } continue; } - final String dataPath = pkg.pkg.getDataDir(); - final boolean isDebug = (pkg.pkg.getFlags() & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + final ApplicationInfo ai = pkg.pkg.applicationInfo; + final String dataPath = ai.dataDir; + final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; final int[] gids = pkg.getPermissionsState().computeGids(userIds); // Avoid any application that has a space in its path. @@ -2688,13 +2723,13 @@ public final class Settings { // system/core/libpackagelistparser // sb.setLength(0); - sb.append(pkg.pkg.getPackageName()); + sb.append(ai.packageName); sb.append(" "); - sb.append(pkg.pkg.getUid()); + sb.append(ai.uid); sb.append(isDebug ? " 1 " : " 0 "); sb.append(dataPath); sb.append(" "); - sb.append(pkg.pkg.getSeInfo()); + sb.append(ai.seInfo); sb.append(" "); if (gids != null && gids.length > 0) { sb.append(gids[0]); @@ -2706,9 +2741,9 @@ public final class Settings { sb.append("none"); } sb.append(" "); - sb.append(pkg.pkg.isProfileableByShell() ? "1" : "0"); + sb.append(ai.isProfileableByShell() ? "1" : "0"); sb.append(" "); - sb.append(pkg.pkg.getLongVersionCode()); + sb.append(String.valueOf(ai.longVersionCode)); sb.append("\n"); writer.append(sb); } @@ -2757,6 +2792,12 @@ public final class Settings { serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId)); } + if (pkg.parentPackageName != null) { + serializer.attribute(null, "parentPackageName", pkg.parentPackageName); + } + + writeChildPackagesLPw(serializer, pkg.childPackageNames); + writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions); // If this is a shared user, the permissions will be written there. @@ -2820,10 +2861,15 @@ public final class Settings { serializer.attribute(null, "categoryHint", Integer.toString(pkg.categoryHint)); } + if (pkg.parentPackageName != null) { + serializer.attribute(null, "parentPackageName", pkg.parentPackageName); + } if (pkg.updateAvailable) { serializer.attribute(null, "updateAvailable", "true"); } + writeChildPackagesLPw(serializer, pkg.childPackageNames); + writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions); pkg.signatures.writeXml(serializer, "sigs", mPastSignatures); @@ -3116,13 +3162,13 @@ public final class Settings { LocalServices.getService(PackageManagerInternal.class); for (PackageSetting ps : mPackages.values()) { if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null - && ps.pkg.getPreferredActivityFilters() != null) { - List<ComponentParseUtils.ParsedActivityIntentInfo> intents - = ps.pkg.getPreferredActivityFilters(); + && ps.pkg.preferredActivityFilters != null) { + ArrayList<PackageParser.ActivityIntentInfo> intents + = ps.pkg.preferredActivityFilters; for (int i=0; i<intents.size(); i++) { - ComponentParseUtils.ParsedActivityIntentInfo aii = intents.get(i); + PackageParser.ActivityIntentInfo aii = intents.get(i); applyDefaultPreferredActivityLPw(pmInternal, aii, new ComponentName( - ps.name, aii.getClassName()), userId); + ps.name, aii.activity.className), userId); } } } @@ -3481,7 +3527,7 @@ public final class Settings { PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr, secondaryCpuAbiStr, cpuAbiOverrideStr, versionCode, pkgFlags, pkgPrivateFlags, - 0 /*sharedUserId*/, null, null); + parentPackageName, null /*childPackageNames*/, 0 /*sharedUserId*/, null, null); String timeStampStr = parser.getAttributeValue(null, "ft"); if (timeStampStr != null) { try { @@ -3530,6 +3576,12 @@ public final class Settings { if (parser.getName().equals(TAG_PERMISSIONS)) { readInstallPermissionsLPr(parser, ps.getPermissionsState()); + } else if (parser.getName().equals(TAG_CHILD_PACKAGE)) { + String childPackageName = parser.getAttributeValue(null, ATTR_NAME); + if (ps.childPackageNames == null) { + ps.childPackageNames = new ArrayList<>(); + } + ps.childPackageNames.add(childPackageName); } else if (parser.getName().equals(TAG_USES_STATIC_LIB)) { readUsesStaticLibLPw(parser, ps); } else { @@ -3574,6 +3626,7 @@ public final class Settings { PackageSetting packageSetting = null; String version = null; long versionCode = 0; + String parentPackageName; try { name = parser.getAttributeValue(null, ATTR_NAME); realName = parser.getAttributeValue(null, "realName"); @@ -3585,6 +3638,8 @@ public final class Settings { legacyCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi"); + parentPackageName = parser.getAttributeValue(null, "parentPackageName"); + legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath"); primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi"); secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi"); @@ -3711,7 +3766,7 @@ public final class Settings { packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags, - pkgPrivateFlags, + pkgPrivateFlags, parentPackageName, null /*childPackageNames*/, null /*usesStaticLibraries*/, null /*usesStaticLibraryVersions*/); if (PackageManagerService.DEBUG_SETTINGS) Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId=" @@ -3730,8 +3785,8 @@ public final class Settings { packageSetting = new PackageSetting(name.intern(), realName, new File( codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString, - versionCode, pkgFlags, pkgPrivateFlags, - sharedUserId, + versionCode, pkgFlags, pkgPrivateFlags, parentPackageName, + null /*childPackageNames*/, sharedUserId, null /*usesStaticLibraries*/, null /*usesStaticLibraryVersions*/); packageSetting.setTimeStamp(timeStamp); packageSetting.firstInstallTime = firstInstallTime; @@ -3839,6 +3894,12 @@ public final class Settings { packageSetting.keySetData.addDefinedKeySet(id, alias); } else if (tagName.equals(TAG_DOMAIN_VERIFICATION)) { readDomainVerificationLPw(parser, packageSetting); + } else if (tagName.equals(TAG_CHILD_PACKAGE)) { + String childPackageName = parser.getAttributeValue(null, ATTR_NAME); + if (packageSetting.childPackageNames == null) { + packageSetting.childPackageNames = new ArrayList<>(); + } + packageSetting.childPackageNames.add(childPackageName); } else { PackageManagerService.reportSettingsProblem(Log.WARN, "Unknown element under <package>: " + parser.getName()); @@ -3991,13 +4052,13 @@ public final class Settings { Iterator<PackageSetting> packagesIterator = packages.iterator(); for (int i = 0; i < packagesCount; i++) { PackageSetting ps = packagesIterator.next(); - if (ps.pkg == null) { + if (ps.pkg == null || ps.pkg.applicationInfo == null) { continue; } final boolean shouldInstall = ps.isSystem() && (skipPackageWhitelist || installablePackages.contains(ps.name)) && !ArrayUtils.contains(disallowedPackages, ps.name) && - !ps.pkg.isHiddenUntilInstalled(); + !ps.pkg.applicationInfo.hiddenUntilInstalled; // Only system apps are initially installed. ps.setInstalled(shouldInstall, userHandle); if (!shouldInstall) { @@ -4008,8 +4069,8 @@ public final class Settings { volumeUuids[i] = ps.volumeUuid; names[i] = ps.name; appIds[i] = ps.appId; - seinfos[i] = ps.pkg.getSeInfo(); - targetSdkVersions[i] = ps.pkg.getTargetSdkVersion(); + seinfos[i] = ps.pkg.applicationInfo.seInfo; + targetSdkVersions[i] = ps.pkg.applicationInfo.targetSdkVersion; } } t.traceBegin("createAppData"); @@ -4119,6 +4180,28 @@ public final class Settings { return mVerifierDeviceIdentity; } + boolean hasOtherDisabledSystemPkgWithChildLPr(String parentPackageName, + String childPackageName) { + final int packageCount = mDisabledSysPackages.size(); + for (int i = 0; i < packageCount; i++) { + PackageSetting disabledPs = mDisabledSysPackages.valueAt(i); + if (disabledPs.childPackageNames == null || disabledPs.childPackageNames.isEmpty()) { + continue; + } + if (disabledPs.name.equals(parentPackageName)) { + continue; + } + final int childCount = disabledPs.childPackageNames.size(); + for (int j = 0; j < childCount; j++) { + String currChildPackageName = disabledPs.childPackageNames.get(j); + if (currChildPackageName.equals(childPackageName)) { + return true; + } + } + } + return false; + } + /** * Returns the disabled {@link PackageSetting} for the provided package name if one exists, * {@code null} otherwise. @@ -4141,6 +4224,26 @@ public final class Settings { return getDisabledSystemPkgLPr(enabledPackageSetting.name); } + /** + * Fetches an array of the child {@link PackageSetting}s for all child package names referenced + * by the provided parent {@link PackageSetting} or {@code null} if no children are referenced. + * + * Note: Any child packages not found will be null in the returned array. + */ + @Nullable + public PackageSetting[] getChildSettingsLPr(PackageSetting parentPackageSetting) { + if (parentPackageSetting == null || !parentPackageSetting.hasChildPackages()) { + return null; + } + final int childCount = parentPackageSetting.childPackageNames.size(); + PackageSetting[] children = + new PackageSetting[childCount]; + for (int i = 0; i < childCount; i++) { + children[i] = mPackages.get(parentPackageSetting.childPackageNames.get(i)); + } + return children; + } + boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId) { final PackageSetting ps = mPackages.get(componentInfo.packageName); if (ps == null) return false; @@ -4149,15 +4252,6 @@ public final class Settings { return userState.isMatch(componentInfo, flags); } - boolean isEnabledAndMatchLPr(AndroidPackage pkg, ParsedComponent component, int flags, - int userId) { - final PackageSetting ps = mPackages.get(component.getPackageName()); - if (ps == null) return false; - - final PackageUserState userState = ps.readUserState(userId); - return userState.isMatch(pkg.isSystem(), pkg.isEnabled(), component, flags); - } - String getInstallerPackageNameLPr(String packageName) { final PackageSetting pkg = mPackages.get(packageName); if (pkg == null) { @@ -4375,7 +4469,6 @@ public final class Settings { void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf, Date date, List<UserInfo> users, boolean dumpAll, boolean dumpAllComponents) { - AndroidPackage pkg = ps.pkg; if (checkinTag != null) { pw.print(checkinTag); pw.print(","); @@ -4391,16 +4484,15 @@ public final class Settings { pw.print(","); pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?"); pw.println(); - if (pkg != null) { + if (ps.pkg != null) { pw.print(checkinTag); pw.print("-"); pw.print("splt,"); pw.print("base,"); - pw.println(pkg.getBaseRevisionCode()); - if (pkg.getSplitNames() != null) { - int[] splitRevisionCodes = pkg.getSplitRevisionCodes(); - for (int i = 0; i < pkg.getSplitNames().length; i++) { + pw.println(ps.pkg.baseRevisionCode); + if (ps.pkg.splitNames != null) { + for (int i = 0; i < ps.pkg.splitNames.length; i++) { pw.print(checkinTag); pw.print("-"); pw.print("splt,"); - pw.print(pkg.getSplitNames()[i]); pw.print(","); - pw.println(splitRevisionCodes[i]); + pw.print(ps.pkg.splitNames[i]); pw.print(","); + pw.println(ps.pkg.splitRevisionCodes[i]); } } } @@ -4447,7 +4539,7 @@ public final class Settings { if (ps.sharedUser != null) { pw.print(prefix); pw.print(" sharedUser="); pw.println(ps.sharedUser); } - pw.print(prefix); pw.print(" pkg="); pw.println(pkg); + pw.print(prefix); pw.print(" pkg="); pw.println(ps.pkg); pw.print(prefix); pw.print(" codePath="); pw.println(ps.codePathString); if (permissionNames == null) { pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.resourcePathString); @@ -4457,123 +4549,140 @@ public final class Settings { pw.print(prefix); pw.print(" secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString); } pw.print(prefix); pw.print(" versionCode="); pw.print(ps.versionCode); - if (pkg != null) { - pw.print(" minSdk="); pw.print(pkg.getMinSdkVersion()); - pw.print(" targetSdk="); pw.print(pkg.getTargetSdkVersion()); + if (ps.pkg != null) { + pw.print(" minSdk="); pw.print(ps.pkg.applicationInfo.minSdkVersion); + pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion); } pw.println(); - if (pkg != null) { - pw.print(prefix); pw.print(" versionName="); pw.println(pkg.getVersionName()); - pw.print(prefix); pw.print(" splits="); dumpSplitNames(pw, pkg); pw.println(); - final int apkSigningVersion = pkg.getSigningDetails().signatureSchemeVersion; + if (ps.pkg != null) { + if (ps.pkg.parentPackage != null) { + PackageParser.Package parentPkg = ps.pkg.parentPackage; + PackageSetting pps = mPackages.get(parentPkg.packageName); + if (pps == null || !pps.codePathString.equals(parentPkg.codePath)) { + pps = mDisabledSysPackages.get(parentPkg.packageName); + } + if (pps != null) { + pw.print(prefix); pw.print(" parentPackage="); + pw.println(pps.realName != null ? pps.realName : pps.name); + } + } else if (ps.pkg.childPackages != null) { + pw.print(prefix); pw.print(" childPackages=["); + final int childCount = ps.pkg.childPackages.size(); + for (int i = 0; i < childCount; i++) { + PackageParser.Package childPkg = ps.pkg.childPackages.get(i); + PackageSetting cps = mPackages.get(childPkg.packageName); + if (cps == null || !cps.codePathString.equals(childPkg.codePath)) { + cps = mDisabledSysPackages.get(childPkg.packageName); + } + if (cps != null) { + if (i > 0) { + pw.print(", "); + } + pw.print(cps.realName != null ? cps.realName : cps.name); + } + } + pw.println("]"); + } + pw.print(prefix); pw.print(" versionName="); pw.println(ps.pkg.mVersionName); + pw.print(prefix); pw.print(" splits="); dumpSplitNames(pw, ps.pkg); pw.println(); + final int apkSigningVersion = ps.pkg.mSigningDetails.signatureSchemeVersion; pw.print(prefix); pw.print(" apkSigningVersion="); pw.println(apkSigningVersion); - // TODO(b/135203078): Is there anything to print here with AppInfo removed? pw.print(prefix); pw.print(" applicationInfo="); - pw.println(pkg.toAppInfo().toString()); - pw.print(prefix); pw.print(" flags="); printFlags(pw, pkg.getFlags(), + pw.println(ps.pkg.applicationInfo.toString()); + pw.print(prefix); pw.print(" flags="); printFlags(pw, ps.pkg.applicationInfo.flags, FLAG_DUMP_SPEC); pw.println(); - if (pkg.getPrivateFlags() != 0) { + if (ps.pkg.applicationInfo.privateFlags != 0) { pw.print(prefix); pw.print(" privateFlags="); printFlags(pw, - pkg.getPrivateFlags(), PRIVATE_FLAG_DUMP_SPEC); pw.println(); + ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println(); } - pw.print(prefix); pw.print(" forceQueryable="); pw.println(ps.pkg.isForceQueryable()); - if (ps.pkg.getQueriesPackages() != null) { - pw.append(prefix).append(" queriesPackages=").println(ps.pkg.getQueriesPackages()); + pw.print(prefix); pw.print(" forceQueryable="); pw.println(ps.pkg.mForceQueryable); + if (ps.pkg.mQueriesPackages != null) { + pw.append(prefix).append(" queriesPackages=").println(ps.pkg.mQueriesPackages); } - if (ps.pkg.getQueriesIntents() != null) { - pw.append(prefix).append(" queriesIntents=").println(ps.pkg.getQueriesIntents()); + if (ps.pkg.mQueriesIntents != null) { + pw.append(prefix).append(" queriesIntents=").println(ps.pkg.mQueriesIntents); } - pw.print(prefix); pw.print(" dataDir="); pw.println(ps.pkg.getDataDir()); + pw.print(prefix); pw.print(" dataDir="); pw.println(ps.pkg.applicationInfo.dataDir); pw.print(prefix); pw.print(" supportsScreens=["); boolean first = true; - if ((pkg.getFlags() & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) { + if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) { if (!first) pw.print(", "); first = false; pw.print("small"); } - if ((pkg.getFlags() & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) { + if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) { if (!first) pw.print(", "); first = false; pw.print("medium"); } - if ((pkg.getFlags() & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) { + if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) { if (!first) pw.print(", "); first = false; pw.print("large"); } - if ((pkg.getFlags() & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) { + if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) { if (!first) pw.print(", "); first = false; pw.print("xlarge"); } - if ((pkg.getFlags() & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) { + if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) { if (!first) pw.print(", "); first = false; pw.print("resizeable"); } - if ((pkg.getFlags() & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) { + if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) { if (!first) pw.print(", "); first = false; pw.print("anyDensity"); } pw.println("]"); - List<String> libraryNames = pkg.getLibraryNames(); - if (libraryNames != null && libraryNames.size() > 0) { + if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) { pw.print(prefix); pw.println(" dynamic libraries:"); - for (int i = 0; i< libraryNames.size(); i++) { + for (int i = 0; i<ps.pkg.libraryNames.size(); i++) { pw.print(prefix); pw.print(" "); - pw.println(libraryNames.get(i)); + pw.println(ps.pkg.libraryNames.get(i)); } } - if (pkg.getStaticSharedLibName() != null) { + if (ps.pkg.staticSharedLibName != null) { pw.print(prefix); pw.println(" static library:"); pw.print(prefix); pw.print(" "); - pw.print("name:"); pw.print(pkg.getStaticSharedLibName()); - pw.print(" version:"); pw.println(pkg.getStaticSharedLibVersion()); + pw.print("name:"); pw.print(ps.pkg.staticSharedLibName); + pw.print(" version:"); pw.println(ps.pkg.staticSharedLibVersion); } - - List<String> usesLibraries = pkg.getUsesLibraries(); - if (usesLibraries != null && usesLibraries.size() > 0) { + if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) { pw.print(prefix); pw.println(" usesLibraries:"); - for (int i=0; i< usesLibraries.size(); i++) { - pw.print(prefix); pw.print(" "); pw.println(usesLibraries.get(i)); + for (int i=0; i<ps.pkg.usesLibraries.size(); i++) { + pw.print(prefix); pw.print(" "); pw.println(ps.pkg.usesLibraries.get(i)); } } - - List<String> usesStaticLibraries = pkg.getUsesStaticLibraries(); - long[] usesStaticLibrariesVersions = pkg.getUsesStaticLibrariesVersions(); - if (usesStaticLibraries != null - && usesStaticLibraries.size() > 0) { + if (ps.pkg.usesStaticLibraries != null + && ps.pkg.usesStaticLibraries.size() > 0) { pw.print(prefix); pw.println(" usesStaticLibraries:"); - for (int i=0; i< usesStaticLibraries.size(); i++) { + for (int i=0; i<ps.pkg.usesStaticLibraries.size(); i++) { pw.print(prefix); pw.print(" "); - pw.print(usesStaticLibraries.get(i)); pw.print(" version:"); - pw.println(usesStaticLibrariesVersions[i]); + pw.print(ps.pkg.usesStaticLibraries.get(i)); pw.print(" version:"); + pw.println(ps.pkg.usesStaticLibrariesVersions[i]); } } - - List<String> usesOptionalLibraries = pkg.getUsesOptionalLibraries(); - if (usesOptionalLibraries != null - && usesOptionalLibraries.size() > 0) { + if (ps.pkg.usesOptionalLibraries != null + && ps.pkg.usesOptionalLibraries.size() > 0) { pw.print(prefix); pw.println(" usesOptionalLibraries:"); - for (int i=0; i< usesOptionalLibraries.size(); i++) { + for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) { pw.print(prefix); pw.print(" "); - pw.println(usesOptionalLibraries.get(i)); + pw.println(ps.pkg.usesOptionalLibraries.get(i)); } } - - String[] usesLibraryFiles = pkg.getUsesLibraryFiles(); - if (usesLibraryFiles != null - && usesLibraryFiles.length > 0) { + if (ps.pkg.usesLibraryFiles != null + && ps.pkg.usesLibraryFiles.length > 0) { pw.print(prefix); pw.println(" usesLibraryFiles:"); - for (int i=0; i< usesLibraryFiles.length; i++) { - pw.print(prefix); pw.print(" "); pw.println(usesLibraryFiles[i]); + for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) { + pw.print(prefix); pw.print(" "); pw.println(ps.pkg.usesLibraryFiles[i]); } } } @@ -4601,40 +4710,40 @@ public final class Settings { pw.print(prefix); pw.print(" pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC); pw.println(); - if (pkg != null && pkg.getOverlayTarget() != null) { - pw.print(prefix); pw.print(" overlayTarget="); pw.println(pkg.getOverlayTarget()); - pw.print(prefix); pw.print(" overlayCategory="); pw.println(pkg.getOverlayCategory()); + if (ps.pkg != null && ps.pkg.mOverlayTarget != null) { + pw.print(prefix); pw.print(" overlayTarget="); pw.println(ps.pkg.mOverlayTarget); + pw.print(prefix); pw.print(" overlayCategory="); pw.println(ps.pkg.mOverlayCategory); } - if (pkg != null && pkg.getPermissions() != null && pkg.getPermissions().size() > 0) { - final List<ParsedPermission> perms = pkg.getPermissions(); + if (ps.pkg != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) { + final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions; pw.print(prefix); pw.println(" declared permissions:"); for (int i=0; i<perms.size(); i++) { - ParsedPermission perm = perms.get(i); + PackageParser.Permission perm = perms.get(i); if (permissionNames != null - && !permissionNames.contains(perm.getName())) { + && !permissionNames.contains(perm.info.name)) { continue; } - pw.print(prefix); pw.print(" "); pw.print(perm.getName()); + pw.print(prefix); pw.print(" "); pw.print(perm.info.name); pw.print(": prot="); - pw.print(PermissionInfo.protectionToString(perm.protectionLevel)); - if ((perm.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) { + pw.print(PermissionInfo.protectionToString(perm.info.protectionLevel)); + if ((perm.info.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) { pw.print(", COSTS_MONEY"); } - if ((perm.flags&PermissionInfo.FLAG_REMOVED) != 0) { + if ((perm.info.flags&PermissionInfo.FLAG_REMOVED) != 0) { pw.print(", HIDDEN"); } - if ((perm.flags&PermissionInfo.FLAG_INSTALLED) != 0) { + if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) { pw.print(", INSTALLED"); } pw.println(); } } - if ((permissionNames != null || dumpAll) && pkg != null - && pkg.getRequestedPermissions() != null - && pkg.getRequestedPermissions().size() > 0) { - final List<String> perms = pkg.getRequestedPermissions(); + if ((permissionNames != null || dumpAll) && ps.pkg != null + && ps.pkg.requestedPermissions != null + && ps.pkg.requestedPermissions.size() > 0) { + final ArrayList<String> perms = ps.pkg.requestedPermissions; pw.print(prefix); pw.println(" requested permissions:"); for (int i=0; i<perms.size(); i++) { String perm = perms.get(i); @@ -4671,13 +4780,6 @@ public final class Settings { pw.print(ps.getHidden(user.id)); pw.print(" suspended="); pw.print(ps.getSuspended(user.id)); - if (ps.getSuspended(user.id)) { - final PackageUserState pus = ps.readUserState(user.id); - pw.print(" suspendingPackage="); - pw.print(pus.suspendingPackage); - pw.print(" dialogInfo="); - pw.print(pus.dialogInfo); - } pw.print(" stopped="); pw.print(ps.getStopped(user.id)); pw.print(" notLaunched="); @@ -4689,6 +4791,23 @@ public final class Settings { pw.print(" virtual="); pw.println(ps.getVirtulalPreload(user.id)); + if (ps.getSuspended(user.id)) { + pw.print(prefix); + pw.println(" Suspend params:"); + final PackageUserState pus = ps.readUserState(user.id); + for (int i = 0; i < pus.suspendParams.size(); i++) { + pw.print(prefix); + pw.print(" suspendingPackage="); + pw.print(pus.suspendParams.keyAt(i)); + final PackageUserState.SuspendParams params = pus.suspendParams.valueAt(i); + if (params != null) { + pw.print(" dialogInfo="); + pw.print(params.dialogInfo); + } + pw.println(); + } + } + String[] overlayPaths = ps.getOverlayPaths(user.id); if (overlayPaths != null && overlayPaths.length > 0) { pw.print(prefix); pw.println(" overlay paths:"); @@ -4901,24 +5020,22 @@ public final class Settings { pw.print(mReadMessages.toString()); } - private static void dumpSplitNames(PrintWriter pw, AndroidPackage pkg) { + private static void dumpSplitNames(PrintWriter pw, PackageParser.Package pkg) { if (pkg == null) { pw.print("unknown"); } else { // [base:10, config.mdpi, config.xhdpi:12] pw.print("["); pw.print("base"); - if (pkg.getBaseRevisionCode() != 0) { - pw.print(":"); pw.print(pkg.getBaseRevisionCode()); + if (pkg.baseRevisionCode != 0) { + pw.print(":"); pw.print(pkg.baseRevisionCode); } - String[] splitNames = pkg.getSplitNames(); - int[] splitRevisionCodes = pkg.getSplitRevisionCodes(); - if (splitNames != null) { - for (int i = 0; i < splitNames.length; i++) { + if (pkg.splitNames != null) { + for (int i = 0; i < pkg.splitNames.length; i++) { pw.print(", "); - pw.print(splitNames[i]); - if (splitRevisionCodes[i] != 0) { - pw.print(":"); pw.print(splitRevisionCodes[i]); + pw.print(pkg.splitNames[i]); + if (pkg.splitRevisionCodes[i] != 0) { + pw.print(":"); pw.print(pkg.splitRevisionCodes[i]); } } } @@ -4994,23 +5111,22 @@ public final class Settings { } void dumpComponents(PrintWriter pw, String prefix, PackageSetting ps) { - // TODO(b/135203078): ParsedComponent toString methods for dumping - dumpComponents(pw, prefix, "activities:", ps.pkg.getActivities()); - dumpComponents(pw, prefix, "services:", ps.pkg.getServices()); - dumpComponents(pw, prefix, "receivers:", ps.pkg.getReceivers()); - dumpComponents(pw, prefix, "providers:", ps.pkg.getProviders()); - dumpComponents(pw, prefix, "instrumentations:", ps.pkg.getInstrumentations()); + dumpComponents(pw, prefix, ps, "activities:", ps.pkg.activities); + dumpComponents(pw, prefix, ps, "services:", ps.pkg.services); + dumpComponents(pw, prefix, ps, "receivers:", ps.pkg.receivers); + dumpComponents(pw, prefix, ps, "providers:", ps.pkg.providers); + dumpComponents(pw, prefix, ps, "instrumentations:", ps.pkg.instrumentation); } - void dumpComponents(PrintWriter pw, String prefix, String label, - List<? extends ParsedComponent> list) { + void dumpComponents(PrintWriter pw, String prefix, PackageSetting ps, + String label, List<? extends PackageParser.Component<?>> list) { final int size = CollectionUtils.size(list); if (size == 0) { return; } pw.print(prefix);pw.println(label); for (int i = 0; i < size; i++) { - final ParsedComponent component = list.get(i); + final PackageParser.Component<?> component = list.get(i); pw.print(prefix);pw.print(" "); pw.println(component.getComponentName().flattenToShortString()); } diff --git a/services/core/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java index cff19443a79b..2ee07a2037c3 100644 --- a/services/core/java/com/android/server/pm/SharedUserSetting.java +++ b/services/core/java/com/android/server/pm/SharedUserSetting.java @@ -18,7 +18,7 @@ package com.android.server.pm; import android.annotation.Nullable; import android.content.pm.ApplicationInfo; -import android.content.pm.parsing.AndroidPackage; +import android.content.pm.PackageParser; import android.service.pm.PackageServiceDumpProto; import android.util.ArraySet; import android.util.proto.ProtoOutputStream; @@ -46,7 +46,7 @@ public final class SharedUserSetting extends SettingBase { // that all apps within the sharedUser run in the same selinux context. int seInfoTargetSdkVersion; - final ArraySet<PackageSetting> packages = new ArraySet<>(); + final ArraySet<PackageSetting> packages = new ArraySet<PackageSetting>(); final PackageSignatures signatures = new PackageSignatures(); Boolean signaturesChanged; @@ -98,7 +98,7 @@ public final class SharedUserSetting extends SettingBase { // If this is the first package added to this shared user, temporarily (until next boot) use // its targetSdkVersion when assigning seInfo for the shared user. if ((packages.size() == 0) && (packageSetting.pkg != null)) { - seInfoTargetSdkVersion = packageSetting.pkg.getTargetSdkVersion(); + seInfoTargetSdkVersion = packageSetting.pkg.applicationInfo.targetSdkVersion; } if (packages.add(packageSetting)) { setFlags(this.pkgFlags | packageSetting.pkgFlags); @@ -106,11 +106,11 @@ public final class SharedUserSetting extends SettingBase { } } - public @Nullable List<AndroidPackage> getPackages() { + public @Nullable List<PackageParser.Package> getPackages() { if (packages == null || packages.size() == 0) { return null; } - final ArrayList<AndroidPackage> pkgList = new ArrayList<>(packages.size()); + final ArrayList<PackageParser.Package> pkgList = new ArrayList<>(packages.size()); for (PackageSetting ps : packages) { if ((ps == null) || (ps.pkg == null)) { continue; @@ -131,20 +131,20 @@ public final class SharedUserSetting extends SettingBase { * restrictive selinux domain. */ public void fixSeInfoLocked() { - final List<AndroidPackage> pkgList = getPackages(); + final List<PackageParser.Package> pkgList = getPackages(); if (pkgList == null || pkgList.size() == 0) { return; } - for (AndroidPackage pkg : pkgList) { - if (pkg.getTargetSdkVersion() < seInfoTargetSdkVersion) { - seInfoTargetSdkVersion = pkg.getTargetSdkVersion(); + for (PackageParser.Package pkg : pkgList) { + if (pkg.applicationInfo.targetSdkVersion < seInfoTargetSdkVersion) { + seInfoTargetSdkVersion = pkg.applicationInfo.targetSdkVersion; } } - for (AndroidPackage pkg : pkgList) { + for (PackageParser.Package pkg : pkgList) { final boolean isPrivileged = isPrivileged() | pkg.isPrivileged(); - pkg.mutate().setSeInfo(SELinuxMMAC.getSeInfo(pkg, isPrivileged, - seInfoTargetSdkVersion)); + pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo(pkg, isPrivileged, + seInfoTargetSdkVersion); } } diff --git a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java index 793ea47bfd43..036d1e807f97 100644 --- a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java +++ b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java @@ -23,7 +23,6 @@ import android.annotation.UserIdInt; import android.content.pm.PackageManagerInternal; import android.content.pm.PackageParser; import android.content.pm.UserInfo; -import android.content.pm.parsing.AndroidPackage; import android.content.res.Resources; import android.os.SystemProperties; import android.os.UserHandle; @@ -152,15 +151,15 @@ class UserSystemPackageInstaller { return; } final boolean install = - (userWhitelist == null || userWhitelist.contains(pkg.getPackageName())) - && !pkg.isHiddenUntilInstalled(); + (userWhitelist == null || userWhitelist.contains(pkg.packageName)) + && !pkg.applicationInfo.hiddenUntilInstalled; if (isUpgrade && !isFirstBoot && !install) { return; // To be careful, we don’t uninstall apps during OTAs } final boolean changed = pmInt.setInstalled(pkg, userId, install); if (changed) { Slog.i(TAG, (install ? "Installed " : "Uninstalled ") - + pkg.getPackageName() + " for user " + userId); + + pkg.packageName + " for user " + userId); } }); } @@ -181,7 +180,7 @@ class UserSystemPackageInstaller { // Check whether all whitelisted packages are indeed on the system. for (String pkgName : allWhitelistedPackages) { - AndroidPackage pkg = pmInt.getPackage(pkgName); + PackageParser.Package pkg = pmInt.getPackage(pkgName); if (pkg == null) { Slog.w(TAG, pkgName + " is whitelisted but not present."); } else if (!pkg.isSystem()) { @@ -195,8 +194,8 @@ class UserSystemPackageInstaller { } final boolean doWtf = isEnforceMode(mode); pmInt.forEachPackage(pkg -> { - if (pkg.isSystem() && !allWhitelistedPackages.contains(pkg.getManifestPackageName())) { - final String msg = "System package " + pkg.getManifestPackageName() + if (pkg.isSystem() && !allWhitelistedPackages.contains(pkg.manifestPackageName)) { + final String msg = "System package " + pkg.manifestPackageName + " is not whitelisted using 'install-in-user-type' in SystemConfig " + "for any user types!"; if (doWtf) { @@ -287,7 +286,7 @@ class UserSystemPackageInstaller { if (shouldInstallPackage(pkg, mWhitelitsedPackagesForUserTypes, whitelistedPackages, isImplicitWhitelistMode, isSystemUser)) { // Although the whitelist uses manifest names, this function returns packageNames. - installPackages.add(pkg.getPackageName()); + installPackages.add(pkg.packageName); } }); return installPackages; @@ -308,12 +307,12 @@ class UserSystemPackageInstaller { * @param isSystemUser whether the user is USER_SYSTEM (which gets special treatment). */ @VisibleForTesting - static boolean shouldInstallPackage(AndroidPackage sysPkg, + static boolean shouldInstallPackage(PackageParser.Package sysPkg, @NonNull ArrayMap<String, Integer> userTypeWhitelist, @NonNull Set<String> userWhitelist, boolean isImplicitWhitelistMode, boolean isSystemUser) { - final String pkgName = sysPkg.getManifestPackageName(); + final String pkgName = sysPkg.manifestPackageName; boolean install = (isImplicitWhitelistMode && !userTypeWhitelist.containsKey(pkgName)) || userWhitelist.contains(pkgName); diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java index 661497cac332..b3f1867fdb06 100644 --- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java +++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java @@ -25,13 +25,13 @@ import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageParser; import android.content.pm.dex.ArtManager; import android.content.pm.dex.ArtManager.ProfileType; import android.content.pm.dex.ArtManagerInternal; import android.content.pm.dex.DexMetadataHelper; import android.content.pm.dex.ISnapshotRuntimeProfileCallback; import android.content.pm.dex.PackageOptimizationInfo; -import android.content.pm.parsing.AndroidPackage; import android.os.Binder; import android.os.Build; import android.os.Handler; @@ -386,10 +386,9 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { * - create the current primary profile to save time at app startup time. * - copy the profiles from the associated dex metadata file to the reference profile. */ - public void prepareAppProfiles( - AndroidPackage pkg, @UserIdInt int user, + public void prepareAppProfiles(PackageParser.Package pkg, @UserIdInt int user, boolean updateReferenceProfileContent) { - final int appId = UserHandle.getAppId(pkg.getUid()); + final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); if (user < 0) { Slog.wtf(TAG, "Invalid user id: " + user); return; @@ -412,24 +411,23 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { dexMetadataPath = dexMetadata == null ? null : dexMetadata.getAbsolutePath(); } synchronized (mInstaller) { - boolean result = mInstaller.prepareAppProfile(pkg.getPackageName(), user, appId, + boolean result = mInstaller.prepareAppProfile(pkg.packageName, user, appId, profileName, codePath, dexMetadataPath); if (!result) { Slog.e(TAG, "Failed to prepare profile for " + - pkg.getPackageName() + ":" + codePath); + pkg.packageName + ":" + codePath); } } } } catch (InstallerException e) { - Slog.e(TAG, "Failed to prepare profile for " + pkg.getPackageName(), e); + Slog.e(TAG, "Failed to prepare profile for " + pkg.packageName, e); } } /** * Prepares the app profiles for a set of users. {@see ArtManagerService#prepareAppProfiles}. */ - public void prepareAppProfiles( - AndroidPackage pkg, int[] user, + public void prepareAppProfiles(PackageParser.Package pkg, int[] user, boolean updateReferenceProfileContent) { for (int i = 0; i < user.length; i++) { prepareAppProfiles(pkg, user[i], updateReferenceProfileContent); @@ -439,12 +437,12 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { /** * Clear the profiles for the given package. */ - public void clearAppProfiles(AndroidPackage pkg) { + public void clearAppProfiles(PackageParser.Package pkg) { try { ArrayMap<String, String> packageProfileNames = getPackageProfileNames(pkg); for (int i = packageProfileNames.size() - 1; i >= 0; i--) { String profileName = packageProfileNames.valueAt(i); - mInstaller.clearAppProfiles(pkg.getPackageName(), profileName); + mInstaller.clearAppProfiles(pkg.packageName, profileName); } } catch (InstallerException e) { Slog.w(TAG, String.valueOf(e)); @@ -454,15 +452,15 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { /** * Dumps the profiles for the given package. */ - public void dumpProfiles(AndroidPackage pkg) { - final int sharedGid = UserHandle.getSharedAppGid(pkg.getUid()); + public void dumpProfiles(PackageParser.Package pkg) { + final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); try { ArrayMap<String, String> packageProfileNames = getPackageProfileNames(pkg); for (int i = packageProfileNames.size() - 1; i >= 0; i--) { String codePath = packageProfileNames.keyAt(i); String profileName = packageProfileNames.valueAt(i); synchronized (mInstallLock) { - mInstaller.dumpProfiles(sharedGid, pkg.getPackageName(), profileName, codePath); + mInstaller.dumpProfiles(sharedGid, pkg.packageName, profileName, codePath); } } } catch (InstallerException e) { @@ -473,13 +471,14 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { /** * Compile layout resources in a given package. */ - public boolean compileLayouts(AndroidPackage pkg) { + public boolean compileLayouts(PackageParser.Package pkg) { try { - final String packageName = pkg.getPackageName(); - final String apkPath = pkg.getBaseCodePath(); - final String outDexFile = pkg.getDataDir() + "/code_cache/compiled_view.dex"; - if (pkg.isPrivileged() || pkg.isEmbeddedDexUsed() - || pkg.isDefaultToDeviceProtectedStorage()) { + final String packageName = pkg.packageName; + final String apkPath = pkg.baseCodePath; + final ApplicationInfo appInfo = pkg.applicationInfo; + final String outDexFile = appInfo.dataDir + "/code_cache/compiled_view.dex"; + if (appInfo.isPrivilegedApp() || appInfo.isEmbeddedDexUsed() + || appInfo.isDefaultToDeviceProtectedStorage()) { // Privileged apps prefer to load trusted code so they don't use compiled views. // If the app is not privileged but prefers code integrity, also avoid compiling // views. @@ -493,7 +492,7 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { try { synchronized (mInstallLock) { return mInstaller.compileLayouts(apkPath, packageName, outDexFile, - pkg.getUid()); + appInfo.uid); } } finally { Binder.restoreCallingIdentity(callingId); @@ -509,19 +508,15 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { * Build the profiles names for all the package code paths (excluding resource only paths). * Return the map [code path -> profile name]. */ - private ArrayMap<String, String> getPackageProfileNames(AndroidPackage pkg) { + private ArrayMap<String, String> getPackageProfileNames(PackageParser.Package pkg) { ArrayMap<String, String> result = new ArrayMap<>(); - if ((pkg.getFlags() & ApplicationInfo.FLAG_HAS_CODE) != 0) { - result.put(pkg.getBaseCodePath(), ArtManager.getProfileName(null)); + if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) { + result.put(pkg.baseCodePath, ArtManager.getProfileName(null)); } - - String[] splitCodePaths = pkg.getSplitCodePaths(); - int[] splitFlags = pkg.getSplitFlags(); - String[] splitNames = pkg.getSplitNames(); - if (!ArrayUtils.isEmpty(splitCodePaths)) { - for (int i = 0; i < splitCodePaths.length; i++) { - if ((splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0) { - result.put(splitCodePaths[i], ArtManager.getProfileName(splitNames[i])); + if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { + for (int i = 0; i < pkg.splitCodePaths.length; i++) { + if ((pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0) { + result.put(pkg.splitCodePaths[i], ArtManager.getProfileName(pkg.splitNames[i])); } } } diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java index 5df5380ab8ab..f56231fc02af 100644 --- a/services/core/java/com/android/server/pm/dex/DexManager.java +++ b/services/core/java/com/android/server/pm/dex/DexManager.java @@ -595,7 +595,7 @@ public class DexManager { // We found the package. Now record the usage for all declared ISAs. boolean update = false; - for (String isa : getAppDexInstructionSets(info.primaryCpuAbi, info.secondaryCpuAbi)) { + for (String isa : getAppDexInstructionSets(info)) { boolean newUpdate = mPackageDexUsage.record(searchResult.mOwningPackageName, dexPath, userId, isa, isUsedByOtherApps, /*primaryOrSplit*/ false, searchResult.mOwningPackageName, diff --git a/services/core/java/com/android/server/pm/dex/DexoptUtils.java b/services/core/java/com/android/server/pm/dex/DexoptUtils.java index 6e6b137d23a2..5a473c1819c1 100644 --- a/services/core/java/com/android/server/pm/dex/DexoptUtils.java +++ b/services/core/java/com/android/server/pm/dex/DexoptUtils.java @@ -18,12 +18,10 @@ package com.android.server.pm.dex; import android.content.pm.ApplicationInfo; import android.content.pm.SharedLibraryInfo; -import android.content.pm.parsing.AndroidPackage; import android.util.Slog; import android.util.SparseArray; import com.android.internal.os.ClassLoaderFactory; -import com.android.internal.util.ArrayUtils; import java.io.File; import java.util.List; @@ -68,7 +66,7 @@ public final class DexoptUtils { * {@link android.app.LoadedApk#makePaths( * android.app.ActivityThread, boolean, ApplicationInfo, List, List)}. */ - public static String[] getClassLoaderContexts(AndroidPackage pkg, + public static String[] getClassLoaderContexts(ApplicationInfo info, List<SharedLibraryInfo> sharedLibraries, boolean[] pathsWithCode) { // The base class loader context contains only the shared library. String sharedLibrariesContext = ""; @@ -77,8 +75,8 @@ public final class DexoptUtils { } String baseApkContextClassLoader = encodeClassLoader( - "", pkg.getAppInfoClassLoaderName(), sharedLibrariesContext); - if (pkg.getSplitCodePaths() == null) { + "", info.classLoaderName, sharedLibrariesContext); + if (info.getSplitCodePaths() == null) { // The application has no splits. return new String[] {baseApkContextClassLoader}; } @@ -86,11 +84,11 @@ public final class DexoptUtils { // The application has splits. Compute their class loader contexts. // First, cache the relative paths of the splits and do some sanity checks - String[] splitRelativeCodePaths = getSplitRelativeCodePaths(pkg); + String[] splitRelativeCodePaths = getSplitRelativeCodePaths(info); // The splits have an implicit dependency on the base apk. // This means that we have to add the base apk file in addition to the shared libraries. - String baseApkName = new File(pkg.getBaseCodePath()).getName(); + String baseApkName = new File(info.getBaseCodePath()).getName(); String baseClassPath = baseApkName; // The result is stored in classLoaderContexts. @@ -99,11 +97,7 @@ public final class DexoptUtils { String[] classLoaderContexts = new String[/*base apk*/ 1 + splitRelativeCodePaths.length]; classLoaderContexts[0] = pathsWithCode[0] ? baseApkContextClassLoader : null; - SparseArray<int[]> splitDependencies = pkg.getSplitDependencies(); - - if (!pkg.requestsIsolatedSplitLoading() - || splitDependencies == null - || splitDependencies.size() == 0) { + if (!info.requestsIsolatedSplitLoading() || info.splitDependencies == null) { // If the app didn't request for the splits to be loaded in isolation or if it does not // declare inter-split dependencies, then all the splits will be loaded in the base // apk class loader (in the order of their definition). @@ -111,7 +105,7 @@ public final class DexoptUtils { for (int i = 1; i < classLoaderContexts.length; i++) { if (pathsWithCode[i]) { classLoaderContexts[i] = encodeClassLoader( - classpath, pkg.getAppInfoClassLoaderName(), sharedLibrariesContext); + classpath, info.classLoaderName, sharedLibrariesContext); } else { classLoaderContexts[i] = null; } @@ -138,10 +132,11 @@ public final class DexoptUtils { String[] splitClassLoaderEncodingCache = new String[splitRelativeCodePaths.length]; for (int i = 0; i < splitRelativeCodePaths.length; i++) { splitClassLoaderEncodingCache[i] = encodeClassLoader(splitRelativeCodePaths[i], - pkg.getSplitClassLoaderNames()[i]); + info.splitClassLoaderNames[i]); } String splitDependencyOnBase = encodeClassLoader( - baseClassPath, pkg.getClassLoaderName()); + baseClassPath, info.classLoaderName); + SparseArray<int[]> splitDependencies = info.splitDependencies; // Note that not all splits have dependencies (e.g. configuration splits) // The splits without dependencies will have classLoaderContexts[config_split_index] @@ -159,8 +154,7 @@ public final class DexoptUtils { // We also need to add the class loader of the current split which should // come first in the context. for (int i = 1; i < classLoaderContexts.length; i++) { - String splitClassLoader = encodeClassLoader("", - pkg.getSplitClassLoaderNames()[i - 1]); + String splitClassLoader = encodeClassLoader("", info.splitClassLoaderNames[i - 1]); if (pathsWithCode[i]) { // If classLoaderContexts[i] is null it means that the split does not have // any dependency. In this case its context equals its declared class loader. @@ -400,11 +394,11 @@ public final class DexoptUtils { * Returns the relative paths of the splits declared by the application {@code info}. * Assumes that the application declares a non-null array of splits. */ - private static String[] getSplitRelativeCodePaths(AndroidPackage pkg) { - String baseCodePath = new File(pkg.getBaseCodePath()).getParent(); - String[] splitCodePaths = pkg.getSplitCodePaths(); - String[] splitRelativeCodePaths = new String[ArrayUtils.size(splitCodePaths)]; - for (int i = 0; i < splitRelativeCodePaths.length; i++) { + private static String[] getSplitRelativeCodePaths(ApplicationInfo info) { + String baseCodePath = new File(info.getBaseCodePath()).getParent(); + String[] splitCodePaths = info.getSplitCodePaths(); + String[] splitRelativeCodePaths = new String[splitCodePaths.length]; + for (int i = 0; i < splitCodePaths.length; i++) { File pathFile = new File(splitCodePaths[i]); splitRelativeCodePaths[i] = pathFile.getName(); // Sanity check that the base paths of the splits are all the same. diff --git a/services/core/java/com/android/server/pm/dex/ViewCompiler.java b/services/core/java/com/android/server/pm/dex/ViewCompiler.java index b7443f36e494..8d8e17e92b3d 100644 --- a/services/core/java/com/android/server/pm/dex/ViewCompiler.java +++ b/services/core/java/com/android/server/pm/dex/ViewCompiler.java @@ -16,10 +16,10 @@ package com.android.server.pm.dex; -import android.content.pm.parsing.AndroidPackage; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageParser; import android.os.Binder; import android.util.Log; - import com.android.internal.annotations.GuardedBy; import com.android.server.pm.Installer; @@ -33,18 +33,19 @@ public class ViewCompiler { mInstaller = installer; } - public boolean compileLayouts(AndroidPackage pkg) { + public boolean compileLayouts(PackageParser.Package pkg) { try { - final String packageName = pkg.getPackageName(); - final String apkPath = pkg.getBaseCodePath(); - final String outDexFile = pkg.getDataDir() + "/code_cache/compiled_view.dex"; + final String packageName = pkg.packageName; + final String apkPath = pkg.baseCodePath; + final ApplicationInfo appInfo = pkg.applicationInfo; + final String outDexFile = appInfo.dataDir + "/code_cache/compiled_view.dex"; Log.i("PackageManager", "Compiling layouts in " + packageName + " (" + apkPath + ") to " + outDexFile); long callingId = Binder.clearCallingIdentity(); try { synchronized (mInstallLock) { return mInstaller.compileLayouts(apkPath, packageName, outDexFile, - pkg.getUid()); + appInfo.uid); } } finally { Binder.restoreCallingIdentity(callingId); diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java index 29248b50830a..6d22faa7032e 100644 --- a/services/core/java/com/android/server/pm/permission/BasePermission.java +++ b/services/core/java/com/android/server/pm/permission/BasePermission.java @@ -29,12 +29,10 @@ import static com.android.server.pm.Settings.TAG_ITEM; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.content.pm.PackageManagerInternal; +import android.content.pm.PackageParser; +import android.content.pm.PackageParser.Permission; import android.content.pm.PermissionInfo; import android.content.pm.Signature; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermission; -import android.content.pm.parsing.PackageInfoUtils; import android.os.UserHandle; import android.util.Log; import android.util.Slog; @@ -91,7 +89,7 @@ public final class BasePermission { int protectionLevel; - ParsedPermission perm; + PackageParser.Permission perm; PermissionInfo pendingPermissionInfo; @@ -115,6 +113,12 @@ public final class BasePermission { protectionLevel = PermissionInfo.PROTECTION_SIGNATURE; } + @Override + public String toString() { + return "BasePermission{" + Integer.toHexString(System.identityHashCode(this)) + " " + name + + "}"; + } + public String getName() { return name; } @@ -140,7 +144,7 @@ public final class BasePermission { this.gids = gids; this.perUser = perUser; } - public void setPermission(@Nullable ParsedPermission perm) { + public void setPermission(@Nullable Permission perm) { this.perm = perm; } public void setSourcePackageSetting(PackageSettingBase sourcePackageSetting) { @@ -161,13 +165,13 @@ public final class BasePermission { public int calculateFootprint(BasePermission perm) { if (uid == perm.uid) { - return perm.name.length() + perm.perm.calculateFootprint(); + return perm.name.length() + perm.perm.info.calculateFootprint(); } return 0; } - public boolean isPermission(ParsedPermission perm) { - return Objects.equals(this.perm.className, perm.className); + public boolean isPermission(Permission perm) { + return this.perm == perm; } public boolean isDynamic() { @@ -185,24 +189,29 @@ public final class BasePermission { } public boolean isRemoved() { - return perm != null && (perm.flags & PermissionInfo.FLAG_REMOVED) != 0; + return perm != null && perm.info != null + && (perm.info.flags & PermissionInfo.FLAG_REMOVED) != 0; } public boolean isSoftRestricted() { - return perm != null && (perm.flags & PermissionInfo.FLAG_SOFT_RESTRICTED) != 0; + return perm != null && perm.info != null + && (perm.info.flags & PermissionInfo.FLAG_SOFT_RESTRICTED) != 0; } public boolean isHardRestricted() { - return perm != null && (perm.flags & PermissionInfo.FLAG_HARD_RESTRICTED) != 0; + return perm != null && perm.info != null + && (perm.info.flags & PermissionInfo.FLAG_HARD_RESTRICTED) != 0; } public boolean isHardOrSoftRestricted() { - return perm != null && (perm.flags & (PermissionInfo.FLAG_HARD_RESTRICTED + return perm != null && perm.info != null + && (perm.info.flags & (PermissionInfo.FLAG_HARD_RESTRICTED | PermissionInfo.FLAG_SOFT_RESTRICTED)) != 0; } public boolean isImmutablyRestricted() { - return perm != null && (perm.flags & PermissionInfo.FLAG_IMMUTABLY_RESTRICTED) != 0; + return perm != null && perm.info != null + && (perm.info.flags & PermissionInfo.FLAG_IMMUTABLY_RESTRICTED) != 0; } public boolean isSignature() { @@ -288,12 +297,13 @@ public final class BasePermission { (this.protectionLevel != protectionLevel || perm == null || uid != tree.uid - || !Objects.equals(perm.getPackageName(), tree.perm.getPackageName()) - || !comparePermissionInfos(perm, info)); + || !perm.owner.equals(tree.perm.owner) + || !comparePermissionInfos(perm.info, info)); this.protectionLevel = protectionLevel; info = new PermissionInfo(info); info.protectionLevel = protectionLevel; - perm = new ParsedPermission(tree.perm); + perm = new PackageParser.Permission(tree.perm.owner, info); + perm.info.packageName = tree.perm.info.packageName; uid = tree.uid; return changed; } @@ -306,89 +316,71 @@ public final class BasePermission { final BasePermission tree = findPermissionTree(permissionTrees, name); if (tree != null && tree.perm != null) { sourcePackageSetting = tree.sourcePackageSetting; - perm = new ParsedPermission(tree.perm); - perm.protectionLevel = pendingPermissionInfo.protectionLevel; - perm.flags = pendingPermissionInfo.flags; - perm.setGroup(pendingPermissionInfo.group); - perm.backgroundPermission = pendingPermissionInfo.backgroundPermission; - perm.descriptionRes = pendingPermissionInfo.descriptionRes; - perm.requestRes = pendingPermissionInfo.requestRes; - perm.setPackageName(tree.perm.getPackageName()); - perm.setName(name); + perm = new PackageParser.Permission(tree.perm.owner, + new PermissionInfo(pendingPermissionInfo)); + perm.info.packageName = tree.perm.info.packageName; + perm.info.name = name; uid = tree.uid; } } } - static BasePermission createOrUpdate(PackageManagerInternal packageManagerInternal, - @Nullable BasePermission bp, @NonNull ParsedPermission p, - @NonNull AndroidPackage pkg, Collection<BasePermission> permissionTrees, + static BasePermission createOrUpdate(@Nullable BasePermission bp, @NonNull Permission p, + @NonNull PackageParser.Package pkg, Collection<BasePermission> permissionTrees, boolean chatty) { - final PackageSettingBase pkgSetting = - (PackageSettingBase) packageManagerInternal.getPackageSetting(pkg.getPackageName()); + final PackageSettingBase pkgSetting = (PackageSettingBase) pkg.mExtras; // Allow system apps to redefine non-system permissions - if (bp != null && !Objects.equals(bp.sourcePackageName, p.getPackageName())) { - final boolean currentOwnerIsSystem; - if (bp.perm == null) { - currentOwnerIsSystem = false; - } else { - AndroidPackage currentPackage = packageManagerInternal.getPackage( - bp.perm.getPackageName()); - if (currentPackage == null) { - currentOwnerIsSystem = false; - } else { - currentOwnerIsSystem = currentPackage.isSystem(); - } - } - - if (pkg.isSystem()) { + if (bp != null && !Objects.equals(bp.sourcePackageName, p.info.packageName)) { + final boolean currentOwnerIsSystem = (bp.perm != null + && bp.perm.owner.isSystem()); + if (p.owner.isSystem()) { if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { // It's a built-in permission and no owner, take ownership now - p.flags |= PermissionInfo.FLAG_INSTALLED; bp.sourcePackageSetting = pkgSetting; bp.perm = p; - bp.uid = pkg.getUid(); - bp.sourcePackageName = p.getPackageName(); + bp.uid = pkg.applicationInfo.uid; + bp.sourcePackageName = p.info.packageName; + p.info.flags |= PermissionInfo.FLAG_INSTALLED; } else if (!currentOwnerIsSystem) { - String msg = "New decl " + pkg + " of permission " - + p.getName() + " is system; overriding " + bp.sourcePackageName; + String msg = "New decl " + p.owner + " of permission " + + p.info.name + " is system; overriding " + bp.sourcePackageName; PackageManagerService.reportSettingsProblem(Log.WARN, msg); bp = null; } } } if (bp == null) { - bp = new BasePermission(p.getName(), p.getPackageName(), TYPE_NORMAL); + bp = new BasePermission(p.info.name, p.info.packageName, TYPE_NORMAL); } StringBuilder r = null; if (bp.perm == null) { if (bp.sourcePackageName == null - || bp.sourcePackageName.equals(p.getPackageName())) { - final BasePermission tree = findPermissionTree(permissionTrees, p.getName()); + || bp.sourcePackageName.equals(p.info.packageName)) { + final BasePermission tree = findPermissionTree(permissionTrees, p.info.name); if (tree == null - || tree.sourcePackageName.equals(p.getPackageName())) { - p.flags |= PermissionInfo.FLAG_INSTALLED; + || tree.sourcePackageName.equals(p.info.packageName)) { bp.sourcePackageSetting = pkgSetting; bp.perm = p; - bp.uid = pkg.getUid(); - bp.sourcePackageName = p.getPackageName(); + bp.uid = pkg.applicationInfo.uid; + bp.sourcePackageName = p.info.packageName; + p.info.flags |= PermissionInfo.FLAG_INSTALLED; if (chatty) { if (r == null) { r = new StringBuilder(256); } else { r.append(' '); } - r.append(p.getName()); + r.append(p.info.name); } } else { - Slog.w(TAG, "Permission " + p.getName() + " from package " - + p.getPackageName() + " ignored: base tree " + Slog.w(TAG, "Permission " + p.info.name + " from package " + + p.info.packageName + " ignored: base tree " + tree.name + " is from package " + tree.sourcePackageName); } } else { - Slog.w(TAG, "Permission " + p.getName() + " from package " - + p.getPackageName() + " ignored: original from " + Slog.w(TAG, "Permission " + p.info.name + " from package " + + p.info.packageName + " ignored: original from " + bp.sourcePackageName); } } else if (chatty) { @@ -398,10 +390,10 @@ public final class BasePermission { r.append(' '); } r.append("DUP:"); - r.append(p.getName()); + r.append(p.info.name); } - if (bp.perm != null && Objects.equals(bp.perm.className, p.className)) { - bp.protectionLevel = p.protectionLevel; + if (bp.perm == p) { + bp.protectionLevel = p.info.protectionLevel; } if (PackageManagerService.DEBUG_PACKAGE_SCANNING && r != null) { Log.d(TAG, " Permissions: " + r); @@ -425,17 +417,17 @@ public final class BasePermission { throw new SecurityException("No permission tree found for " + permName); } - public void enforceDeclaredUsedAndRuntimeOrDevelopment(AndroidPackage pkg, - PackageSetting pkgSetting) { + public void enforceDeclaredUsedAndRuntimeOrDevelopment(PackageParser.Package pkg) { + final PackageSetting pkgSetting = (PackageSetting) pkg.mExtras; final PermissionsState permsState = pkgSetting.getPermissionsState(); - int index = pkg.getRequestedPermissions().indexOf(name); + int index = pkg.requestedPermissions.indexOf(name); if (!permsState.hasRequestedPermission(name) && index == -1) { - throw new SecurityException("Package " + pkg.getPackageName() + throw new SecurityException("Package " + pkg.packageName + " has not requested permission " + name); } if (!isRuntime() && !isDevelopment()) { - throw new SecurityException("Permission " + name + " requested by " - + pkg.getPackageName() + " is not a changeable permission type"); + throw new SecurityException("Permission " + name + + " requested by " + pkg.packageName + " is not a changeable permission type"); } } @@ -453,12 +445,12 @@ public final class BasePermission { public @Nullable PermissionInfo generatePermissionInfo(@NonNull String groupName, int flags) { if (groupName == null) { - if (perm == null || perm.getGroup() == null) { + if (perm == null || perm.info.group == null) { return generatePermissionInfo(protectionLevel, flags); } } else { - if (perm != null && groupName.equals(perm.getGroup())) { - return PackageInfoUtils.generatePermissionInfo(perm, flags); + if (perm != null && groupName.equals(perm.info.group)) { + return PackageParser.generatePermissionInfo(perm, flags); } } return null; @@ -468,8 +460,8 @@ public final class BasePermission { PermissionInfo permissionInfo; if (perm != null) { final boolean protectionLevelChanged = protectionLevel != adjustedProtectionLevel; - permissionInfo = PackageInfoUtils.generatePermissionInfo(perm, flags); - if (protectionLevelChanged) { + permissionInfo = PackageParser.generatePermissionInfo(perm, flags); + if (protectionLevelChanged && permissionInfo == perm.info) { // if we return different protection level, don't use the cached info permissionInfo = new PermissionInfo(permissionInfo); permissionInfo.protectionLevel = adjustedProtectionLevel; @@ -549,18 +541,14 @@ public final class BasePermission { serializer.attribute(null, "protection", Integer.toString(protectionLevel)); } if (type == BasePermission.TYPE_DYNAMIC) { - if (perm != null || pendingPermissionInfo != null) { + final PermissionInfo pi = perm != null ? perm.info : pendingPermissionInfo; + if (pi != null) { serializer.attribute(null, "type", "dynamic"); - int icon = perm != null ? perm.icon : pendingPermissionInfo.icon; - CharSequence nonLocalizedLabel = perm != null - ? perm.nonLocalizedLabel - : pendingPermissionInfo.nonLocalizedLabel; - - if (icon != 0) { - serializer.attribute(null, "icon", Integer.toString(icon)); + if (pi.icon != 0) { + serializer.attribute(null, "icon", Integer.toString(pi.icon)); } - if (nonLocalizedLabel != null) { - serializer.attribute(null, "label", nonLocalizedLabel.toString()); + if (pi.nonLocalizedLabel != null) { + serializer.attribute(null, "label", pi.nonLocalizedLabel.toString()); } } } @@ -580,14 +568,14 @@ public final class BasePermission { return s1.equals(s2); } - private static boolean comparePermissionInfos(ParsedPermission pi1, PermissionInfo pi2) { + private static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { if (pi1.icon != pi2.icon) return false; if (pi1.logo != pi2.logo) return false; if (pi1.protectionLevel != pi2.protectionLevel) return false; - if (!compareStrings(pi1.getName(), pi2.name)) return false; + if (!compareStrings(pi1.name, pi2.name)) return false; if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; // We'll take care of setting this one. - if (!compareStrings(pi1.getPackageName(), pi2.packageName)) return false; + if (!compareStrings(pi1.packageName, pi2.packageName)) return false; // These are not currently stored in settings. //if (!compareStrings(pi1.group, pi2.group)) return false; //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; @@ -623,9 +611,9 @@ public final class BasePermission { pw.println(PermissionInfo.protectionToString(protectionLevel)); if (perm != null) { pw.print(" perm="); pw.println(perm); - if ((perm.flags & PermissionInfo.FLAG_INSTALLED) == 0 - || (perm.flags & PermissionInfo.FLAG_REMOVED) != 0) { - pw.print(" flags=0x"); pw.println(Integer.toHexString(perm.flags)); + if ((perm.info.flags & PermissionInfo.FLAG_INSTALLED) == 0 + || (perm.info.flags & PermissionInfo.FLAG_REMOVED) != 0) { + pw.print(" flags=0x"); pw.println(Integer.toHexString(perm.info.flags)); } } if (sourcePackageSetting != null) { @@ -637,20 +625,4 @@ public final class BasePermission { } return true; } - - @Override - public String toString() { - return "BasePermission{" + - "name='" + name + '\'' + - ", type=" + type + - ", sourcePackageName='" + sourcePackageName + '\'' + - ", sourcePackageSetting=" + sourcePackageSetting + - ", protectionLevel=" + protectionLevel + - ", perm=" + perm + - ", pendingPermissionInfo=" + pendingPermissionInfo + - ", uid=" + uid + - ", gids=" + Arrays.toString(gids) + - ", perUser=" + perUser + - '}'; - } } diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index fc8d52005a1c..53156345bb4e 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -64,13 +64,10 @@ import android.content.pm.PackageManager.PermissionInfoFlags; import android.content.pm.PackageManager.PermissionWhitelistFlags; import android.content.pm.PackageManagerInternal; import android.content.pm.PackageParser; +import android.content.pm.PackageParser.Package; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermission; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup; -import android.content.pm.parsing.PackageInfoUtils; import android.content.pm.permission.SplitPermissionInfoParcelable; import android.metrics.LogMaker; import android.os.Binder; @@ -423,8 +420,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } - @Nullable - BasePermission getPermission(String permName) { + @Nullable BasePermission getPermission(String permName) { synchronized (mLock) { return mSettings.getPermissionLocked(permName); } @@ -458,9 +454,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { } synchronized (mLock) { final int n = mSettings.mPermissionGroups.size(); - final ArrayList<PermissionGroupInfo> out = new ArrayList<>(n); - for (ParsedPermissionGroup pg : mSettings.mPermissionGroups.values()) { - out.add(PackageInfoUtils.generatePermissionGroupInfo(pg, flags)); + final ArrayList<PermissionGroupInfo> out = + new ArrayList<PermissionGroupInfo>(n); + for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) { + out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); } return new ParceledListSlice<>(out); } @@ -476,7 +473,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { return null; } synchronized (mLock) { - return PackageInfoUtils.generatePermissionGroupInfo( + return PackageParser.generatePermissionGroupInfo( mSettings.mPermissionGroups.get(groupName), flags); } } @@ -600,13 +597,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { false, // requirePermissionWhenSameUser "getPermissionFlags"); - final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); - if (pkg == null) { - return 0; - } - final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting( - pkg.getPackageName()); - if (ps == null) { + final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName); + if (pkg == null || pkg.mExtras == null) { return 0; } synchronized (mLock) { @@ -617,6 +609,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) { return 0; } + final PackageSetting ps = (PackageSetting) pkg.mExtras; PermissionsState permissionsState = ps.getPermissionsState(); return permissionsState.getPermissionFlags(permName, userId); } @@ -703,10 +696,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION; } - final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); - final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting( - packageName); - if (pkg == null || ps == null) { + final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName); + if (pkg == null || pkg.mExtras == null) { Log.e(TAG, "Unknown package: " + packageName); return; } @@ -722,6 +713,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { throw new IllegalArgumentException("Unknown permission: " + permName); } + final PackageSetting ps = (PackageSetting) pkg.mExtras; final PermissionsState permissionsState = ps.getPermissionsState(); final boolean hadState = permissionsState.getRuntimePermissionState(permName, userId) != null; @@ -734,11 +726,11 @@ public class PermissionManagerService extends IPermissionManager.Stub { // Install and runtime permissions are stored in different places, // so figure out what permission changed and persist the change. if (permissionsState.getInstallPermissionState(permName) != null) { - callback.onInstallPermissionUpdatedNotifyListener(pkg.getUid()); + callback.onInstallPermissionUpdatedNotifyListener(pkg.applicationInfo.uid); } else if (permissionsState.getRuntimePermissionState(permName, userId) != null || hadState) { - callback.onPermissionUpdatedNotifyListener(new int[]{userId}, false, - pkg.getUid()); + callback.onPermissionUpdatedNotifyListener(new int[] { userId }, false, + pkg.applicationInfo.uid); } } } @@ -770,16 +762,18 @@ public class PermissionManagerService extends IPermissionManager.Stub { ? flagValues : flagValues & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; final boolean[] changed = new boolean[1]; - mPackageManagerInt.forEachPackage(pkg -> { - final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting( - pkg.getPackageName()); - if (ps == null) { - return; + mPackageManagerInt.forEachPackage(new Consumer<PackageParser.Package>() { + @Override + public void accept(Package pkg) { + final PackageSetting ps = (PackageSetting) pkg.mExtras; + if (ps == null) { + return; + } + final PermissionsState permissionsState = ps.getPermissionsState(); + changed[0] |= permissionsState.updatePermissionFlagsForAllPermissions( + userId, effectiveFlagMask, effectiveFlagValues); + mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); } - final PermissionsState permissionsState = ps.getPermissionsState(); - changed[0] |= permissionsState.updatePermissionFlagsForAllPermissions( - userId, effectiveFlagMask, effectiveFlagValues); - mOnPermissionChangeListeners.onPermissionsChanged(pkg.getUid()); }); if (changed[0]) { @@ -799,75 +793,68 @@ public class PermissionManagerService extends IPermissionManager.Stub { final CheckPermissionDelegate checkPermissionDelegate; synchronized (mLock) { + if (mCheckPermissionDelegate == null) { + return checkPermissionImpl(permName, pkgName, userId); + } checkPermissionDelegate = mCheckPermissionDelegate; } - if (checkPermissionDelegate == null) { - return checkPermissionImpl(permName, pkgName, userId); - } return checkPermissionDelegate.checkPermission(permName, pkgName, userId, - this::checkPermissionImpl); + PermissionManagerService.this::checkPermissionImpl); } - private int checkPermissionImpl(@NonNull String permissionName, @NonNull String packageName, - @UserIdInt int userId) { - final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); + private int checkPermissionImpl(String permName, String pkgName, int userId) { + final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName); if (pkg == null) { return PackageManager.PERMISSION_DENIED; } - return checkPermissionInternal(pkg, true, permissionName, true, userId) - ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED; + return checkPermissionInternal(pkg, true, permName, userId); } - private boolean checkPermissionInternal(@NonNull AndroidPackage pkg, boolean isPackageExplicit, - @NonNull String permissionName, boolean useRequestedPermissionsForLegacyApps, - @UserIdInt int userId) { + private int checkPermissionInternal(@NonNull Package pkg, boolean isPackageExplicit, + @NonNull String permissionName, @UserIdInt int userId) { final int callingUid = getCallingUid(); - if (isPackageExplicit || pkg.getSharedUserId() == null) { + if (isPackageExplicit || pkg.mSharedUserId == null) { if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) { - return false; + return PackageManager.PERMISSION_DENIED; } } else { if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { - return false; + return PackageManager.PERMISSION_DENIED; } } - final int uid = UserHandle.getUid(userId, pkg.getUid()); - final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting( - pkg.getPackageName()); + final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); + final PackageSetting ps = (PackageSetting) pkg.mExtras; if (ps == null) { - return false; + return PackageManager.PERMISSION_DENIED; } final PermissionsState permissionsState = ps.getPermissionsState(); - if (checkSinglePermissionInternal(uid, permissionsState, permissionName, - useRequestedPermissionsForLegacyApps)) { - return true; + if (checkSinglePermissionInternal(uid, permissionsState, permissionName)) { + return PackageManager.PERMISSION_GRANTED; } final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName); - if (fullerPermissionName != null && checkSinglePermissionInternal(uid, permissionsState, - fullerPermissionName, useRequestedPermissionsForLegacyApps)) { - return true; + if (fullerPermissionName != null + && checkSinglePermissionInternal(uid, permissionsState, fullerPermissionName)) { + return PackageManager.PERMISSION_GRANTED; } - return false; + return PackageManager.PERMISSION_DENIED; } private boolean checkSinglePermissionInternal(int uid, - @NonNull PermissionsState permissionsState, @NonNull String permissionName, - boolean useRequestedPermissionsForLegacyApps) { + @NonNull PermissionsState permissionsState, @NonNull String permissionName) { boolean hasPermission = permissionsState.hasPermission(permissionName, UserHandle.getUserId(uid)); - if (!hasPermission && useRequestedPermissionsForLegacyApps - && mSettings.isPermissionRuntime(permissionName)) { + if (!hasPermission && mSettings.isPermissionRuntime(permissionName)) { final String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid); final int packageNamesSize = packageNames != null ? packageNames.length : 0; for (int i = 0; i < packageNamesSize; i++) { - final AndroidPackage pkg = mPackageManagerInt.getPackage(packageNames[i]); - if (pkg != null && pkg.getTargetSdkVersion() < Build.VERSION_CODES.M - && pkg.getRequestedPermissions().contains(permissionName)) { + final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageNames[i]); + if (pkg != null && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M + && pkg.requestedPermissions.contains(permissionName)) { hasPermission = true; break; } @@ -904,13 +891,12 @@ public class PermissionManagerService extends IPermissionManager.Stub { checkPermissionDelegate = mCheckPermissionDelegate; } return checkPermissionDelegate.checkUidPermission(permName, uid, - this::checkUidPermissionImpl); + PermissionManagerService.this::checkUidPermissionImpl); } - private int checkUidPermissionImpl(@NonNull String permissionName, int uid) { - final AndroidPackage pkg = mPackageManagerInt.getPackage(uid); - return checkUidPermissionInternal(uid, pkg, permissionName, true) - ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED; + private int checkUidPermissionImpl(String permName, int uid) { + final PackageParser.Package pkg = mPackageManagerInt.getPackage(uid); + return checkUidPermissionInternal(pkg, uid, permName); } /** @@ -920,25 +906,24 @@ public class PermissionManagerService extends IPermissionManager.Stub { * * @see SystemConfig#getSystemPermissions() */ - private boolean checkUidPermissionInternal(int uid, @Nullable AndroidPackage pkg, - @NonNull String permissionName, boolean useRequestedPermissionsForLegacyApps) { + private int checkUidPermissionInternal(@Nullable Package pkg, int uid, + @NonNull String permissionName) { if (pkg != null) { final int userId = UserHandle.getUserId(uid); - return checkPermissionInternal(pkg, false, permissionName, - useRequestedPermissionsForLegacyApps, userId); + return checkPermissionInternal(pkg, false, permissionName, userId); } if (checkSingleUidPermissionInternal(uid, permissionName)) { - return true; + return PackageManager.PERMISSION_GRANTED; } final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName); if (fullerPermissionName != null && checkSingleUidPermissionInternal(uid, fullerPermissionName)) { - return true; + return PackageManager.PERMISSION_GRANTED; } - return false; + return PackageManager.PERMISSION_DENIED; } private boolean checkSingleUidPermissionInternal(int uid, @NonNull String permissionName) { @@ -948,17 +933,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } - private int computeRuntimePermissionAppOpMode(int uid, @NonNull String permissionName) { - boolean granted = isUidPermissionGranted(uid, permissionName); - // TODO: Foreground permissions. - return granted ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED; - } - - private boolean isUidPermissionGranted(int uid, @NonNull String permissionName) { - final AndroidPackage pkg = mPackageManagerInt.getPackage(uid); - return checkUidPermissionInternal(uid, pkg, permissionName, false); - } - @Override public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { mContext.enforceCallingOrSelfPermission( @@ -996,7 +970,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { "getWhitelistedRestrictedPermissions for user " + userId); } - final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); + final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName); if (pkg == null) { return null; } @@ -1029,7 +1003,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { final long identity = Binder.clearCallingIdentity(); try { final PermissionsState permissionsState = - PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg); + PackageManagerServiceUtils.getPermissionsState(pkg); if (permissionsState == null) { return null; } @@ -1047,9 +1021,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { ArrayList<String> whitelistedPermissions = null; - final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions()); + final int permissionCount = pkg.requestedPermissions.size(); for (int i = 0; i < permissionCount; i++) { - final String permissionName = pkg.getRequestedPermissions().get(i); + final String permissionName = pkg.requestedPermissions.get(i); final int currentFlags = permissionsState.getPermissionFlags(permissionName, userId); if ((currentFlags & queryFlags) != 0) { @@ -1146,7 +1120,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { "setWhitelistedRestrictedPermissions for user " + userId); } - final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); + final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName); if (pkg == null) { return false; } @@ -1175,7 +1149,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS); } final List<String> whitelistedPermissions = - getWhitelistedRestrictedPermissions(pkg.getPackageName(), flags, userId); + getWhitelistedRestrictedPermissions(pkg.packageName, flags, userId); if (permissions == null || permissions.isEmpty()) { if (whitelistedPermissions == null || whitelistedPermissions.isEmpty()) { return true; @@ -1249,10 +1223,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { false, // requirePermissionWhenSameUser "grantRuntimePermission"); - final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); - final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting( - packageName); - if (pkg == null || ps == null) { + final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName); + if (pkg == null || pkg.mExtras == null) { Log.e(TAG, "Unknown package: " + packageName); return; } @@ -1267,19 +1239,21 @@ public class PermissionManagerService extends IPermissionManager.Stub { throw new IllegalArgumentException("Unknown package: " + packageName); } - bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps); + bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg); // If a permission review is required for legacy apps we represent // their permissions as always granted runtime ones since we need // to keep the review required permission flag per user while an // install permission's state is shared across all users. - if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M + if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M && bp.isRuntime()) { return; } - final int uid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid())); + final int uid = UserHandle.getUid(userId, + UserHandle.getAppId(pkg.applicationInfo.uid)); + final PackageSetting ps = (PackageSetting) pkg.mExtras; final PermissionsState permissionsState = ps.getPermissionsState(); final int flags = permissionsState.getPermissionFlags(permName, userId); @@ -1302,7 +1276,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { } if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext, - pkg.toAppInfo(), UserHandle.of(userId), permName).mayGrantPermission()) { + pkg.applicationInfo, UserHandle.of(userId), permName).mayGrantPermission()) { Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package " + packageName); return; @@ -1325,7 +1299,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { + permName + " for package " + packageName); } - if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) { + if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); return; } @@ -1338,7 +1312,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { if (callback != null) { - callback.onGidsChanged(UserHandle.getAppId(pkg.getUid()), userId); + callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId); } } break; @@ -1411,10 +1385,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { false, // requirePermissionWhenSameUser "revokeRuntimePermission"); - final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); - final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting( - packageName); - if (pkg == null || ps == null) { + final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName); + if (pkg == null || pkg.mExtras == null) { Log.e(TAG, "Unknown package: " + packageName); return; } @@ -1426,17 +1398,18 @@ public class PermissionManagerService extends IPermissionManager.Stub { throw new IllegalArgumentException("Unknown permission: " + permName); } - bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps); + bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg); // If a permission review is required for legacy apps we represent // their permissions as always granted runtime ones since we need // to keep the review required permission flag per user while an // install permission's state is shared across all users. - if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M + if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M && bp.isRuntime()) { return; } + final PackageSetting ps = (PackageSetting) pkg.mExtras; final PermissionsState permissionsState = ps.getPermissionsState(); final int flags = permissionsState.getPermissionFlags(permName, userId); @@ -1479,7 +1452,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (callback != null) { callback.onPermissionRevoked(UserHandle.getUid(userId, - UserHandle.getAppId(pkg.getUid())), userId); + UserHandle.getAppId(pkg.applicationInfo.uid)), userId); } if (bp.isRuntime()) { @@ -1504,7 +1477,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { StorageManager.UUID_PRIVATE_INTERNAL, false, mDefaultPermissionCallback); for (final int userId : UserManagerService.getInstance().getUserIds()) { mPackageManagerInt.forEachPackage( - (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId)); + (PackageParser.Package pkg) -> resetRuntimePermissionsInternal(pkg, userId)); } } @@ -1515,9 +1488,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { * @param userId The device user for which to do a reset. */ @GuardedBy("mLock") - private void resetRuntimePermissionsInternal(final AndroidPackage pkg, + private void resetRuntimePermissionsInternal(final PackageParser.Package pkg, final int userId) { - final String packageName = pkg.getPackageName(); + final String packageName = pkg.packageName; // These are flags that can change base on user actions. final int userSettableMask = FLAG_PERMISSION_USER_SET @@ -1529,7 +1502,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { | FLAG_PERMISSION_POLICY_FIXED; // Delay and combine non-async permission callbacks - final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions()); + final int permissionCount = pkg.requestedPermissions.size(); final boolean[] permissionRemoved = new boolean[1]; final ArraySet<Long> revokedPermissions = new ArraySet<>(); final IntArray syncUpdatedUsers = new IntArray(permissionCount); @@ -1587,7 +1560,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { final AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class); for (int i = 0; i < permissionCount; i++) { - final String permName = pkg.getRequestedPermissions().get(i); + final String permName = pkg.requestedPermissions.get(i); final BasePermission bp; synchronized (mLock) { bp = mSettings.getPermissionLocked(permName); @@ -1602,7 +1575,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { // If shared user we just reset the state to which only this app contributed. final String sharedUserId = - mPackageManagerInt.getSharedUserIdForPackage(pkg.getPackageName()); + mPackageManagerInt.getSharedUserIdForPackage(pkg.packageName); final String[] pkgNames = mPackageManagerInt.getPackagesForSharedUserId(sharedUserId, userId); if (pkgNames != null && pkgNames.length > 0) { @@ -1610,10 +1583,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { final int packageCount = pkgNames.length; for (int j = 0; j < packageCount; j++) { final String sharedPkgName = pkgNames[j]; - final AndroidPackage sharedPkg = + final PackageParser.Package sharedPkg = mPackageManagerInt.getPackage(sharedPkgName); - if (sharedPkg != null && !sharedPkg.getPackageName().equals(packageName) - && sharedPkg.getRequestedPermissions().contains(permName)) { + if (sharedPkg != null && !sharedPkg.packageName.equals(packageName) + && sharedPkg.requestedPermissions.contains(permName)) { used = true; break; } @@ -2041,16 +2014,15 @@ public class PermissionManagerService extends IPermissionManager.Stub { return protectionLevel; } // Normalize package name to handle renamed packages and static libs - final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); + final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName); if (pkg == null) { return protectionLevel; } - if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) { + if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) { return protectionLevelMasked; } // Apps that target O see flags for all protection levels. - final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting( - pkg.getPackageName()); + final PackageSetting ps = (PackageSetting) pkg.mExtras; if (ps == null) { return protectionLevel; } @@ -2071,35 +2043,35 @@ public class PermissionManagerService extends IPermissionManager.Stub { * @param permissionCallback Callback for permission changed */ private void revokeRuntimePermissionsIfGroupChanged( - @NonNull AndroidPackage newPackage, - @NonNull AndroidPackage oldPackage, + @NonNull PackageParser.Package newPackage, + @NonNull PackageParser.Package oldPackage, @NonNull ArrayList<String> allPackageNames, @NonNull PermissionCallback permissionCallback) { - final int numOldPackagePermissions = ArrayUtils.size(oldPackage.getPermissions()); + final int numOldPackagePermissions = oldPackage.permissions.size(); final ArrayMap<String, String> oldPermissionNameToGroupName = new ArrayMap<>(numOldPackagePermissions); for (int i = 0; i < numOldPackagePermissions; i++) { - final ParsedPermission permission = oldPackage.getPermissions().get(i); + final PackageParser.Permission permission = oldPackage.permissions.get(i); - if (permission.parsedPermissionGroup != null) { - oldPermissionNameToGroupName.put(permission.getName(), - permission.parsedPermissionGroup.getName()); + if (permission.group != null) { + oldPermissionNameToGroupName.put(permission.info.name, + permission.group.info.name); } } final int callingUid = Binder.getCallingUid(); - final int numNewPackagePermissions = ArrayUtils.size(newPackage.getPermissions()); + final int numNewPackagePermissions = newPackage.permissions.size(); for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions; newPermissionNum++) { - final ParsedPermission newPermission = - newPackage.getPermissions().get(newPermissionNum); - final int newProtection = newPermission.getProtection(); + final PackageParser.Permission newPermission = + newPackage.permissions.get(newPermissionNum); + final int newProtection = newPermission.info.getProtection(); if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) { - final String permissionName = newPermission.getName(); - final String newPermissionGroupName = newPermission.parsedPermissionGroup == null - ? null : newPermission.parsedPermissionGroup.getName(); + final String permissionName = newPermission.info.name; + final String newPermissionGroupName = + newPermission.group == null ? null : newPermission.group.info.name; final String oldPermissionGroupName = oldPermissionNameToGroupName.get( permissionName); @@ -2117,7 +2089,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { userId); if (permissionState == PackageManager.PERMISSION_GRANTED) { EventLog.writeEvent(0x534e4554, "72710897", - newPackage.getUid(), + newPackage.applicationInfo.uid, "Revoking permission " + permissionName + " from package " + packageName + " as the group changed from " + oldPermissionGroupName + @@ -2138,56 +2110,54 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } - private void addAllPermissions(AndroidPackage pkg, boolean chatty) { - final int N = ArrayUtils.size(pkg.getPermissions()); + private void addAllPermissions(PackageParser.Package pkg, boolean chatty) { + final int N = pkg.permissions.size(); for (int i=0; i<N; i++) { - ParsedPermission p = pkg.getPermissions().get(i); + PackageParser.Permission p = pkg.permissions.get(i); // Assume by default that we did not install this permission into the system. - p.flags &= ~PermissionInfo.FLAG_INSTALLED; + p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; synchronized (PermissionManagerService.this.mLock) { // Now that permission groups have a special meaning, we ignore permission // groups for legacy apps to prevent unexpected behavior. In particular, // permissions for one app being granted to someone just because they happen // to be in a group defined by another app (before this had no implications). - if (pkg.getTargetSdkVersion() > Build.VERSION_CODES.LOLLIPOP_MR1) { - p.parsedPermissionGroup = mSettings.mPermissionGroups.get(p.getGroup()); + if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { + p.group = mSettings.mPermissionGroups.get(p.info.group); // Warn for a permission in an unknown group. if (DEBUG_PERMISSIONS - && p.getGroup() != null && p.parsedPermissionGroup == null) { - Slog.i(TAG, "Permission " + p.getName() + " from package " - + p.getPackageName() + " in an unknown group " + p.getGroup()); + && p.info.group != null && p.group == null) { + Slog.i(TAG, "Permission " + p.info.name + " from package " + + p.info.packageName + " in an unknown group " + p.info.group); } } if (p.tree) { final BasePermission bp = BasePermission.createOrUpdate( - mPackageManagerInt, - mSettings.getPermissionTreeLocked(p.getName()), p, pkg, + mSettings.getPermissionTreeLocked(p.info.name), p, pkg, mSettings.getAllPermissionTreesLocked(), chatty); - mSettings.putPermissionTreeLocked(p.getName(), bp); + mSettings.putPermissionTreeLocked(p.info.name, bp); } else { final BasePermission bp = BasePermission.createOrUpdate( - mPackageManagerInt, - mSettings.getPermissionLocked(p.getName()), + mSettings.getPermissionLocked(p.info.name), p, pkg, mSettings.getAllPermissionTreesLocked(), chatty); - mSettings.putPermissionLocked(p.getName(), bp); + mSettings.putPermissionLocked(p.info.name, bp); } } } } - private void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) { - final int N = ArrayUtils.size(pkg.getPermissionGroups()); + private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) { + final int N = pkg.permissionGroups.size(); StringBuilder r = null; for (int i=0; i<N; i++) { - final ParsedPermissionGroup pg = pkg.getPermissionGroups().get(i); - final ParsedPermissionGroup cur = mSettings.mPermissionGroups.get(pg.getName()); - final String curPackageName = (cur == null) ? null : cur.getPackageName(); - final boolean isPackageUpdate = pg.getPackageName().equals(curPackageName); + final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); + final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name); + final String curPackageName = (cur == null) ? null : cur.info.packageName; + final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName); if (cur == null || isPackageUpdate) { - mSettings.mPermissionGroups.put(pg.getName(), pg); + mSettings.mPermissionGroups.put(pg.info.name, pg); if (chatty && DEBUG_PACKAGE_SCANNING) { if (r == null) { r = new StringBuilder(256); @@ -2197,12 +2167,12 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (isPackageUpdate) { r.append("UPD:"); } - r.append(pg.getName()); + r.append(pg.info.name); } } else { - Slog.w(TAG, "Permission group " + pg.getName() + " from package " - + pg.getPackageName() + " ignored: original from " - + cur.getPackageName()); + Slog.w(TAG, "Permission group " + pg.info.name + " from package " + + pg.info.packageName + " ignored: original from " + + cur.info.packageName); if (chatty && DEBUG_PACKAGE_SCANNING) { if (r == null) { r = new StringBuilder(256); @@ -2210,7 +2180,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { r.append(' '); } r.append("DUP:"); - r.append(pg.getName()); + r.append(pg.info.name); } } } @@ -2220,15 +2190,15 @@ public class PermissionManagerService extends IPermissionManager.Stub { } - private void removeAllPermissions(AndroidPackage pkg, boolean chatty) { + private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) { synchronized (mLock) { - int N = ArrayUtils.size(pkg.getPermissions()); + int N = pkg.permissions.size(); StringBuilder r = null; for (int i=0; i<N; i++) { - ParsedPermission p = pkg.getPermissions().get(i); - BasePermission bp = mSettings.mPermissions.get(p.getName()); + PackageParser.Permission p = pkg.permissions.get(i); + BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name); if (bp == null) { - bp = mSettings.mPermissionTrees.get(p.getName()); + bp = mSettings.mPermissionTrees.get(p.info.name); } if (bp != null && bp.isPermission(p)) { bp.setPermission(null); @@ -2238,14 +2208,14 @@ public class PermissionManagerService extends IPermissionManager.Stub { } else { r.append(' '); } - r.append(p.getName()); + r.append(p.info.name); } } if (p.isAppOp()) { ArraySet<String> appOpPkgs = - mSettings.mAppOpPermissionPackages.get(p.getName()); + mSettings.mAppOpPermissionPackages.get(p.info.name); if (appOpPkgs != null) { - appOpPkgs.remove(pkg.getPackageName()); + appOpPkgs.remove(pkg.packageName); } } } @@ -2253,14 +2223,14 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); } - N = pkg.getRequestedPermissions().size(); + N = pkg.requestedPermissions.size(); r = null; for (int i=0; i<N; i++) { - String perm = pkg.getRequestedPermissions().get(i); + String perm = pkg.requestedPermissions.get(i); if (mSettings.isPermissionAppOp(perm)) { ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm); if (appOpPkgs != null) { - appOpPkgs.remove(pkg.getPackageName()); + appOpPkgs.remove(pkg.packageName); if (appOpPkgs.isEmpty()) { mSettings.mAppOpPermissionPackages.remove(perm); } @@ -2289,7 +2259,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { * @param packageOfInterest If this is the name of {@code pkg} add extra logging * @param callback Result call back */ - private void restorePermissionState(@NonNull AndroidPackage pkg, boolean replace, + private void restorePermissionState(@NonNull PackageParser.Package pkg, boolean replace, @Nullable String packageOfInterest, @Nullable PermissionCallback callback) { // IMPORTANT: There are two types of permissions: install and runtime. // Install time permissions are granted when the app is installed to @@ -2302,8 +2272,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { // being upgraded to target a newer SDK, in which case dangerous permissions // are transformed from install time to runtime ones. - final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting( - pkg.getPackageName()); + final PackageSetting ps = (PackageSetting) pkg.mExtras; if (ps == null) { return; } @@ -2344,25 +2313,23 @@ public class PermissionManagerService extends IPermissionManager.Stub { synchronized (mLock) { ArraySet<String> newImplicitPermissions = new ArraySet<>(); - final int N = pkg.getRequestedPermissions().size(); + final int N = pkg.requestedPermissions.size(); for (int i = 0; i < N; i++) { - final String permName = pkg.getRequestedPermissions().get(i); + final String permName = pkg.requestedPermissions.get(i); final BasePermission bp = mSettings.getPermissionLocked(permName); final boolean appSupportsRuntimePermissions = - pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M; + pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M; String upgradedActivityRecognitionPermission = null; if (DEBUG_INSTALL) { - Log.i(TAG, "Package " + pkg.getPackageName() - + " checking " + permName + ": " + bp); + Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp); } if (bp == null || bp.getSourcePackageSetting() == null) { - if (packageOfInterest == null || packageOfInterest.equals( - pkg.getPackageName())) { + if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { if (DEBUG_PERMISSIONS) { Slog.i(TAG, "Unknown permission " + permName - + " in package " + pkg.getPackageName()); + + " in package " + pkg.packageName); } } continue; @@ -2371,14 +2338,14 @@ public class PermissionManagerService extends IPermissionManager.Stub { // Cache newImplicitPermissions before modifing permissionsState as for the shared // uids the original and new state are the same object if (!origPermissions.hasRequestedPermission(permName) - && (pkg.getImplicitPermissions().contains(permName) + && (pkg.implicitPermissions.contains(permName) || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) { - if (pkg.getImplicitPermissions().contains(permName)) { + if (pkg.implicitPermissions.contains(permName)) { // If permName is an implicit permission, try to auto-grant newImplicitPermissions.add(permName); if (DEBUG_PERMISSIONS) { - Slog.i(TAG, permName + " is newly added for " + pkg.getPackageName()); + Slog.i(TAG, permName + " is newly added for " + pkg.packageName); } } else { // Special case for Activity Recognition permission. Even if AR permission @@ -2401,7 +2368,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (DEBUG_PERMISSIONS) { Slog.i(TAG, permName + " is newly added for " - + pkg.getPackageName()); + + pkg.packageName); } break; } @@ -2410,10 +2377,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { } // Limit ephemeral apps to ephemeral allowed permissions. - if (pkg.isInstantApp() && !bp.isInstant()) { + if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) { if (DEBUG_PERMISSIONS) { Log.i(TAG, "Denying non-ephemeral permission " + bp.getName() - + " for package " + pkg.getPackageName()); + + " for package " + pkg.packageName); } continue; } @@ -2421,7 +2388,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) { if (DEBUG_PERMISSIONS) { Log.i(TAG, "Denying runtime-only permission " + bp.getName() - + " for package " + pkg.getPackageName()); + + " for package " + pkg.packageName); } continue; } @@ -2432,7 +2399,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { // Keep track of app op permissions. if (bp.isAppOp()) { - mSettings.addAppOpPackage(perm, pkg.getPackageName()); + mSettings.addAppOpPackage(perm, pkg.packageName); } if (bp.isNormal()) { @@ -2458,7 +2425,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (DEBUG_PERMISSIONS) { Slog.i(TAG, "Considering granting permission " + perm + " to package " - + pkg.getPackageName()); + + pkg.packageName); } if (grant != GRANT_DENIED) { @@ -2744,10 +2711,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { default: { if (packageOfInterest == null - || packageOfInterest.equals(pkg.getPackageName())) { + || packageOfInterest.equals(pkg.packageName)) { if (DEBUG_PERMISSIONS) { Slog.i(TAG, "Not granting permission " + perm - + " to package " + pkg.getPackageName() + + " to package " + pkg.packageName + " because it was previously installed without"); } } @@ -2762,9 +2729,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { changedInstallPermission = true; if (DEBUG_PERMISSIONS) { Slog.i(TAG, "Un-granting permission " + perm - + " from package " + pkg.getPackageName() + + " from package " + pkg.packageName + " (protectionLevel=" + bp.getProtectionLevel() - + " flags=0x" + Integer.toHexString(pkg.getFlags()) + + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) + ")"); } } else if (bp.isAppOp()) { @@ -2772,11 +2739,11 @@ public class PermissionManagerService extends IPermissionManager.Stub { // not to be granted, there is a UI for the user to decide. if (DEBUG_PERMISSIONS && (packageOfInterest == null - || packageOfInterest.equals(pkg.getPackageName()))) { + || packageOfInterest.equals(pkg.packageName))) { Slog.i(TAG, "Not granting permission " + perm - + " to package " + pkg.getPackageName() + + " to package " + pkg.packageName + " (protectionLevel=" + bp.getProtectionLevel() - + " flags=0x" + Integer.toHexString(pkg.getFlags()) + + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) + ")"); } } @@ -2806,7 +2773,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { } for (int userId : updatedUserIds) { - notifyRuntimePermissionStateChanged(pkg.getPackageName(), userId); + notifyRuntimePermissionStateChanged(pkg.packageName, userId); } } @@ -2822,10 +2789,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { * @return The updated value of the {@code updatedUserIds} parameter */ private @NonNull int[] revokePermissionsNoLongerImplicitLocked( - @NonNull PermissionsState ps, @NonNull AndroidPackage pkg, + @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg, @NonNull int[] updatedUserIds) { - String pkgName = pkg.getPackageName(); - boolean supportsRuntimePermissions = pkg.getTargetSdkVersion() + String pkgName = pkg.packageName; + boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M; int[] users = UserManagerService.getInstance().getUserIds(); @@ -2834,7 +2801,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { int userId = users[i]; for (String permission : ps.getPermissions(userId)) { - if (!pkg.getImplicitPermissions().contains(permission)) { + if (!pkg.implicitPermissions.contains(permission)) { if (!ps.hasInstallPermission(permission)) { int flags = ps.getRuntimePermissionState(permission, userId).getFlags(); @@ -2884,9 +2851,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { */ private void inheritPermissionStateToNewImplicitPermissionLocked( @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm, - @NonNull PermissionsState ps, @NonNull AndroidPackage pkg, + @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg, @UserIdInt int userId) { - String pkgName = pkg.getPackageName(); + String pkgName = pkg.packageName; boolean isGranted = false; int flags = 0; @@ -2933,10 +2900,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { * @return The ids of the users that are changed */ private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated( - @NonNull AndroidPackage pkg, boolean replace, @NonNull int[] updatedUserIds) { - if (replace && pkg.hasRequestedLegacyExternalStorage() && ( - pkg.getRequestedPermissions().contains(READ_EXTERNAL_STORAGE) - || pkg.getRequestedPermissions().contains(WRITE_EXTERNAL_STORAGE))) { + @NonNull PackageParser.Package pkg, boolean replace, @NonNull int[] updatedUserIds) { + if (replace && pkg.applicationInfo.hasRequestedLegacyExternalStorage() && ( + pkg.requestedPermissions.contains(READ_EXTERNAL_STORAGE) + || pkg.requestedPermissions.contains(WRITE_EXTERNAL_STORAGE))) { return UserManagerService.getInstance().getUserIds(); } @@ -2955,10 +2922,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { */ private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked( @NonNull PermissionsState origPs, - @NonNull PermissionsState ps, @NonNull AndroidPackage pkg, + @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg, @NonNull ArraySet<String> newImplicitPermissions, @NonNull int[] updatedUserIds) { - String pkgName = pkg.getPackageName(); + String pkgName = pkg.packageName; ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>(); final List<SplitPermissionInfoParcelable> permissionList = getSplitPermissions(); @@ -3038,17 +3005,17 @@ public class PermissionManagerService extends IPermissionManager.Stub { SystemConfig.getInstance().getSplitPermissions()); } - private boolean isNewPlatformPermissionForPackage(String perm, AndroidPackage pkg) { + private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { boolean allowed = false; final int NP = PackageParser.NEW_PERMISSIONS.length; for (int ip=0; ip<NP; ip++) { final PackageParser.NewPermissionInfo npi = PackageParser.NEW_PERMISSIONS[ip]; if (npi.name.equals(perm) - && pkg.getTargetSdkVersion() < npi.sdkVersion) { + && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { allowed = true; Log.i(TAG, "Auto-granting " + perm + " to old pkg " - + pkg.getPackageName()); + + pkg.packageName); break; } } @@ -3062,26 +3029,29 @@ public class PermissionManagerService extends IPermissionManager.Stub { * * <p>This handles parent/child apps. */ - private boolean hasPrivappWhitelistEntry(String perm, AndroidPackage pkg) { - ArraySet<String> wlPermissions; + private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) { + ArraySet<String> wlPermissions = null; if (pkg.isVendor()) { wlPermissions = - SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.getPackageName()); + SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName); } else if (pkg.isProduct()) { wlPermissions = - SystemConfig.getInstance().getProductPrivAppPermissions(pkg.getPackageName()); + SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName); } else if (pkg.isSystemExt()) { wlPermissions = SystemConfig.getInstance().getSystemExtPrivAppPermissions( - pkg.getPackageName()); + pkg.packageName); } else { - wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.getPackageName()); + wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName); } - - return wlPermissions != null && wlPermissions.contains(perm); + // Let's check if this package is whitelisted... + boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm); + // If it's not, we'll also tail-recurse to the parent. + return whitelisted || + pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage); } - private boolean grantSignaturePermission(String perm, AndroidPackage pkg, + private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, BasePermission bp, PermissionsState origPermissions) { boolean oemPermission = bp.isOEM(); boolean vendorPrivilegedPermission = bp.isVendorPrivileged(); @@ -3089,7 +3059,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { boolean privappPermissionsDisable = RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE; boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName()); - boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName()); + boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName); if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged() && !platformPackage && platformPermission) { if (!hasPrivappWhitelistEntry(perm, pkg)) { @@ -3099,22 +3069,22 @@ public class PermissionManagerService extends IPermissionManager.Stub { ArraySet<String> deniedPermissions = null; if (pkg.isVendor()) { deniedPermissions = SystemConfig.getInstance() - .getVendorPrivAppDenyPermissions(pkg.getPackageName()); + .getVendorPrivAppDenyPermissions(pkg.packageName); } else if (pkg.isProduct()) { deniedPermissions = SystemConfig.getInstance() - .getProductPrivAppDenyPermissions(pkg.getPackageName()); + .getProductPrivAppDenyPermissions(pkg.packageName); } else if (pkg.isSystemExt()) { deniedPermissions = SystemConfig.getInstance() - .getSystemExtPrivAppDenyPermissions(pkg.getPackageName()); + .getSystemExtPrivAppDenyPermissions(pkg.packageName); } else { deniedPermissions = SystemConfig.getInstance() - .getPrivAppDenyPermissions(pkg.getPackageName()); + .getPrivAppDenyPermissions(pkg.packageName); } final boolean permissionViolation = deniedPermissions == null || !deniedPermissions.contains(perm); if (permissionViolation) { Slog.w(TAG, "Privileged permission " + perm + " for package " - + pkg.getPackageName() + " (" + pkg.getCodePath() + + pkg.packageName + " (" + pkg.codePath + ") not in privapp-permissions whitelist"); if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) { @@ -3122,7 +3092,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { mPrivappPermissionsViolations = new ArraySet<>(); } mPrivappPermissionsViolations.add( - pkg.getPackageName() + " (" + pkg.getCodePath() + "): " + perm); + pkg.packageName + " (" + pkg.codePath + "): " + perm); } } else { return false; @@ -3135,7 +3105,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { } final String systemPackageName = mPackageManagerInt.getKnownPackageName( PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM); - final AndroidPackage systemPackage = + final PackageParser.Package systemPackage = mPackageManagerInt.getPackage(systemPackageName); // check if the package is allow to use this signature permission. A package is allowed to @@ -3146,23 +3116,24 @@ public class PermissionManagerService extends IPermissionManager.Stub { // package, and the defining package still trusts the old certificate for permissions // - or it shares the above relationships with the system package boolean allowed = - pkg.getSigningDetails().hasAncestorOrSelf( + pkg.mSigningDetails.hasAncestorOrSelf( bp.getSourcePackageSetting().getSigningDetails()) || bp.getSourcePackageSetting().getSigningDetails().checkCapability( - pkg.getSigningDetails(), + pkg.mSigningDetails, PackageParser.SigningDetails.CertCapabilities.PERMISSION) - || pkg.getSigningDetails().hasAncestorOrSelf(systemPackage.getSigningDetails()) - || systemPackage.getSigningDetails().checkCapability( - pkg.getSigningDetails(), + || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails) + || systemPackage.mSigningDetails.checkCapability( + pkg.mSigningDetails, PackageParser.SigningDetails.CertCapabilities.PERMISSION); if (!allowed && (privilegedPermission || oemPermission)) { if (pkg.isSystem()) { // For updated system applications, a privileged/oem permission // is granted only if it had been defined by the original application. if (pkg.isUpdatedSystemApp()) { - final PackageSetting disabledPs = (PackageSetting) mPackageManagerInt - .getDisabledSystemPackage(pkg.getPackageName()); - final AndroidPackage disabledPkg = disabledPs == null ? null : disabledPs.pkg; + final PackageParser.Package disabledPkg = + mPackageManagerInt.getDisabledSystemPackage(pkg.packageName); + final PackageSetting disabledPs = + (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null; if (disabledPs != null && disabledPs.getPermissionsState().hasInstallPermission(perm)) { // If the original was granted this permission, we take @@ -3187,10 +3158,40 @@ public class PermissionManagerService extends IPermissionManager.Stub { && canGrantOemPermission(disabledPs, perm)))) { allowed = true; } + // Also if a privileged parent package on the system image or any of + // its children requested a privileged/oem permission, the updated child + // packages can also get the permission. + if (pkg.parentPackage != null) { + final PackageParser.Package disabledParentPkg = mPackageManagerInt + .getDisabledSystemPackage(pkg.parentPackage.packageName); + final PackageSetting disabledParentPs = (disabledParentPkg != null) + ? (PackageSetting) disabledParentPkg.mExtras : null; + if (disabledParentPkg != null + && ((privilegedPermission && disabledParentPs.isPrivileged()) + || (oemPermission && disabledParentPs.isOem()))) { + if (isPackageRequestingPermission(disabledParentPkg, perm) + && canGrantOemPermission(disabledParentPs, perm)) { + allowed = true; + } else if (disabledParentPkg.childPackages != null) { + for (PackageParser.Package disabledChildPkg + : disabledParentPkg.childPackages) { + final PackageSetting disabledChildPs = + (disabledChildPkg != null) + ? (PackageSetting) disabledChildPkg.mExtras + : null; + if (isPackageRequestingPermission(disabledChildPkg, perm) + && canGrantOemPermission( + disabledChildPs, perm)) { + allowed = true; + break; + } + } + } + } + } } } else { - final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting( - pkg.getPackageName()); + final PackageSetting ps = (PackageSetting) pkg.mExtras; allowed = (privilegedPermission && pkg.isPrivileged()) || (oemPermission && pkg.isOem() && canGrantOemPermission(ps, perm)); @@ -3201,8 +3202,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (allowed && privilegedPermission && !vendorPrivilegedPermission && pkg.isVendor()) { Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk " - + pkg.getPackageName() - + " because it isn't a 'vendorPrivileged' permission."); + + pkg.packageName + " because it isn't a 'vendorPrivileged' permission."); allowed = false; } } @@ -3210,7 +3210,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (!allowed) { if (!allowed && bp.isPre23() - && pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) { + && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { // If this was a previously normal/dangerous permission that got moved // to a system permission as part of the runtime permission redesign, then // we still want to blindly grant it to old apps. @@ -3220,9 +3220,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { // need a separate flag anymore. Hence we need to check which // permissions are needed by the permission controller if (!allowed && bp.isInstaller() - && (pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName( + && (pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM)) - || pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName( + || pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER, UserHandle.USER_SYSTEM)))) { // If this permission is to be granted to the system installer and @@ -3230,7 +3230,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { allowed = true; } if (!allowed && bp.isVerifier() - && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName( + && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) { // If this permission is to be granted to the system verifier and // this app is a verifier, then it gets the permission. @@ -3247,41 +3247,41 @@ public class PermissionManagerService extends IPermissionManager.Stub { allowed = origPermissions.hasInstallPermission(perm); } if (!allowed && bp.isSetup() - && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName( + && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) { // If this permission is to be granted to the system setup wizard and // this app is a setup wizard, then it gets the permission. allowed = true; } if (!allowed && bp.isSystemTextClassifier() - && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName( + && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER, UserHandle.USER_SYSTEM))) { // Special permissions for the system default text classifier. allowed = true; } if (!allowed && bp.isConfigurator() - && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName( + && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( PackageManagerInternal.PACKAGE_CONFIGURATOR, UserHandle.USER_SYSTEM))) { // Special permissions for the device configurator. allowed = true; } if (!allowed && bp.isWellbeing() - && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName( + && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM))) { // Special permission granted only to the OEM specified wellbeing app allowed = true; } if (!allowed && bp.isDocumenter() - && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName( + && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM))) { // If this permission is to be granted to the documenter and // this app is the documenter, then it gets the permission. allowed = true; } if (!allowed && bp.isIncidentReportApprover() - && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName( + && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER, UserHandle.USER_SYSTEM))) { // If this permission is to be granted to the incident report approver and @@ -3289,7 +3289,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { allowed = true; } if (!allowed && bp.isAppPredictor() - && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName( + && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM))) { // Special permissions for the system app predictor. allowed = true; @@ -3312,27 +3312,26 @@ public class PermissionManagerService extends IPermissionManager.Stub { return Boolean.TRUE == granted; } - private boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg, + private boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg, @UserIdInt int userId) { // Permission review applies only to apps not supporting the new permission model. - if (pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M) { + if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { return false; } // Legacy apps have the permission and get user consent on launch. - final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting( - pkg.getPackageName()); - if (ps == null) { + if (pkg.mExtras == null) { return false; } + final PackageSetting ps = (PackageSetting) pkg.mExtras; final PermissionsState permissionsState = ps.getPermissionsState(); return permissionsState.isPermissionReviewRequired(userId); } - private boolean isPackageRequestingPermission(AndroidPackage pkg, String permission) { - final int permCount = pkg.getRequestedPermissions().size(); + private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { + final int permCount = pkg.requestedPermissions.size(); for (int j = 0; j < permCount; j++) { - String requestedPermission = pkg.getRequestedPermissions().get(j); + String requestedPermission = pkg.requestedPermissions.get(j); if (permission.equals(requestedPermission)) { return true; } @@ -3340,7 +3339,41 @@ public class PermissionManagerService extends IPermissionManager.Stub { return false; } - private void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds, + @GuardedBy("mLock") + private void grantRuntimePermissionsGrantedToDisabledPackageLocked( + PackageParser.Package pkg, int callingUid, PermissionCallback callback) { + if (pkg.parentPackage == null) { + return; + } + if (pkg.requestedPermissions == null) { + return; + } + final PackageParser.Package disabledPkg = + mPackageManagerInt.getDisabledSystemPackage(pkg.parentPackage.packageName); + if (disabledPkg == null || disabledPkg.mExtras == null) { + return; + } + final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras; + if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) { + return; + } + final int permCount = pkg.requestedPermissions.size(); + for (int i = 0; i < permCount; i++) { + String permission = pkg.requestedPermissions.get(i); + BasePermission bp = mSettings.getPermissionLocked(permission); + if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) { + continue; + } + for (int userId : mUserManagerInt.getUserIds()) { + if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) { + grantRuntimePermissionInternal( + permission, pkg.packageName, false, callingUid, userId, callback); + } + } + } + } + + private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, String[] grantedPermissions, int callingUid, PermissionCallback callback) { for (int userId : userIds) { grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid, @@ -3348,10 +3381,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } - private void grantRequestedRuntimePermissionsForUser(AndroidPackage pkg, int userId, + private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, String[] grantedPermissions, int callingUid, PermissionCallback callback) { - PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting( - pkg.getPackageName()); + PackageSetting ps = (PackageSetting) pkg.mExtras; if (ps == null) { return; } @@ -3364,12 +3396,12 @@ public class PermissionManagerService extends IPermissionManager.Stub { final int compatFlags = PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT; - final boolean supportsRuntimePermissions = pkg.getTargetSdkVersion() + final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M; - final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.getPackageName(), userId); + final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId); - for (String permission : pkg.getRequestedPermissions()) { + for (String permission : pkg.requestedPermissions) { final BasePermission bp; synchronized (mLock) { bp = mSettings.getPermissionLocked(permission); @@ -3383,14 +3415,14 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (supportsRuntimePermissions) { // Installer cannot change immutable permissions. if ((flags & immutableFlags) == 0) { - grantRuntimePermissionInternal(permission, pkg.getPackageName(), false, + grantRuntimePermissionInternal(permission, pkg.packageName, false, callingUid, userId, callback); } } else { // In permission review mode we clear the review flag and the revoked compat // flag when we are asked to install the app with all permissions granted. if ((flags & compatFlags) != 0) { - updatePermissionFlagsInternal(permission, pkg.getPackageName(), compatFlags, + updatePermissionFlagsInternal(permission, pkg.packageName, compatFlags, 0, callingUid, userId, false, callback); } } @@ -3398,11 +3430,11 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } - private void setWhitelistedRestrictedPermissionsForUser(@NonNull AndroidPackage pkg, + private void setWhitelistedRestrictedPermissionsForUser(@NonNull PackageParser.Package pkg, @UserIdInt int userId, @Nullable List<String> permissions, int callingUid, @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) { final PermissionsState permissionsState = - PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg); + PackageManagerServiceUtils.getPermissionsState(pkg); if (permissionsState == null) { return; } @@ -3410,9 +3442,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { ArraySet<String> oldGrantedRestrictedPermissions = null; boolean updatePermissions = false; - final int permissionCount = pkg.getRequestedPermissions().size(); + final int permissionCount = pkg.requestedPermissions.size(); for (int i = 0; i < permissionCount; i++) { - final String permissionName = pkg.getRequestedPermissions().get(i); + final String permissionName = pkg.requestedPermissions.get(i); final BasePermission bp = mSettings.getPermissionLocked(permissionName); @@ -3488,19 +3520,19 @@ public class PermissionManagerService extends IPermissionManager.Stub { // If we are whitelisting an app that does not support runtime permissions // we need to make sure it goes through the permission review UI at launch. - if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M + if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M && !wasWhitelisted && isWhitelisted) { mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; } - updatePermissionFlagsInternal(permissionName, pkg.getPackageName(), mask, newFlags, + updatePermissionFlagsInternal(permissionName, pkg.packageName, mask, newFlags, callingUid, userId, false, null /*callback*/); } if (updatePermissions) { // Update permission of this app to take into account the new whitelist state. - restorePermissionState(pkg, false, pkg.getPackageName(), callback); + restorePermissionState(pkg, false, pkg.packageName, callback); // If this resulted in losing a permission we need to kill the app. if (oldGrantedRestrictedPermissions != null) { @@ -3509,9 +3541,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { final String permission = oldGrantedRestrictedPermissions.valueAt(i); // Sometimes we create a new permission state instance during update. final PermissionsState newPermissionsState = - PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg); + PackageManagerServiceUtils.getPermissionsState(pkg); if (!newPermissionsState.hasPermission(permission, userId)) { - callback.onPermissionRevoked(pkg.getUid(), userId); + callback.onPermissionRevoked(pkg.applicationInfo.uid, userId); break; } } @@ -3524,17 +3556,17 @@ public class PermissionManagerService extends IPermissionManager.Stub { SharedUserSetting suSetting, int[] allUserIds) { // Collect all used permissions in the UID final ArraySet<String> usedPermissions = new ArraySet<>(); - final List<AndroidPackage> pkgList = suSetting.getPackages(); + final List<PackageParser.Package> pkgList = suSetting.getPackages(); if (pkgList == null || pkgList.size() == 0) { return EmptyArray.INT; } - for (AndroidPackage pkg : pkgList) { - if (pkg.getRequestedPermissions() == null) { + for (PackageParser.Package pkg : pkgList) { + if (pkg.requestedPermissions == null) { continue; } - final int requestedPermCount = pkg.getRequestedPermissions().size(); + final int requestedPermCount = pkg.requestedPermissions.size(); for (int j = 0; j < requestedPermCount; j++) { - String permission = pkg.getRequestedPermissions().get(j); + String permission = pkg.requestedPermissions.get(j); BasePermission bp = mSettings.getPermissionLocked(permission); if (bp != null) { usedPermissions.add(permission); @@ -3596,12 +3628,18 @@ public class PermissionManagerService extends IPermissionManager.Stub { * @param allPackages All currently known packages * @param callback Callback to call after permission changes */ - private void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg, + private void updatePermissions(@NonNull String packageName, @Nullable PackageParser.Package pkg, @NonNull PermissionCallback callback) { final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG : 0); updatePermissions( packageName, pkg, getVolumeUuidForPackage(pkg), flags, callback); + if (pkg != null && pkg.childPackages != null) { + for (PackageParser.Package childPkg : pkg.childPackages) { + updatePermissions(childPkg.packageName, childPkg, + getVolumeUuidForPackage(childPkg), flags, callback); + } + } } /** @@ -3637,9 +3675,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { // Only system declares background permissions, hence mapping does never change. mBackgroundPermissions = new ArrayMap<>(); for (BasePermission bp : mSettings.getAllPermissionsLocked()) { - if (bp.perm != null && bp.perm.backgroundPermission != null) { + if (bp.perm != null && bp.perm.info != null + && bp.perm.info.backgroundPermission != null) { String fgPerm = bp.name; - String bgPerm = bp.perm.backgroundPermission; + String bgPerm = bp.perm.info.backgroundPermission; List<String> fgPerms = mBackgroundPermissions.get(bgPerm); if (fgPerms == null) { @@ -3700,7 +3739,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { * @param callback Callback to call after permission changes */ private void updatePermissions(final @Nullable String changingPkgName, - final @Nullable AndroidPackage changingPkg, + final @Nullable PackageParser.Package changingPkg, final @Nullable String replaceVolumeUuid, @UpdatePermissionFlags int flags, final @Nullable PermissionCallback callback) { @@ -3733,7 +3772,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { // Now update the permissions for all packages. if ((flags & UPDATE_PERMISSIONS_ALL) != 0) { final boolean replaceAll = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0); - mPackageManagerInt.forEachPackage((AndroidPackage pkg) -> { + mPackageManagerInt.forEachPackage((Package pkg) -> { if (pkg == changingPkg) { return; } @@ -3772,7 +3811,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { * @return {@code true} if a permission source package might have changed */ private boolean updatePermissionSourcePackage(@Nullable String packageName, - @Nullable AndroidPackage pkg, + @Nullable PackageParser.Package pkg, final @Nullable PermissionCallback callback) { boolean changed = false; @@ -3795,8 +3834,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) { final int userId = userIds[userIdNum]; - mPackageManagerInt.forEachPackage((AndroidPackage p) -> { - final String pName = p.getPackageName(); + mPackageManagerInt.forEachPackage((Package p) -> { + final String pName = p.packageName; final ApplicationInfo appInfo = mPackageManagerInt.getApplicationInfo(pName, 0, Process.SYSTEM_UID, UserHandle.USER_SYSTEM); @@ -3841,13 +3880,11 @@ public class PermissionManagerService extends IPermissionManager.Stub { } if (needsUpdate != null) { for (final BasePermission bp : needsUpdate) { - final AndroidPackage sourcePkg = + final PackageParser.Package sourcePkg = mPackageManagerInt.getPackage(bp.getSourcePackageName()); - final PackageSetting sourcePs = - (PackageSetting) mPackageManagerInt.getPackageSetting( - bp.getSourcePackageName()); synchronized (mLock) { - if (sourcePkg != null && sourcePs != null) { + if (sourcePkg != null && sourcePkg.mExtras != null) { + final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras; if (bp.getSourcePackageSetting() == null) { bp.setSourcePackageSetting(sourcePs); } @@ -3880,7 +3917,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { * @return {@code true} if a permission tree ownership might have changed */ private boolean updatePermissionTreeSourcePackage(@Nullable String packageName, - @Nullable AndroidPackage pkg) { + @Nullable PackageParser.Package pkg) { boolean changed = false; Set<BasePermission> needsUpdate = null; @@ -3906,13 +3943,11 @@ public class PermissionManagerService extends IPermissionManager.Stub { } if (needsUpdate != null) { for (final BasePermission bp : needsUpdate) { - final AndroidPackage sourcePkg = + final PackageParser.Package sourcePkg = mPackageManagerInt.getPackage(bp.getSourcePackageName()); - final PackageSetting sourcePs = - (PackageSetting) mPackageManagerInt.getPackageSetting( - bp.getSourcePackageName()); synchronized (mLock) { - if (sourcePkg != null && sourcePs != null) { + if (sourcePkg != null && sourcePkg.mExtras != null) { + final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras; if (bp.getSourcePackageSetting() == null) { bp.setSourcePackageSetting(sourcePs); } @@ -4035,28 +4070,24 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } - private static String getVolumeUuidForPackage(AndroidPackage pkg) { + private static String getVolumeUuidForPackage(PackageParser.Package pkg) { if (pkg == null) { return StorageManager.UUID_PRIVATE_INTERNAL; } if (pkg.isExternal()) { - if (TextUtils.isEmpty(pkg.getVolumeUuid())) { + if (TextUtils.isEmpty(pkg.volumeUuid)) { return StorageManager.UUID_PRIMARY_PHYSICAL; } else { - return pkg.getVolumeUuid(); + return pkg.volumeUuid; } } else { return StorageManager.UUID_PRIVATE_INTERNAL; } } - private static boolean hasPermission(AndroidPackage pkg, String permName) { - if (pkg.getPermissions() == null) { - return false; - } - - for (int i = pkg.getPermissions().size() - 1; i >= 0; i--) { - if (pkg.getPermissions().get(i).getName().equals(permName)) { + private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) { + for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { + if (pkgInfo.permissions.get(i).info.name.equals(permName)) { return true; } } @@ -4095,39 +4126,37 @@ public class PermissionManagerService extends IPermissionManager.Stub { PermissionManagerService.this.systemReady(); } @Override - public boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg, - @UserIdInt int userId) { + public boolean isPermissionsReviewRequired(@NonNull Package pkg, @UserIdInt int userId) { return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId); } - @Override public void revokeRuntimePermissionsIfGroupChanged( - @NonNull AndroidPackage newPackage, - @NonNull AndroidPackage oldPackage, + @NonNull PackageParser.Package newPackage, + @NonNull PackageParser.Package oldPackage, @NonNull ArrayList<String> allPackageNames) { PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage, oldPackage, allPackageNames, mDefaultPermissionCallback); } @Override - public void addAllPermissions(AndroidPackage pkg, boolean chatty) { + public void addAllPermissions(Package pkg, boolean chatty) { PermissionManagerService.this.addAllPermissions(pkg, chatty); } @Override - public void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) { + public void addAllPermissionGroups(Package pkg, boolean chatty) { PermissionManagerService.this.addAllPermissionGroups(pkg, chatty); } @Override - public void removeAllPermissions(AndroidPackage pkg, boolean chatty) { + public void removeAllPermissions(Package pkg, boolean chatty) { PermissionManagerService.this.removeAllPermissions(pkg, chatty); } @Override - public void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds, + public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, String[] grantedPermissions, int callingUid) { PermissionManagerService.this.grantRequestedRuntimePermissions( pkg, userIds, grantedPermissions, callingUid, mDefaultPermissionCallback); } @Override - public void setWhitelistedRestrictedPermissions(@NonNull AndroidPackage pkg, + public void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg, @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid, @PackageManager.PermissionWhitelistFlags int flags) { for (int userId : userIds) { @@ -4142,7 +4171,13 @@ public class PermissionManagerService extends IPermissionManager.Stub { packageName, permissions, flags, userId); } @Override - public void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) { + public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg, + int callingUid) { + PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked( + pkg, callingUid, mDefaultPermissionCallback); + } + @Override + public void updatePermissions(@NonNull String packageName, @Nullable Package pkg) { PermissionManagerService.this .updatePermissions(packageName, pkg, mDefaultPermissionCallback); } @@ -4152,13 +4187,13 @@ public class PermissionManagerService extends IPermissionManager.Stub { .updateAllPermissions(volumeUuid, sdkUpdated, mDefaultPermissionCallback); } @Override - public void resetRuntimePermissions(AndroidPackage pkg, int userId) { + public void resetRuntimePermissions(Package pkg, int userId) { PermissionManagerService.this.resetRuntimePermissionsInternal(pkg, userId); } @Override public void resetAllRuntimePermissions(final int userId) { mPackageManagerInt.forEachPackage( - (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId)); + (PackageParser.Package pkg) -> resetRuntimePermissionsInternal(pkg, userId)); } @Override public String[] getAppOpPermissionPackages(String permName, int callingUid) { @@ -4204,9 +4239,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { for (int i = 0; i < numTotalPermissions; i++) { BasePermission bp = mSettings.mPermissions.valueAt(i); - if (bp.perm != null && bp.protectionLevel == protectionLevel) { - matchingPermissions.add( - PackageInfoUtils.generatePermissionInfo(bp.perm, 0)); + if (bp.perm != null && bp.perm.info != null + && bp.protectionLevel == protectionLevel) { + matchingPermissions.add(bp.perm.info); } } } @@ -4423,12 +4458,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { StorageManager.UUID_PRIVATE_INTERNAL, true, mDefaultPermissionCallback); } } - - @Override - public int computeRuntimePermissionAppOpMode(int uid, @NonNull String permissionName) { - return PermissionManagerService.this.computeRuntimePermissionAppOpMode(uid, - permissionName); - } } private static final class OnPermissionChangeListeners extends Handler { diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java index 752c2dc15d52..04ec5ba04bb6 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java @@ -21,8 +21,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.pm.PackageManager; +import android.content.pm.PackageParser; import android.content.pm.PermissionInfo; -import android.content.pm.parsing.AndroidPackage; import android.permission.PermissionManagerInternal; import java.util.ArrayList; @@ -173,14 +173,16 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager public abstract void systemReady(); - public abstract boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg, + public abstract boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg, @UserIdInt int userId); + public abstract void grantRuntimePermissionsGrantedToDisabledPackage( + @NonNull PackageParser.Package pkg, int callingUid); public abstract void grantRequestedRuntimePermissions( - @NonNull AndroidPackage pkg, @NonNull int[] userIds, + @NonNull PackageParser.Package pkg, @NonNull int[] userIds, @NonNull String[] grantedPermissions, int callingUid); public abstract void setWhitelistedRestrictedPermissions( - @NonNull AndroidPackage pkg, @NonNull int[] userIds, + @NonNull PackageParser.Package pkg, @NonNull int[] userIds, @NonNull List<String> permissions, int callingUid, @PackageManager.PermissionWhitelistFlags int whitelistFlags); /** Sets the whitelisted, restricted permissions for the given package. */ @@ -202,7 +204,7 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager * @param callback Callback to call after permission changes */ public abstract void updatePermissions(@NonNull String packageName, - @Nullable AndroidPackage pkg); + @Nullable PackageParser.Package pkg); /** * Update all permissions for all apps. @@ -222,7 +224,7 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager * Resets any user permission state changes (eg. permissions and flags) of all * packages installed for the given user. * - * @see #resetRuntimePermissions(AndroidPackage, int) + * @see #resetRuntimePermissions(android.content.pm.PackageParser.Package, int) */ public abstract void resetAllRuntimePermissions(@UserIdInt int userId); @@ -230,7 +232,7 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager * Resets any user permission state changes (eg. permissions and flags) of the * specified package for the given user. */ - public abstract void resetRuntimePermissions(@NonNull AndroidPackage pkg, + public abstract void resetRuntimePermissions(@NonNull PackageParser.Package pkg, @UserIdInt int userId); /** @@ -243,8 +245,8 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager * @param allPackageNames All packages */ public abstract void revokeRuntimePermissionsIfGroupChanged( - @NonNull AndroidPackage newPackage, - @NonNull AndroidPackage oldPackage, + @NonNull PackageParser.Package newPackage, + @NonNull PackageParser.Package oldPackage, @NonNull ArrayList<String> allPackageNames); /** @@ -253,9 +255,9 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager * NOTE: argument {@code groupTEMP} is temporary until mPermissionGroups is moved to * the permission settings. */ - public abstract void addAllPermissions(@NonNull AndroidPackage pkg, boolean chatty); - public abstract void addAllPermissionGroups(@NonNull AndroidPackage pkg, boolean chatty); - public abstract void removeAllPermissions(@NonNull AndroidPackage pkg, boolean chatty); + public abstract void addAllPermissions(@NonNull PackageParser.Package pkg, boolean chatty); + public abstract void addAllPermissionGroups(@NonNull PackageParser.Package pkg, boolean chatty); + public abstract void removeAllPermissions(@NonNull PackageParser.Package pkg, boolean chatty); /** Retrieve the packages that have requested the given app op permission */ public abstract @Nullable String[] getAppOpPermissionPackages( @@ -443,13 +445,4 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager /** Called when a new user has been created. */ public abstract void onNewUserCreated(@UserIdInt int userId); - - /** - * Compute an app op mode based on its runtime permission state. - * - * @param uid the uid for the app op - * @param permissionName the permission name for the app op - * @return the computed mode - */ - public abstract int computeRuntimePermissionAppOpMode(int uid, @NonNull String permissionName); } diff --git a/services/core/java/com/android/server/pm/permission/PermissionSettings.java b/services/core/java/com/android/server/pm/permission/PermissionSettings.java index 254b720c57a0..3d8cf2ddc2cc 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionSettings.java +++ b/services/core/java/com/android/server/pm/permission/PermissionSettings.java @@ -18,7 +18,7 @@ package com.android.server.pm.permission; import android.annotation.NonNull; import android.annotation.Nullable; -import android.content.pm.parsing.ComponentParseUtils; +import android.content.pm.PackageParser; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; @@ -65,8 +65,8 @@ public class PermissionSettings { * name to permission group object. */ @GuardedBy("mLock") - final ArrayMap<String, ComponentParseUtils.ParsedPermissionGroup> mPermissionGroups = - new ArrayMap<>(); + final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = + new ArrayMap<String, PackageParser.PermissionGroup>(); /** * Set of packages that request a particular app op. The mapping is from permission diff --git a/services/core/java/com/android/server/pm/permission/PermissionsState.java b/services/core/java/com/android/server/pm/permission/PermissionsState.java index a78f5c4202f0..505a0e22eac4 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionsState.java +++ b/services/core/java/com/android/server/pm/permission/PermissionsState.java @@ -23,7 +23,6 @@ import android.util.ArraySet; import android.util.SparseArray; import android.util.SparseBooleanArray; -import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ArrayUtils; import java.util.ArrayList; @@ -31,6 +30,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; +import com.android.internal.annotations.GuardedBy; /** * This class encapsulates the permissions for a package or a shared user. diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java index 2f667133d64f..f3826e9ee4c9 100644 --- a/services/core/java/com/android/server/policy/PermissionPolicyService.java +++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java @@ -37,8 +37,8 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManagerInternal.PackageListObserver; +import android.content.pm.PackageParser; import android.content.pm.PermissionInfo; -import android.content.pm.parsing.AndroidPackage; import android.os.Build; import android.os.Process; import android.os.RemoteException; @@ -356,10 +356,10 @@ public final class PermissionPolicyService extends SystemService { pkg.sharedUserId, userId); if (sharedPkgNames != null) { for (String sharedPkgName : sharedPkgNames) { - final AndroidPackage sharedPkg = packageManagerInternal + final PackageParser.Package sharedPkg = packageManagerInternal .getPackage(sharedPkgName); if (sharedPkg != null) { - synchroniser.addPackage(sharedPkg.getPackageName()); + synchroniser.addPackage(sharedPkg.packageName); } } } @@ -376,8 +376,7 @@ public final class PermissionPolicyService extends SystemService { PackageManagerInternal.class); final PermissionToOpSynchroniser synchronizer = new PermissionToOpSynchroniser( getUserContext(getContext(), UserHandle.of(userId))); - packageManagerInternal.forEachPackage( - (pkg) -> synchronizer.addPackage(pkg.getPackageName())); + packageManagerInternal.forEachPackage((pkg) -> synchronizer.addPackage(pkg.packageName)); synchronizer.syncPackages(); } diff --git a/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java b/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java index 712012d9e621..017c684e7449 100644 --- a/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java +++ b/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java @@ -21,6 +21,7 @@ import android.annotation.UserIdInt; import android.app.role.RoleManager; import android.content.ComponentName; import android.content.Context; +import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.ResolveInfo; @@ -34,9 +35,9 @@ import com.android.internal.util.CollectionUtils; import com.android.server.LocalServices; import com.android.server.role.RoleManagerService; -import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; /** * Logic to retrieve the various legacy(pre-Q) equivalents of role holders. @@ -125,9 +126,21 @@ public class LegacyRoleResolutionPolicy implements RoleManagerService.RoleHolder } case RoleManager.ROLE_HOME: { PackageManager packageManager = mContext.getPackageManager(); - List<ResolveInfo> resolveInfos = new ArrayList<>(); - ComponentName componentName = packageManager.getHomeActivities(resolveInfos); - String packageName = componentName != null ? componentName.getPackageName() : null; + String packageName; + if (packageManager.isDeviceUpgrading()) { + ResolveInfo resolveInfo = packageManager.resolveActivityAsUser( + new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME), + PackageManager.MATCH_DEFAULT_ONLY + | PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); + packageName = resolveInfo != null && resolveInfo.activityInfo != null + ? resolveInfo.activityInfo.packageName : null; + if (packageName != null && isSettingsApplication(packageName, userId)) { + packageName = null; + } + } else { + packageName = null; + } return CollectionUtils.singletonOrEmpty(packageName); } case RoleManager.ROLE_EMERGENCY: { @@ -142,4 +155,16 @@ public class LegacyRoleResolutionPolicy implements RoleManagerService.RoleHolder } } } + + private boolean isSettingsApplication(@NonNull String packageName, @UserIdInt int userId) { + PackageManager packageManager = mContext.getPackageManager(); + ResolveInfo resolveInfo = packageManager.resolveActivityAsUser(new Intent( + Settings.ACTION_SETTINGS), PackageManager.MATCH_DEFAULT_ONLY + | PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); + if (resolveInfo == null || resolveInfo.activityInfo == null) { + return false; + } + return Objects.equals(packageName, resolveInfo.activityInfo.packageName); + } } diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java index 06876352da0b..282fed8434ed 100644 --- a/services/core/java/com/android/server/role/RoleManagerService.java +++ b/services/core/java/com/android/server/role/RoleManagerService.java @@ -269,6 +269,7 @@ public class RoleManagerService extends SystemService implements RoleUserState.C maybeMigrateRole(RoleManager.ROLE_DIALER, userId); maybeMigrateRole(RoleManager.ROLE_SMS, userId); maybeMigrateRole(RoleManager.ROLE_EMERGENCY, userId); + maybeMigrateRole(RoleManager.ROLE_HOME, userId); // Some package state has changed, so grant default roles again. Slog.i(LOG_TAG, "Granting default roles..."); @@ -308,12 +309,12 @@ public class RoleManagerService extends SystemService implements RoleUserState.C ByteArrayOutputStream out = new ByteArrayOutputStream(); pm.forEachInstalledPackage(FunctionalUtils.uncheckExceptions(pkg -> { - out.write(pkg.getPackageName().getBytes()); + out.write(pkg.packageName.getBytes()); out.write(BitUtils.toBytes(pkg.getLongVersionCode())); - out.write(pm.getApplicationEnabledState(pkg.getPackageName(), userId)); + out.write(pm.getApplicationEnabledState(pkg.packageName, userId)); ArraySet<String> enabledComponents = - pm.getEnabledComponents(pkg.getPackageName(), userId); + pm.getEnabledComponents(pkg.packageName, userId); int numComponents = CollectionUtils.size(enabledComponents); out.write(numComponents); for (int i = 0; i < numComponents; i++) { @@ -321,12 +322,12 @@ public class RoleManagerService extends SystemService implements RoleUserState.C } ArraySet<String> disabledComponents = - pm.getDisabledComponents(pkg.getPackageName(), userId); + pm.getDisabledComponents(pkg.packageName, userId); numComponents = CollectionUtils.size(disabledComponents); for (int i = 0; i < numComponents; i++) { out.write(disabledComponents.valueAt(i).getBytes()); } - for (Signature signature : pkg.getSigningDetails().signatures) { + for (Signature signature : pkg.mSigningDetails.signatures) { out.write(signature.toByteArray()); } }), userId); diff --git a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java index a9f44b9bbeb1..1123f70b4334 100644 --- a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java +++ b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java @@ -51,7 +51,7 @@ public class AppDataRollbackHelper { * {@code userIds}. Updates said {@code packageRollbackInfo} with the inodes of the CE user data * snapshot folders. */ - @GuardedBy("rollback.getLock") + @GuardedBy("rollback.mLock") // TODO(b/136241838): Move into Rollback and synchronize there. public void snapshotAppData( int snapshotId, PackageRollbackInfo packageRollbackInfo, int[] userIds) { @@ -88,7 +88,7 @@ public class AppDataRollbackHelper { * to {@code packageRollbackInfo} are restricted to the removal or addition of {@code * userId} to the list of pending backups or restores. */ - @GuardedBy("rollback.getLock") + @GuardedBy("rollback.mLock") // TODO(b/136241838): Move into Rollback and synchronize there. public boolean restoreAppData(int rollbackId, PackageRollbackInfo packageRollbackInfo, int userId, int appId, String seInfo) { @@ -133,7 +133,7 @@ public class AppDataRollbackHelper { * Deletes an app data snapshot with a given {@code rollbackId} for a specified package * {@code packageName} for a given {@code user}. */ - @GuardedBy("rollback.getLock") + @GuardedBy("rollback.mLock") // TODO(b/136241838): Move into Rollback and synchronize there. public void destroyAppDataSnapshot(int rollbackId, PackageRollbackInfo packageRollbackInfo, int user) { @@ -162,7 +162,7 @@ public class AppDataRollbackHelper { * * @return true if any backups or restores were found for the userId */ - @GuardedBy("rollback.getLock") + @GuardedBy("rollback.mLock") boolean commitPendingBackupAndRestoreForUser(int userId, Rollback rollback) { boolean foundBackupOrRestore = false; for (PackageRollbackInfo info : rollback.info.getPackages()) { diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java index 78b8b2e78772..1cf07cb47f2f 100644 --- a/services/core/java/com/android/server/rollback/Rollback.java +++ b/services/core/java/com/android/server/rollback/Rollback.java @@ -40,6 +40,7 @@ import android.util.SparseLongArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ArrayUtils; +import com.android.internal.util.IndentingPrintWriter; import java.io.File; import java.io.IOException; @@ -53,11 +54,6 @@ import java.util.List; /** * Information about a rollback available for a set of atomically installed packages. - * - * <p>When accessing the state of a Rollback object, the caller is responsible for synchronization. - * The lock object provided by {@link #getLock} should be acquired when accessing any of the mutable - * state of a Rollback, including from the {@link RollbackInfo} and any of the - * {@link PackageRollbackInfo} objects held within. */ class Rollback { @@ -101,11 +97,7 @@ class Rollback { /** * The rollback info for this rollback. - * - * <p>Any access to this field that touches any mutable state should be synchronized on - * {@link #getLock}. */ - @GuardedBy("getLock") public final RollbackInfo info; /** @@ -146,8 +138,6 @@ class Rollback { /** * Lock object to guard all access to Rollback state. - * - * @see #getLock */ private final Object mLock = new Object(); @@ -185,23 +175,8 @@ class Rollback { } /** - * Returns a lock object that should be acquired before accessing any Rollback state from - * {@link RollbackManagerServiceImpl}. - * - * <p>Note that while holding this lock, the lock for {@link RollbackManagerServiceImpl} should - * not be acquired (but it is ok to acquire this lock while already holding the lock for that - * class). - */ - // TODO(b/136241838): Move rollback functionality into this class and synchronize on the lock - // internally. Remove this method once this has been done for all cases. - Object getLock() { - return mLock; - } - - /** * Whether the rollback is for rollback of a staged install. */ - @GuardedBy("getLock") boolean isStaged() { return info.isStaged(); } @@ -216,17 +191,20 @@ class Rollback { /** * Returns the time when the upgrade occurred, for purposes of expiring rollback data. */ - @GuardedBy("getLock") Instant getTimestamp() { - return mTimestamp; + synchronized (mLock) { + return mTimestamp; + } } /** * Sets the time at which upgrade occurred. */ - @GuardedBy("getLock") void setTimestamp(Instant timestamp) { - mTimestamp = timestamp; + synchronized (mLock) { + mTimestamp = timestamp; + RollbackStore.saveRollback(this); + } } /** @@ -240,33 +218,46 @@ class Rollback { /** * Returns true if the rollback is in the ENABLING state. */ - @GuardedBy("getLock") boolean isEnabling() { - return mState == ROLLBACK_STATE_ENABLING; + synchronized (mLock) { + return mState == ROLLBACK_STATE_ENABLING; + } } /** * Returns true if the rollback is in the AVAILABLE state. */ - @GuardedBy("getLock") boolean isAvailable() { - return mState == ROLLBACK_STATE_AVAILABLE; + synchronized (mLock) { + return mState == ROLLBACK_STATE_AVAILABLE; + } } /** * Returns true if the rollback is in the COMMITTED state. */ - @GuardedBy("getLock") boolean isCommitted() { - return mState == ROLLBACK_STATE_COMMITTED; + synchronized (mLock) { + return mState == ROLLBACK_STATE_COMMITTED; + } } /** * Returns true if the rollback is in the DELETED state. */ - @GuardedBy("getLock") boolean isDeleted() { - return mState == ROLLBACK_STATE_DELETED; + synchronized (mLock) { + return mState == ROLLBACK_STATE_DELETED; + } + } + + /** + * Saves this rollback to persistent storage. + */ + void saveRollback() { + synchronized (mLock) { + RollbackStore.saveRollback(this); + } } /** @@ -274,7 +265,6 @@ class Rollback { * * @return boolean True if the rollback was enabled successfully for the specified package. */ - @GuardedBy("getLock") boolean enableForPackage(String packageName, long newVersion, long installedVersion, boolean isApex, String sourceDir, String[] splitSourceDirs) { try { @@ -295,7 +285,9 @@ class Rollback { new IntArray() /* pendingBackups */, new ArrayList<>() /* pendingRestores */, isApex, new IntArray(), new SparseLongArray() /* ceSnapshotInodes */); - info.getPackages().add(packageRollbackInfo); + synchronized (mLock) { + info.getPackages().add(packageRollbackInfo); + } return true; } @@ -304,19 +296,33 @@ class Rollback { * Snapshots user data for the provided package and user ids. Does nothing if this rollback is * not in the ENABLING state. */ - @GuardedBy("getLock") void snapshotUserData(String packageName, int[] userIds, AppDataRollbackHelper dataHelper) { - if (!isEnabling()) { - return; - } + synchronized (mLock) { + if (!isEnabling()) { + return; + } + + for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { + if (pkgRollbackInfo.getPackageName().equals(packageName)) { + dataHelper.snapshotAppData(info.getRollbackId(), pkgRollbackInfo, userIds); - for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { - if (pkgRollbackInfo.getPackageName().equals(packageName)) { - dataHelper.snapshotAppData(info.getRollbackId(), pkgRollbackInfo, userIds); + RollbackStore.saveRollback(this); + pkgRollbackInfo.getSnapshottedUsers().addAll(IntArray.wrap(userIds)); + break; + } + } + } + } + /** + * Commits the pending backups and restores for a given {@code userId}. If this rollback has a + * pending backup, it is updated with a mapping from {@code userId} to inode of the CE user data + * snapshot. + */ + void commitPendingBackupAndRestoreForUser(int userId, AppDataRollbackHelper dataHelper) { + synchronized (mLock) { + if (dataHelper.commitPendingBackupAndRestoreForUser(userId, this)) { RollbackStore.saveRollback(this); - pkgRollbackInfo.getSnapshottedUsers().addAll(IntArray.wrap(userIds)); - break; } } } @@ -326,168 +332,170 @@ class Rollback { * current time and saves the rollback. Does nothing if this rollback is already in the * DELETED state. */ - @GuardedBy("getLock") void makeAvailable() { - if (isDeleted()) { - Slog.w(TAG, "Cannot make deleted rollback available."); - return; + synchronized (mLock) { + if (isDeleted()) { + Slog.w(TAG, "Cannot make deleted rollback available."); + return; + } + mState = ROLLBACK_STATE_AVAILABLE; + mTimestamp = Instant.now(); + RollbackStore.saveRollback(this); } - mState = ROLLBACK_STATE_AVAILABLE; - mTimestamp = Instant.now(); - RollbackStore.saveRollback(this); } /** * Commits the rollback. */ - @GuardedBy("getLock") void commit(final Context context, List<VersionedPackage> causePackages, String callerPackageName, IntentSender statusReceiver) { - - if (!isAvailable()) { - sendFailure(context, statusReceiver, - RollbackManager.STATUS_FAILURE_ROLLBACK_UNAVAILABLE, - "Rollback unavailable"); - return; - } - - // Get a context to use to install the downgraded version of the package. - Context pkgContext; - try { - pkgContext = context.createPackageContext(callerPackageName, 0); - } catch (PackageManager.NameNotFoundException e) { - sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE, - "Invalid callerPackageName"); - return; - } - - PackageManager pm = pkgContext.getPackageManager(); - try { - PackageInstaller packageInstaller = pm.getPackageInstaller(); - PackageInstaller.SessionParams parentParams = new PackageInstaller.SessionParams( - PackageInstaller.SessionParams.MODE_FULL_INSTALL); - parentParams.setRequestDowngrade(true); - parentParams.setMultiPackage(); - if (isStaged()) { - parentParams.setStaged(); + synchronized (mLock) { + if (!isAvailable()) { + sendFailure(context, statusReceiver, + RollbackManager.STATUS_FAILURE_ROLLBACK_UNAVAILABLE, + "Rollback unavailable"); + return; } - int parentSessionId = packageInstaller.createSession(parentParams); - PackageInstaller.Session parentSession = packageInstaller.openSession( - parentSessionId); + // Get a context to use to install the downgraded version of the package. + Context pkgContext; + try { + pkgContext = context.createPackageContext(callerPackageName, 0); + } catch (PackageManager.NameNotFoundException e) { + sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE, + "Invalid callerPackageName"); + return; + } - for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { - PackageInstaller.SessionParams params = new PackageInstaller.SessionParams( + PackageManager pm = pkgContext.getPackageManager(); + try { + PackageInstaller packageInstaller = pm.getPackageInstaller(); + PackageInstaller.SessionParams parentParams = new PackageInstaller.SessionParams( PackageInstaller.SessionParams.MODE_FULL_INSTALL); - // TODO: We can't get the installerPackageName for apex - // (b/123920130). Is it okay to ignore the installer package - // for apex? - if (!pkgRollbackInfo.isApex()) { - String installerPackageName = - pm.getInstallerPackageName(pkgRollbackInfo.getPackageName()); - if (installerPackageName != null) { - params.setInstallerPackageName(installerPackageName); - } - } - params.setRequestDowngrade(true); - params.setRequiredInstalledVersionCode( - pkgRollbackInfo.getVersionRolledBackFrom().getLongVersionCode()); + parentParams.setRequestDowngrade(true); + parentParams.setMultiPackage(); if (isStaged()) { - params.setStaged(); - } - if (pkgRollbackInfo.isApex()) { - params.setInstallAsApex(); - } - int sessionId = packageInstaller.createSession(params); - PackageInstaller.Session session = packageInstaller.openSession(sessionId); - File[] packageCodePaths = RollbackStore.getPackageCodePaths( - this, pkgRollbackInfo.getPackageName()); - if (packageCodePaths == null) { - sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE, - "Backup copy of package inaccessible"); - return; + parentParams.setStaged(); } - for (File packageCodePath : packageCodePaths) { - try (ParcelFileDescriptor fd = ParcelFileDescriptor.open(packageCodePath, - ParcelFileDescriptor.MODE_READ_ONLY)) { - final long token = Binder.clearCallingIdentity(); - try { - session.write(packageCodePath.getName(), 0, - packageCodePath.length(), - fd); - } finally { - Binder.restoreCallingIdentity(token); + int parentSessionId = packageInstaller.createSession(parentParams); + PackageInstaller.Session parentSession = packageInstaller.openSession( + parentSessionId); + + for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { + PackageInstaller.SessionParams params = new PackageInstaller.SessionParams( + PackageInstaller.SessionParams.MODE_FULL_INSTALL); + // TODO: We can't get the installerPackageName for apex + // (b/123920130). Is it okay to ignore the installer package + // for apex? + if (!pkgRollbackInfo.isApex()) { + String installerPackageName = + pm.getInstallerPackageName(pkgRollbackInfo.getPackageName()); + if (installerPackageName != null) { + params.setInstallerPackageName(installerPackageName); } } - } - parentSession.addChildSessionId(sessionId); - } + params.setRequestDowngrade(true); + params.setRequiredInstalledVersionCode( + pkgRollbackInfo.getVersionRolledBackFrom().getLongVersionCode()); + if (isStaged()) { + params.setStaged(); + } + if (pkgRollbackInfo.isApex()) { + params.setInstallAsApex(); + } + int sessionId = packageInstaller.createSession(params); + PackageInstaller.Session session = packageInstaller.openSession(sessionId); + File[] packageCodePaths = RollbackStore.getPackageCodePaths( + this, pkgRollbackInfo.getPackageName()); + if (packageCodePaths == null) { + sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE, + "Backup copy of package inaccessible"); + return; + } - final LocalIntentReceiver receiver = new LocalIntentReceiver( - (Intent result) -> { - int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, - PackageInstaller.STATUS_FAILURE); - if (status != PackageInstaller.STATUS_SUCCESS) { - // Committing the rollback failed, but we still have all the info we - // need to try rolling back again, so restore the rollback state to how - // it was before we tried committing. - // TODO: Should we just kill this rollback if commit failed? - // Why would we expect commit not to fail again? - // TODO: Could this cause a rollback to be resurrected - // if it should otherwise have expired by now? - synchronized (mLock) { - mState = ROLLBACK_STATE_AVAILABLE; - mRestoreUserDataInProgress = false; + for (File packageCodePath : packageCodePaths) { + try (ParcelFileDescriptor fd = ParcelFileDescriptor.open(packageCodePath, + ParcelFileDescriptor.MODE_READ_ONLY)) { + final long token = Binder.clearCallingIdentity(); + try { + session.write(packageCodePath.getName(), 0, + packageCodePath.length(), + fd); + } finally { + Binder.restoreCallingIdentity(token); } - sendFailure(context, statusReceiver, - RollbackManager.STATUS_FAILURE_INSTALL, - "Rollback downgrade install failed: " - + result.getStringExtra( - PackageInstaller.EXTRA_STATUS_MESSAGE)); - return; } + } + parentSession.addChildSessionId(sessionId); + } - synchronized (mLock) { - if (!isStaged()) { - // All calls to restoreUserData should have - // completed by now for a non-staged install. - mRestoreUserDataInProgress = false; + final LocalIntentReceiver receiver = new LocalIntentReceiver( + (Intent result) -> { + int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, + PackageInstaller.STATUS_FAILURE); + if (status != PackageInstaller.STATUS_SUCCESS) { + // Committing the rollback failed, but we still have all the info we + // need to try rolling back again, so restore the rollback state to + // how it was before we tried committing. + // TODO: Should we just kill this rollback if commit failed? + // Why would we expect commit not to fail again? + // TODO: Could this cause a rollback to be resurrected + // if it should otherwise have expired by now? + synchronized (mLock) { + mState = ROLLBACK_STATE_AVAILABLE; + mRestoreUserDataInProgress = false; + } + sendFailure(context, statusReceiver, + RollbackManager.STATUS_FAILURE_INSTALL, + "Rollback downgrade install failed: " + + result.getStringExtra( + PackageInstaller.EXTRA_STATUS_MESSAGE)); + return; } - info.setCommittedSessionId(parentSessionId); - info.getCausePackages().addAll(causePackages); - RollbackStore.deletePackageCodePaths(this); - RollbackStore.saveRollback(this); - } + synchronized (mLock) { + if (!isStaged()) { + // All calls to restoreUserData should have + // completed by now for a non-staged install. + mRestoreUserDataInProgress = false; + } + + info.setCommittedSessionId(parentSessionId); + info.getCausePackages().addAll(causePackages); + RollbackStore.deletePackageCodePaths(this); + RollbackStore.saveRollback(this); + } - // Send success. - try { - final Intent fillIn = new Intent(); - fillIn.putExtra( - RollbackManager.EXTRA_STATUS, RollbackManager.STATUS_SUCCESS); - statusReceiver.sendIntent(context, 0, fillIn, null, null); - } catch (IntentSender.SendIntentException e) { - // Nowhere to send the result back to, so don't bother. - } + // Send success. + try { + final Intent fillIn = new Intent(); + fillIn.putExtra( + RollbackManager.EXTRA_STATUS, + RollbackManager.STATUS_SUCCESS); + statusReceiver.sendIntent(context, 0, fillIn, null, null); + } catch (IntentSender.SendIntentException e) { + // Nowhere to send the result back to, so don't bother. + } - Intent broadcast = new Intent(Intent.ACTION_ROLLBACK_COMMITTED); + Intent broadcast = new Intent(Intent.ACTION_ROLLBACK_COMMITTED); - for (UserInfo userInfo : UserManager.get(context).getUsers(true)) { - context.sendBroadcastAsUser(broadcast, - userInfo.getUserHandle(), - Manifest.permission.MANAGE_ROLLBACKS); + for (UserInfo userInfo : UserManager.get(context).getUsers(true)) { + context.sendBroadcastAsUser(broadcast, + userInfo.getUserHandle(), + Manifest.permission.MANAGE_ROLLBACKS); + } } - } - ); - - mState = ROLLBACK_STATE_COMMITTED; - mRestoreUserDataInProgress = true; - parentSession.commit(receiver.getIntentSender()); - } catch (IOException e) { - Slog.e(TAG, "Rollback failed", e); - sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE, - "IOException: " + e.toString()); + ); + + mState = ROLLBACK_STATE_COMMITTED; + mRestoreUserDataInProgress = true; + parentSession.commit(receiver.getIntentSender()); + } catch (IOException e) { + Slog.e(TAG, "Rollback failed", e); + sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE, + "IOException: " + e.toString()); + } } } @@ -498,138 +506,156 @@ class Rollback { * @return boolean True if this rollback has a restore in progress and contains the specified * package. */ - @GuardedBy("getLock") boolean restoreUserDataForPackageIfInProgress(String packageName, int[] userIds, int appId, String seInfo, AppDataRollbackHelper dataHelper) { - if (!isRestoreUserDataInProgress()) { - return false; - } + synchronized (mLock) { + if (!isRestoreUserDataInProgress()) { + return false; + } - boolean foundPackage = false; - for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { - if (pkgRollbackInfo.getPackageName().equals(packageName)) { - foundPackage = true; - boolean changedRollback = false; - for (int userId : userIds) { - changedRollback |= dataHelper.restoreAppData( - info.getRollbackId(), pkgRollbackInfo, userId, appId, seInfo); - } - // We've updated metadata about this rollback, so save it to flash. - if (changedRollback) { - RollbackStore.saveRollback(this); + boolean foundPackage = false; + for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { + if (pkgRollbackInfo.getPackageName().equals(packageName)) { + foundPackage = true; + boolean changedRollback = false; + for (int userId : userIds) { + changedRollback |= dataHelper.restoreAppData( + info.getRollbackId(), pkgRollbackInfo, userId, appId, seInfo); + } + // We've updated metadata about this rollback, so save it to flash. + if (changedRollback) { + RollbackStore.saveRollback(this); + } + break; } - break; } + return foundPackage; } - return foundPackage; } /** * Deletes app data snapshots associated with this rollback, and moves to the DELETED state. */ - @GuardedBy("getLock") void delete(AppDataRollbackHelper dataHelper) { - for (PackageRollbackInfo pkgInfo : info.getPackages()) { - IntArray snapshottedUsers = pkgInfo.getSnapshottedUsers(); - for (int i = 0; i < snapshottedUsers.size(); i++) { - // Destroy app data snapshot. - int userId = snapshottedUsers.get(i); - - dataHelper.destroyAppDataSnapshot(info.getRollbackId(), pkgInfo, userId); + synchronized (mLock) { + for (PackageRollbackInfo pkgInfo : info.getPackages()) { + IntArray snapshottedUsers = pkgInfo.getSnapshottedUsers(); + for (int i = 0; i < snapshottedUsers.size(); i++) { + // Destroy app data snapshot. + int userId = snapshottedUsers.get(i); + + dataHelper.destroyAppDataSnapshot(info.getRollbackId(), pkgInfo, userId); + } } - } - RollbackStore.deleteRollback(this); - mState = ROLLBACK_STATE_DELETED; + RollbackStore.deleteRollback(this); + mState = ROLLBACK_STATE_DELETED; + } } /** * Returns the id of the post-reboot apk session for a staged install, if any. */ - @GuardedBy("getLock") int getApkSessionId() { - return mApkSessionId; + synchronized (mLock) { + return mApkSessionId; + } } /** * Sets the id of the post-reboot apk session for a staged install. */ - @GuardedBy("getLock") void setApkSessionId(int apkSessionId) { - mApkSessionId = apkSessionId; + synchronized (mLock) { + mApkSessionId = apkSessionId; + RollbackStore.saveRollback(this); + } } /** * Returns true if we are expecting the package manager to call restoreUserData for this * rollback because it has just been committed but the rollback has not yet been fully applied. */ - @GuardedBy("getLock") boolean isRestoreUserDataInProgress() { - return mRestoreUserDataInProgress; + synchronized (mLock) { + return mRestoreUserDataInProgress; + } } /** * Sets whether we are expecting the package manager to call restoreUserData for this * rollback because it has just been committed but the rollback has not yet been fully applied. */ - @GuardedBy("getLock") void setRestoreUserDataInProgress(boolean restoreUserDataInProgress) { - mRestoreUserDataInProgress = restoreUserDataInProgress; + synchronized (mLock) { + mRestoreUserDataInProgress = restoreUserDataInProgress; + RollbackStore.saveRollback(this); + } } /** * Returns true if this rollback includes the package with the provided {@code packageName}. */ - @GuardedBy("getLock") boolean includesPackage(String packageName) { - for (PackageRollbackInfo packageRollbackInfo : info.getPackages()) { - if (packageRollbackInfo.getPackageName().equals(packageName)) { - return true; + synchronized (mLock) { + for (PackageRollbackInfo packageRollbackInfo : info.getPackages()) { + if (packageRollbackInfo.getPackageName().equals(packageName)) { + return true; + } } + return false; } - return false; } /** * Returns true if this rollback includes the package with the provided {@code packageName} * with a <i>version rolled back from</i> that is not {@code versionCode}. */ - @GuardedBy("getLock") boolean includesPackageWithDifferentVersion(String packageName, long versionCode) { - for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { - if (pkgRollbackInfo.getPackageName().equals(packageName) - && pkgRollbackInfo.getVersionRolledBackFrom().getLongVersionCode() - != versionCode) { - return true; + synchronized (mLock) { + for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { + if (pkgRollbackInfo.getPackageName().equals(packageName) + && pkgRollbackInfo.getVersionRolledBackFrom().getLongVersionCode() + != versionCode) { + return true; + } } + return false; } - return false; } /** * Returns a list containing the names of all the packages included in this rollback. */ - @GuardedBy("getLock") List<String> getPackageNames() { - List<String> result = new ArrayList<>(); - for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { - result.add(pkgRollbackInfo.getPackageName()); + synchronized (mLock) { + List<String> result = new ArrayList<>(); + for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { + result.add(pkgRollbackInfo.getPackageName()); + } + return result; } - return result; } /** * Returns a list containing the names of all the apex packages included in this rollback. */ - @GuardedBy("getLock") List<String> getApexPackageNames() { - List<String> result = new ArrayList<>(); - for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { - if (pkgRollbackInfo.isApex()) { - result.add(pkgRollbackInfo.getPackageName()); + synchronized (mLock) { + List<String> result = new ArrayList<>(); + for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { + if (pkgRollbackInfo.isApex()) { + result.add(pkgRollbackInfo.getPackageName()); + } } + return result; + } + } + + int getPackageCount() { + synchronized (mLock) { + return info.getPackages().size(); } - return result; } static String rollbackStateToString(@RollbackState int state) { @@ -651,8 +677,39 @@ class Rollback { throw new ParseException("Invalid rollback state: " + state, 0); } - @GuardedBy("getLock") String getStateAsString() { - return rollbackStateToString(mState); + synchronized (mLock) { + return rollbackStateToString(mState); + } + } + + void dump(IndentingPrintWriter ipw) { + synchronized (mLock) { + ipw.println(info.getRollbackId() + ":"); + ipw.increaseIndent(); + ipw.println("-state: " + getStateAsString()); + ipw.println("-timestamp: " + getTimestamp()); + if (getStagedSessionId() != -1) { + ipw.println("-stagedSessionId: " + getStagedSessionId()); + } + ipw.println("-packages:"); + ipw.increaseIndent(); + for (PackageRollbackInfo pkg : info.getPackages()) { + ipw.println(pkg.getPackageName() + + " " + pkg.getVersionRolledBackFrom().getLongVersionCode() + + " -> " + pkg.getVersionRolledBackTo().getLongVersionCode()); + } + ipw.decreaseIndent(); + if (isCommitted()) { + ipw.println("-causePackages:"); + ipw.increaseIndent(); + for (VersionedPackage cPkg : info.getCausePackages()) { + ipw.println(cPkg.getPackageName() + " " + cPkg.getLongVersionCode()); + } + ipw.decreaseIndent(); + ipw.println("-committedSessionId: " + info.getCommittedSessionId()); + } + ipw.decreaseIndent(); + } } } diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java index 2221dff79336..cd44f64ada4f 100644 --- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java @@ -36,7 +36,6 @@ import android.content.pm.ParceledListSlice; import android.content.pm.UserInfo; import android.content.pm.VersionedPackage; import android.content.rollback.IRollbackManager; -import android.content.rollback.PackageRollbackInfo; import android.content.rollback.RollbackInfo; import android.content.rollback.RollbackManager; import android.os.Binder; @@ -215,7 +214,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { synchronized (mLock) { for (NewRollback rollback : mNewRollbacks) { if (rollback.hasToken(token)) { - rollback.isCancelled = true; + rollback.setCancelled(); return; } } @@ -278,10 +277,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { List<RollbackInfo> rollbacks = new ArrayList<>(); for (int i = 0; i < mRollbacks.size(); ++i) { Rollback rollback = mRollbacks.get(i); - synchronized (rollback.getLock()) { - if (rollback.isAvailable()) { - rollbacks.add(rollback.info); - } + if (rollback.isAvailable()) { + rollbacks.add(rollback.info); } } return new ParceledListSlice<>(rollbacks); @@ -296,10 +293,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { List<RollbackInfo> rollbacks = new ArrayList<>(); for (int i = 0; i < mRollbacks.size(); ++i) { Rollback rollback = mRollbacks.get(i); - synchronized (rollback.getLock()) { - if (rollback.isCommitted()) { - rollbacks.add(rollback.info); - } + if (rollback.isCommitted()) { + rollbacks.add(rollback.info); } } return new ParceledListSlice<>(rollbacks); @@ -332,11 +327,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { Iterator<Rollback> iter = mRollbacks.iterator(); while (iter.hasNext()) { Rollback rollback = iter.next(); - synchronized (rollback.getLock()) { - rollback.setTimestamp( - rollback.getTimestamp().plusMillis(timeDifference)); - RollbackStore.saveRollback(rollback); - } + rollback.setTimestamp( + rollback.getTimestamp().plusMillis(timeDifference)); } } } @@ -367,9 +359,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { "Rollback unavailable"); return; } - synchronized (rollback.getLock()) { - rollback.commit(mContext, causePackages, callerPackageName, statusReceiver); - } + rollback.commit(mContext, causePackages, callerPackageName, statusReceiver); } @Override @@ -404,18 +394,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { Iterator<Rollback> iter = mRollbacks.iterator(); while (iter.hasNext()) { Rollback rollback = iter.next(); - synchronized (rollback.getLock()) { - if (rollback.includesPackage(packageName)) { - iter.remove(); - rollback.delete(mAppDataRollbackHelper); - } + if (rollback.includesPackage(packageName)) { + iter.remove(); + rollback.delete(mAppDataRollbackHelper); } } for (NewRollback newRollback : mNewRollbacks) { - synchronized (newRollback.rollback.getLock()) { - if (newRollback.rollback.includesPackage(packageName)) { - newRollback.isCancelled = true; - } + if (newRollback.rollback.includesPackage(packageName)) { + newRollback.setCancelled(); } } } @@ -448,12 +434,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { for (int i = 0; i < rollbacks.size(); i++) { Rollback rollback = rollbacks.get(i); - synchronized (rollback.getLock()) { - if (mAppDataRollbackHelper.commitPendingBackupAndRestoreForUser( - userId, rollback)) { - RollbackStore.saveRollback(rollback); - } - } + rollback.commitPendingBackupAndRestoreForUser(userId, mAppDataRollbackHelper); } latch.countDown(); @@ -489,48 +470,41 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { Set<String> apexPackageNames = new HashSet<>(); synchronized (mLock) { for (Rollback rollback : mRollbacks) { - synchronized (rollback.getLock()) { - if (rollback.isStaged()) { - if (rollback.isEnabling()) { - enabling.add(rollback); - } else if (rollback.isRestoreUserDataInProgress()) { - restoreInProgress.add(rollback); - } - - apexPackageNames.addAll(rollback.getApexPackageNames()); + if (rollback.isStaged()) { + if (rollback.isEnabling()) { + enabling.add(rollback); + } else if (rollback.isRestoreUserDataInProgress()) { + restoreInProgress.add(rollback); } + + apexPackageNames.addAll(rollback.getApexPackageNames()); } } } for (Rollback rollback : enabling) { PackageInstaller installer = mContext.getPackageManager().getPackageInstaller(); - synchronized (rollback.getLock()) { - PackageInstaller.SessionInfo session = - installer.getSessionInfo(rollback.getStagedSessionId()); - if (session == null || session.isStagedSessionFailed()) { - // TODO: Do we need to remove this from - // mRollbacks, or is it okay to leave as - // unavailable until the next reboot when it will go - // away on its own? - rollback.delete(mAppDataRollbackHelper); - } else if (session.isStagedSessionApplied()) { - makeRollbackAvailable(rollback); - } + PackageInstaller.SessionInfo session = + installer.getSessionInfo(rollback.getStagedSessionId()); + if (session == null || session.isStagedSessionFailed()) { + // TODO: Do we need to remove this from + // mRollbacks, or is it okay to leave as + // unavailable until the next reboot when it will go + // away on its own? + rollback.delete(mAppDataRollbackHelper); + } else if (session.isStagedSessionApplied()) { + makeRollbackAvailable(rollback); } } for (Rollback rollback : restoreInProgress) { PackageInstaller installer = mContext.getPackageManager().getPackageInstaller(); - synchronized (rollback.getLock()) { - PackageInstaller.SessionInfo session = - installer.getSessionInfo(rollback.getStagedSessionId()); - // TODO: What if session is null? - if (session != null) { - if (session.isStagedSessionApplied() || session.isStagedSessionFailed()) { - rollback.setRestoreUserDataInProgress(false); - RollbackStore.saveRollback(rollback); - } + PackageInstaller.SessionInfo session = + installer.getSessionInfo(rollback.getStagedSessionId()); + // TODO: What if session is null? + if (session != null) { + if (session.isStagedSessionApplied() || session.isStagedSessionFailed()) { + rollback.setRestoreUserDataInProgress(false); } } } @@ -565,14 +539,12 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { Iterator<Rollback> iter = mRollbacks.iterator(); while (iter.hasNext()) { Rollback rollback = iter.next(); - synchronized (rollback.getLock()) { - // TODO: Should we remove rollbacks in the ENABLING state here? - if ((rollback.isEnabling() || rollback.isAvailable()) - && rollback.includesPackageWithDifferentVersion(packageName, - installedVersion)) { - iter.remove(); - rollback.delete(mAppDataRollbackHelper); - } + // TODO: Should we remove rollbacks in the ENABLING state here? + if ((rollback.isEnabling() || rollback.isAvailable()) + && rollback.includesPackageWithDifferentVersion(packageName, + installedVersion)) { + iter.remove(); + rollback.delete(mAppDataRollbackHelper); } } } @@ -615,18 +587,17 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { Iterator<Rollback> iter = mRollbacks.iterator(); while (iter.hasNext()) { Rollback rollback = iter.next(); - synchronized (rollback.getLock()) { - if (!rollback.isAvailable()) { - continue; - } - if (!now.isBefore( - rollback.getTimestamp() - .plusMillis(mRollbackLifetimeDurationInMillis))) { - iter.remove(); - rollback.delete(mAppDataRollbackHelper); - } else if (oldest == null || oldest.isAfter(rollback.getTimestamp())) { - oldest = rollback.getTimestamp(); - } + if (!rollback.isAvailable()) { + continue; + } + Instant rollbackTimestamp = rollback.getTimestamp(); + if (!now.isBefore( + rollbackTimestamp + .plusMillis(mRollbackLifetimeDurationInMillis))) { + iter.remove(); + rollback.delete(mAppDataRollbackHelper); + } else if (oldest == null || oldest.isAfter(rollbackTimestamp)) { + oldest = rollbackTimestamp; } } } @@ -734,12 +705,10 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { synchronized (mLock) { for (int i = 0; i < mRollbacks.size(); ++i) { Rollback rollback = mRollbacks.get(i); - synchronized (rollback.getLock()) { - if (rollback.getApkSessionId() == parentSession.getSessionId()) { - // This is the apk session for a staged session with rollback enabled. We do - // not need to create a new rollback for this session. - return true; - } + if (rollback.getApkSessionId() == parentSession.getSessionId()) { + // This is the apk session for a staged session with rollback enabled. We do + // not need to create a new rollback for this session. + return true; } } } @@ -829,11 +798,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { } ApplicationInfo appInfo = pkgInfo.applicationInfo; - synchronized (rollback.getLock()) { - return rollback.enableForPackage(packageName, newPackage.versionCode, - pkgInfo.getLongVersionCode(), isApex, appInfo.sourceDir, - appInfo.splitSourceDirs); - } + return rollback.enableForPackage(packageName, newPackage.versionCode, + pkgInfo.getLongVersionCode(), isApex, appInfo.sourceDir, + appInfo.splitSourceDirs); } @Override @@ -858,16 +825,12 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { // staged installs for (int i = 0; i < mRollbacks.size(); i++) { Rollback rollback = mRollbacks.get(i); - synchronized (rollback.getLock()) { - rollback.snapshotUserData(packageName, userIds, mAppDataRollbackHelper); - } + rollback.snapshotUserData(packageName, userIds, mAppDataRollbackHelper); } // non-staged installs for (NewRollback rollback : mNewRollbacks) { - synchronized (rollback.rollback.getLock()) { - rollback.rollback.snapshotUserData( - packageName, userIds, mAppDataRollbackHelper); - } + rollback.rollback.snapshotUserData( + packageName, userIds, mAppDataRollbackHelper); } } } @@ -877,11 +840,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { synchronized (mLock) { for (int i = 0; i < mRollbacks.size(); ++i) { Rollback rollback = mRollbacks.get(i); - synchronized (rollback.getLock()) { - if (rollback.restoreUserDataForPackageIfInProgress( - packageName, userIds, appId, seInfo, mAppDataRollbackHelper)) { - return; - } + if (rollback.restoreUserDataForPackageIfInProgress( + packageName, userIds, appId, seInfo, mAppDataRollbackHelper)) { + return; } } } @@ -970,10 +931,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { } if (rollback != null) { - synchronized (rollback.getLock()) { - rollback.setApkSessionId(apkSessionId); - RollbackStore.saveRollback(rollback); - } + rollback.setApkSessionId(apkSessionId); } }); } @@ -1076,12 +1034,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { if (newRollback != null) { Rollback rollback = completeEnableRollback(newRollback, success); - if (rollback != null) { - synchronized (rollback.getLock()) { - if (!rollback.isStaged()) { - makeRollbackAvailable(rollback); - } - } + if (rollback != null && !rollback.isStaged()) { + makeRollbackAvailable(rollback); } } } @@ -1091,34 +1045,30 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { * Add a rollback to the list of rollbacks. This should be called after rollback has been * enabled for all packages in the rollback. It does not make the rollback available yet. * - * <p>Note that no rollback-specific locks should be held when this method is called. - * * @return the Rollback instance for a successfully enable-completed rollback, * or null on error. */ private Rollback completeEnableRollback(NewRollback newRollback, boolean success) { Rollback rollback = newRollback.rollback; - synchronized (rollback.getLock()) { - if (!success) { - // The install session was aborted, clean up the pending install. - rollback.delete(mAppDataRollbackHelper); - return null; - } - if (newRollback.isCancelled) { - Slog.e(TAG, "Rollback has been cancelled by PackageManager"); - rollback.delete(mAppDataRollbackHelper); - return null; - } - + if (!success) { + // The install session was aborted, clean up the pending install. + rollback.delete(mAppDataRollbackHelper); + return null; + } - if (rollback.info.getPackages().size() != newRollback.packageSessionIds.length) { - Slog.e(TAG, "Failed to enable rollback for all packages in session."); - rollback.delete(mAppDataRollbackHelper); - return null; - } + if (newRollback.isCancelled()) { + Slog.e(TAG, "Rollback has been cancelled by PackageManager"); + rollback.delete(mAppDataRollbackHelper); + return null; + } - RollbackStore.saveRollback(rollback); + if (rollback.getPackageCount() != newRollback.getPackageSessionIdCount()) { + Slog.e(TAG, "Failed to enable rollback for all packages in session."); + rollback.delete(mAppDataRollbackHelper); + return null; } + + rollback.saveRollback(); synchronized (mLock) { // Note: There is a small window of time between when // the session has been committed by the package @@ -1186,34 +1136,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); synchronized (mLock) { for (Rollback rollback : mRollbacks) { - synchronized (rollback.getLock()) { - RollbackInfo info = rollback.info; - ipw.println(info.getRollbackId() + ":"); - ipw.increaseIndent(); - ipw.println("-state: " + rollback.getStateAsString()); - ipw.println("-timestamp: " + rollback.getTimestamp()); - if (rollback.getStagedSessionId() != -1) { - ipw.println("-stagedSessionId: " + rollback.getStagedSessionId()); - } - ipw.println("-packages:"); - ipw.increaseIndent(); - for (PackageRollbackInfo pkg : info.getPackages()) { - ipw.println(pkg.getPackageName() - + " " + pkg.getVersionRolledBackFrom().getLongVersionCode() - + " -> " + pkg.getVersionRolledBackTo().getLongVersionCode()); - } - ipw.decreaseIndent(); - if (rollback.isCommitted()) { - ipw.println("-causePackages:"); - ipw.increaseIndent(); - for (VersionedPackage cPkg : info.getCausePackages()) { - ipw.println(cPkg.getPackageName() + " " + cPkg.getLongVersionCode()); - } - ipw.decreaseIndent(); - ipw.println("-committedSessionId: " + info.getCommittedSessionId()); - } - ipw.decreaseIndent(); - } + rollback.dump(ipw); } } } @@ -1233,22 +1156,51 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { public final Rollback rollback; /** - * This array holds all of the rollback tokens associated with package sessions included - * in this rollback. This is used to identify which rollback should be cancelled in case - * {@link PackageManager} sends an {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK} intent. + * This array holds all of the rollback tokens associated with package sessions included in + * this rollback. */ + @GuardedBy("mNewRollbackLock") private final IntArray mTokens = new IntArray(); /** - * Session ids for all packages in the install. - * For multi-package sessions, this is the list of child session ids. - * For normal sessions, this list is a single element with the normal + * Session ids for all packages in the install. For multi-package sessions, this is the list + * of child session ids. For normal sessions, this list is a single element with the normal * session id. */ - public final int[] packageSessionIds; + private final int[] mPackageSessionIds; + + @GuardedBy("mNewRollbackLock") + private boolean mIsCancelled = false; + + private final Object mNewRollbackLock = new Object(); + + NewRollback(Rollback rollback, int[] packageSessionIds) { + this.rollback = rollback; + this.mPackageSessionIds = packageSessionIds; + } + + /** + * Adds a rollback token to be associated with this NewRollback. This may be used to + * identify which rollback should be cancelled in case {@link PackageManager} sends an + * {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK} intent. + */ + void addToken(int token) { + synchronized (mNewRollbackLock) { + mTokens.add(token); + } + } + + /** + * Returns true if this NewRollback is associated with the provided {@code token}. + */ + boolean hasToken(int token) { + synchronized (mNewRollbackLock) { + return mTokens.indexOf(token) != -1; + } + } /** - * Flag to determine whether the rollback has been cancelled. + * Returns true if this NewRollback has been cancelled. * * <p>Rollback could be invalidated and cancelled if RollbackManager receives * {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK} from {@link PackageManager}. @@ -1258,19 +1210,38 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { * {@link PackageInstaller.SessionCallback#onFinished(int, boolean)} before it broadcasts * {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK}. */ - public boolean isCancelled = false; + boolean isCancelled() { + synchronized (mNewRollbackLock) { + return mIsCancelled; + } + } - NewRollback(Rollback rollback, int[] packageSessionIds) { - this.rollback = rollback; - this.packageSessionIds = packageSessionIds; + /** + * Sets this NewRollback to be marked as cancelled. + */ + void setCancelled() { + synchronized (mNewRollbackLock) { + mIsCancelled = true; + } } - public void addToken(int token) { - mTokens.add(token); + /** + * Returns true if this NewRollback contains the provided {@code packageSessionId}. + */ + boolean containsSessionId(int packageSessionId) { + for (int id : mPackageSessionIds) { + if (id == packageSessionId) { + return true; + } + } + return false; } - public boolean hasToken(int token) { - return mTokens.indexOf(token) != -1; + /** + * Returns the number of package session ids in this NewRollback. + */ + int getPackageSessionIdCount() { + return mPackageSessionIds.length; } } @@ -1301,14 +1272,13 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { * Returns null if no NewRollback is found for the given package * session. */ + @GuardedBy("mLock") NewRollback getNewRollbackForPackageSessionLocked(int packageSessionId) { // We expect mNewRollbacks to be a very small list; linear search // should be plenty fast. for (NewRollback newRollback: mNewRollbacks) { - for (int id : newRollback.packageSessionIds) { - if (id == packageSessionId) { - return newRollback; - } + if (newRollback.containsSessionId(packageSessionId)) { + return newRollback; } } return null; diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java index a9331aa5648f..eadd09cf46ee 100644 --- a/services/core/java/com/android/server/rollback/RollbackStore.java +++ b/services/core/java/com/android/server/rollback/RollbackStore.java @@ -252,7 +252,7 @@ class RollbackStore { /** * Saves the given rollback to persistent storage. */ - @GuardedBy("rollback.getLock") + @GuardedBy("rollback.mLock") static void saveRollback(Rollback rollback) { try { JSONObject dataJson = new JSONObject(); diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java index e488cc91f9ba..9d9a37c13bdd 100644 --- a/services/core/java/com/android/server/wm/ActivityDisplay.java +++ b/services/core/java/com/android/server/wm/ActivityDisplay.java @@ -50,9 +50,9 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; import static com.android.server.wm.RootActivityContainer.FindTaskResult; import static com.android.server.wm.RootActivityContainer.TAG_STATES; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; @@ -76,6 +76,7 @@ import android.view.Display; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.am.EventLogTags; +import com.android.server.protolog.common.ProtoLog; import java.io.PrintWriter; import java.util.ArrayList; @@ -84,8 +85,7 @@ import java.util.ArrayList; * Exactly one of these classes per Display in the system. Capable of holding zero or more * attached {@link ActivityStack}s. */ -class ActivityDisplay extends ConfigurationContainer<ActivityStack> - implements WindowContainerListener { +class ActivityDisplay extends ConfigurationContainer<ActivityStack> { private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityDisplay" : TAG_ATM; private static final String TAG_STACK = TAG + POSTFIX_STACK; @@ -201,11 +201,6 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> } } - @Override - public void onInitializeOverrideConfiguration(Configuration config) { - getRequestedOverrideConfiguration().updateFrom(config); - } - void addChild(ActivityStack stack, int position) { if (position == POSITION_BOTTOM) { position = 0; @@ -291,9 +286,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> } // Since positionChildAt() is called during the creation process of pinned stacks, - // ActivityStack#getStack() can be null. In this special case, - // since DisplayContest#positionStackAt() is called in TaskStack#onConfigurationChanged(), - // we don't have to call WindowContainerController#positionChildAt() here. + // ActivityStack#getStack() can be null. if (stack.getTaskStack() != null && mDisplayContent != null) { mDisplayContent.positionStackAt(insertPosition, stack.getTaskStack(), includingParents); @@ -1202,8 +1195,8 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> // Stacks could be reparented from the removed display to other display. While // reparenting the last stack of the removed display, the remove display is ready to be // released (no more ActivityStack). But, we cannot release it at that moment or the - // related WindowContainer and WindowContainerController will also be removed. So, we - // set display as removed after reparenting stack finished. + // related WindowContainer will also be removed. So, we set display as removed after + // reparenting stack finished. final ActivityDisplay toDisplay = mRootActivityContainer.getDefaultDisplay(); mRootActivityContainer.mStackSupervisor.beginDeferResume(); try { @@ -1304,8 +1297,8 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> final AppWindowToken newFocus; final IBinder token = r.appToken; if (token == null) { - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Clearing focused app, displayId=" - + mDisplayId); + ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Clearing focused app, displayId=%d", + mDisplayId); newFocus = null; } else { newFocus = mService.mWindowManager.mRoot.getAppWindowToken(token); @@ -1313,8 +1306,9 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> Slog.w(TAG_WM, "Attempted to set focus to non-existing app token: " + token + ", displayId=" + mDisplayId); } - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Set focused app to: " + newFocus - + " moveFocusNow=" + moveFocusNow + " displayId=" + mDisplayId); + ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, + "Set focused app to: %s moveFocusNow=%b displayId=%d", newFocus, + moveFocusNow, mDisplayId); } final boolean changed = mDisplayContent.setFocusedApp(newFocus); diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index c54ccd4d6844..c9e84ec2c69b 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -154,12 +154,11 @@ import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_W import static com.android.server.wm.IdentifierProto.HASH_CODE; import static com.android.server.wm.IdentifierProto.TITLE; import static com.android.server.wm.IdentifierProto.USER_ID; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW; import static com.android.server.wm.TaskPersister.DEBUG; import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; @@ -239,6 +238,7 @@ import com.android.server.AttributeCache.Entry; import com.android.server.am.AppTimeTracker; import com.android.server.am.EventLogTags; import com.android.server.am.PendingIntentRecord; +import com.android.server.protolog.common.ProtoLog; import com.android.server.uri.UriPermissionOwner; import com.android.server.wm.ActivityMetricsLogger.WindowingModeTransitionInfoSnapshot; import com.android.server.wm.ActivityStack.ActivityState; @@ -1183,11 +1183,10 @@ final class ActivityRecord extends ConfigurationContainer { info.applicationInfo.targetSdkVersion, info.screenOrientation, mRotationAnimationHint, mLaunchTaskBehind, isAlwaysFocusable()); - if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) { - Slog.v(TAG, "addAppToken: " - + mAppWindowToken + " task=" + container + " at " - + Integer.MAX_VALUE); - } + ProtoLog.v(WM_DEBUG_ADD_REMOVE, "addAppToken: %s" + + " task=%s at %d", mAppWindowToken, container, + Integer.MAX_VALUE); + container.addChild(mAppWindowToken, Integer.MAX_VALUE /* add on top */); } @@ -1204,12 +1203,11 @@ final class ActivityRecord extends ConfigurationContainer { CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags, IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning, boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) { - if (DEBUG_STARTING_WINDOW) { - Slog.v(TAG, "setAppStartingWindow: token=" + appToken - + " pkg=" + pkg + " transferFrom=" + transferFrom + " newTask=" + newTask - + " taskSwitch=" + taskSwitch + " processRunning=" + processRunning - + " allowTaskSnapshot=" + allowTaskSnapshot); - } + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "setAppStartingWindow: token=%s" + + " pkg=%s transferFrom=%s newTask=%b taskSwitch=%b processRunning=%b" + + " allowTaskSnapshot=%b", appToken, pkg, transferFrom, newTask, taskSwitch, + processRunning, allowTaskSnapshot); + if (mAppWindowToken == null) { Slog.w(TAG_WM, "Attempted to set icon of non-existing app token: " + appToken); return false; @@ -3215,7 +3213,7 @@ final class ActivityRecord extends ConfigurationContainer { // Window configuration changes only effect windows, so don't require a screen freeze. int freezableConfigChanges = configChanges & ~(CONFIG_WINDOW_CONFIGURATION); if (freezableConfigChanges == 0 && mAppWindowToken.okToDisplay()) { - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Skipping set freeze of " + appToken); + ProtoLog.v(WM_DEBUG_ORIENTATION, "Skipping set freeze of %s", appToken); return; } @@ -3229,11 +3227,9 @@ final class ActivityRecord extends ConfigurationContainer { if (mAppWindowToken == null) { return; } - if (DEBUG_ORIENTATION) { - Slog.v(TAG_WM, "Clear freezing of " + appToken + ": hidden=" - + mAppWindowToken.isHidden() + " freezing=" - + mAppWindowToken.isFreezingScreen()); - } + ProtoLog.v(WM_DEBUG_ORIENTATION, + "Clear freezing of %s: hidden=%b freezing=%b", appToken, + mAppWindowToken.isHidden(), mAppWindowToken.isFreezingScreen()); mAppWindowToken.stopFreezingScreen(true, force); } } diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index 2ab3e01278e9..ab1f258df8c7 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -2106,7 +2106,11 @@ class ActivityStack extends ConfigurationContainer { boolean aboveTop = top != null; final boolean stackShouldBeVisible = shouldBeVisible(starting); boolean behindFullscreenActivity = !stackShouldBeVisible; - final boolean resumeTopActivity = isFocusable() && isInStackLocked(starting) == null; + // We should not resume activities that being launched behind because these + // activities are actually behind other fullscreen activities, but still required + // to be visible (such as performing Recents animation). + final boolean resumeTopActivity = isFocusable() && isInStackLocked(starting) == null + && top != null && !top.mLaunchTaskBehind; for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { final TaskRecord task = mTaskHistory.get(taskNdx); final ArrayList<ActivityRecord> activities = task.mActivities; @@ -2332,11 +2336,7 @@ class ActivityStack extends ConfigurationContainer { r.setVisible(true); } if (r != starting) { - // We should not resume activities that being launched behind because these - // activities are actually behind other fullscreen activities, but still required - // to be visible (such as performing Recents animation). - mStackSupervisor.startSpecificActivityLocked(r, andResume && !r.mLaunchTaskBehind, - true /* checkConfig */); + mStackSupervisor.startSpecificActivityLocked(r, andResume, true /* checkConfig */); return true; } } diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java index 9d08e10c6dea..cc69b5a7205f 100644 --- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java +++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java @@ -249,7 +249,8 @@ class ActivityStartInterceptor { if (PLATFORM_PACKAGE_NAME.equals(suspendingPackage)) { return interceptSuspendedByAdminPackage(); } - final SuspendDialogInfo dialogInfo = pmi.getSuspendedDialogInfo(suspendedPackage, mUserId); + final SuspendDialogInfo dialogInfo = pmi.getSuspendedDialogInfo(suspendedPackage, + suspendingPackage, mUserId); mIntent = SuspendedAppActivity.createSuspendedAppInterceptIntent(suspendedPackage, suspendingPackage, dialogInfo, mUserId); mCallingPid = mRealCallingPid; diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 66d52cc9bf5a..93c461f3add9 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -70,8 +70,9 @@ import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnte import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation; import static com.android.server.wm.AppTransitionProto.APP_TRANSITION_STATE; import static com.android.server.wm.AppTransitionProto.LAST_USED_APP_TRANSITION; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerInternal.AppTransitionListener; @@ -131,6 +132,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.DumpUtils.Dump; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.AttributeCache; +import com.android.server.protolog.common.ProtoLog; import com.android.server.wm.animation.ClipRectLRAnimation; import com.android.server.wm.animation.ClipRectTBAnimation; import com.android.server.wm.animation.CurvedTranslateAnimation; @@ -1630,70 +1632,61 @@ public class AppTransition implements Dump { a = loadAnimationRes(lp, enter ? com.android.internal.R.anim.voice_activity_open_enter : com.android.internal.R.anim.voice_activity_open_exit); - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, - "applyAnimation voice:" - + " anim=" + a + " transit=" + appTransitionToString(transit) - + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, + "applyAnimation voice: anim=%s transit=%s isEntrance=%b Callers=%s", a, + appTransitionToString(transit), enter, Debug.getCallers(3)); } else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_CLOSE || transit == TRANSIT_TASK_CLOSE || transit == TRANSIT_TASK_TO_BACK)) { a = loadAnimationRes(lp, enter ? com.android.internal.R.anim.voice_activity_close_enter : com.android.internal.R.anim.voice_activity_close_exit); - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, - "applyAnimation voice:" - + " anim=" + a + " transit=" + appTransitionToString(transit) - + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, + "applyAnimation voice: anim=%s transit=%s isEntrance=%b Callers=%s", a, + appTransitionToString(transit), enter, Debug.getCallers(3)); } else if (transit == TRANSIT_ACTIVITY_RELAUNCH) { a = createRelaunchAnimation(frame, insets); - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, - "applyAnimation:" - + " anim=" + a + " nextAppTransition=" + mNextAppTransition - + " transit=" + appTransitionToString(transit) - + " Callers=" + Debug.getCallers(3)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, + "applyAnimation: anim=%s nextAppTransition=%d transit=%s Callers=%s", a, + mNextAppTransition, appTransitionToString(transit), + Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) { a = loadAnimationRes(mNextAppTransitionPackage, enter ? mNextAppTransitionEnter : mNextAppTransitionExit); - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, - "applyAnimation:" - + " anim=" + a + " nextAppTransition=ANIM_CUSTOM" - + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter - + " Callers=" + Debug.getCallers(3)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, + "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s " + + "isEntrance=%b Callers=%s", + a, appTransitionToString(transit), enter, Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) { a = loadAnimationRes(mNextAppTransitionPackage, mNextAppTransitionInPlace); - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, - "applyAnimation:" - + " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE" - + " transit=" + appTransitionToString(transit) - + " Callers=" + Debug.getCallers(3)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, + "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM_IN_PLACE " + + "transit=%s Callers=%s", + a, appTransitionToString(transit), Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) { a = createClipRevealAnimationLocked(transit, enter, frame, displayFrame); - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, - "applyAnimation:" - + " anim=" + a + " nextAppTransition=ANIM_CLIP_REVEAL" - + " transit=" + appTransitionToString(transit) - + " Callers=" + Debug.getCallers(3)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, + "applyAnimation: anim=%s nextAppTransition=ANIM_CLIP_REVEAL " + + "transit=%s Callers=%s", + a, appTransitionToString(transit), Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) { a = createScaleUpAnimationLocked(transit, enter, frame); - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, - "applyAnimation:" - + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP" - + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter - + " Callers=" + Debug.getCallers(3)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, + "applyAnimation: anim=%s nextAppTransition=ANIM_SCALE_UP transit=%s " + + "isEntrance=%s Callers=%s", + a, appTransitionToString(transit), enter, Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP || mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) { mNextAppTransitionScaleUp = (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP); a = createThumbnailEnterExitAnimationLocked(getThumbnailTransitionState(enter), frame, transit, taskId); - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { - String animName = mNextAppTransitionScaleUp ? - "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN"; - Slog.v(TAG, "applyAnimation:" - + " anim=" + a + " nextAppTransition=" + animName - + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter - + " Callers=" + Debug.getCallers(3)); - } + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, + "applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b " + + "Callers=%s", + a, mNextAppTransitionScaleUp + ? "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN", + appTransitionToString(transit), enter, Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP || mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN) { mNextAppTransitionScaleUp = @@ -1701,30 +1694,27 @@ public class AppTransition implements Dump { a = createAspectScaledThumbnailEnterExitAnimationLocked( getThumbnailTransitionState(enter), uiMode, orientation, transit, frame, insets, surfaceInsets, stableInsets, freeform, taskId); - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { - String animName = mNextAppTransitionScaleUp ? - "ANIM_THUMBNAIL_ASPECT_SCALE_UP" : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN"; - Slog.v(TAG, "applyAnimation:" - + " anim=" + a + " nextAppTransition=" + animName - + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter - + " Callers=" + Debug.getCallers(3)); - } + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, + "applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b " + + "Callers=%s", + a, mNextAppTransitionScaleUp + ? "ANIM_THUMBNAIL_ASPECT_SCALE_UP" + : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN", + appTransitionToString(transit), enter, Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS && enter) { a = loadAnimationRes("android", com.android.internal.R.anim.task_open_enter_cross_profile_apps); - Slog.v(TAG, - "applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS:" - + " anim=" + a + " transit=" + appTransitionToString(transit) - + " isEntrance=true" + " Callers=" + Debug.getCallers(3)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, + "applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS: " + + "anim=%s transit=%s isEntrance=true Callers=%s", + a, appTransitionToString(transit), Debug.getCallers(3)); } else if (transit == TRANSIT_TASK_CHANGE_WINDOWING_MODE) { // In the absence of a specific adapter, we just want to keep everything stationary. a = new AlphaAnimation(1.f, 1.f); a.setDuration(WindowChangeAnimationSpec.ANIMATION_DURATION); - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { - Slog.v(TAG, "applyAnimation:" - + " anim=" + a + " transit=" + appTransitionToString(transit) - + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3)); - } + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, + "applyAnimation: anim=%s transit=%s isEntrance=%b Callers=%s", + a, appTransitionToString(transit), enter, Debug.getCallers(3)); } else { int animAttr = 0; switch (transit) { @@ -1787,12 +1777,11 @@ public class AppTransition implements Dump { : WindowAnimation_launchTaskBehindTargetAnimation; } a = animAttr != 0 ? loadAnimationAttr(lp, animAttr, transit) : null; - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, - "applyAnimation:" - + " anim=" + a - + " animAttr=0x" + Integer.toHexString(animAttr) - + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter - + " Callers=" + Debug.getCallers(3)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, + "applyAnimation: anim=%s animAttr=0x%x transit=%s isEntrance=%b " + + "Callers=%s", + a, animAttr, appTransitionToString(transit), enter, + Debug.getCallers(3)); } return a; } @@ -1941,8 +1930,8 @@ public class AppTransition implements Dump { } void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter) { - if (DEBUG_APP_TRANSITIONS) Slog.i(TAG, "Override pending remote transitionSet=" - + isTransitionSet() + " adapter=" + remoteAnimationAdapter); + ProtoLog.i(WM_DEBUG_APP_TRANSITIONS, "Override pending remote transitionSet=%b adapter=%s", + isTransitionSet(), remoteAnimationAdapter); if (isTransitionSet()) { clear(); mNextAppTransitionType = NEXT_TRANSIT_TYPE_REMOTE; @@ -2214,12 +2203,11 @@ public class AppTransition implements Dump { */ boolean prepareAppTransitionLocked(@TransitionType int transit, boolean alwaysKeepCurrent, @TransitionFlags int flags, boolean forceOverride) { - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Prepare app transition:" - + " transit=" + appTransitionToString(transit) - + " " + this - + " alwaysKeepCurrent=" + alwaysKeepCurrent - + " displayId=" + mDisplayContent.getDisplayId() - + " Callers=" + Debug.getCallers(5)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "Prepare app transition: transit=%s %s alwaysKeepCurrent=%b displayId=%d " + + "Callers=%s", + appTransitionToString(transit), this, alwaysKeepCurrent, + mDisplayContent.getDisplayId(), Debug.getCallers(5)); final boolean allowSetCrashing = !isKeyguardTransit(mNextAppTransition) && transit == TRANSIT_CRASHING_ACTIVITY_CLOSE; if (forceOverride || isKeyguardTransit(transit) || !isTransitionSet() @@ -2305,15 +2293,14 @@ public class AppTransition implements Dump { } if (isTransitionSet() || !dc.mOpeningApps.isEmpty() || !dc.mClosingApps.isEmpty() || !dc.mChangingApps.isEmpty()) { - if (DEBUG_APP_TRANSITIONS) { - Slog.v(TAG_WM, "*** APP TRANSITION TIMEOUT." - + " displayId=" + dc.getDisplayId() - + " isTransitionSet()=" - + dc.mAppTransition.isTransitionSet() - + " mOpeningApps.size()=" + dc.mOpeningApps.size() - + " mClosingApps.size()=" + dc.mClosingApps.size() - + " mChangingApps.size()=" + dc.mChangingApps.size()); - } + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "*** APP TRANSITION TIMEOUT. displayId=%d isTransitionSet()=%b " + + "mOpeningApps.size()=%d mClosingApps.size()=%d " + + "mChangingApps.size()=%d", + dc.getDisplayId(), dc.mAppTransition.isTransitionSet(), + dc.mOpeningApps.size(), dc.mClosingApps.size(), + dc.mChangingApps.size()); + setTimeout(); mService.mWindowPlacerLocked.performSurfacePlacement(); } diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java index 6b2f9da77f62..20a871baada4 100644 --- a/services/core/java/com/android/server/wm/AppTransitionController.java +++ b/services/core/java/com/android/server/wm/AppTransitionController.java @@ -48,7 +48,7 @@ import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_S import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_SPLASH_SCREEN; import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_WINDOWS_DRAWN; import static com.android.server.wm.AppTransition.isKeyguardGoingAwayTransit; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -66,6 +66,7 @@ import android.view.WindowManager.LayoutParams; import android.view.animation.Animation; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.protolog.common.ProtoLog; import java.util.function.Predicate; @@ -104,7 +105,7 @@ public class AppTransitionController { } Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "AppTransitionReady"); - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO"); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "**** GOOD TO GO"); final AppTransition appTransition = mDisplayContent.mAppTransition; int transit = appTransition.getAppTransition(); if (mDisplayContent.mSkipAppTransitionAnimation && !isKeyguardGoingAwayTransit(transit)) { @@ -348,7 +349,7 @@ public class AppTransitionController { final int appsCount = openingApps.size(); for (int i = 0; i < appsCount; i++) { AppWindowToken wtoken = openingApps.valueAt(i); - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Now opening app %s", wtoken); if (!wtoken.commitVisibility(animLp, true, transit, false, voiceInteraction)) { // This token isn't going to be animating. Add it to the list of tokens to @@ -383,7 +384,7 @@ public class AppTransitionController { for (int i = 0; i < appsCount; i++) { AppWindowToken wtoken = closingApps.valueAt(i); - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Now closing app %s", wtoken); // TODO: Do we need to add to mNoAnimationNotifyOnTransitionFinished like above if not // animating? wtoken.commitVisibility(animLp, false, transit, false, voiceInteraction); @@ -410,7 +411,7 @@ public class AppTransitionController { final int appsCount = apps.size(); for (int i = 0; i < appsCount; i++) { AppWindowToken wtoken = apps.valueAt(i); - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now changing app" + wtoken); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Now changing app %s", wtoken); wtoken.cancelAnimationOnly(); wtoken.applyAnimationLocked(null, transit, true, false); wtoken.updateReportedVisibilityLocked(); @@ -445,13 +446,12 @@ public class AppTransitionController { } private boolean transitionGoodToGo(ArraySet<AppWindowToken> apps, SparseIntArray outReasons) { - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, - "Checking " + apps.size() + " opening apps (frozen=" - + mService.mDisplayFrozen + " timeout=" - + mDisplayContent.mAppTransition.isTimeout() + ")..."); - final ScreenRotationAnimation screenRotationAnimation = - mService.mAnimator.getScreenRotationAnimationLocked( - Display.DEFAULT_DISPLAY); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "Checking %d opening apps (frozen=%b timeout=%b)...", apps.size(), + mService.mDisplayFrozen, mDisplayContent.mAppTransition.isTimeout()); + + final ScreenRotationAnimation screenRotationAnimation = mService.mRoot.getDisplayContent( + Display.DEFAULT_DISPLAY).getRotationAnimation(); if (!mDisplayContent.mAppTransition.isTimeout()) { // Imagine the case where we are changing orientation due to an app transition, but a @@ -463,20 +463,18 @@ public class AppTransitionController { // app transition. if (screenRotationAnimation != null && screenRotationAnimation.isAnimating() && mDisplayContent.getDisplayRotation().needsUpdate()) { - if (DEBUG_APP_TRANSITIONS) { - Slog.v(TAG, "Delaying app transition for screen rotation animation to finish"); - } + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "Delaying app transition for screen rotation animation to finish"); return false; } for (int i = 0; i < apps.size(); i++) { AppWindowToken wtoken = apps.valueAt(i); - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, - "Check opening app=" + wtoken + ": allDrawn=" - + wtoken.allDrawn + " startingDisplayed=" - + wtoken.startingDisplayed + " startingMoved=" - + wtoken.startingMoved + " isRelaunching()=" - + wtoken.isRelaunching() + " startingWindow=" - + wtoken.startingWindow); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "Check opening app=%s: allDrawn=%b startingDisplayed=%b " + + "startingMoved=%b isRelaunching()=%b startingWindow=%s", + wtoken, wtoken.allDrawn, wtoken.startingDisplayed, + wtoken.startingMoved, wtoken.isRelaunching(), + wtoken.startingWindow); final boolean allDrawn = wtoken.allDrawn && !wtoken.isRelaunching(); @@ -496,15 +494,13 @@ public class AppTransitionController { // We also need to wait for the specs to be fetched, if needed. if (mDisplayContent.mAppTransition.isFetchingAppTransitionsSpecs()) { - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true"); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "isFetchingAppTransitionSpecs=true"); return false; } if (!mDisplayContent.mUnknownAppVisibilityController.allResolved()) { - if (DEBUG_APP_TRANSITIONS) { - Slog.v(TAG, "unknownApps is not empty: " - + mDisplayContent.mUnknownAppVisibilityController.getDebugMessage()); - } + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "unknownApps is not empty: %s", + mDisplayContent.mUnknownAppVisibilityController.getDebugMessage()); return false; } @@ -549,22 +545,20 @@ public class AppTransitionController { true /* ignoreHidden */); boolean openingCanBeWallpaperTarget = canBeWallpaperTarget(openingApps); - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, - "New wallpaper target=" + wallpaperTarget - + ", oldWallpaper=" + oldWallpaper - + ", openingApps=" + openingApps - + ", closingApps=" + closingApps); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "New wallpaper target=%s, oldWallpaper=%s, openingApps=%s, closingApps=%s", + wallpaperTarget, oldWallpaper, openingApps, closingApps); if (openingCanBeWallpaperTarget && transit == TRANSIT_KEYGUARD_GOING_AWAY) { transit = TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER; - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, - "New transit: " + AppTransition.appTransitionToString(transit)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "New transit: %s", AppTransition.appTransitionToString(transit)); } // We never want to change from a Keyguard transit to a non-Keyguard transit, as our logic // relies on the fact that we always execute a Keyguard transition after preparing one. else if (!isKeyguardGoingAwayTransit(transit)) { if (closingAppHasWallpaper && openingAppHasWallpaper) { - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!"); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Wallpaper animation!"); switch (transit) { case TRANSIT_ACTIVITY_OPEN: case TRANSIT_TASK_OPEN: @@ -577,16 +571,17 @@ public class AppTransitionController { transit = TRANSIT_WALLPAPER_INTRA_CLOSE; break; } - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, - "New transit: " + AppTransition.appTransitionToString(transit)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "New transit: %s", AppTransition.appTransitionToString(transit)); } else if (oldWallpaper != null && !mDisplayContent.mOpeningApps.isEmpty() && !openingApps.contains(oldWallpaper.mAppToken) && closingApps.contains(oldWallpaper.mAppToken) && topClosingApp == oldWallpaper.mAppToken) { // We are transitioning from an activity with a wallpaper to one without. transit = TRANSIT_WALLPAPER_CLOSE; - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit away from wallpaper: " - + AppTransition.appTransitionToString(transit)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "New transit away from wallpaper: %s", + AppTransition.appTransitionToString(transit)); } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() && openingApps.contains(wallpaperTarget.mAppToken) && topOpeningApp == wallpaperTarget.mAppToken @@ -594,8 +589,8 @@ public class AppTransitionController { // We are transitioning from an activity without // a wallpaper to now showing the wallpaper transit = TRANSIT_WALLPAPER_OPEN; - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit into wallpaper: " - + AppTransition.appTransitionToString(transit)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "New transit into wallpaper: %s", + AppTransition.appTransitionToString(transit)); } } return transit; @@ -722,8 +717,7 @@ public class AppTransitionController { final WindowState win = mDisplayContent.findFocusedWindow(); if (win != null) { final AppWindowToken wtoken = win.mAppToken; - if (DEBUG_APP_TRANSITIONS) - Slog.v(TAG, "Now animating app in place " + wtoken); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Now animating app in place %s", wtoken); wtoken.cancelAnimation(); wtoken.applyAnimationLocked(null, transit, false, false); wtoken.updateReportedVisibilityLocked(); diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/AppWindowThumbnail.java index b52ade415bd4..2b05024415b9 100644 --- a/services/core/java/com/android/server/wm/AppWindowThumbnail.java +++ b/services/core/java/com/android/server/wm/AppWindowThumbnail.java @@ -22,7 +22,7 @@ import static android.view.SurfaceControl.METADATA_WINDOW_TYPE; import static com.android.server.wm.AppWindowThumbnailProto.HEIGHT; import static com.android.server.wm.AppWindowThumbnailProto.SURFACE_ANIMATOR; import static com.android.server.wm.AppWindowThumbnailProto.WIDTH; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; +import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION; @@ -31,7 +31,6 @@ import android.graphics.GraphicBuffer; import android.graphics.PixelFormat; import android.graphics.Point; import android.os.Binder; -import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.Surface; import android.view.SurfaceControl; @@ -39,6 +38,7 @@ import android.view.SurfaceControl.Builder; import android.view.SurfaceControl.Transaction; import android.view.animation.Animation; +import com.android.server.protolog.common.ProtoLog; import com.android.server.wm.SurfaceAnimator.Animatable; import java.util.function.Supplier; @@ -104,9 +104,7 @@ class AppWindowThumbnail implements Animatable { window != null ? window.mOwnerUid : Binder.getCallingUid()) .build(); - if (SHOW_TRANSACTIONS) { - Slog.i(TAG, " THUMBNAIL " + mSurfaceControl + ": CREATE"); - } + ProtoLog.i(WM_SHOW_TRANSACTIONS, " THUMBNAIL %s: CREATE", mSurfaceControl); // Transfer the thumbnail to the surface drawSurface.copyFrom(mSurfaceControl); diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index f647fe46f067..266862820017 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -62,17 +62,16 @@ import static com.android.server.wm.AppWindowTokenProto.STARTING_MOVED; import static com.android.server.wm.AppWindowTokenProto.STARTING_WINDOW; import static com.android.server.wm.AppWindowTokenProto.THUMBNAIL; import static com.android.server.wm.AppWindowTokenProto.WINDOW_TOKEN; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS_ANIM; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN; @@ -124,6 +123,7 @@ import com.android.server.LocalServices; import com.android.server.display.color.ColorDisplayService; import com.android.server.policy.WindowManagerPolicy; import com.android.server.policy.WindowManagerPolicy.StartingSurface; +import com.android.server.protolog.common.ProtoLog; import com.android.server.wm.RemoteAnimationController.RemoteAnimationRecord; import com.android.server.wm.WindowManagerService.H; @@ -388,8 +388,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree removeDeadWindows(); if (startingWindow != null) { - if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting " - + win.mToken + ": first real window is shown, no animation"); + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Finish starting %s" + + ": first real window is shown, no animation", win.mToken); // If this initial window is animating, stop it -- we will do an animation to reveal // it from behind the starting window, so there is no need for it to also be doing its // own stuff. @@ -480,8 +480,9 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree if (mClientHidden == hideClient || (hideClient && mDeferHidingClient)) { return; } - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setClientHidden: " + this - + " clientHidden=" + hideClient + " Callers=" + Debug.getCallers(5)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "setClientHidden: %s clientHidden=%b Callers=%s", this, hideClient, + Debug.getCallers(5)); mClientHidden = hideClient; sendAppVisibilityToClients(); } @@ -507,12 +508,10 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree return; } - if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) { - Slog.v(TAG_WM, "setAppVisibility(" - + appToken + ", visible=" + visible + "): " + appTransition - + " hidden=" + isHidden() + " hiddenRequested=" - + hiddenRequested + " Callers=" + Debug.getCallers(6)); - } + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "setAppVisibility(%s, visible=%b): %s hidden=%b hiddenRequested=%b Callers=%s", + appToken, visible, appTransition, isHidden(), hiddenRequested, + Debug.getCallers(6)); final DisplayContent displayContent = getDisplayContent(); displayContent.mOpeningApps.remove(this); @@ -548,17 +547,20 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree if (isHidden()) { waitingToShow = true; - // Let's reset the draw state in order to prevent the starting window to be - // immediately dismissed when the app still has the surface. - forAllWindows(w -> { - if (w.mWinAnimator.mDrawState == HAS_DRAWN) { - w.mWinAnimator.resetDrawState(); - - // Force add to mResizingWindows, so that we are guaranteed to get - // another reportDrawn callback. - w.resetLastContentInsets(); - } - }, true /* traverseTopToBottom */); + // If the client isn't hidden, we don't need to reset the drawing state. + if (isClientHidden()) { + // Let's reset the draw state in order to prevent the starting window to be + // immediately dismissed when the app still has the surface. + forAllWindows(w -> { + if (w.mWinAnimator.mDrawState == HAS_DRAWN) { + w.mWinAnimator.resetDrawState(); + + // Force add to mResizingWindows, so that we are guaranteed to get + // another reportDrawn callback. + w.resetLastContentInsets(); + } + }, true /* traverseTopToBottom */); + } } } @@ -570,7 +572,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree requestUpdateWallpaperIfNeeded(); - if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "No longer Stopped: " + this); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, "No longer Stopped: %s", this); mAppStopped = false; transferStartingWindowFromHiddenAboveTokenIfNeeded(); @@ -593,10 +595,10 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree if (win != null) { final AppWindowToken focusedToken = win.mAppToken; if (focusedToken != null) { - if (DEBUG_APP_TRANSITIONS) { - Slog.d(TAG_WM, "TRANSIT_TASK_OPEN_BEHIND, " - + " adding " + focusedToken + " to mOpeningApps"); - } + ProtoLog.d(WM_DEBUG_APP_TRANSITIONS, + "TRANSIT_TASK_OPEN_BEHIND, adding %s to mOpeningApps", + focusedToken); + // Force animation to be loaded. displayContent.mOpeningApps.add(focusedToken); } @@ -635,8 +637,9 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree final AccessibilityController accessibilityController = mWmService.mAccessibilityController; boolean changed = false; - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, - "Changing app " + this + " hidden=" + isHidden() + " performLayout=" + performLayout); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "Changing app %s hidden=%b performLayout=%b", this, isHidden(), + performLayout); boolean runningAppAnimation = false; @@ -678,10 +681,9 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree forAllWindows(mWmService::makeWindowFreezingScreenIfNeededLocked, true); } - if (DEBUG_APP_TRANSITIONS) { - Slog.v(TAG_WM, "commitVisibility: " + this - + ": hidden=" + isHidden() + " hiddenRequested=" + hiddenRequested); - } + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "commitVisibility: %s: hidden=%b hiddenRequested=%b", this, + isHidden(), hiddenRequested); if (changed) { displayContent.getInputMonitor().setUpdateInputWindowsNeededLw(); @@ -884,7 +886,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } mRemovingFromDisplay = true; - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + this); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Removing app token: %s", this); boolean delayed = commitVisibility(null, false, TRANSIT_UNSET, true, mVoiceInteraction); @@ -900,11 +902,12 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree delayed = true; } - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app " + this + " delayed=" + delayed - + " animation=" + getAnimation() + " animating=" + isSelfAnimating()); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "Removing app %s delayed=%b animation=%s animating=%b", this, delayed, + getAnimation(), isSelfAnimating()); - if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: " - + this + " delayed=" + delayed + " Callers=" + Debug.getCallers(4)); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, "removeAppToken: %s" + + " delayed=%b Callers=%s", this, delayed, Debug.getCallers(4)); if (mStartingData != null) { removeStartingWindow(); @@ -920,8 +923,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree final TaskStack stack = getStack(); if (delayed && !isEmpty()) { // set the token aside because it has an active animation to be finished - if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, - "removeAppToken make exiting: " + this); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, + "removeAppToken make exiting: %s", this); if (stack != null) { stack.mExitingAppTokens.add(this); } @@ -941,8 +944,9 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree final DisplayContent dc = getDisplayContent(); if (dc.mFocusedApp == this) { - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this - + " displayId=" + dc.getDisplayId()); + ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, + "Removing focused app token:%s displayId=%d", this, + dc.getDisplayId()); dc.setFocusedApp(null); mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/); } @@ -1006,8 +1010,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree * up of the surfaces */ void notifyAppResumed(boolean wasStopped) { - if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped - + " " + this); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, "notifyAppResumed: wasStopped=%b %s", + wasStopped, this); mAppStopped = false; // Allow the window to turn the screen on once the app is resumed again. setCurrentLaunchCanTurnScreenOn(true); @@ -1021,7 +1025,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree * keeping alive in case they were still being used. */ void notifyAppStopped() { - if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, "notifyAppStopped: %s", this); mAppStopped = true; // Reset the last saved PiP snap fraction on app stop. mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(mActivityComponent); @@ -1084,12 +1088,12 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree void postWindowRemoveStartingWindowCleanup(WindowState win) { // TODO: Something smells about the code below...Is there a better way? if (startingWindow == win) { - if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win); + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Notify removed startingWindow %s", win); removeStartingWindow(); } else if (mChildren.size() == 0) { // If this is the last window and we had requested a starting transition window, // well there is no point now. - if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingData"); + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Nulling last startingData"); mStartingData = null; if (mHiddenSetFromTransferredStartingWindow) { // We set the hidden state to false for the token from a transferred starting window. @@ -1100,8 +1104,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } else if (mChildren.size() == 1 && startingSurface != null && !isRelaunching()) { // If this is the last window except for a starting transition window, // we need to get rid of the starting transition. - if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Last window, removing starting window " - + win); + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Last window, removing starting window %s", win); removeStartingWindow(); } } @@ -1110,8 +1113,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree for (int winNdx = mChildren.size() - 1; winNdx >= 0; --winNdx) { WindowState win = mChildren.get(winNdx); if (win.mAppDied) { - if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG, - "removeDeadWindows: " + win); + ProtoLog.w(WM_DEBUG_ADD_REMOVE, + "removeDeadWindows: %s", win); // Set mDestroying, we don't want any animation or delayed removal here. win.mDestroying = true; // Also removes child windows. @@ -1132,8 +1135,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } void setWillReplaceWindows(boolean animate) { - if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, - "Marking app token " + this + " with replacing windows."); + ProtoLog.d(WM_DEBUG_ADD_REMOVE, + "Marking app token %s with replacing windows.", this); for (int i = mChildren.size() - 1; i >= 0; i--) { final WindowState w = mChildren.get(i); @@ -1142,8 +1145,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } void setWillReplaceChildWindows() { - if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this - + " with replacing child windows."); + ProtoLog.d(WM_DEBUG_ADD_REMOVE, "Marking app token %s" + + " with replacing child windows.", this); for (int i = mChildren.size() - 1; i >= 0; i--) { final WindowState w = mChildren.get(i); w.setWillReplaceChildWindows(); @@ -1151,8 +1154,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } void clearWillReplaceWindows() { - if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, - "Resetting app token " + this + " of replacing window marks."); + ProtoLog.d(WM_DEBUG_ADD_REMOVE, + "Resetting app token %s of replacing window marks.", this); for (int i = mChildren.size() - 1; i >= 0; i--) { final WindowState w = mChildren.get(i); @@ -1317,10 +1320,9 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } void reparent(Task task, int position) { - if (DEBUG_ADD_REMOVE) { - Slog.i(TAG_WM, "reparent: moving app token=" + this - + " to task=" + task.mTaskId + " at " + position); - } + ProtoLog.i(WM_DEBUG_ADD_REMOVE, "reparent: moving app token=%s" + + " to task=%d at %d", this, task.mTaskId, position); + if (task == null) { throw new IllegalArgumentException("reparent: could not find task"); } @@ -1336,8 +1338,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree + " belongs to a different stack than " + task); } - if (DEBUG_ADD_REMOVE) Slog.i(TAG, "reParentWindowToken: removing window token=" + this - + " from task=" + currentTask); + ProtoLog.i(WM_DEBUG_ADD_REMOVE, "reParentWindowToken: removing window token=%s" + + " from task=%s" , this, currentTask); final DisplayContent prevDisplayContent = getDisplayContent(); mReparenting = true; @@ -1457,9 +1459,10 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } void startFreezingScreen() { - if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden=" - + isHidden() + " freezing=" + mFreezingScreen + " hiddenRequested=" - + hiddenRequested); + ProtoLog.i(WM_DEBUG_ORIENTATION, + "Set freezing of %s: hidden=%b freezing=%b hiddenRequested=%b. %s", + appToken, isHidden(), mFreezingScreen, hiddenRequested, + new RuntimeException().fillInStackTrace()); if (!hiddenRequested) { if (!mFreezingScreen) { mFreezingScreen = true; @@ -1483,7 +1486,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree if (!mFreezingScreen) { return; } - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force); + ProtoLog.v(WM_DEBUG_ORIENTATION, + "Clear freezing of %s force=%b", this, force); final int count = mChildren.size(); boolean unfrozeWindows = false; for (int i = 0; i < count; i++) { @@ -1491,7 +1495,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree unfrozeWindows |= w.onStopFreezingScreen(); } if (force || unfrozeWindows) { - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this); + ProtoLog.v(WM_DEBUG_ORIENTATION, "No longer freezing: %s", this); mFreezingScreen = false; mWmService.unregisterAppFreezeListener(this); mWmService.mAppsFreezingScreen--; @@ -1542,8 +1546,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree // letting windows get shown immediately without any more transitions. getDisplayContent().mSkipAppTransitionAnimation = true; - if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow - + " from " + fromToken + " to " + this); + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Moving existing starting %s" + + " from %s to %s", tStartingWindow, fromToken, this); final long origId = Binder.clearCallingIdentity(); try { @@ -1561,8 +1565,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree tStartingWindow.mToken = this; tStartingWindow.mAppToken = this; - if (DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, - "Removing starting " + tStartingWindow + " from " + fromToken); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, + "Removing starting %s from %s", tStartingWindow, fromToken); fromToken.removeChild(tStartingWindow); fromToken.postWindowRemoveStartingWindowCleanup(tStartingWindow); fromToken.mHiddenSetFromTransferredStartingWindow = false; @@ -1603,8 +1607,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } else if (fromToken.mStartingData != null) { // The previous app was getting ready to show a // starting window, but hasn't yet done so. Steal it! - if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, - "Moving pending starting from " + fromToken + " to " + this); + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, + "Moving pending starting from %s to %s", fromToken, this); mStartingData = fromToken.mStartingData; fromToken.mStartingData = null; fromToken.startingMoved = true; @@ -1876,9 +1880,10 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree if (mFreezingScreen) { showAllWindowsLocked(); stopFreezingScreen(false, true); - if (DEBUG_ORIENTATION) Slog.i(TAG, - "Setting mOrientationChangeComplete=true because wtoken " + this - + " numInteresting=" + mNumInterestingWindows + " numDrawn=" + mNumDrawnWindows); + ProtoLog.i(WM_DEBUG_ORIENTATION, + "Setting mOrientationChangeComplete=true because wtoken %s " + + "numInteresting=%d numDrawn=%d", + this, mNumInterestingWindows, mNumDrawnWindows); // This will set mOrientationChangeComplete and cause a pass through layout. setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER, "checkAppWindowsReadyToShow: freezingScreen"); @@ -1982,7 +1987,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree boolean isInterestingAndDrawn = false; if (!allDrawn && w.mightAffectAllDrawn()) { - if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) { + if (DEBUG_VISIBILITY || WM_DEBUG_ORIENTATION.isLogToLogcat()) { Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw() + ", isAnimationSet=" + isSelfAnimating()); if (!w.isDrawnLw()) { @@ -2003,10 +2008,12 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree if (w.isDrawnLw()) { mNumDrawnWindows++; - if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawn: " - + this + " w=" + w + " numInteresting=" + mNumInterestingWindows - + " freezingScreen=" + mFreezingScreen - + " mAppFreezing=" + w.mAppFreezing); + if (DEBUG_VISIBILITY || WM_DEBUG_ORIENTATION.isLogToLogcat()) { + Slog.v(TAG, "tokenMayBeDrawn: " + + this + " w=" + w + " numInteresting=" + mNumInterestingWindows + + " freezingScreen=" + mFreezingScreen + + " mAppFreezing=" + w.mAppFreezing); + } isInterestingAndDrawn = true; } @@ -2122,9 +2129,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree // If this is a translucent window, then don't show a starting window -- the current // effect (a full-screen opaque starting window that fades away to the real contents // when it is ready) does not work for this. - if (DEBUG_STARTING_WINDOW) { - Slog.v(TAG, "Checking theme of starting window: 0x" + Integer.toHexString(theme)); - } + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Checking theme of starting window: 0x%x", theme); if (theme != 0) { AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme, com.android.internal.R.styleable.Window, @@ -2142,11 +2147,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree com.android.internal.R.styleable.Window_windowShowWallpaper, false); final boolean windowDisableStarting = ent.array.getBoolean( com.android.internal.R.styleable.Window_windowDisablePreview, false); - if (DEBUG_STARTING_WINDOW) { - Slog.v(TAG, "Translucent=" + windowIsTranslucent - + " Floating=" + windowIsFloating - + " ShowWallpaper=" + windowShowWallpaper); - } + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Translucent=%s Floating=%s ShowWallpaper=%s", + windowIsTranslucent, windowIsFloating, windowShowWallpaper); if (windowIsTranslucent) { return false; } @@ -2178,7 +2180,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree return false; } - if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SplashScreenStartingData"); + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Creating SplashScreenStartingData"); mStartingData = new SplashScreenStartingData(mWmService, pkg, theme, compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags, getMergedOverrideConfiguration()); @@ -2192,7 +2194,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree return false; } - if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SnapshotStartingData"); + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Creating SnapshotStartingData"); mStartingData = new SnapshotStartingData(mWmService, snapshot); scheduleAddStartingWindow(); return true; @@ -2203,7 +2205,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree // want to process the message ASAP, before any other queued // messages. if (!mWmService.mAnimationHandler.hasCallbacks(mAddStartingWindow)) { - if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING"); + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Enqueueing ADD_STARTING"); mWmService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow); } } @@ -2220,18 +2222,17 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree if (mStartingData == null) { // Animation has been canceled... do nothing. - if (DEBUG_STARTING_WINDOW) { - Slog.v(TAG, "startingData was nulled out before handling" - + " mAddStartingWindow: " + AppWindowToken.this); - } + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, + "startingData was nulled out before handling" + + " mAddStartingWindow: %s", AppWindowToken.this); return; } startingData = mStartingData; } - if (DEBUG_STARTING_WINDOW) { - Slog.v(TAG, "Add starting " + this + ": startingData=" + startingData); - } + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Add starting %s: startingData=%s", + this, startingData); + WindowManagerPolicy.StartingSurface surface = null; try { @@ -2245,27 +2246,28 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree // If the window was successfully added, then // we need to remove it. if (removed || mStartingData == null) { - if (DEBUG_STARTING_WINDOW) { - Slog.v(TAG, "Aborted starting " + AppWindowToken.this - + ": removed=" + removed + " startingData=" + mStartingData); - } + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, + "Aborted starting %s: removed=%b startingData=%s", + AppWindowToken.this, removed, mStartingData); + startingWindow = null; mStartingData = null; abort = true; } else { startingSurface = surface; } - if (DEBUG_STARTING_WINDOW && !abort) { - Slog.v(TAG, - "Added starting " + AppWindowToken.this + ": startingWindow=" - + startingWindow + " startingView=" + startingSurface); + if (!abort) { + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, + "Added starting %s: startingWindow=%s startingView=%s", + AppWindowToken.this, startingWindow, startingSurface); } } if (abort) { surface.remove(); } - } else if (DEBUG_STARTING_WINDOW) { - Slog.v(TAG, "Surface returned was null: " + AppWindowToken.this); + } else { + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Surface returned was null: %s", + AppWindowToken.this); } } }; @@ -2308,9 +2310,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree if (mStartingData != null) { // Starting window has not been added yet, but it is scheduled to be added. // Go ahead and cancel the request. - if (DEBUG_STARTING_WINDOW) { - Slog.v(TAG_WM, "Clearing startingData for token=" + this); - } + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Clearing startingData for token=%s", this); mStartingData = null; } return; @@ -2324,31 +2324,28 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree startingWindow = null; startingDisplayed = false; if (surface == null) { - if (DEBUG_STARTING_WINDOW) { - Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't " + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, + "startingWindow was set but startingSurface==null, couldn't " + "remove"); - } + return; } } else { - if (DEBUG_STARTING_WINDOW) { - Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:" - + this); - } + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, + "Tried to remove starting window but startingWindow was null: %s", + this); return; } - if (DEBUG_STARTING_WINDOW) { - Slog.v(TAG_WM, "Schedule remove starting " + this - + " startingWindow=" + startingWindow - + " startingView=" + startingSurface - + " Callers=" + Debug.getCallers(5)); - } + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Schedule remove starting %s startingWindow=%s" + + " startingView=%s Callers=%s", + this, startingWindow, startingSurface, Debug.getCallers(5)); + // Use the same thread to remove the window as we used to add it, as otherwise we end up // with things in the view hierarchy being called from different threads. mWmService.mAnimationHandler.post(() -> { - if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Removing startingView=" + surface); + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Removing startingView=%s", surface); try { surface.remove(); } catch (Exception e) { @@ -2544,7 +2541,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree * Creates a layer to apply crop to an animation. */ private SurfaceControl createAnimationBoundsLayer(Transaction t) { - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.i(TAG, "Creating animation bounds layer"); + ProtoLog.i(WM_DEBUG_APP_TRANSITIONS_ANIM, "Creating animation bounds layer"); final SurfaceControl.Builder builder = makeAnimationLeash() .setParent(getAnimationLeashParent()) .setName(getSurfaceControl() + " - animation-bounds"); @@ -2580,10 +2577,9 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree boolean isVoiceInteraction) { if (mWmService.mDisableTransitionAnimation || !shouldAnimate(transit)) { - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { - Slog.v(TAG_WM, "applyAnimation: transition animation is disabled or skipped." - + " atoken=" + this); - } + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, + "applyAnimation: transition animation is disabled or skipped. " + + "atoken=%s", this); cancelAnimation(); return false; } @@ -2683,8 +2679,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree final DisplayInfo displayInfo = displayContent.getDisplayInfo(); final int width = displayInfo.appWidth; final int height = displayInfo.appHeight; - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM, - "applyAnimation: atoken=" + this); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, + "applyAnimation: atoken=%s", this); // Determine the visible rect to calculate the thumbnail clip final WindowState win = findMainWindow(); @@ -2724,9 +2720,10 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree // screen gets the enter animation. Both appear in the mOpeningApps set. enter = false; } - if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "Loading animation for app transition." - + " transit=" + AppTransition.appTransitionToString(transit) + " enter=" + enter - + " frame=" + frame + " insets=" + insets + " surfaceInsets=" + surfaceInsets); + ProtoLog.d(WM_DEBUG_APP_TRANSITIONS, + "Loading animation for app transition. transit=%s enter=%b frame=%s insets=%s " + + "surfaceInsets=%s", + AppTransition.appTransitionToString(transit), enter, frame, insets, surfaceInsets); final Configuration displayConfig = displayContent.getConfiguration(); final Animation a = getDisplayContent().mAppTransition.loadAnimation(lp, transit, enter, displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets, @@ -2982,7 +2979,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree final GraphicBuffer thumbnailHeader = getDisplayContent().mAppTransition.getAppTransitionThumbnailHeader(taskId); if (thumbnailHeader == null) { - if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId); + ProtoLog.d(WM_DEBUG_APP_TRANSITIONS, "No thumbnail header bitmap for: %d", taskId); return; } clearThumbnail(); diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java index 7557271a2416..b4cecff728fd 100644 --- a/services/core/java/com/android/server/wm/BlackFrame.java +++ b/services/core/java/com/android/server/wm/BlackFrame.java @@ -16,16 +16,14 @@ package com.android.server.wm; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; -import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; +import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC; -import android.graphics.Matrix; import android.graphics.Rect; -import android.util.Slog; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; +import com.android.server.protolog.common.ProtoLog; + import java.io.PrintWriter; import java.util.function.Supplier; @@ -33,14 +31,15 @@ import java.util.function.Supplier; * Four black surfaces put together to make a black frame. */ public class BlackFrame { - class BlackSurface { + static class BlackSurface { final int left; final int top; final int layer; final SurfaceControl surface; BlackSurface(SurfaceControl.Transaction transaction, int layer, - int l, int t, int r, int b, DisplayContent dc) throws OutOfResourcesException { + int l, int t, int r, int b, DisplayContent dc, + SurfaceControl surfaceControl) throws OutOfResourcesException { left = l; top = t; this.layer = layer; @@ -50,7 +49,7 @@ public class BlackFrame { surface = dc.makeOverlay() .setName("BlackSurface") .setColorLayer() - .setParent(null) // TODO: Work-around for b/69259549 + .setParent(surfaceControl) .build(); transaction.setWindowCrop(surface, w, h); transaction.setLayerStack(surface, dc.getDisplayId()); @@ -58,46 +57,15 @@ public class BlackFrame { transaction.setLayer(surface, layer); transaction.setPosition(surface, left, top); transaction.show(surface); - if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG_WM, - " BLACK " + surface + ": CREATE layer=" + layer); - } - - void setAlpha(SurfaceControl.Transaction t, float alpha) { - t.setAlpha(surface, alpha); - } - - void setMatrix(SurfaceControl.Transaction t, Matrix matrix) { - mTmpMatrix.setTranslate(left, top); - mTmpMatrix.postConcat(matrix); - mTmpMatrix.getValues(mTmpFloats); - t.setPosition(surface, mTmpFloats[Matrix.MTRANS_X], - mTmpFloats[Matrix.MTRANS_Y]); - t.setMatrix(surface, - mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y], - mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]); - if (false) { - Slog.i(TAG_WM, "Black Surface @ (" + left + "," + top + "): (" - + mTmpFloats[Matrix.MTRANS_X] + "," - + mTmpFloats[Matrix.MTRANS_Y] + ") matrix=[" - + mTmpFloats[Matrix.MSCALE_X] + "," - + mTmpFloats[Matrix.MSCALE_Y] + "][" - + mTmpFloats[Matrix.MSKEW_X] + "," - + mTmpFloats[Matrix.MSKEW_Y] + "]"); - } - } - - void clearMatrix(SurfaceControl.Transaction t) { - t.setMatrix(surface, 1, 0, 0, 1); + ProtoLog.i(WM_SHOW_SURFACE_ALLOC, + " BLACK %s: CREATE layer=%d", surface, layer); } } - final Rect mOuterRect; - final Rect mInnerRect; - final Matrix mTmpMatrix = new Matrix(); - final float[] mTmpFloats = new float[9]; - final BlackSurface[] mBlackSurfaces = new BlackSurface[4]; + private final Rect mOuterRect; + private final Rect mInnerRect; + private final BlackSurface[] mBlackSurfaces = new BlackSurface[4]; - final boolean mForceDefaultOrientation; private final Supplier<SurfaceControl.Transaction> mTransactionFactory; public void printTo(String prefix, PrintWriter pw) { @@ -114,12 +82,12 @@ public class BlackFrame { } public BlackFrame(Supplier<SurfaceControl.Transaction> factory, SurfaceControl.Transaction t, - Rect outer, Rect inner, int layer, DisplayContent dc, boolean forceDefaultOrientation) + Rect outer, Rect inner, int layer, DisplayContent dc, boolean forceDefaultOrientation, + SurfaceControl surfaceControl) throws OutOfResourcesException { boolean success = false; mTransactionFactory = factory; - mForceDefaultOrientation = forceDefaultOrientation; // TODO: Why do we use 4 surfaces instead of just one big one behind the screenshot? // b/68253229 @@ -128,19 +96,20 @@ public class BlackFrame { try { if (outer.top < inner.top) { mBlackSurfaces[0] = new BlackSurface(t, layer, - outer.left, outer.top, inner.right, inner.top, dc); + outer.left, outer.top, inner.right, inner.top, dc, surfaceControl); } if (outer.left < inner.left) { mBlackSurfaces[1] = new BlackSurface(t, layer, - outer.left, inner.top, inner.left, outer.bottom, dc); + outer.left, inner.top, inner.left, outer.bottom, dc, surfaceControl); } if (outer.bottom > inner.bottom) { mBlackSurfaces[2] = new BlackSurface(t, layer, - inner.left, inner.bottom, outer.right, outer.bottom, dc); + inner.left, inner.bottom, outer.right, outer.bottom, dc, + surfaceControl); } if (outer.right > inner.right) { mBlackSurfaces[3] = new BlackSurface(t, layer, - inner.right, outer.top, outer.right, inner.bottom, dc); + inner.right, outer.top, outer.right, inner.bottom, dc, surfaceControl); } success = true; } finally { @@ -151,51 +120,14 @@ public class BlackFrame { } public void kill() { - if (mBlackSurfaces != null) { - SurfaceControl.Transaction t = mTransactionFactory.get(); - for (int i=0; i<mBlackSurfaces.length; i++) { - if (mBlackSurfaces[i] != null) { - if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG_WM, - " BLACK " + mBlackSurfaces[i].surface + ": DESTROY"); - t.remove(mBlackSurfaces[i].surface); - mBlackSurfaces[i] = null; - } - } - t.apply(); - } - } - - public void hide(SurfaceControl.Transaction t) { - if (mBlackSurfaces != null) { - for (int i=0; i<mBlackSurfaces.length; i++) { - if (mBlackSurfaces[i] != null) { - t.hide(mBlackSurfaces[i].surface); - } - } - } - } - - public void setAlpha(SurfaceControl.Transaction t, float alpha) { - for (int i=0; i<mBlackSurfaces.length; i++) { - if (mBlackSurfaces[i] != null) { - mBlackSurfaces[i].setAlpha(t, alpha); - } - } - } - - public void setMatrix(SurfaceControl.Transaction t, Matrix matrix) { - for (int i=0; i<mBlackSurfaces.length; i++) { - if (mBlackSurfaces[i] != null) { - mBlackSurfaces[i].setMatrix(t, matrix); - } - } - } - - public void clearMatrix(SurfaceControl.Transaction t) { - for (int i=0; i<mBlackSurfaces.length; i++) { + SurfaceControl.Transaction t = mTransactionFactory.get(); + for (int i = 0; i < mBlackSurfaces.length; i++) { if (mBlackSurfaces[i] != null) { - mBlackSurfaces[i].clearMatrix(t); + ProtoLog.i(WM_SHOW_SURFACE_ALLOC, " BLACK %s: DESTROY", mBlackSurfaces[i].surface); + t.remove(mBlackSurfaces[i].surface); + mBlackSurfaces[i] = null; } } + t.apply(); } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 6462744703a3..6fafa9f7360d 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -100,24 +100,21 @@ import static com.android.server.wm.DisplayContentProto.ROTATION; import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION; import static com.android.server.wm.DisplayContentProto.STACKS; import static com.android.server.wm.DisplayContentProto.WINDOW_CONTAINER; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_SCREEN_ON; +import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.H.REPORT_FOCUS_CHANGE; @@ -133,7 +130,6 @@ import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_ASSIG import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES; import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT; import static com.android.server.wm.WindowManagerService.dipToPixel; -import static com.android.server.wm.WindowManagerService.logSurface; import static com.android.server.wm.WindowState.EXCLUSION_LEFT; import static com.android.server.wm.WindowState.EXCLUSION_RIGHT; import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP; @@ -202,6 +198,7 @@ import com.android.internal.util.function.pooled.PooledConsumer; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.AnimationThread; import com.android.server.policy.WindowManagerPolicy; +import com.android.server.protolog.common.ProtoLog; import com.android.server.wm.utils.DisplayRotationUtil; import com.android.server.wm.utils.RotationCache; import com.android.server.wm.utils.WmDisplayCutout; @@ -497,6 +494,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo /** Windows removed since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */ final ArrayList<WindowState> mWinRemovedSinceNullFocus = new ArrayList<>(); + private ScreenRotationAnimation mScreenRotationAnimation; + /** * We organize all top-level Surfaces in to the following layers. * mOverlayLayer contains a few Surfaces which are always on top of others @@ -521,9 +520,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo */ private int mDeferUpdateImeTargetCount; - /** Temporary float array to retrieve 3x3 matrix values. */ - private final float[] mTmpFloats = new float[9]; - private MagnificationSpec mMagnificationSpec; private InputMonitor mInputMonitor; @@ -600,8 +596,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private final ToBooleanFunction<WindowState> mFindFocusedWindow = w -> { final AppWindowToken focusedApp = mFocusedApp; - if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + w - + ", flags=" + w.mAttrs.flags + ", canReceive=" + w.canReceiveKeys()); + ProtoLog.v(WM_DEBUG_FOCUS, "Looking for focus: %s, flags=%d, canReceive=%b", + w, w.mAttrs.flags, w.canReceiveKeys()); if (!w.canReceiveKeys()) { return false; @@ -611,22 +607,22 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // If this window's application has been removed, just skip it. if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) { - if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because " - + (wtoken.removed ? "removed" : "sendingToBottom")); + ProtoLog.v(WM_DEBUG_FOCUS, "Skipping %s because %s", wtoken, + (wtoken.removed ? "removed" : "sendingToBottom")); return false; } if (focusedApp == null) { - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp=null" - + " using new focus @ " + w); + ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, + "findFocusedWindow: focusedApp=null using new focus @ %s", w); mTmpWindow = w; return true; } if (!focusedApp.windowsAreFocusable()) { // Current focused app windows aren't focusable... - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp windows not" - + " focusable using new focus @ " + w); + ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: focusedApp windows not" + + " focusable using new focus @ %s", w); mTmpWindow = w; return true; } @@ -636,14 +632,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (wtoken != null && w.mAttrs.type != TYPE_APPLICATION_STARTING) { if (focusedApp.compareTo(wtoken) > 0) { // App stack below focused app stack. No focus for you!!! - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, - "findFocusedWindow: Reached focused app=" + focusedApp); + ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, + "findFocusedWindow: Reached focused app=%s", focusedApp); mTmpWindow = null; return true; } } - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ " + w); + ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: Found new focus @ %s", w); mTmpWindow = w; return true; }; @@ -1146,7 +1142,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo */ void initializeDisplayOverrideConfiguration() { if (mAcitvityDisplay != null) { - mAcitvityDisplay.onInitializeOverrideConfiguration(getRequestedOverrideConfiguration()); + mAcitvityDisplay.getRequestedOverrideConfiguration() + .updateFrom(getRequestedOverrideConfiguration()); } } @@ -1309,9 +1306,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo void applyRotationLocked(final int oldRotation, final int rotation) { mDisplayRotation.applyCurrentRotation(rotation); final boolean rotateSeamlessly = mDisplayRotation.isRotatingSeamlessly(); - final ScreenRotationAnimation screenRotationAnimation = rotateSeamlessly - ? null : mWmService.mAnimator.getScreenRotationAnimationLocked(mDisplayId); final Transaction transaction = getPendingTransaction(); + ScreenRotationAnimation screenRotationAnimation = rotateSeamlessly + ? null : getRotationAnimation(); // We need to update our screen size information to match the new rotation. If the rotation // has actually changed then this method will return true and, according to the comment at // the top of the method, the caller is obligated to call computeNewConfigurationLocked(). @@ -1334,7 +1331,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo forAllWindows(w -> { if (w.mHasSurface && !rotateSeamlessly) { - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Set mOrientationChanging of " + w); + ProtoLog.v(WM_DEBUG_ORIENTATION, "Set mOrientationChanging of %s", w); w.setOrientationChanging(true); mWmService.mRoot.mOrientationChangeComplete = false; w.mLastFreezeDuration = 0; @@ -1998,8 +1995,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (mWmService.mDisplayFrozen) { if (mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) { - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId - + " is frozen, return " + mLastWindowForcedOrientation); + ProtoLog.v(WM_DEBUG_ORIENTATION, + "Display id=%d is frozen, return %d", mDisplayId, + mLastWindowForcedOrientation); // If the display is frozen, some activities may be in the middle of restarting, and // thus have removed their old window. If the window has the flag to hide the lock // screen, then the lock screen can re-appear and inflict its own orientation on us. @@ -2011,8 +2009,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // window. We don't want to check the show when locked window directly though as // things aren't stable while the display is frozen, for example the window could be // momentarily unavailable due to activity relaunch. - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId - + " is frozen while keyguard locked, return " + getLastOrientation()); + ProtoLog.v(WM_DEBUG_ORIENTATION, + "Display id=%d is frozen while keyguard locked, return %d", + mDisplayId, getLastOrientation()); return getLastOrientation(); } } else { @@ -2393,6 +2392,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo super.removeImmediately(); if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this); mPointerEventDispatcher.dispose(); + setRotationAnimation(null); mWmService.mAnimator.removeDisplayLocked(mDisplayId); mWindowingLayer.release(); mOverlayLayer.release(); @@ -2557,6 +2557,17 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return delta; } + public void setRotationAnimation(ScreenRotationAnimation screenRotationAnimation) { + if (mScreenRotationAnimation != null) { + mScreenRotationAnimation.kill(); + } + mScreenRotationAnimation = screenRotationAnimation; + } + + public ScreenRotationAnimation getRotationAnimation() { + return mScreenRotationAnimation; + } + private static void createRotationMatrix(int rotation, float displayWidth, float displayHeight, Matrix outMatrix) { // For rotations without Z-ordering we don't need the target rectangle's position. @@ -2619,8 +2630,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo proto.write(DPI, mBaseDisplayDensity); mDisplayInfo.writeToProto(proto, DISPLAY_INFO); proto.write(ROTATION, getRotation()); - final ScreenRotationAnimation screenRotationAnimation = - mWmService.mAnimator.getScreenRotationAnimationLocked(mDisplayId); + final ScreenRotationAnimation screenRotationAnimation = getRotationAnimation(); if (screenRotationAnimation != null) { screenRotationAnimation.writeToProto(proto, SCREEN_ROTATION_ANIMATION); } @@ -2732,6 +2742,16 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } + final ScreenRotationAnimation rotationAnimation = getRotationAnimation(); + if (rotationAnimation != null) { + pw.print(subPrefix); + pw.println(" mScreenRotationAnimation:"); + rotationAnimation.printTo(" ", pw); + } else if (dumpAll) { + pw.print(subPrefix); + pw.println(" no ScreenRotationAnimation "); + } + pw.println(); // Dump stack references @@ -2851,7 +2871,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo forAllWindows(mFindFocusedWindow, true /* traverseTopToBottom */); if (mTmpWindow == null) { - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows."); + ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: No focusable windows."); return null; } return mTmpWindow; @@ -2897,11 +2917,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mWmService.mH.obtainMessage(REPORT_FOCUS_CHANGE, this).sendToTarget(); } - if (DEBUG_FOCUS_LIGHT || DEBUG) { - Slog.v(TAG_WM, "Changing focus from " - + mCurrentFocus + " to " + newFocus + " displayId=" + getDisplayId() - + " Callers=" + Debug.getCallers(4)); - } + ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Changing focus from %s to %s displayId=%d Callers=%s", + mCurrentFocus, newFocus, getDisplayId(), Debug.getCallers(4)); final WindowState oldFocus = mCurrentFocus; mCurrentFocus = newFocus; mLosingFocus.remove(newFocus); @@ -3038,7 +3055,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): " + w + " surface=" + wsa.mSurfaceController + " token=" + w.mAppToken); - if (SHOW_TRANSACTIONS) logSurface(w, "LEAK DESTROY", false); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE LEAK DESTROY: %s", w); wsa.destroySurface(); mTmpWindow = w; } @@ -3372,12 +3389,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo com.android.internal.R.bool.config_checkWallpaperAtBoot) && !mWmService.mOnlyCore; - if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG_WM, - "******** booted=" + mWmService.mSystemBooted - + " msg=" + mWmService.mShowingBootMessages - + " haveBoot=" + mHaveBootMsg + " haveApp=" + mHaveApp - + " haveWall=" + mHaveWallpaper + " wallEnabled=" + wallpaperEnabled - + " haveKeyguard=" + mHaveKeyguard); + ProtoLog.i(WM_DEBUG_SCREEN_ON, + "******** booted=%b msg=%b haveBoot=%b haveApp=%b haveWall=%b " + + "wallEnabled=%b haveKeyguard=%b", + mWmService.mSystemBooted, mWmService.mShowingBootMessages, mHaveBootMsg, + mHaveApp, mHaveWallpaper, wallpaperEnabled, mHaveKeyguard); // If we are turning on the screen to show the boot message, don't do it until the boot // message is actually displayed. @@ -3741,7 +3757,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo convertCropForSurfaceFlinger(frame, rot, dw, dh); final ScreenRotationAnimation screenRotationAnimation = - mWmService.mAnimator.getScreenRotationAnimationLocked(DEFAULT_DISPLAY); + mWmService.mRoot.getDisplayContent(DEFAULT_DISPLAY).getRotationAnimation(); final boolean inRotation = screenRotationAnimation != null && screenRotationAnimation.isAnimating(); if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG_WM, "Taking screenshot while rotating"); @@ -4214,8 +4230,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // associated with it will be removed as soon as their animations are // complete. cancelAnimation(); - if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, - "performLayout: App token exiting now removed" + token); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, + "performLayout: App token exiting now removed %s", token); token.removeIfPossible(); } } @@ -4245,15 +4261,15 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo final int orientation = super.getOrientation(); if (orientation != SCREEN_ORIENTATION_UNSET && orientation != SCREEN_ORIENTATION_BEHIND) { - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, - "App is requesting an orientation, return " + orientation - + " for display id=" + mDisplayId); + ProtoLog.v(WM_DEBUG_ORIENTATION, + "App is requesting an orientation, return %d for display id=%d", + orientation, mDisplayId); return orientation; } - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, - "No app is requesting an orientation, return " + getLastOrientation() - + " for display id=" + mDisplayId); + ProtoLog.v(WM_DEBUG_ORIENTATION, + "No app is requesting an orientation, return %d for display id=%d", + getLastOrientation(), mDisplayId); // The next app has not been requested to be visible, so we keep the current orientation // to prevent freezing/unfreezing the display too early. return getLastOrientation(); @@ -4490,8 +4506,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return SCREEN_ORIENTATION_UNSET; } } - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req - + " for display id=" + mDisplayId); + ProtoLog.v(WM_DEBUG_ORIENTATION, + "%s forcing orientation to %d for display id=%d", win, req, + mDisplayId); return (mLastWindowForcedOrientation = req); } @@ -4666,20 +4683,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo void prepareSurfaces() { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "prepareSurfaces"); try { - final ScreenRotationAnimation screenRotationAnimation = - mWmService.mAnimator.getScreenRotationAnimationLocked(mDisplayId); final Transaction transaction = getPendingTransaction(); - if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) { - screenRotationAnimation.getEnterTransformation().getMatrix().getValues(mTmpFloats); - transaction.setMatrix(mWindowingLayer, - mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y], - mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]); - transaction.setPosition(mWindowingLayer, - mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y]); - transaction.setAlpha(mWindowingLayer, - screenRotationAnimation.getEnterTransformation().getAlpha()); - } - super.prepareSurfaces(); // TODO: Once we totally eliminate global transaction we will pass transaction in here @@ -4759,10 +4763,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo void executeAppTransition() { if (mAppTransition.isTransitionSet()) { - if (DEBUG_APP_TRANSITIONS) { - Slog.w(TAG_WM, "Execute app transition: " + mAppTransition + ", displayId: " - + mDisplayId + " Callers=" + Debug.getCallers(5)); - } + ProtoLog.w(WM_DEBUG_APP_TRANSITIONS, + "Execute app transition: %s, displayId: %d Callers=%s", + mAppTransition, mDisplayId, Debug.getCallers(5)); mAppTransition.setReady(); mWmService.mWindowPlacerLocked.requestTraversal(); } @@ -4909,6 +4912,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return mWindowingLayer; } + SurfaceControl getOverlayLayer() { + return mOverlayLayer; + } + /** * Updates the display's system gesture exclusion. * diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 10d48c4d5282..7be4dbd99766 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -98,9 +98,9 @@ import static com.android.server.policy.WindowManagerPolicy.TRANSIT_PREVIEW_DONE import static com.android.server.policy.WindowManagerPolicy.TRANSIT_SHOW; import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT; import static com.android.server.wm.ActivityTaskManagerInternal.SleepToken; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -168,6 +168,7 @@ import com.android.server.policy.WindowManagerPolicy.NavigationBarPosition; import com.android.server.policy.WindowManagerPolicy.ScreenOnListener; import com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs; import com.android.server.policy.WindowOrientationListener; +import com.android.server.protolog.common.ProtoLog; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.wallpaper.WallpaperManagerInternal; import com.android.server.wm.utils.InsetUtils; @@ -765,19 +766,19 @@ public class DisplayPolicy { /** Return false if it is not ready to turn on. */ public boolean finishScreenTurningOn() { synchronized (mLock) { - if (DEBUG_SCREEN_ON) Slog.d(TAG, - "finishScreenTurningOn: mAwake=" + mAwake - + ", mScreenOnEarly=" + mScreenOnEarly - + ", mScreenOnFully=" + mScreenOnFully - + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete - + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete); + ProtoLog.d(WM_DEBUG_SCREEN_ON, + "finishScreenTurningOn: mAwake=%b, mScreenOnEarly=%b, " + + "mScreenOnFully=%b, mKeyguardDrawComplete=%b, " + + "mWindowManagerDrawComplete=%b", + mAwake, mScreenOnEarly, mScreenOnFully, mKeyguardDrawComplete, + mWindowManagerDrawComplete); if (mScreenOnFully || !mScreenOnEarly || !mWindowManagerDrawComplete || (mAwake && !mKeyguardDrawComplete)) { return false; } - if (DEBUG_SCREEN_ON) Slog.i(TAG, "Finished screen turning on..."); + ProtoLog.i(WM_DEBUG_SCREEN_ON, "Finished screen turning on..."); mScreenOnListener = null; mScreenOnFully = true; } diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index 4d188f4f1e19..414e496ae57e 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -23,8 +23,8 @@ import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS; import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_ACTIVE; @@ -58,6 +58,7 @@ import com.android.server.LocalServices; import com.android.server.UiThread; import com.android.server.policy.WindowManagerPolicy; import com.android.server.policy.WindowOrientationListener; +import com.android.server.protolog.common.ProtoLog; import com.android.server.statusbar.StatusBarManagerInternal; import java.io.PrintWriter; @@ -399,24 +400,24 @@ public class DisplayRotation { if (mDeferredRotationPauseCount > 0) { // Rotation updates have been paused temporarily. Defer the update until updates // have been resumed. - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, rotation is paused."); + ProtoLog.v(WM_DEBUG_ORIENTATION, "Deferring rotation, rotation is paused."); return false; } final ScreenRotationAnimation screenRotationAnimation = - mService.mAnimator.getScreenRotationAnimationLocked(displayId); + mDisplayContent.getRotationAnimation(); if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) { // Rotation updates cannot be performed while the previous rotation change animation // is still in progress. Skip this update. We will try updating again after the // animation is finished and the display is unfrozen. - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, animation in progress."); + ProtoLog.v(WM_DEBUG_ORIENTATION, "Deferring rotation, animation in progress."); return false; } if (mService.mDisplayFrozen) { // Even if the screen rotation animation has finished (e.g. isAnimating returns // false), there is still some time where we haven't yet unfrozen the display. We // also need to abort rotation here. - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, + ProtoLog.v(WM_DEBUG_ORIENTATION, "Deferring rotation, still finishing previous rotation"); return false; } @@ -424,30 +425,30 @@ public class DisplayRotation { if (!mService.mDisplayEnabled) { // No point choosing a rotation if the display is not enabled. - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, display is not enabled."); + ProtoLog.v(WM_DEBUG_ORIENTATION, "Deferring rotation, display is not enabled."); return false; } final int oldRotation = mRotation; final int lastOrientation = mLastOrientation; final int rotation = rotationForOrientation(lastOrientation, oldRotation); - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Computed rotation=" + rotation + " for display id=" - + displayId + " based on lastOrientation=" + lastOrientation - + " and oldRotation=" + oldRotation); + ProtoLog.v(WM_DEBUG_ORIENTATION, + "Computed rotation=%d for display id=%d based on lastOrientation=%d and " + + "oldRotation=%d", + rotation, displayId, lastOrientation, oldRotation); - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + displayId - + " selected orientation " + lastOrientation - + ", got rotation " + rotation); + ProtoLog.v(WM_DEBUG_ORIENTATION, + "Display id=%d selected orientation %d, got rotation %d", displayId, + lastOrientation, rotation); if (oldRotation == rotation) { // No change. return false; } - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + displayId - + " rotation changed to " + rotation - + " from " + oldRotation - + ", lastOrientation=" + lastOrientation); + ProtoLog.v(WM_DEBUG_ORIENTATION, + "Display id=%d rotation changed to %d from %d, lastOrientation=%d", + displayId, rotation, oldRotation, lastOrientation); if (DisplayContent.deltaRotation(rotation, oldRotation) != 2) { mDisplayContent.mWaitingForConfig = true; @@ -551,9 +552,8 @@ public class DisplayRotation { mSeamlessRotationCount--; } if (mSeamlessRotationCount == 0) { - if (DEBUG_ORIENTATION) { - Slog.i(TAG, "Performing post-rotate rotation after seamless rotation"); - } + ProtoLog.i(WM_DEBUG_ORIENTATION, + "Performing post-rotate rotation after seamless rotation"); // Finish seamless rotation. mRotatingSeamlessly = false; @@ -844,11 +844,12 @@ public class DisplayRotation { // Could have been invoked due to screen turning on or off or // change of the currently visible window's orientation. - if (DEBUG_ORIENTATION) Slog.v(TAG, "screenOnEarly=" + screenOnEarly - + ", awake=" + awake + ", currentAppOrientation=" + mCurrentAppOrientation - + ", orientationSensorEnabled=" + mOrientationListener.mEnabled - + ", keyguardDrawComplete=" + keyguardDrawComplete - + ", windowManagerDrawComplete=" + windowManagerDrawComplete); + ProtoLog.v(WM_DEBUG_ORIENTATION, + "screenOnEarly=%b, awake=%b, currentAppOrientation=%d, " + + "orientationSensorEnabled=%b, keyguardDrawComplete=%b, " + + "windowManagerDrawComplete=%b", + screenOnEarly, awake, mCurrentAppOrientation, mOrientationListener.mEnabled, + keyguardDrawComplete, windowManagerDrawComplete); boolean disable = true; // Note: We postpone the rotating of the screen until the keyguard as well as the @@ -952,14 +953,11 @@ public class DisplayRotation { */ @VisibleForTesting int rotationForOrientation(int orientation, int lastRotation) { - if (DEBUG_ORIENTATION) { - Slog.v(TAG, "rotationForOrientation(orient=" - + orientation + ", last=" + lastRotation - + "); user=" + mUserRotation + " " - + (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED - ? "USER_ROTATION_LOCKED" : "") + ProtoLog.v(WM_DEBUG_ORIENTATION, "rotationForOrientation(orient=%d, last=%d); user=%d %s", + orientation, lastRotation, mUserRotation, + mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED + ? "USER_ROTATION_LOCKED" : "" ); - } if (isFixedToUserRotation()) { return mUserRotation; @@ -1059,11 +1057,19 @@ public class DisplayRotation { preferredRotation = lastRotation; } } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED - && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) { - // Apply rotation lock. Does not apply to NOSENSOR. + && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR + && orientation != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE + && orientation != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + && orientation != ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE + && orientation != ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT) { + // Apply rotation lock. Does not apply to NOSENSOR or specific rotations. // The idea is that the user rotation expresses a weak preference for the direction // of gravity and as NOSENSOR is never affected by gravity, then neither should // NOSENSOR be affected by rotation lock (although it will be affected by docks). + // Also avoid setting user rotation when app has preference over one particular rotation + // to avoid leaving the rotation to the reverse of it which has the compatible + // orientation, but isn't what app wants, when the user rotation is the reverse of the + // preferred rotation. preferredRotation = mUserRotation; } else { // No overriding preference. @@ -1372,7 +1378,7 @@ public class DisplayRotation { @Override public void onProposedRotationChanged(int rotation) { - if (DEBUG_ORIENTATION) Slog.v(TAG, "onProposedRotationChanged, rotation=" + rotation); + ProtoLog.v(WM_DEBUG_ORIENTATION, "onProposedRotationChanged, rotation=%d", rotation); Runnable r = mRunnableCache.get(rotation, null); if (r == null) { r = new UpdateRunnable(rotation); @@ -1385,14 +1391,14 @@ public class DisplayRotation { public void enable(boolean clearCurrentRotation) { super.enable(clearCurrentRotation); mEnabled = true; - if (DEBUG_ORIENTATION) Slog.v(TAG, "Enabling listeners"); + ProtoLog.v(WM_DEBUG_ORIENTATION, "Enabling listeners"); } @Override public void disable() { super.disable(); mEnabled = false; - if (DEBUG_ORIENTATION) Slog.v(TAG, "Disabling listeners"); + ProtoLog.v(WM_DEBUG_ORIENTATION, "Disabling listeners"); } } diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index 3c616945f762..34820acfeccc 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -19,10 +19,10 @@ package com.android.server.wm; import static com.android.server.wm.DragDropController.MSG_ANIMATION_END; import static com.android.server.wm.DragDropController.MSG_DRAG_END_TIMEOUT; import static com.android.server.wm.DragDropController.MSG_TEAR_DOWN_DRAG_AND_DROP_INPUT; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; +import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.animation.Animator; @@ -58,6 +58,7 @@ import android.view.animation.Interpolator; import com.android.internal.view.IDragAndDropPermissions; import com.android.server.LocalServices; +import com.android.server.protolog.common.ProtoLog; import java.util.ArrayList; @@ -300,9 +301,7 @@ class DragState { mDragWindowHandle.frameBottom = mDisplaySize.y; // Pause rotations before a drag. - if (DEBUG_ORIENTATION) { - Slog.d(TAG_WM, "Pausing rotation during drag"); - } + ProtoLog.d(WM_DEBUG_ORIENTATION, "Pausing rotation during drag"); mDisplayContent.getDisplayRotation().pause(); } @@ -319,9 +318,7 @@ class DragState { mDragApplicationHandle = null; // Resume rotations after a drag. - if (DEBUG_ORIENTATION) { - Slog.d(TAG_WM, "Resuming rotation after drag"); - } + ProtoLog.d(WM_DEBUG_ORIENTATION, "Resuming rotation after drag"); mDisplayContent.getDisplayRotation().resume(); } } @@ -499,10 +496,9 @@ class DragState { Slog.i(TAG_WM, ">>> OPEN TRANSACTION notifyMoveLocked"); } mTransaction.setPosition(mSurfaceControl, x - mThumbOffsetX, y - mThumbOffsetY).apply(); - if (SHOW_TRANSACTIONS) { - Slog.i(TAG_WM, " DRAG " + mSurfaceControl + ": pos=(" + (int) (x - mThumbOffsetX) + "," - + (int) (y - mThumbOffsetY) + ")"); - } + ProtoLog.i(WM_SHOW_TRANSACTIONS, "DRAG %s: pos=(%d,%d)", mSurfaceControl, + (int) (x - mThumbOffsetX), (int) (y - mThumbOffsetY)); + notifyLocationLocked(x, y); } diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 8e0531ce3652..932b4fac4592 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -26,7 +26,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLP import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -49,6 +49,7 @@ import android.view.SurfaceControl; import com.android.server.AnimationThread; import com.android.server.policy.WindowManagerPolicy; +import com.android.server.protolog.common.ProtoLog; import java.io.PrintWriter; import java.util.Set; @@ -331,9 +332,7 @@ final class InputMonitor { * Layer assignment is assumed to be complete by the time this is called. */ public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) { - if (DEBUG_FOCUS_LIGHT || DEBUG_INPUT) { - Slog.d(TAG_WM, "Input focus has changed to " + newWindow); - } + ProtoLog.d(WM_DEBUG_FOCUS_LIGHT, "Input focus has changed to %s", newWindow); if (newWindow != mInputFocus) { if (newWindow != null && newWindow.canReceiveKeys()) { diff --git a/services/core/java/com/android/server/wm/ProtoLogGroup.java b/services/core/java/com/android/server/wm/ProtoLogGroup.java index 313ccebc778d..2e0ef14e4303 100644 --- a/services/core/java/com/android/server/wm/ProtoLogGroup.java +++ b/services/core/java/com/android/server/wm/ProtoLogGroup.java @@ -27,8 +27,38 @@ import com.android.server.protolog.common.ProtoLog; * must be included in services.core.wm.protologgroups build target. */ public enum ProtoLogGroup implements IProtoLogGroup { - GENERIC_WM(true, true, false, "WindowManager"), - + WM_ERROR(true, true, true, Consts.TAG_WM), + WM_DEBUG_ORIENTATION(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true, + Consts.TAG_WM), + WM_DEBUG_FOCUS_LIGHT(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), + WM_DEBUG_BOOT(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), + WM_DEBUG_RESIZE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), + WM_DEBUG_ADD_REMOVE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), + WM_DEBUG_FOCUS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM), + WM_DEBUG_STARTING_WINDOW(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), + WM_SHOW_TRANSACTIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), + WM_SHOW_SURFACE_ALLOC(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), + WM_DEBUG_APP_TRANSITIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), + WM_DEBUG_APP_TRANSITIONS_ANIM(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), + WM_DEBUG_RECENTS_ANIMATIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), + WM_DEBUG_DRAW(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM), + WM_DEBUG_REMOTE_ANIMATIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), + WM_DEBUG_SCREEN_ON(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM), + WM_DEBUG_KEEP_SCREEN_ON(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), + WM_DEBUG_WINDOW_MOVEMENT(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), TEST_GROUP(true, true, false, "WindowManagetProtoLogTest"); private final boolean mEnabled; @@ -95,4 +125,11 @@ public enum ProtoLogGroup implements IProtoLogGroup { "Test completed successfully: %b %d %o %x %e %g %f %% %s.", true, 1, 2, 3, 0.4, 0.5, 0.6, "ok"); } + + private static class Consts { + private static final String TAG_WM = "WindowManager"; + + private static final boolean ENABLE_DEBUG = true; + private static final boolean ENABLE_LOG_TO_PROTO_DEBUG = true; + } } diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java index 5cabbd97b1f7..31f4584cded9 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimation.java +++ b/services/core/java/com/android/server/wm/RecentsAnimation.java @@ -28,10 +28,10 @@ import static android.view.WindowManager.TRANSIT_NONE; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.BoundsAnimationController.BOUNDS; import static com.android.server.wm.BoundsAnimationController.FADE_IN; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS; import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_TOP; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS; import android.annotation.Nullable; import android.app.ActivityOptions; @@ -42,6 +42,7 @@ import android.os.Trace; import android.util.Slog; import android.view.IRecentsAnimationRunner; +import com.android.server.protolog.common.ProtoLog; import com.android.server.wm.RecentsAnimationController.RecentsAnimationCallbacks; /** @@ -51,7 +52,6 @@ import com.android.server.wm.RecentsAnimationController.RecentsAnimationCallback class RecentsAnimation implements RecentsAnimationCallbacks, ActivityDisplay.OnStackOrderChangedListener { private static final String TAG = RecentsAnimation.class.getSimpleName(); - private static final boolean DEBUG = DEBUG_RECENTS_ANIMATIONS; private final ActivityTaskManagerService mService; private final ActivityStackSupervisor mStackSupervisor; @@ -101,7 +101,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks, * is updated to the current one. */ void preloadRecentsActivity() { - if (DEBUG) Slog.d(TAG, "Preload recents with " + mTargetIntent); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Preload recents with %s", + mTargetIntent); ActivityStack targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED, mTargetActivityType); ActivityRecord targetActivity = getTargetActivity(targetStack); @@ -116,7 +117,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks, // keeps the original stopped state. targetActivity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */, true /* ignoreVisibility */); - if (DEBUG) Slog.d(TAG, "Updated config=" + targetActivity.getConfiguration()); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Updated config=%s", + targetActivity.getConfiguration()); } } else { // Create the activity record. Because the activity is invisible, this doesn't really @@ -131,7 +133,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, } if (!targetActivity.attachedToProcess()) { - if (DEBUG) Slog.d(TAG, "Real start recents"); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Real start recents"); mStackSupervisor.startSpecificActivityLocked(targetActivity, false /* andResume */, false /* checkConfig */); // Make sure the activity won't be involved in transition. @@ -155,7 +157,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, } void startRecentsActivity(IRecentsAnimationRunner recentsAnimationRunner) { - if (DEBUG) Slog.d(TAG, "startRecentsActivity(): intent=" + mTargetIntent); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "startRecentsActivity(): intent=%s", mTargetIntent); Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "RecentsAnimation#startRecentsActivity"); // TODO(multi-display) currently only support recents animation in default display. @@ -163,8 +165,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks, mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent; if (!mWindowManager.canStartRecentsAnimation()) { notifyAnimationCancelBeforeStart(recentsAnimationRunner); - if (DEBUG) Slog.d(TAG, "Can't start recents animation, nextAppTransition=" - + dc.mAppTransition.getAppTransition()); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, + "Can't start recents animation, nextAppTransition=%s", + dc.mAppTransition.getAppTransition()); return; } @@ -178,7 +181,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks, mRestoreTargetBehindStack = display.getStackAbove(targetStack); if (mRestoreTargetBehindStack == null) { notifyAnimationCancelBeforeStart(recentsAnimationRunner); - if (DEBUG) Slog.d(TAG, "No stack above target stack=" + targetStack); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, + "No stack above target stack=%s", targetStack); return; } } @@ -201,8 +205,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks, if (hasExistingActivity) { // Move the recents activity into place for the animation if it is not top most mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack); - if (DEBUG) Slog.d(TAG, "Moved stack=" + targetStack + " behind stack=" - + mDefaultDisplay.getStackAbove(targetStack)); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Moved stack=%s behind stack=%s", + targetStack, mDefaultDisplay.getStackAbove(targetStack)); // If there are multiple tasks in the target stack (ie. the home stack, with 3p // and default launchers coexisting), then move the task to the top as a part of @@ -220,17 +224,15 @@ class RecentsAnimation implements RecentsAnimationCallbacks, mTargetActivityType); targetActivity = getTargetActivity(targetStack); mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack); - if (DEBUG) { - Slog.d(TAG, "Moved stack=" + targetStack + " behind stack=" - + mDefaultDisplay.getStackAbove(targetStack)); - } + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Moved stack=%s behind stack=%s", + targetStack, mDefaultDisplay.getStackAbove(targetStack)); mWindowManager.prepareAppTransition(TRANSIT_NONE, false); mWindowManager.executeAppTransition(); // TODO: Maybe wait for app to draw in this particular case? - if (DEBUG) Slog.d(TAG, "Started intent=" + mTargetIntent); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Started intent=%s", mTargetIntent); } // Mark the target activity as launch-behind to bump its visibility for the @@ -268,9 +270,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks, private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode, boolean sendUserLeaveHint) { synchronized (mService.mGlobalLock) { - if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller=" - + mWindowManager.getRecentsAnimationController() - + " reorderMode=" + reorderMode); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, + "onAnimationFinished(): controller=%s reorderMode=%d", + mWindowManager.getRecentsAnimationController(), reorderMode); // Unregister for stack order changes mDefaultDisplay.unregisterStackOrderChangedListener(this); @@ -308,9 +310,10 @@ class RecentsAnimation implements RecentsAnimationCallbacks, final ActivityRecord targetActivity = targetStack != null ? targetStack.isInStackLocked(mLaunchedTargetActivity) : null; - if (DEBUG) Slog.d(TAG, "onAnimationFinished(): targetStack=" + targetStack - + " targetActivity=" + targetActivity - + " mRestoreTargetBehindStack=" + mRestoreTargetBehindStack); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, + "onAnimationFinished(): targetStack=%s targetActivity=%s " + + "mRestoreTargetBehindStack=%s", + targetStack, targetActivity, mRestoreTargetBehindStack); if (targetActivity == null) { return; } @@ -333,25 +336,28 @@ class RecentsAnimation implements RecentsAnimationCallbacks, targetStack.moveToFront("RecentsAnimation.onAnimationFinished()"); } - if (DEBUG) { + if (WM_DEBUG_RECENTS_ANIMATIONS.isLogToAny()) { final ActivityStack topStack = getTopNonAlwaysOnTopStack(); if (topStack != targetStack) { - Slog.w(TAG, "Expected target stack=" + targetStack - + " to be top most but found stack=" + topStack); + ProtoLog.w(WM_DEBUG_RECENTS_ANIMATIONS, + "Expected target stack=%s" + + " to be top most but found stack=%s", + targetStack, topStack); } } } else if (reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION){ // Restore the target stack to its previous position final ActivityDisplay display = targetActivity.getDisplay(); display.moveStackBehindStack(targetStack, mRestoreTargetBehindStack); - if (DEBUG) { + if (WM_DEBUG_RECENTS_ANIMATIONS.isLogToAny()) { final ActivityStack aboveTargetStack = mDefaultDisplay.getStackAbove(targetStack); if (mRestoreTargetBehindStack != null && aboveTargetStack != mRestoreTargetBehindStack) { - Slog.w(TAG, "Expected target stack=" + targetStack - + " to restored behind stack=" + mRestoreTargetBehindStack - + " but it is behind stack=" + aboveTargetStack); + ProtoLog.w(WM_DEBUG_RECENTS_ANIMATIONS, + "Expected target stack=%s to restored behind stack=%s but" + + " it is behind stack=%s", + targetStack, mRestoreTargetBehindStack, aboveTargetStack); } } } else { @@ -402,7 +408,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, @Override public void onStackOrderChanged(ActivityStack stack) { - if (DEBUG) Slog.d(TAG, "onStackOrderChanged(): stack=" + stack); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "onStackOrderChanged(): stack=%s", stack); if (mDefaultDisplay.getIndexOf(stack) == -1 || !stack.shouldBeVisible(null)) { // The stack is not visible, so ignore this change return; diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 795a2ca67ac3..bd27905e1a0f 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -29,8 +29,8 @@ import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_W import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM; import static com.android.server.wm.AnimationAdapterProto.REMOTE; import static com.android.server.wm.BoundsAnimationController.FADE_IN; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS; import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS; import static com.android.server.wm.WindowManagerInternal.AppTransitionListener; import android.annotation.IntDef; @@ -57,6 +57,7 @@ import android.view.SurfaceControl.Transaction; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import com.android.server.inputmethod.InputMethodManagerInternal; +import com.android.server.protolog.common.ProtoLog; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import com.android.server.wm.utils.InsetUtils; @@ -65,6 +66,7 @@ import com.google.android.collect.Sets; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.stream.Collectors; /** * Controls a single instance of the remote driven recents animation. In particular, this allows @@ -178,8 +180,8 @@ public class RecentsAnimationController implements DeathRecipient { @Override public TaskSnapshot screenshotTask(int taskId) { - if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "screenshotTask(" + taskId + "):" - + " mCanceled=" + mCanceled); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, + "screenshotTask(%d): mCanceled=%b", taskId, mCanceled); final long token = Binder.clearCallingIdentity(); try { synchronized (mService.getWindowManagerLock()) { @@ -208,8 +210,8 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void finish(boolean moveHomeToTop, boolean sendUserLeaveHint) { - if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "finish(" + moveHomeToTop + "):" - + " mCanceled=" + mCanceled); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, + "finish(%b): mCanceled=%b", moveHomeToTop, mCanceled); final long token = Binder.clearCallingIdentity(); try { synchronized (mService.getWindowManagerLock()) { @@ -250,8 +252,8 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void setInputConsumerEnabled(boolean enabled) { - if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "setInputConsumerEnabled(" + enabled + "):" - + " mCanceled=" + mCanceled); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, + "setInputConsumerEnabled(%s): mCanceled=%b", enabled, mCanceled); final long token = Binder.clearCallingIdentity(); try { synchronized (mService.getWindowManagerLock()) { @@ -392,8 +394,8 @@ public class RecentsAnimationController implements DeathRecipient { final AppWindowToken recentsComponentAppToken = targetStack.getTopChild().getTopFullscreenAppToken(); if (recentsComponentAppToken != null) { - if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "setHomeApp(" - + recentsComponentAppToken.getName() + ")"); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, + "setHomeApp(%s)", recentsComponentAppToken.getName()); mTargetAppToken = recentsComponentAppToken; if (recentsComponentAppToken.windowsCanBeWallpaperTarget()) { mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; @@ -418,7 +420,7 @@ public class RecentsAnimationController implements DeathRecipient { @VisibleForTesting AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) { - if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "addAnimation(" + task.getName() + ")"); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "addAnimation(%s)", task.getName()); final TaskAnimationAdapter taskAdapter = new TaskAnimationAdapter(task, isRecentTaskInvisible); task.startAnimation(task.getPendingTransaction(), taskAdapter, false /* hidden */); @@ -429,8 +431,8 @@ public class RecentsAnimationController implements DeathRecipient { @VisibleForTesting void removeAnimation(TaskAnimationAdapter taskAdapter) { - if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "removeAnimation(" - + taskAdapter.mTask.mTaskId + ")"); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, + "removeAnimation(%d)", taskAdapter.mTask.mTaskId); taskAdapter.mTask.setCanAffectSystemUiFlags(true); taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter); mPendingAnimations.remove(taskAdapter); @@ -438,14 +440,14 @@ public class RecentsAnimationController implements DeathRecipient { @VisibleForTesting void removeWallpaperAnimation(WallpaperAnimationAdapter wallpaperAdapter) { - if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "removeWallpaperAnimation()"); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "removeWallpaperAnimation()"); wallpaperAdapter.getLeashFinishedCallback().onAnimationFinished(wallpaperAdapter); mPendingWallpaperAnimations.remove(wallpaperAdapter); } void startAnimation() { - if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "startAnimation(): mPendingStart=" + mPendingStart - + " mCanceled=" + mCanceled); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, + "startAnimation(): mPendingStart=%b mCanceled=%b", mPendingStart, mCanceled); if (!mPendingStart || mCanceled) { // Skip starting if we've already started or canceled the animation return; @@ -483,13 +485,10 @@ public class RecentsAnimationController implements DeathRecipient { } mRunner.onAnimationStart(mController, appTargets, wallpaperTargets, contentInsets, minimizedHomeBounds); - if (DEBUG_RECENTS_ANIMATIONS) { - Slog.d(TAG, "startAnimation(): Notify animation start:"); - for (int i = 0; i < mPendingAnimations.size(); i++) { - final Task task = mPendingAnimations.get(i).mTask; - Slog.d(TAG, "\t" + task.mTaskId); - } - } + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, + "startAnimation(): Notify animation start: %s", + mPendingAnimations.stream() + .map(anim->anim.mTask.mTaskId).collect(Collectors.toList())); } catch (RemoteException e) { Slog.e(TAG, "Failed to start recents animation", e); } @@ -513,7 +512,7 @@ public class RecentsAnimationController implements DeathRecipient { } private RemoteAnimationTarget[] createWallpaperAnimations() { - if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "createWallpaperAnimations()"); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "createWallpaperAnimations()"); return WallpaperAnimationAdapter.startWallpaperAnimations(mService, 0L, 0L, adapter -> { synchronized (mService.mGlobalLock) { @@ -533,7 +532,7 @@ public class RecentsAnimationController implements DeathRecipient { } private void cancelAnimation(@ReorderMode int reorderMode, boolean screenshot, String reason) { - if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "cancelAnimation(): reason=" + reason); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "cancelAnimation(): reason=%s", reason); synchronized (mService.getWindowManagerLock()) { if (mCanceled) { // We've already canceled the animation @@ -627,9 +626,7 @@ public class RecentsAnimationController implements DeathRecipient { mRecentScreenshotAnimator = new SurfaceAnimator( animatable, () -> { - if (DEBUG_RECENTS_ANIMATIONS) { - Slog.d(TAG, "mRecentScreenshotAnimator finish"); - } + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "mRecentScreenshotAnimator finish"); mCallbacks.onAnimationFinished(reorderMode, false /* sendUserLeaveHint */); }, mService); mRecentScreenshotAnimator.transferAnimation(task.mSurfaceAnimator); @@ -637,9 +634,10 @@ public class RecentsAnimationController implements DeathRecipient { } void cleanupAnimation(@ReorderMode int reorderMode) { - if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, - "cleanupAnimation(): Notify animation finished mPendingAnimations=" - + mPendingAnimations.size() + " reorderMode=" + reorderMode); + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, + "cleanupAnimation(): Notify animation finished mPendingAnimations=%d " + + "reorderMode=%d", + mPendingAnimations.size(), reorderMode); for (int i = mPendingAnimations.size() - 1; i >= 0; i--) { final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i); if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) { diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java index 87bda4a545e1..2b2ae927dd96 100644 --- a/services/core/java/com/android/server/wm/RemoteAnimationController.java +++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java @@ -17,9 +17,8 @@ package com.android.server.wm; import static com.android.server.wm.AnimationAdapterProto.REMOTE; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_REMOTE_ANIMATIONS; import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_REMOTE_ANIMATIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -39,6 +38,8 @@ import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import com.android.internal.util.FastPrintWriter; +import com.android.server.protolog.ProtoLogImpl; +import com.android.server.protolog.common.ProtoLog; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import com.android.server.wm.utils.InsetUtils; @@ -51,7 +52,6 @@ import java.util.ArrayList; */ class RemoteAnimationController implements DeathRecipient { private static final String TAG = TAG_WITH_CLASS_NAME - || (DEBUG_REMOTE_ANIMATIONS && !DEBUG_APP_TRANSITIONS) ? "RemoteAnimationController" : TAG_WM; private static final long TIMEOUT_MS = 2000; @@ -86,8 +86,8 @@ class RemoteAnimationController implements DeathRecipient { */ RemoteAnimationRecord createRemoteAnimationRecord(AppWindowToken appWindowToken, Point position, Rect stackBounds, Rect startBounds) { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "createAnimationAdapter(): token=" - + appWindowToken); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createAnimationAdapter(): token=%s", + appWindowToken); final RemoteAnimationRecord adapters = new RemoteAnimationRecord(appWindowToken, position, stackBounds, startBounds); mPendingAnimations.add(adapters); @@ -98,11 +98,11 @@ class RemoteAnimationController implements DeathRecipient { * Called when the transition is ready to be started, and all leashes have been set up. */ void goodToGo() { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "goodToGo()"); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo()"); if (mPendingAnimations.isEmpty() || mCanceled) { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "goodToGo(): Animation finished already," - + " canceled=" + mCanceled - + " mPendingAnimations=" + mPendingAnimations.size()); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, + "goodToGo(): Animation finished already, canceled=%s mPendingAnimations=%d", + mCanceled, mPendingAnimations.size()); onAnimationFinished(); return; } @@ -115,7 +115,7 @@ class RemoteAnimationController implements DeathRecipient { // Create the app targets final RemoteAnimationTarget[] appTargets = createAppAnimations(); if (appTargets.length == 0) { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "goodToGo(): No apps to animate"); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo(): No apps to animate"); onAnimationFinished(); return; } @@ -131,8 +131,8 @@ class RemoteAnimationController implements DeathRecipient { Slog.e(TAG, "Failed to start remote animation", e); onAnimationFinished(); } - if (DEBUG_REMOTE_ANIMATIONS) { - Slog.d(TAG, "startAnimation(): Notify animation start:"); + if (ProtoLogImpl.isEnabled(WM_DEBUG_REMOTE_ANIMATIONS)) { + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation(): Notify animation start:"); writeStartDebugStatement(); } }); @@ -140,7 +140,7 @@ class RemoteAnimationController implements DeathRecipient { } void cancelAnimation(String reason) { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "cancelAnimation(): reason=" + reason); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "cancelAnimation(): reason=%s", reason); synchronized (mService.getWindowManagerLock()) { if (mCanceled) { return; @@ -152,28 +152,28 @@ class RemoteAnimationController implements DeathRecipient { } private void writeStartDebugStatement() { - Slog.i(TAG, "Starting remote animation"); + ProtoLog.i(WM_DEBUG_REMOTE_ANIMATIONS, "Starting remote animation"); final StringWriter sw = new StringWriter(); final FastPrintWriter pw = new FastPrintWriter(sw); for (int i = mPendingAnimations.size() - 1; i >= 0; i--) { mPendingAnimations.get(i).mAdapter.dump(pw, ""); } pw.close(); - Slog.i(TAG, sw.toString()); + ProtoLog.i(WM_DEBUG_REMOTE_ANIMATIONS, "%s", sw.toString()); } private RemoteAnimationTarget[] createAppAnimations() { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "createAppAnimations()"); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createAppAnimations()"); final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>(); for (int i = mPendingAnimations.size() - 1; i >= 0; i--) { final RemoteAnimationRecord wrappers = mPendingAnimations.get(i); final RemoteAnimationTarget target = wrappers.createRemoteAnimationTarget(); if (target != null) { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "\tAdd token=" + wrappers.mAppWindowToken); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tAdd token=%s", wrappers.mAppWindowToken); targets.add(target); } else { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "\tRemove token=" - + wrappers.mAppWindowToken); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tRemove token=%s", + wrappers.mAppWindowToken); // We can't really start an animation but we still need to make sure to finish the // pending animation that was started by SurfaceAnimator @@ -194,7 +194,7 @@ class RemoteAnimationController implements DeathRecipient { } private RemoteAnimationTarget[] createWallpaperAnimations() { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "createWallpaperAnimations()"); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createWallpaperAnimations()"); return WallpaperAnimationAdapter.startWallpaperAnimations(mService, mRemoteAnimationAdapter.getDuration(), mRemoteAnimationAdapter.getStatusBarTransitionDelay(), @@ -207,15 +207,15 @@ class RemoteAnimationController implements DeathRecipient { } private void onAnimationFinished() { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "onAnimationFinished(): mPendingAnimations=" - + mPendingAnimations.size()); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "onAnimationFinished(): mPendingAnimations=%d", + mPendingAnimations.size()); mHandler.removeCallbacks(mTimeoutRunnable); synchronized (mService.mGlobalLock) { unlinkToDeathOfRunner(); releaseFinishedCallback(); mService.openSurfaceTransaction(); try { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "onAnimationFinished(): Notify animation finished:"); for (int i = mPendingAnimations.size() - 1; i >= 0; i--) { final RemoteAnimationRecord adapters = mPendingAnimations.get(i); @@ -228,14 +228,14 @@ class RemoteAnimationController implements DeathRecipient { .onAnimationFinished(adapters.mThumbnailAdapter); } mPendingAnimations.remove(i); - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "\tapp=" + adapters.mAppWindowToken); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tapp=%s", adapters.mAppWindowToken); } for (int i = mPendingWallpaperAnimations.size() - 1; i >= 0; i--) { final WallpaperAnimationAdapter adapter = mPendingWallpaperAnimations.get(i); adapter.getLeashFinishedCallback().onAnimationFinished(adapter); mPendingWallpaperAnimations.remove(i); - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "\twallpaper=" + adapter.getToken()); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\twallpaper=%s", adapter.getToken()); } } catch (Exception e) { Slog.e(TAG, "Failed to finish remote animation", e); @@ -245,7 +245,7 @@ class RemoteAnimationController implements DeathRecipient { } } setRunningRemoteAnimation(false); - if (DEBUG_REMOTE_ANIMATIONS) Slog.i(TAG, "Finishing remote animation"); + ProtoLog.i(WM_DEBUG_REMOTE_ANIMATIONS, "Finishing remote animation"); } private void invokeAnimationCancelled() { @@ -306,7 +306,7 @@ class RemoteAnimationController implements DeathRecipient { @Override public void onAnimationFinished() throws RemoteException { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "app-onAnimationFinished(): mOuter=" + mOuter); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "app-onAnimationFinished(): mOuter=%s", mOuter); final long token = Binder.clearCallingIdentity(); try { if (mOuter != null) { @@ -326,7 +326,7 @@ class RemoteAnimationController implements DeathRecipient { * to prevent memory leak. */ void release() { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "app-release(): mOuter=" + mOuter); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "app-release(): mOuter=%s", mOuter); mOuter = null; } }; @@ -420,7 +420,7 @@ class RemoteAnimationController implements DeathRecipient { @Override public void startAnimation(SurfaceControl animationLeash, Transaction t, OnAnimationFinishedCallback finishCallback) { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "startAnimation"); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation"); // Restore z-layering, position and stack crop until client has a chance to modify it. t.setLayer(animationLeash, mRecord.mAppWindowToken.getPrefixOrderIndex()); diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 4365d0325545..78fcb37aacd1 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -29,20 +29,19 @@ import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; +import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC; +import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; import static com.android.server.wm.RootWindowContainerProto.DISPLAYS; import static com.android.server.wm.RootWindowContainerProto.WINDOWS; import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; -import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT; @@ -50,7 +49,6 @@ import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES; import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE; -import static com.android.server.wm.WindowManagerService.logSurface; import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE; import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION; import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING; @@ -80,6 +78,7 @@ import android.view.SurfaceControl; import android.view.WindowManager; import com.android.server.EventLogTags; +import com.android.server.protolog.common.ProtoLog; import java.io.PrintWriter; import java.util.ArrayList; @@ -195,8 +194,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> mTopFocusedDisplayId = topFocusedDisplayId; mWmService.mInputManager.setFocusedDisplay(topFocusedDisplayId); mWmService.mPolicy.setTopFocusedDisplay(topFocusedDisplayId); - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "New topFocusedDisplayId=" - + topFocusedDisplayId); + ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "New topFocusedDisplayId=%d", + topFocusedDisplayId); } return changed; } @@ -457,13 +456,13 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } void removeReplacedWindows() { - if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION removeReplacedWindows"); + ProtoLog.i(WM_SHOW_TRANSACTIONS, ">>> OPEN TRANSACTION removeReplacedWindows"); mWmService.openSurfaceTransaction(); try { forAllWindows(sRemoveReplacedWindowsConsumer, true /* traverseTopToBottom */); } finally { mWmService.closeSurfaceTransaction("removeReplacedWindows"); - if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION removeReplacedWindows"); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION removeReplacedWindows"); } } @@ -539,8 +538,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> Slog.w(TAG_WM, "Looks like we have reclaimed some memory, clearing surface for retry."); if (surfaceController != null) { - if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin, - "RECOVER DESTROY", false); + ProtoLog.i(WM_SHOW_SURFACE_ALLOC, + "SURFACE RECOVER DESTROY: %s", winAnimator.mWin); winAnimator.destroySurface(); if (winAnimator.mWin.mAppToken != null) { winAnimator.mWin.mAppToken.removeStartingWindow(); @@ -651,8 +650,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent> handleResizingWindows(); - if (DEBUG_ORIENTATION && mWmService.mDisplayFrozen) Slog.v(TAG, - "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete); + if (mWmService.mDisplayFrozen) { + ProtoLog.v(WM_DEBUG_ORIENTATION, + "With display frozen, orientationChangeComplete=%b", + mOrientationChangeComplete); + } if (mOrientationChangeComplete) { if (mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) { mWmService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE; @@ -714,7 +716,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } if (mUpdateRotation) { - if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation"); + ProtoLog.d(WM_DEBUG_ORIENTATION, "Performing post-rotate rotation"); mUpdateRotation = updateRotationUnchecked(); } @@ -868,29 +870,26 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final int privateflags = attrs.privateFlags; boolean displayHasContent = false; - if (DEBUG_KEEP_SCREEN_ON) { - Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked w: " + w - + ", w.mHasSurface: " + w.mHasSurface - + ", w.isOnScreen(): " + onScreen - + ", w.isDisplayedLw(): " + w.isDisplayedLw() - + ", w.mAttrs.userActivityTimeout: " + w.mAttrs.userActivityTimeout); - } + ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, + "handleNotObscuredLocked w: %s, w.mHasSurface: %b, w.isOnScreen(): %b, w" + + ".isDisplayedLw(): %b, w.mAttrs.userActivityTimeout: %d", + w, w.mHasSurface, onScreen, w.isDisplayedLw(), w.mAttrs.userActivityTimeout); if (w.mHasSurface && onScreen) { if (!syswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) { mUserActivityTimeout = w.mAttrs.userActivityTimeout; - if (DEBUG_KEEP_SCREEN_ON) { - Slog.d(TAG, "mUserActivityTimeout set to " + mUserActivityTimeout); - } + ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "mUserActivityTimeout set to %d", + mUserActivityTimeout); } } if (w.mHasSurface && canBeSeen) { if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) { mHoldScreen = w.mSession; mHoldScreenWindow = w; - } else if (DEBUG_KEEP_SCREEN_ON && w == mWmService.mLastWakeLockHoldingWindow) { - Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding " - + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by" - + Debug.getCallers(10)); + } else if (w == mWmService.mLastWakeLockHoldingWindow) { + ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, + "handleNotObscuredLocked: %s was holding screen wakelock but no longer " + + "has FLAG_KEEP_SCREEN_ON!!! called by%s", + w, Debug.getCallers(10)); } if (!syswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) { mScreenBrightness = w.mAttrs.screenBrightness; diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java index cbaf098fa4bd..157bd3b0038b 100644 --- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java @@ -16,10 +16,9 @@ package com.android.server.wm; +import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC; import static com.android.server.wm.ScreenRotationAnimationProto.ANIMATION_RUNNING; import static com.android.server.wm.ScreenRotationAnimationProto.STARTED; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER; @@ -27,6 +26,7 @@ import static com.android.server.wm.WindowStateAnimator.WINDOW_FREEZE_LAYER; import android.content.Context; import android.graphics.Matrix; +import android.graphics.Point; import android.graphics.Rect; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -39,8 +39,38 @@ import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Transformation; +import com.android.server.protolog.common.ProtoLog; + import java.io.PrintWriter; +/** + * This class handles the rotation animation when the device is rotated. + * + * <p> + * The screen rotation animation is composed of 4 different part: + * <ul> + * <li> The screenshot: <p> + * A screenshot of the whole screen prior the change of orientation is taken to hide the + * element resizing below. The screenshot is then animated to rotate and cross-fade to + * the new orientation with the content in the new orientation. + * + * <li> The windows on the display: <p>y + * Once the device is rotated, the screen and its content are in the new orientation. The + * animation first rotate the new content into the old orientation to then be able to + * animate to the new orientation + * + * <li> The exiting Blackframe: <p> + * Because the change of orientation might change the width and height of the content (i.e + * when rotating from portrait to landscape) we "crop" the new content using black frames + * around the screenshot so the new content does not go beyond the screenshot's bounds + * + * <li> The entering Blackframe: <p> + * The enter Blackframe is similar to the exit Blackframe but is only used when a custom + * rotation animation is used and matches the new content size instead of the screenshot. + * </ul> + * + * Each part has its own Surface which are then animated by {@link SurfaceAnimator}s. + */ class ScreenRotationAnimation { private static final String TAG = TAG_WITH_CLASS_NAME ? "ScreenRotationAnimation" : TAG_WM; @@ -66,6 +96,8 @@ class ScreenRotationAnimation { private final Matrix mSnapshotFinalMatrix = new Matrix(); private final Matrix mExitFrameFinalMatrix = new Matrix(); private final WindowManagerService mService; + private SurfaceControl mEnterBlackFrameLayer; + private SurfaceControl mRotationLayer; private SurfaceControl mSurfaceControl; private BlackFrame mEnteringBlackFrame; private int mWidth, mHeight; @@ -81,15 +113,14 @@ class ScreenRotationAnimation { // rotations. private Animation mRotateExitAnimation; private Animation mRotateEnterAnimation; + private Animation mRotateAlphaAnimation; private boolean mStarted; private boolean mAnimRunning; private boolean mFinishAnimReady; private long mFinishAnimStartTime; private boolean mForceDefaultOrientation; private BlackFrame mExitingBlackFrame; - private boolean mMoreRotateEnter; - private boolean mMoreRotateExit; - private long mHalfwayPoint; + private SurfaceRotationAnimationController mSurfaceRotationAnimationController; public ScreenRotationAnimation(Context context, DisplayContent displayContent, boolean fixedToUserRotation, boolean isSecure, WindowManagerService service) { @@ -126,11 +157,23 @@ class ScreenRotationAnimation { mOriginalRotation = originalRotation; mOriginalWidth = originalWidth; mOriginalHeight = originalHeight; + mSurfaceRotationAnimationController = new SurfaceRotationAnimationController(); final SurfaceControl.Transaction t = mService.mTransactionFactory.get(); try { - mSurfaceControl = displayContent.makeOverlay() + mRotationLayer = displayContent.makeOverlay() + .setName("RotationLayer") + .setContainerLayer() + .build(); + + mEnterBlackFrameLayer = displayContent.makeOverlay() + .setName("EnterBlackFrameLayer") + .setContainerLayer() + .build(); + + mSurfaceControl = displayContent.makeSurface(null) .setName("ScreenshotSurface") + .setParent(mRotationLayer) .setBufferSize(mWidth, mHeight) .setSecure(isSecure) .build(); @@ -160,8 +203,10 @@ class ScreenRotationAnimation { if (gb.containsSecureLayers()) { t.setSecure(mSurfaceControl, true); } + t.setLayer(mRotationLayer, SCREEN_FREEZE_LAYER_BASE); t.setLayer(mSurfaceControl, SCREEN_FREEZE_LAYER_SCREENSHOT); t.setAlpha(mSurfaceControl, 0); + t.show(mRotationLayer); t.show(mSurfaceControl); } else { Slog.w(TAG, "Unable to take screenshot of display " + displayId); @@ -171,10 +216,8 @@ class ScreenRotationAnimation { Slog.w(TAG, "Unable to allocate freeze surface", e); } - if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { - Slog.i(TAG_WM, - " FREEZE " + mSurfaceControl + ": CREATE"); - } + ProtoLog.i(WM_SHOW_SURFACE_ALLOC, + " FREEZE %s: CREATE", mSurfaceControl); setRotation(t, originalRotation); t.apply(); } @@ -211,22 +254,26 @@ class ScreenRotationAnimation { return mSurfaceControl != null; } - private void setSnapshotTransform(SurfaceControl.Transaction t, Matrix matrix, float alpha) { - if (mSurfaceControl != null) { - matrix.getValues(mTmpFloats); - float x = mTmpFloats[Matrix.MTRANS_X]; - float y = mTmpFloats[Matrix.MTRANS_Y]; - if (mForceDefaultOrientation) { - mDisplayContent.getBounds(mCurrentDisplayRect); - x -= mCurrentDisplayRect.left; - y -= mCurrentDisplayRect.top; - } - t.setPosition(mSurfaceControl, x, y); - t.setMatrix(mSurfaceControl, - mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y], - mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]); - t.setAlpha(mSurfaceControl, alpha); + private void setRotationTransform(SurfaceControl.Transaction t, Matrix matrix) { + if (mRotationLayer == null) { + return; } + matrix.getValues(mTmpFloats); + float x = mTmpFloats[Matrix.MTRANS_X]; + float y = mTmpFloats[Matrix.MTRANS_Y]; + if (mForceDefaultOrientation) { + mDisplayContent.getBounds(mCurrentDisplayRect); + x -= mCurrentDisplayRect.left; + y -= mCurrentDisplayRect.top; + } + t.setPosition(mRotationLayer, x, y); + t.setMatrix(mRotationLayer, + mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y], + mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]); + + t.setAlpha(mSurfaceControl, (float) 1.0); + t.setAlpha(mRotationLayer, (float) 1.0); + t.show(mRotationLayer); } public void printTo(String prefix, PrintWriter pw) { @@ -237,7 +284,9 @@ class ScreenRotationAnimation { if (mExitingBlackFrame != null) { mExitingBlackFrame.printTo(prefix + " ", pw); } - pw.print(prefix); pw.print("mEnteringBlackFrame="); pw.println(mEnteringBlackFrame); + pw.print(prefix); + pw.print("mEnteringBlackFrame="); + pw.println(mEnteringBlackFrame); if (mEnteringBlackFrame != null) { mEnteringBlackFrame.printTo(prefix + " ", pw); } @@ -283,7 +332,7 @@ class ScreenRotationAnimation { int delta = DisplayContent.deltaRotation(rotation, Surface.ROTATION_0); createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix); - setSnapshotTransform(t, mSnapshotInitialMatrix, 1.0f); + setRotationTransform(t, mSnapshotInitialMatrix); } /** @@ -304,6 +353,9 @@ class ScreenRotationAnimation { // Figure out how the screen has moved from the original rotation. int delta = DisplayContent.deltaRotation(mCurRotation, mOriginalRotation); + mRotateAlphaAnimation = AnimationUtils.loadAnimation(mContext, + com.android.internal.R.anim.screen_rotate_alpha); + final boolean customAnim; if (exitAnim != 0 && enterAnim != 0) { customAnim = true; @@ -353,6 +405,8 @@ class ScreenRotationAnimation { mRotateExitAnimation.scaleCurrentDuration(animationScale); mRotateEnterAnimation.restrictDuration(maxAnimationDuration); mRotateEnterAnimation.scaleCurrentDuration(animationScale); + mRotateAlphaAnimation.restrictDuration(maxAnimationDuration); + mRotateAlphaAnimation.scaleCurrentDuration(animationScale); if (!customAnim && mExitingBlackFrame == null) { try { @@ -373,13 +427,12 @@ class ScreenRotationAnimation { outer = mCurrentDisplayRect; inner = mOriginalDisplayRect; } else { - outer = new Rect(-mOriginalWidth * 1, -mOriginalHeight * 1, - mOriginalWidth * 2, mOriginalHeight * 2); - inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight); + outer = new Rect(-mWidth, -mHeight, mWidth * 2, mHeight * 2); + inner = new Rect(0, 0, mWidth, mHeight); } mExitingBlackFrame = new BlackFrame(mService.mTransactionFactory, t, outer, inner, - SCREEN_FREEZE_LAYER_EXIT, mDisplayContent, mForceDefaultOrientation); - mExitingBlackFrame.setMatrix(t, mFrameInitialMatrix); + SCREEN_FREEZE_LAYER_EXIT, mDisplayContent, mForceDefaultOrientation, + mRotationLayer); } catch (OutOfResourcesException e) { Slog.w(TAG, "Unable to allocate black surface", e); } @@ -387,16 +440,17 @@ class ScreenRotationAnimation { if (customAnim && mEnteringBlackFrame == null) { try { - Rect outer = new Rect(-finalWidth * 1, -finalHeight * 1, + Rect outer = new Rect(-finalWidth, -finalHeight, finalWidth * 2, finalHeight * 2); Rect inner = new Rect(0, 0, finalWidth, finalHeight); mEnteringBlackFrame = new BlackFrame(mService.mTransactionFactory, t, outer, inner, - SCREEN_FREEZE_LAYER_ENTER, mDisplayContent, false); + SCREEN_FREEZE_LAYER_ENTER, mDisplayContent, false, mEnterBlackFrameLayer); } catch (OutOfResourcesException e) { Slog.w(TAG, "Unable to allocate black surface", e); } } + mSurfaceRotationAnimationController.startAnimation(); return true; } @@ -421,14 +475,27 @@ class ScreenRotationAnimation { } public void kill() { + if (mSurfaceRotationAnimationController != null) { + mSurfaceRotationAnimationController.cancel(); + mSurfaceRotationAnimationController = null; + } if (mSurfaceControl != null) { - if (SHOW_TRANSACTIONS || - SHOW_SURFACE_ALLOC) { - Slog.i(TAG_WM, - " FREEZE " + mSurfaceControl + ": DESTROY"); - } - mService.mTransactionFactory.get().remove(mSurfaceControl).apply(); + ProtoLog.i(WM_SHOW_SURFACE_ALLOC, " FREEZE %s: DESTROY", mSurfaceControl); mSurfaceControl = null; + SurfaceControl.Transaction t = mService.mTransactionFactory.get(); + if (mRotationLayer != null) { + if (mRotationLayer.isValid()) { + t.remove(mRotationLayer); + } + mRotationLayer = null; + } + if (mEnterBlackFrameLayer != null) { + if (mEnterBlackFrameLayer.isValid()) { + t.remove(mEnterBlackFrameLayer); + } + mEnterBlackFrameLayer = null; + } + t.apply(); } if (mExitingBlackFrame != null) { mExitingBlackFrame.kill(); @@ -446,124 +513,186 @@ class ScreenRotationAnimation { mRotateEnterAnimation.cancel(); mRotateEnterAnimation = null; } + if (mRotateAlphaAnimation != null) { + mRotateAlphaAnimation.cancel(); + mRotateAlphaAnimation = null; + } } public boolean isAnimating() { - return hasAnimations(); + return mSurfaceRotationAnimationController != null + && mSurfaceRotationAnimationController.isAnimating(); } public boolean isRotating() { return mCurRotation != mOriginalRotation; } - private boolean hasAnimations() { - return mRotateEnterAnimation != null || mRotateExitAnimation != null; + public Transformation getEnterTransformation() { + return mEnterTransformation; } - private boolean stepAnimation(long now) { - if (now > mHalfwayPoint) { - mHalfwayPoint = Long.MAX_VALUE; - } - if (mFinishAnimReady && mFinishAnimStartTime < 0) { - mFinishAnimStartTime = now; - } - - mMoreRotateExit = false; - if (mRotateExitAnimation != null) { - mMoreRotateExit = mRotateExitAnimation.getTransformation(now, - mRotateExitTransformation); - } - - mMoreRotateEnter = false; - if (mRotateEnterAnimation != null) { - mMoreRotateEnter = mRotateEnterAnimation.getTransformation(now, - mRotateEnterTransformation); - } - - if (!mMoreRotateExit) { - if (mRotateExitAnimation != null) { - mRotateExitAnimation.cancel(); - mRotateExitAnimation = null; - mRotateExitTransformation.clear(); + /** + * Utility class that runs a {@link ScreenRotationAnimation} on the {@link + * SurfaceAnimationRunner}. + * <p> + * The rotation animation is divided into the following hierarchy: + * <ul> + * <li> A first rotation layer, containing the blackframes. This layer is animated by the + * "screen_rotate_X_exit" that applies a scale and rotate and where X is value of the rotation. + * <ul> + * <li> A child layer containing the screenshot on which is added an animation of it's + * alpha channel ("screen_rotate_alpha") and that will rotate with his parent layer.</li> + * </ul> + * <li> A second rotation layer used when custom animations are passed in + * {@link ScreenRotationAnimation#startAnimation( + * SurfaceControl.Transaction, long, float, int, int, int, int)}. + * </ul> + * <p> + * Thus an {@link LocalAnimationAdapter.AnimationSpec} is created for each of + * this three {@link SurfaceControl}s which then delegates the animation to the + * {@link ScreenRotationAnimation}. + */ + class SurfaceRotationAnimationController { + private SurfaceAnimator mDisplayAnimator; + private SurfaceAnimator mEnterBlackFrameAnimator; + private SurfaceAnimator mScreenshotRotationAnimator; + private SurfaceAnimator mRotateScreenAnimator; + private final Runnable mNoopCallback = () -> { // b/141177184 + }; + + /** + * Start the rotation animation of the display and the screenshot on the + * {@link SurfaceAnimationRunner}. + */ + void startAnimation() { + mRotateScreenAnimator = startScreenshotAlphaAnimation(); + mDisplayAnimator = startDisplayRotation(); + if (mExitingBlackFrame != null) { + mScreenshotRotationAnimator = startScreenshotRotationAnimation(); } - } - - if (!mMoreRotateEnter) { - if (mRotateEnterAnimation != null) { - mRotateEnterAnimation.cancel(); - mRotateEnterAnimation = null; - mRotateEnterTransformation.clear(); + if (mEnteringBlackFrame != null) { + mEnterBlackFrameAnimator = startEnterBlackFrameAnimation(); } } - mExitTransformation.set(mRotateExitTransformation); - mEnterTransformation.set(mRotateEnterTransformation); - - final boolean more = mMoreRotateEnter || mMoreRotateExit - || !mFinishAnimReady; - - mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix); - - return more; - } - - void updateSurfaces(SurfaceControl.Transaction t) { - if (!mStarted) { - return; - } - - if (mSurfaceControl != null) { - if (!mMoreRotateExit) { - t.hide(mSurfaceControl); + private SimpleSurfaceAnimatable.Builder initializeBuilder() { + return new SimpleSurfaceAnimatable.Builder() + .setPendingTransactionSupplier(mDisplayContent::getPendingTransaction) + .setCommitTransactionRunnable(mDisplayContent::commitPendingTransaction) + .setAnimationLeashSupplier(mDisplayContent::makeOverlay); + } + + private SurfaceAnimator startDisplayRotation() { + return startAnimation(initializeBuilder() + .setAnimationLeashParent(mDisplayContent.getSurfaceControl()) + .setSurfaceControl(mDisplayContent.getWindowingLayer()) + .setParentSurfaceControl(mDisplayContent.getSurfaceControl()) + .setWidth(mDisplayContent.getSurfaceWidth()) + .setHeight(mDisplayContent.getSurfaceHeight()) + .build(), + createWindowAnimationSpec(mRotateEnterAnimation), + this::cancel); + } + + private SurfaceAnimator startScreenshotAlphaAnimation() { + return startAnimation(initializeBuilder() + .setSurfaceControl(mSurfaceControl) + .setAnimationLeashParent(mRotationLayer) + .setWidth(mWidth) + .setHeight(mHeight) + .build(), + createWindowAnimationSpec(mRotateAlphaAnimation), + mNoopCallback); + } + + private SurfaceAnimator startEnterBlackFrameAnimation() { + return startAnimation(initializeBuilder() + .setSurfaceControl(mEnterBlackFrameLayer) + .setAnimationLeashParent(mDisplayContent.getOverlayLayer()) + .build(), + createWindowAnimationSpec(mRotateEnterAnimation), + mNoopCallback); + } + + private SurfaceAnimator startScreenshotRotationAnimation() { + return startAnimation(initializeBuilder() + .setSurfaceControl(mRotationLayer) + .setAnimationLeashParent(mDisplayContent.getOverlayLayer()) + .build(), + createWindowAnimationSpec(mRotateExitAnimation), + this::onAnimationEnd); + } + + private WindowAnimationSpec createWindowAnimationSpec(Animation mAnimation) { + return new WindowAnimationSpec(mAnimation, new Point(0, 0) /* position */, + false /* canSkipFirstFrame */, 0 /* WindowCornerRadius */); + } + + /** + * Start an animation defined by animationSpec on a new {@link SurfaceAnimator}. + * + * @param animatable The animatable used for the animation. + * @param animationSpec The spec of the animation. + * @param animationFinishedCallback Callback passed to the {@link SurfaceAnimator} and + * called when the animation finishes. + * @return The newly created {@link SurfaceAnimator} that as been started. + */ + private SurfaceAnimator startAnimation( + SurfaceAnimator.Animatable animatable, + LocalAnimationAdapter.AnimationSpec animationSpec, + Runnable animationFinishedCallback) { + SurfaceAnimator animator = new SurfaceAnimator( + animatable, animationFinishedCallback, mService); + + LocalAnimationAdapter localAnimationAdapter = new LocalAnimationAdapter( + animationSpec, mService.mSurfaceAnimationRunner); + + animator.startAnimation(mDisplayContent.getPendingTransaction(), + localAnimationAdapter, false); + return animator; + } + + private void onAnimationEnd() { + mEnterBlackFrameAnimator = null; + mScreenshotRotationAnimator = null; + mRotateScreenAnimator = null; + mService.mAnimator.mBulkUpdateParams |= WindowSurfacePlacer.SET_UPDATE_ROTATION; + kill(); + mService.updateRotation(false, false); + AccessibilityController accessibilityController = mService.mAccessibilityController; + + if (accessibilityController != null) { + // We just finished rotation animation which means we did not + // announce the rotation and waited for it to end, announce now. + accessibilityController.onRotationChangedLocked(mDisplayContent); } } - if (mExitingBlackFrame != null) { - if (!mMoreRotateExit) { - mExitingBlackFrame.hide(t); - } else { - mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), - mFrameInitialMatrix); - mExitingBlackFrame.setMatrix(t, mExitFrameFinalMatrix); - if (mForceDefaultOrientation) { - mExitingBlackFrame.setAlpha(t, mExitTransformation.getAlpha()); - } + public void cancel() { + if (mEnterBlackFrameAnimator != null) { + mEnterBlackFrameAnimator.cancelAnimation(); } - } - if (mEnteringBlackFrame != null) { - if (!mMoreRotateEnter) { - mEnteringBlackFrame.hide(t); - } else { - mEnteringBlackFrame.setMatrix(t, mEnterTransformation.getMatrix()); + if (mScreenshotRotationAnimator != null) { + mScreenshotRotationAnimator.cancelAnimation(); } - } - - t.setEarlyWakeup(); - setSnapshotTransform(t, mSnapshotFinalMatrix, mExitTransformation.getAlpha()); - } - public boolean stepAnimationLocked(long now) { - if (!hasAnimations()) { - mFinishAnimReady = false; - return false; - } - - if (!mAnimRunning) { - if (mRotateEnterAnimation != null) { - mRotateEnterAnimation.setStartTime(now); + if (mRotateScreenAnimator != null) { + mRotateScreenAnimator.cancelAnimation(); } - if (mRotateExitAnimation != null) { - mRotateExitAnimation.setStartTime(now); + + if (mDisplayAnimator != null) { + mDisplayAnimator.cancelAnimation(); } - mAnimRunning = true; - mHalfwayPoint = now + mRotateEnterAnimation.getDuration() / 2; } - return stepAnimation(now); - } - - public Transformation getEnterTransformation() { - return mEnterTransformation; + public boolean isAnimating() { + return mDisplayAnimator != null && mDisplayAnimator.isAnimating() + || mEnterBlackFrameAnimator != null && mEnterBlackFrameAnimator.isAnimating() + || mRotateScreenAnimator != null && mRotateScreenAnimator.isAnimating() + || mScreenshotRotationAnimator != null + && mScreenshotRotationAnimator.isAnimating(); + } } } diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 72bb355146d1..b047d8f8a7b9 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -24,9 +24,9 @@ import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType; +import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.Nullable; @@ -56,6 +56,7 @@ import android.view.SurfaceSession; import android.view.WindowManager; import com.android.internal.os.logging.MetricsLoggerWrapper; +import com.android.server.protolog.common.ProtoLog; import com.android.server.wm.WindowManagerService.H; import java.io.PrintWriter; @@ -478,8 +479,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { Slog.v(TAG_WM, "First window added to " + this + ", creating SurfaceSession"); } mSurfaceSession = new SurfaceSession(); - if (SHOW_TRANSACTIONS) Slog.i( - TAG_WM, " NEW SURFACE SESSION " + mSurfaceSession); + ProtoLog.i(WM_SHOW_TRANSACTIONS, " NEW SURFACE SESSION %s", mSurfaceSession); mService.mSessions.add(this); if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) { mService.dispatchNewAnimatorScaleLocked(this); @@ -570,7 +570,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { Slog.v(TAG_WM, "Last window removed from " + this + ", destroying " + mSurfaceSession); } - if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " KILL SURFACE SESSION " + mSurfaceSession); + ProtoLog.i(WM_SHOW_TRANSACTIONS, " KILL SURFACE SESSION %s", mSurfaceSession); try { mSurfaceSession.kill(); } catch (Exception e) { diff --git a/services/core/java/com/android/server/wm/SimpleSurfaceAnimatable.java b/services/core/java/com/android/server/wm/SimpleSurfaceAnimatable.java new file mode 100644 index 000000000000..bf5d5e2653a8 --- /dev/null +++ b/services/core/java/com/android/server/wm/SimpleSurfaceAnimatable.java @@ -0,0 +1,308 @@ +/* + * Copyright (C) 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. + */ + +package com.android.server.wm; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.view.SurfaceControl; + +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Supplier; + +/** + * An implementation of {@link SurfaceAnimator.Animatable} that is instantiated + * using a builder pattern for more convenience over reimplementing the whole interface. + * <p> + * Use {@link SimpleSurfaceAnimatable.Builder} to create a new instance of this class. + * + * @see com.android.server.wm.SurfaceAnimator.Animatable + */ +public class SimpleSurfaceAnimatable implements SurfaceAnimator.Animatable { + private final int mWidth; + private final int mHeight; + private final boolean mShouldDeferAnimationFinish; + private final SurfaceControl mAnimationLeashParent; + private final SurfaceControl mSurfaceControl; + private final SurfaceControl mParentSurfaceControl; + private final Runnable mCommitTransactionRunnable; + private final Supplier<SurfaceControl.Builder> mAnimationLeashFactory; + private final Supplier<SurfaceControl.Transaction> mPendingTransaction; + private final BiConsumer<SurfaceControl.Transaction, SurfaceControl> mOnAnimationLeashCreated; + private final Consumer<SurfaceControl.Transaction> mOnAnimationLeashLost; + private final Consumer<Runnable> mOnAnimationFinished; + + /** + * Use {@link SimpleSurfaceAnimatable.Builder} to create a new instance. + */ + private SimpleSurfaceAnimatable(Builder builder) { + mWidth = builder.mWidth; + mHeight = builder.mHeight; + mShouldDeferAnimationFinish = builder.mShouldDeferAnimationFinish; + mAnimationLeashParent = builder.mAnimationLeashParent; + mSurfaceControl = builder.mSurfaceControl; + mParentSurfaceControl = builder.mParentSurfaceControl; + mCommitTransactionRunnable = builder.mCommitTransactionRunnable; + mAnimationLeashFactory = builder.mAnimationLeashFactory; + mOnAnimationLeashCreated = builder.mOnAnimationLeashCreated; + mOnAnimationLeashLost = builder.mOnAnimationLeashLost; + mPendingTransaction = builder.mPendingTransactionSupplier; + mOnAnimationFinished = builder.mOnAnimationFinished; + } + + @NonNull + @Override + public SurfaceControl.Transaction getPendingTransaction() { + return mPendingTransaction.get(); + } + + @Override + public void commitPendingTransaction() { + mCommitTransactionRunnable.run(); + } + + @Override + public void onAnimationLeashCreated(SurfaceControl.Transaction t, SurfaceControl leash) { + if (mOnAnimationLeashCreated != null) { + mOnAnimationLeashCreated.accept(t, leash); + } + + } + + @Override + public void onAnimationLeashLost(SurfaceControl.Transaction t) { + if (mOnAnimationLeashLost != null) { + mOnAnimationLeashLost.accept(t); + } + } + + @Override + @NonNull + public SurfaceControl.Builder makeAnimationLeash() { + return mAnimationLeashFactory.get(); + } + + @Override + public SurfaceControl getAnimationLeashParent() { + return mAnimationLeashParent; + } + + @Override + @Nullable + public SurfaceControl getSurfaceControl() { + return mSurfaceControl; + } + + @Override + public SurfaceControl getParentSurfaceControl() { + return mParentSurfaceControl; + } + + @Override + public int getSurfaceWidth() { + return mWidth; + } + + @Override + public int getSurfaceHeight() { + return mHeight; + } + + @Override + public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) { + if (mOnAnimationFinished != null) { + mOnAnimationFinished.accept(endDeferFinishCallback); + } + return mShouldDeferAnimationFinish; + } + + /** + * Builder class to create a {@link SurfaceAnimator.Animatable} without having to + * create a new class that implements the interface. + */ + static class Builder { + private int mWidth = -1; + private int mHeight = -1; + private boolean mShouldDeferAnimationFinish = false; + + @Nullable + private SurfaceControl mAnimationLeashParent = null; + + @Nullable + private SurfaceControl mSurfaceControl = null; + + @Nullable + private SurfaceControl mParentSurfaceControl = null; + private Runnable mCommitTransactionRunnable; + + @Nullable + private BiConsumer<SurfaceControl.Transaction, SurfaceControl> mOnAnimationLeashCreated = + null; + + @Nullable + private Consumer<SurfaceControl.Transaction> mOnAnimationLeashLost = null; + + @Nullable + private Consumer<Runnable> mOnAnimationFinished = null; + + @NonNull + private Supplier<SurfaceControl.Transaction> mPendingTransactionSupplier; + + @NonNull + private Supplier<SurfaceControl.Builder> mAnimationLeashFactory; + + /** + * Set the runnable to be called when + * {@link SurfaceAnimator.Animatable#commitPendingTransaction()} + * is called. + * + * @see SurfaceAnimator.Animatable#commitPendingTransaction() + */ + public SimpleSurfaceAnimatable.Builder setCommitTransactionRunnable( + @NonNull Runnable commitTransactionRunnable) { + mCommitTransactionRunnable = commitTransactionRunnable; + return this; + } + + /** + * Set the callback called when + * {@link SurfaceAnimator.Animatable#onAnimationLeashCreated(SurfaceControl.Transaction, + * SurfaceControl)} is called + * + * @see SurfaceAnimator.Animatable#onAnimationLeashCreated(SurfaceControl.Transaction, + * SurfaceControl) + */ + public SimpleSurfaceAnimatable.Builder setOnAnimationLeashCreated( + @Nullable BiConsumer<SurfaceControl.Transaction, SurfaceControl> + onAnimationLeashCreated) { + mOnAnimationLeashCreated = onAnimationLeashCreated; + return this; + } + + /** + * Set the callback called when + * {@link SurfaceAnimator.Animatable#onAnimationLeashLost(SurfaceControl.Transaction)} + * (SurfaceControl.Transaction, SurfaceControl)} is called + * + * @see SurfaceAnimator.Animatable#onAnimationLeashLost(SurfaceControl.Transaction) + */ + public SimpleSurfaceAnimatable.Builder setOnAnimationLeashLost( + @Nullable Consumer<SurfaceControl.Transaction> onAnimationLeashLost) { + mOnAnimationLeashLost = onAnimationLeashLost; + return this; + } + + /** + * @see SurfaceAnimator.Animatable#getPendingTransaction() + */ + public Builder setPendingTransactionSupplier( + @NonNull Supplier<SurfaceControl.Transaction> pendingTransactionSupplier) { + mPendingTransactionSupplier = pendingTransactionSupplier; + return this; + } + + /** + * Set the {@link Supplier} responsible for creating a new animation leash. + * + * @see SurfaceAnimator.Animatable#makeAnimationLeash() + */ + public SimpleSurfaceAnimatable.Builder setAnimationLeashSupplier( + @NonNull Supplier<SurfaceControl.Builder> animationLeashFactory) { + mAnimationLeashFactory = animationLeashFactory; + return this; + } + + /** + * @see SurfaceAnimator.Animatable#getAnimationLeashParent() + */ + public SimpleSurfaceAnimatable.Builder setAnimationLeashParent( + SurfaceControl animationLeashParent) { + mAnimationLeashParent = animationLeashParent; + return this; + } + + /** + * @see SurfaceAnimator.Animatable#getSurfaceControl() + */ + public SimpleSurfaceAnimatable.Builder setSurfaceControl( + @NonNull SurfaceControl surfaceControl) { + mSurfaceControl = surfaceControl; + return this; + } + + /** + * @see SurfaceAnimator.Animatable#getParentSurfaceControl() + */ + public SimpleSurfaceAnimatable.Builder setParentSurfaceControl( + SurfaceControl parentSurfaceControl) { + mParentSurfaceControl = parentSurfaceControl; + return this; + } + + /** + * Default to -1. + * + * @see SurfaceAnimator.Animatable#getSurfaceWidth() + */ + public SimpleSurfaceAnimatable.Builder setWidth(int width) { + mWidth = width; + return this; + } + + /** + * Default to -1. + * + * @see SurfaceAnimator.Animatable#getSurfaceHeight() + */ + public SimpleSurfaceAnimatable.Builder setHeight(int height) { + mHeight = height; + return this; + } + + /** + * Set the value returned by + * {@link SurfaceAnimator.Animatable#shouldDeferAnimationFinish(Runnable)}. + * + * @param onAnimationFinish will be called with the runnable to execute when the animation + * needs to be finished. + * @see SurfaceAnimator.Animatable#shouldDeferAnimationFinish(Runnable) + */ + public SimpleSurfaceAnimatable.Builder setShouldDeferAnimationFinish( + boolean shouldDeferAnimationFinish, + @Nullable Consumer<Runnable> onAnimationFinish) { + mShouldDeferAnimationFinish = shouldDeferAnimationFinish; + mOnAnimationFinished = onAnimationFinish; + return this; + } + + public SurfaceAnimator.Animatable build() { + if (mPendingTransactionSupplier == null) { + throw new IllegalArgumentException("mPendingTransactionSupplier cannot be null"); + } + if (mAnimationLeashFactory == null) { + throw new IllegalArgumentException("mAnimationLeashFactory cannot be null"); + } + if (mCommitTransactionRunnable == null) { + throw new IllegalArgumentException("mCommitTransactionRunnable cannot be null"); + } + if (mSurfaceControl == null) { + throw new IllegalArgumentException("mSurfaceControl cannot be null"); + } + return new SimpleSurfaceAnimatable(this); + } + } +} diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java index fc8a27d64fce..b680fa45f00f 100644 --- a/services/core/java/com/android/server/wm/TaskPositioner.java +++ b/services/core/java/com/android/server/wm/TaskPositioner.java @@ -21,7 +21,7 @@ import static android.app.ActivityTaskManager.RESIZE_MODE_USER_FORCED; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -54,6 +54,7 @@ import android.view.SurfaceControl; import android.view.WindowManager; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.protolog.common.ProtoLog; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -297,9 +298,7 @@ class TaskPositioner implements IBinder.DeathRecipient { mDragWindowHandle.frameBottom = p.y; // Pause rotations before a drag. - if (DEBUG_ORIENTATION) { - Slog.d(TAG, "Pausing rotation during re-position"); - } + ProtoLog.d(WM_DEBUG_ORIENTATION, "Pausing rotation during re-position"); mDisplayContent.getDisplayRotation().pause(); // Notify InputMonitor to take mDragWindowHandle. @@ -340,9 +339,7 @@ class TaskPositioner implements IBinder.DeathRecipient { mDisplayContent.getInputMonitor().updateInputWindowsLw(true /*force*/); // Resume rotations after a drag. - if (DEBUG_ORIENTATION) { - Slog.d(TAG, "Resuming rotation after re-position"); - } + ProtoLog.d(WM_DEBUG_ORIENTATION, "Resuming rotation after re-position"); mDisplayContent.getDisplayRotation().resume(); mDisplayContent = null; mClientCallback.unlinkToDeath(this, 0 /* flags */); diff --git a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java index f291573f854a..adecc36671c9 100644 --- a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java +++ b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java @@ -15,14 +15,15 @@ */ package com.android.server.wm; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS; import android.graphics.GraphicBuffer; -import android.util.Slog; import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceSession; +import com.android.server.protolog.common.ProtoLog; + import java.util.function.Function; /** @@ -45,10 +46,9 @@ class TaskScreenshotAnimatable implements SurfaceAnimator.Animatable { mTask = task; mWidth = (buffer != null) ? buffer.getWidth() : 1; mHeight = (buffer != null) ? buffer.getHeight() : 1; - if (DEBUG_RECENTS_ANIMATIONS) { - Slog.d(TAG, "Creating TaskScreenshotAnimatable: task: " + task - + "width: " + mWidth + "height: " + mHeight); - } + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, + "Creating TaskScreenshotAnimatable: task: %s width: %d height: %d", + task, mWidth, mHeight); mSurfaceControl = surfaceControlFactory.apply(new SurfaceSession()) .setName("RecentTaskScreenshotSurface") .setBufferSize(mWidth, mHeight) diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java index 7456f0d78137..d070850a895f 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java @@ -42,7 +42,7 @@ import static com.android.internal.policy.DecorView.STATUS_BAR_COLOR_VIEW_ATTRIB import static com.android.internal.policy.DecorView.getColorViewLeftInset; import static com.android.internal.policy.DecorView.getColorViewTopInset; import static com.android.internal.policy.DecorView.getNavigationBarRect; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -79,6 +79,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.DecorView; import com.android.internal.view.BaseIWindow; import com.android.server.policy.WindowManagerPolicy.StartingSurface; +import com.android.server.protolog.common.ProtoLog; /** * This class represents a starting window that shows a snapshot. @@ -259,14 +260,14 @@ class TaskSnapshotSurface implements StartingSurface { final long now = SystemClock.uptimeMillis(); if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS) { mHandler.postAtTime(this::remove, mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS); - if (DEBUG_STARTING_WINDOW) { - Slog.v(TAG, "Defer removing snapshot surface in " + (now - mShownTime) + "ms"); - } + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, + "Defer removing snapshot surface in %dms", (now - mShownTime)); + return; } } try { - if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Removing snapshot surface"); + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Removing snapshot surface"); mSession.remove(mWindow); } catch (RemoteException e) { // Local call. @@ -286,8 +287,8 @@ class TaskSnapshotSurface implements StartingSurface { private void drawSnapshot() { mSurface.copyFrom(mSurfaceControl); - if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Drawing snapshot surface sizeMismatch=" - + mSizeMismatch); + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Drawing snapshot surface sizeMismatch=%b", + mSizeMismatch); if (mSizeMismatch) { // The dimensions of the buffer and the window don't match, so attaching the buffer // will fail. Better create a child window with the exact dimensions and fill the parent diff --git a/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java b/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java index 895350b43eeb..513008d3c3c3 100644 --- a/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java +++ b/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java @@ -16,17 +16,17 @@ package com.android.server.wm; import static com.android.server.wm.AnimationAdapterProto.REMOTE; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_REMOTE_ANIMATIONS; import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_REMOTE_ANIMATIONS; import android.graphics.Point; import android.os.SystemClock; -import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; +import com.android.server.protolog.common.ProtoLog; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.function.Consumer; @@ -68,15 +68,11 @@ class WallpaperAnimationAdapter implements AnimationAdapter { final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>(); service.mRoot.forAllWallpaperWindows(wallpaperWindow -> { if (!wallpaperWindow.getDisplayContent().mWallpaperController.isWallpaperVisible()) { - if (DEBUG_REMOTE_ANIMATIONS || DEBUG_RECENTS_ANIMATIONS) { - Slog.d(TAG, "\tNot visible=" + wallpaperWindow); - } + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tNot visible=%s", wallpaperWindow); return; } - if (DEBUG_REMOTE_ANIMATIONS || DEBUG_RECENTS_ANIMATIONS) { - Slog.d(TAG, "\tvisible=" + wallpaperWindow); - } + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tvisible=%s", wallpaperWindow); final WallpaperAnimationAdapter wallpaperAdapter = new WallpaperAnimationAdapter( wallpaperWindow, durationHint, statusBarTransitionDelay, animationCanceledRunnable); @@ -129,7 +125,7 @@ class WallpaperAnimationAdapter implements AnimationAdapter { @Override public void startAnimation(SurfaceControl animationLeash, SurfaceControl.Transaction t, SurfaceAnimator.OnAnimationFinishedCallback finishCallback) { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "startAnimation"); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation"); // Restore z-layering until client has a chance to modify it. t.setLayer(animationLeash, mWallpaperToken.getPrefixOrderIndex()); @@ -139,7 +135,7 @@ class WallpaperAnimationAdapter implements AnimationAdapter { @Override public void onAnimationCancelled(SurfaceControl animationLeash) { - if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "onAnimationCancelled"); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "onAnimationCancelled"); mAnimationCanceledRunnable.accept(this); } diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java index 13902eedbfba..e7b09db9368a 100644 --- a/services/core/java/com/android/server/wm/WallpaperController.java +++ b/services/core/java/com/android/server/wm/WallpaperController.java @@ -24,7 +24,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT; @@ -607,8 +606,9 @@ class WallpaperController { boolean processWallpaperDrawPendingTimeout() { if (mWallpaperDrawState == WALLPAPER_DRAW_PENDING) { mWallpaperDrawState = WALLPAPER_DRAW_TIMEOUT; - if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG, - "*** WALLPAPER DRAW TIMEOUT"); + if (DEBUG_WALLPAPER) { + Slog.v(TAG, "*** WALLPAPER DRAW TIMEOUT"); + } // If there was a pending recents animation, start the animation anyways (it's better // to not see the wallpaper than for the animation to not start) @@ -641,9 +641,11 @@ class WallpaperController { WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION); } - if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG, - "Wallpaper should be visible but has not been drawn yet. " + - "mWallpaperDrawState=" + mWallpaperDrawState); + if (DEBUG_WALLPAPER) { + Slog.v(TAG, + "Wallpaper should be visible but has not been drawn yet. " + + "mWallpaperDrawState=" + mWallpaperDrawState); + } break; } } diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index c7916e829349..f437b284637b 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -16,12 +16,11 @@ package com.android.server.wm; +import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE; -import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION; import android.content.Context; import android.os.Trace; @@ -33,6 +32,7 @@ import android.view.SurfaceControl; import com.android.server.AnimationThread; import com.android.server.policy.WindowManagerPolicy; +import com.android.server.protolog.common.ProtoLog; import java.io.PrintWriter; import java.util.ArrayList; @@ -108,14 +108,6 @@ public class WindowAnimator { } void removeDisplayLocked(final int displayId) { - final DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId); - if (displayAnimator != null) { - if (displayAnimator.mScreenRotationAnimation != null) { - displayAnimator.mScreenRotationAnimation.kill(); - displayAnimator.mScreenRotationAnimation = null; - } - } - mDisplayContentsAnimators.delete(displayId); } @@ -147,7 +139,7 @@ public class WindowAnimator { Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime); } - if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION animate"); + ProtoLog.i(WM_SHOW_TRANSACTIONS, ">>> OPEN TRANSACTION animate"); mService.openSurfaceTransaction(); try { final AccessibilityController accessibilityController = @@ -156,27 +148,6 @@ public class WindowAnimator { for (int i = 0; i < numDisplays; i++) { final int displayId = mDisplayContentsAnimators.keyAt(i); final DisplayContent dc = mService.mRoot.getDisplayContent(displayId); - DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); - - final ScreenRotationAnimation screenRotationAnimation = - displayAnimator.mScreenRotationAnimation; - if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) { - if (screenRotationAnimation.stepAnimationLocked(mCurrentTime)) { - setAnimating(true); - } else { - mBulkUpdateParams |= SET_UPDATE_ROTATION; - screenRotationAnimation.kill(); - displayAnimator.mScreenRotationAnimation = null; - - // display. - if (accessibilityController != null) { - // We just finished rotation animation which means we did not - // announce the rotation and waited for it to end, announce now. - accessibilityController.onRotationChangedLocked(dc); - } - } - } - // Update animations of all applications, including those // associated with exiting/removed apps dc.updateWindowsForAnimator(); @@ -188,12 +159,6 @@ public class WindowAnimator { final DisplayContent dc = mService.mRoot.getDisplayContent(displayId); dc.checkAppWindowsReadyToShow(); - - final ScreenRotationAnimation screenRotationAnimation = - mDisplayContentsAnimators.valueAt(i).mScreenRotationAnimation; - if (screenRotationAnimation != null) { - screenRotationAnimation.updateSurfaces(mTransaction); - } orAnimating(dc.getDockedDividerController().animate(mCurrentTime)); if (accessibilityController != null) { accessibilityController.drawMagnifiedRegionBorderIfNeededLocked(displayId); @@ -213,7 +178,7 @@ public class WindowAnimator { Slog.wtf(TAG, "Unhandled exception in Window Manager", e); } finally { mService.closeSurfaceTransaction("WindowAnimator"); - if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION animate"); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate"); } boolean hasPendingLayoutChanges = mService.mRoot.hasPendingLayoutChanges(this); @@ -273,22 +238,14 @@ public class WindowAnimator { public void dumpLocked(PrintWriter pw, String prefix, boolean dumpAll) { final String subPrefix = " " + prefix; - final String subSubPrefix = " " + subPrefix; for (int i = 0; i < mDisplayContentsAnimators.size(); i++) { pw.print(prefix); pw.print("DisplayContentsAnimator #"); pw.print(mDisplayContentsAnimators.keyAt(i)); pw.println(":"); - final DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayContentsAnimators.keyAt(i)); dc.dumpWindowAnimators(pw, subPrefix); - if (displayAnimator.mScreenRotationAnimation != null) { - pw.print(subPrefix); pw.println("mScreenRotationAnimation:"); - displayAnimator.mScreenRotationAnimation.printTo(subSubPrefix, pw); - } else if (dumpAll) { - pw.print(subPrefix); pw.println("no ScreenRotationAnimation "); - } pw.println(); } @@ -322,23 +279,6 @@ public class WindowAnimator { return displayAnimator; } - void setScreenRotationAnimationLocked(int displayId, ScreenRotationAnimation animation) { - final DisplayContentsAnimator animator = getDisplayContentsAnimatorLocked(displayId); - - if (animator != null) { - animator.mScreenRotationAnimation = animation; - } - } - - ScreenRotationAnimation getScreenRotationAnimationLocked(int displayId) { - if (displayId < 0) { - return null; - } - - DisplayContentsAnimator animator = getDisplayContentsAnimatorLocked(displayId); - return animator != null? animator.mScreenRotationAnimation : null; - } - void requestRemovalOfReplacedWindows(WindowState win) { mRemoveReplacedWindows = true; } @@ -358,7 +298,6 @@ public class WindowAnimator { } private class DisplayContentsAnimator { - ScreenRotationAnimation mScreenRotationAnimation = null; } boolean isAnimating() { diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index ec43ec56a573..264efe0fadbd 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -106,9 +106,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< private final Pools.SynchronizedPool<ForAllWindowsConsumerWrapper> mConsumerWrapperPool = new Pools.SynchronizedPool<>(3); - // The owner/creator for this container. No controller if null. - WindowContainerController mController; - // The display this window container is on. protected DisplayContent mDisplayContent; @@ -356,11 +353,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< if (mParent != null) { mParent.removeChild(this); } - - if (mController != null) { - setController(null); - } - } /** @@ -1005,23 +997,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } while (current != null); } - WindowContainerController getController() { - return mController; - } - - void setController(WindowContainerController controller) { - if (mController != null && controller != null) { - throw new IllegalArgumentException("Can't set controller=" + mController - + " for container=" + this + " Already set to=" + mController); - } - if (controller != null) { - controller.setContainer(this); - } else if (mController != null) { - mController.setContainer(null); - } - mController = controller; - } - SurfaceControl.Builder makeSurface() { final WindowContainer p = getParent(); return p.makeChildSurface(this); diff --git a/services/core/java/com/android/server/wm/WindowContainerController.java b/services/core/java/com/android/server/wm/WindowContainerController.java deleted file mode 100644 index 17bc0e2de1f8..000000000000 --- a/services/core/java/com/android/server/wm/WindowContainerController.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2016 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.server.wm; - -import android.content.res.Configuration; - -/** - * Class that allows the owner/creator of a {@link WindowContainer} to communicate directly with the - * container and make changes. - * Note that public calls (mostly in sub-classes) into this class are assumed to be originating from - * outside the window manager so the window manager lock is held and appropriate permissions are - * checked before calls are allowed to proceed. - * - * Test class: {@link WindowContainerControllerTests} - */ -class WindowContainerController<E extends WindowContainer, I extends WindowContainerListener> - implements ConfigurationContainerListener { - - final WindowManagerService mService; - final RootWindowContainer mRoot; - final WindowManagerGlobalLock mGlobalLock; - - // The window container this controller owns. - E mContainer; - // Interface for communicating changes back to the owner. - final I mListener; - - WindowContainerController(I listener, WindowManagerService service) { - mListener = listener; - mService = service; - mRoot = mService != null ? mService.mRoot : null; - mGlobalLock = mService != null ? mService.mGlobalLock : null; - } - - void setContainer(E container) { - if (mContainer != null && container != null) { - throw new IllegalArgumentException("Can't set container=" + container - + " for controller=" + this + " Already set to=" + mContainer); - } - mContainer = container; - if (mContainer != null && mListener != null) { - mListener.registerConfigurationChangeListener(this); - } - } - - void removeContainer() { - // TODO: See if most uses cases should support removeIfPossible here. - //mContainer.removeIfPossible(); - if (mContainer == null) { - return; - } - - mContainer.setController(null); - mContainer = null; - if (mListener != null) { - mListener.unregisterConfigurationChangeListener(this); - } - } - - @Override - public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) { - synchronized (mGlobalLock) { - if (mContainer == null) { - return; - } - mContainer.onRequestedOverrideConfigurationChanged(overrideConfiguration); - } - } -} diff --git a/services/core/java/com/android/server/wm/WindowContainerListener.java b/services/core/java/com/android/server/wm/WindowContainerListener.java deleted file mode 100644 index 3d3d2e02693c..000000000000 --- a/services/core/java/com/android/server/wm/WindowContainerListener.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2016 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.server.wm; - -import android.content.res.Configuration; - -/** - * Interface used by the owner/creator of the container to listen to changes with the container. - * @see WindowContainerController - */ -public interface WindowContainerListener { - void registerConfigurationChangeListener(ConfigurationContainerListener listener); - void unregisterConfigurationChangeListener(ConfigurationContainerListener listener); - default void onInitializeOverrideConfiguration(Configuration config) {} -} diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java index c366e4d6108b..93b0fd9b1fe3 100644 --- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java +++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java @@ -33,32 +33,19 @@ public class WindowManagerDebugConfig { // Default log tag for the window manager package. static final String TAG_WM = "WindowManager"; - static final boolean DEBUG_RESIZE = false; static final boolean DEBUG = false; - static final boolean DEBUG_ADD_REMOVE = false; - static final boolean DEBUG_FOCUS = false; - static final boolean DEBUG_FOCUS_LIGHT = DEBUG_FOCUS || false; static final boolean DEBUG_ANIM = false; - static final boolean DEBUG_KEYGUARD = false; static final boolean DEBUG_LAYOUT = false; static final boolean DEBUG_LAYERS = false; static final boolean DEBUG_INPUT = false; static final boolean DEBUG_INPUT_METHOD = false; static final boolean DEBUG_VISIBILITY = false; - static final boolean DEBUG_WINDOW_MOVEMENT = false; - static final boolean DEBUG_TOKEN_MOVEMENT = false; - static final boolean DEBUG_ORIENTATION = false; - static final boolean DEBUG_APP_ORIENTATION = false; static final boolean DEBUG_CONFIGURATION = false; - static final boolean DEBUG_APP_TRANSITIONS = false; static final boolean DEBUG_STARTING_WINDOW_VERBOSE = false; - static final boolean DEBUG_STARTING_WINDOW = DEBUG_STARTING_WINDOW_VERBOSE || false; static final boolean DEBUG_WALLPAPER = false; static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER; static final boolean DEBUG_DRAG = false; - static final boolean DEBUG_SCREEN_ON = false; static final boolean DEBUG_SCREENSHOT = false; - static final boolean DEBUG_BOOT = false; static final boolean DEBUG_LAYOUT_REPEATS = false; static final boolean DEBUG_WINDOW_TRACE = false; static final boolean DEBUG_TASK_MOVEMENT = false; @@ -66,17 +53,9 @@ public class WindowManagerDebugConfig { static final boolean DEBUG_STACK = false; static final boolean DEBUG_DISPLAY = false; static final boolean DEBUG_POWER = false; - static final boolean DEBUG_DIM_LAYER = false; - static final boolean SHOW_SURFACE_ALLOC = false; - static final boolean SHOW_TRANSACTIONS = false; - static final boolean SHOW_VERBOSE_TRANSACTIONS = false && SHOW_TRANSACTIONS; - static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS; + static final boolean SHOW_VERBOSE_TRANSACTIONS = false; + static final boolean SHOW_LIGHT_TRANSACTIONS = false; static final boolean SHOW_STACK_CRAWLS = false; static final boolean DEBUG_WINDOW_CROP = false; static final boolean DEBUG_UNKNOWN_APP_VISIBILITY = false; - static final boolean DEBUG_RECENTS_ANIMATIONS = false; - static final boolean DEBUG_REMOTE_ANIMATIONS = DEBUG_APP_TRANSITIONS || false; - - static final String TAG_KEEP_SCREEN_ON = "DebugKeepScreenOn"; - static final boolean DEBUG_KEEP_SCREEN_ON = false; } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 3b298aa36e17..38a22389d529 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -81,27 +81,27 @@ import static com.android.server.LockGuard.INDEX_WINDOW; import static com.android.server.LockGuard.installLock; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_BOOT; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_SCREEN_ON; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_WINDOW_MOVEMENT; +import static com.android.server.wm.ProtoLogGroup.WM_ERROR; +import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSACTIONS; -import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerServiceDumpProto.DISPLAY_FROZEN; @@ -267,6 +267,7 @@ import com.android.server.policy.WindowManagerPolicy; import com.android.server.policy.WindowManagerPolicy.ScreenOffListener; import com.android.server.power.ShutdownThread; import com.android.server.protolog.ProtoLogImpl; +import com.android.server.protolog.common.ProtoLog; import com.android.server.utils.PriorityDump; import java.io.BufferedWriter; @@ -1293,7 +1294,7 @@ public class WindowManagerService extends IWindowManager.Stub // The window manager only throws security exceptions, so let's // log all others. if (!(e instanceof SecurityException)) { - Slog.wtf(TAG_WM, "Window Manager Crash", e); + ProtoLog.wtf(WM_ERROR, "Window Manager Crash %s", e); } throw e; } @@ -1333,38 +1334,41 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayContent displayContent = getDisplayContentOrCreate(displayId, attrs.token); if (displayContent == null) { - Slog.w(TAG_WM, "Attempted to add window to a display that does not exist: " - + displayId + ". Aborting."); + ProtoLog.w(WM_ERROR, "Attempted to add window to a display that does " + + "not exist: %d. Aborting.", displayId); return WindowManagerGlobal.ADD_INVALID_DISPLAY; } if (!displayContent.hasAccess(session.mUid)) { - Slog.w(TAG_WM, "Attempted to add window to a display for which the application " - + "does not have access: " + displayId + ". Aborting."); + ProtoLog.w(WM_ERROR, + "Attempted to add window to a display for which the application " + + "does not have access: %d. Aborting.", displayId); return WindowManagerGlobal.ADD_INVALID_DISPLAY; } if (mWindowMap.containsKey(client.asBinder())) { - Slog.w(TAG_WM, "Window " + client + " is already added"); + ProtoLog.w(WM_ERROR, "Window %s is already added", client); return WindowManagerGlobal.ADD_DUPLICATE_ADD; } if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) { parentWindow = windowForClientLocked(null, attrs.token, false); if (parentWindow == null) { - Slog.w(TAG_WM, "Attempted to add window with token that is not a window: " - + attrs.token + ". Aborting."); + ProtoLog.w(WM_ERROR, "Attempted to add window with token that is not a window: " + + "%s. Aborting.", attrs.token); return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN; } if (parentWindow.mAttrs.type >= FIRST_SUB_WINDOW && parentWindow.mAttrs.type <= LAST_SUB_WINDOW) { - Slog.w(TAG_WM, "Attempted to add window with token that is a sub-window: " - + attrs.token + ". Aborting."); + ProtoLog.w(WM_ERROR, "Attempted to add window with token that is a sub-window: " + + "%s. Aborting.", attrs.token); return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN; } } if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) { - Slog.w(TAG_WM, "Attempted to add private presentation window to a non-private display. Aborting."); + ProtoLog.w(WM_ERROR, + "Attempted to add private presentation window to a non-private display. " + + "Aborting."); return WindowManagerGlobal.ADD_PERMISSION_DENIED; } @@ -1382,46 +1386,48 @@ public class WindowManagerService extends IWindowManager.Stub if (token == null) { if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) { - Slog.w(TAG_WM, "Attempted to add application window with unknown token " - + attrs.token + ". Aborting."); + ProtoLog.w(WM_ERROR, "Attempted to add application window with unknown token " + + "%s. Aborting.", attrs.token); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } if (rootType == TYPE_INPUT_METHOD) { - Slog.w(TAG_WM, "Attempted to add input method window with unknown token " - + attrs.token + ". Aborting."); + ProtoLog.w(WM_ERROR, "Attempted to add input method window with unknown token " + + "%s. Aborting.", attrs.token); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } if (rootType == TYPE_VOICE_INTERACTION) { - Slog.w(TAG_WM, "Attempted to add voice interaction window with unknown token " - + attrs.token + ". Aborting."); + ProtoLog.w(WM_ERROR, + "Attempted to add voice interaction window with unknown token " + + "%s. Aborting.", attrs.token); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } if (rootType == TYPE_WALLPAPER) { - Slog.w(TAG_WM, "Attempted to add wallpaper window with unknown token " - + attrs.token + ". Aborting."); + ProtoLog.w(WM_ERROR, "Attempted to add wallpaper window with unknown token " + + "%s. Aborting.", attrs.token); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } if (rootType == TYPE_DREAM) { - Slog.w(TAG_WM, "Attempted to add Dream window with unknown token " - + attrs.token + ". Aborting."); + ProtoLog.w(WM_ERROR, "Attempted to add Dream window with unknown token " + + "%s. Aborting.", attrs.token); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } if (rootType == TYPE_QS_DIALOG) { - Slog.w(TAG_WM, "Attempted to add QS dialog window with unknown token " - + attrs.token + ". Aborting."); + ProtoLog.w(WM_ERROR, "Attempted to add QS dialog window with unknown token " + + "%s. Aborting.", attrs.token); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } if (rootType == TYPE_ACCESSIBILITY_OVERLAY) { - Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with unknown token " - + attrs.token + ". Aborting."); + ProtoLog.w(WM_ERROR, + "Attempted to add Accessibility overlay window with unknown token " + + "%s. Aborting.", attrs.token); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } if (type == TYPE_TOAST) { // Apps targeting SDK above N MR1 cannot arbitrary add toast windows. if (doesAddToastWindowRequireToken(attrs.packageName, callingUid, parentWindow)) { - Slog.w(TAG_WM, "Attempted to add a toast window with unknown token " - + attrs.token + ". Aborting."); + ProtoLog.w(WM_ERROR, "Attempted to add a toast window with unknown token " + + "%s. Aborting.", attrs.token); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } } @@ -1430,49 +1436,52 @@ public class WindowManagerService extends IWindowManager.Stub (attrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0; token = new WindowToken(this, binder, type, false, displayContent, session.mCanAddInternalSystemWindow, isRoundedCornerOverlay); - } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) { + } else if (rootType >= FIRST_APPLICATION_WINDOW + && rootType <= LAST_APPLICATION_WINDOW) { atoken = token.asAppWindowToken(); if (atoken == null) { - Slog.w(TAG_WM, "Attempted to add window with non-application token " - + token + ". Aborting."); + ProtoLog.w(WM_ERROR, "Attempted to add window with non-application token " + + ".%s Aborting.", token); return WindowManagerGlobal.ADD_NOT_APP_TOKEN; } else if (atoken.removed) { - Slog.w(TAG_WM, "Attempted to add window with exiting application token " - + token + ". Aborting."); + ProtoLog.w(WM_ERROR, "Attempted to add window with exiting application token " + + ".%s Aborting.", token); return WindowManagerGlobal.ADD_APP_EXITING; } else if (type == TYPE_APPLICATION_STARTING && atoken.startingWindow != null) { - Slog.w(TAG_WM, "Attempted to add starting window to token with already existing" - + " starting window"); + ProtoLog.w(WM_ERROR, + "Attempted to add starting window to token with already existing" + + " starting window"); return WindowManagerGlobal.ADD_DUPLICATE_ADD; } } else if (rootType == TYPE_INPUT_METHOD) { if (token.windowType != TYPE_INPUT_METHOD) { - Slog.w(TAG_WM, "Attempted to add input method window with bad token " - + attrs.token + ". Aborting."); - return WindowManagerGlobal.ADD_BAD_APP_TOKEN; + ProtoLog.w(WM_ERROR, "Attempted to add input method window with bad token " + + "%s. Aborting.", attrs.token); + return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } } else if (rootType == TYPE_VOICE_INTERACTION) { if (token.windowType != TYPE_VOICE_INTERACTION) { - Slog.w(TAG_WM, "Attempted to add voice interaction window with bad token " - + attrs.token + ". Aborting."); - return WindowManagerGlobal.ADD_BAD_APP_TOKEN; + ProtoLog.w(WM_ERROR, "Attempted to add voice interaction window with bad token " + + "%s. Aborting.", attrs.token); + return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } } else if (rootType == TYPE_WALLPAPER) { if (token.windowType != TYPE_WALLPAPER) { - Slog.w(TAG_WM, "Attempted to add wallpaper window with bad token " - + attrs.token + ". Aborting."); - return WindowManagerGlobal.ADD_BAD_APP_TOKEN; + ProtoLog.w(WM_ERROR, "Attempted to add wallpaper window with bad token " + + "%s. Aborting.", attrs.token); + return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } } else if (rootType == TYPE_DREAM) { if (token.windowType != TYPE_DREAM) { - Slog.w(TAG_WM, "Attempted to add Dream window with bad token " - + attrs.token + ". Aborting."); - return WindowManagerGlobal.ADD_BAD_APP_TOKEN; + ProtoLog.w(WM_ERROR, "Attempted to add Dream window with bad token " + + "%s. Aborting.", attrs.token); + return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } } else if (rootType == TYPE_ACCESSIBILITY_OVERLAY) { if (token.windowType != TYPE_ACCESSIBILITY_OVERLAY) { - Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with bad token " - + attrs.token + ". Aborting."); + ProtoLog.w(WM_ERROR, + "Attempted to add Accessibility overlay window with bad token " + + "%s. Aborting.", attrs.token); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } } else if (type == TYPE_TOAST) { @@ -1480,18 +1489,19 @@ public class WindowManagerService extends IWindowManager.Stub addToastWindowRequiresToken = doesAddToastWindowRequireToken(attrs.packageName, callingUid, parentWindow); if (addToastWindowRequiresToken && token.windowType != TYPE_TOAST) { - Slog.w(TAG_WM, "Attempted to add a toast window with bad token " - + attrs.token + ". Aborting."); + ProtoLog.w(WM_ERROR, "Attempted to add a toast window with bad token " + + "%s. Aborting.", attrs.token); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } } else if (type == TYPE_QS_DIALOG) { if (token.windowType != TYPE_QS_DIALOG) { - Slog.w(TAG_WM, "Attempted to add QS dialog window with bad token " - + attrs.token + ". Aborting."); + ProtoLog.w(WM_ERROR, "Attempted to add QS dialog window with bad token " + + "%s. Aborting.", attrs.token); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } } else if (token.asAppWindowToken() != null) { - Slog.w(TAG_WM, "Non-null appWindowToken for system window of rootType=" + rootType); + ProtoLog.w(WM_ERROR, "Non-null appWindowToken for system window of rootType=%d", + rootType); // It is not valid to use an app token with other system types; we will // instead make a new token for it (as if null had been passed in for the token). attrs.token = null; @@ -1505,13 +1515,13 @@ public class WindowManagerService extends IWindowManager.Stub if (win.mDeathRecipient == null) { // Client has apparently died, so there is no reason to // continue. - Slog.w(TAG_WM, "Adding window client " + client.asBinder() - + " that is dead, aborting."); + ProtoLog.w(WM_ERROR, "Adding window client %s" + + " that is dead, aborting.", client.asBinder()); return WindowManagerGlobal.ADD_APP_EXITING; } if (win.getDisplayContent() == null) { - Slog.w(TAG_WM, "Adding window to Display that has been removed."); + ProtoLog.w(WM_ERROR, "Adding window to Display that has been removed."); return WindowManagerGlobal.ADD_INVALID_DISPLAY; } @@ -1543,7 +1553,7 @@ public class WindowManagerService extends IWindowManager.Stub // schedule hiding all of its toast windows. if (type == TYPE_TOAST) { if (!displayContent.canAddToastWindowForUid(callingUid)) { - Slog.w(TAG_WM, "Adding more than one toast window for UID at a time."); + ProtoLog.w(WM_ERROR, "Adding more than one toast window for UID at a time."); return WindowManagerGlobal.ADD_DUPLICATE_ADD; } // Make sure this happens before we moved focus as one can make the @@ -1589,8 +1599,8 @@ public class WindowManagerService extends IWindowManager.Stub final AppWindowToken aToken = token.asAppWindowToken(); if (type == TYPE_APPLICATION_STARTING && aToken != null) { aToken.startingWindow = win; - if (DEBUG_STARTING_WINDOW) Slog.v (TAG_WM, "addWindow: " + aToken - + " startingWindow=" + win); + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "addWindow: %s startingWindow=%s", + aToken, win); } boolean imMayMove = true; @@ -1607,7 +1617,7 @@ public class WindowManagerService extends IWindowManager.Stub if (type == TYPE_WALLPAPER) { displayContent.mWallpaperController.clearLastWallpaperTimeoutTime(); displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; - } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) { + } else if ((attrs.flags & FLAG_SHOW_WALLPAPER) != 0) { displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; } else if (displayContent.mWallpaperController.isBelowWallpaperTarget(win)) { // If there is currently a wallpaper being shown, and @@ -1692,10 +1702,9 @@ public class WindowManagerService extends IWindowManager.Stub } displayContent.getInputMonitor().updateInputWindowsLw(false /*force*/); - if (DEBUG || DEBUG_ADD_REMOVE) { - Slog.v(TAG_WM, "addWindow: New client " + client.asBinder() - + ": window=" + win + " Callers=" + Debug.getCallers(5)); - } + ProtoLog.v(WM_DEBUG_ADD_REMOVE, "addWindow: New client %s" + + ": window=%s Callers=%s", client.asBinder(), win, Debug.getCallers(5)); + if (win.isVisibleOrAdding() && displayContent.updateOrientation()) { displayContent.sendNewConfiguration(); @@ -1858,7 +1867,7 @@ public class WindowManagerService extends IWindowManager.Stub * forgetting to add the wiring when a new parent of WindowState is added. */ void postWindowRemoveCleanupLocked(WindowState win) { - if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "postWindowRemoveCleanupLocked: " + win); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, "postWindowRemoveCleanupLocked: %s", win); mWindowMap.remove(win.mClient.asBinder()); final DisplayContent dc = win.getDisplayContent(); @@ -1873,7 +1882,7 @@ public class WindowManagerService extends IWindowManager.Stub mResizingWindows.remove(win); updateNonSystemOverlayWindowsVisibilityIfNeeded(win, false /* surfaceShown */); mWindowsChanged = true; - if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Final remove of window: " + win); + ProtoLog.v(WM_DEBUG_WINDOW_MOVEMENT, "Final remove of window: %s", win); final DisplayContent displayContent = win.getDisplayContent(); if (displayContent.mInputMethodWindow == win) { @@ -1882,7 +1891,7 @@ public class WindowManagerService extends IWindowManager.Stub final WindowToken token = win.mToken; final AppWindowToken atoken = win.mAppToken; - if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Removing " + win + " from " + token); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Removing %s from %s", win, token); // Window will already be removed from token before this post clean-up method is called. if (token.isEmpty()) { if (!token.mPersistOnEmpty) { @@ -1942,11 +1951,6 @@ public class WindowManagerService extends IWindowManager.Stub } } - static void logSurface(SurfaceControl s, String title, String msg) { - String str = " SURFACE " + s + ": " + msg + " / " + title; - Slog.i(TAG_WM, str); - } - static void logWithStack(String tag, String s) { RuntimeException e = null; if (SHOW_STACK_CRAWLS) { @@ -1961,8 +1965,8 @@ public class WindowManagerService extends IWindowManager.Stub try { synchronized (mGlobalLock) { WindowState w = windowForClientLocked(session, client, false); - if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, - "transparentRegionHint=" + region, false); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE transparentRegionHint=%s: %s", + region, w); if ((w != null) && w.mHasSurface) { w.mWinAnimator.setTransparentRegionHintLocked(region); @@ -2186,12 +2190,10 @@ public class WindowManagerService extends IWindowManager.Stub win.mInRelayout = true; win.mViewVisibility = viewVisibility; - if (DEBUG_SCREEN_ON) { - RuntimeException stack = new RuntimeException(); - stack.fillInStackTrace(); - Slog.i(TAG_WM, "Relayout " + win + ": oldVis=" + oldVisibility - + " newVis=" + viewVisibility, stack); - } + ProtoLog.i(WM_DEBUG_SCREEN_ON, + "Relayout %s: oldVis=%d newVis=%d. %s", win, oldVisibility, + viewVisibility, new RuntimeException().fillInStackTrace()); + win.setDisplayLayoutNeeded(); win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0; @@ -2236,9 +2238,9 @@ public class WindowManagerService extends IWindowManager.Stub } catch (Exception e) { displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/); - Slog.w(TAG_WM, "Exception thrown when creating surface for client " - + client + " (" + win.mAttrs.getTitle() + ")", - e); + ProtoLog.w(WM_ERROR, + "Exception thrown when creating surface for client %s (%s). %s", + client, win.mAttrs.getTitle(), e); Binder.restoreCallingIdentity(origId); return 0; } @@ -2362,21 +2364,21 @@ public class WindowManagerService extends IWindowManager.Stub outInsetsState.set(displayContent.getInsetsStateController().getInsetsForDispatch(win)); if (DEBUG) { Slog.v(TAG_WM, "Relayout given client " + client.asBinder() - + ", requestedWidth=" + requestedWidth - + ", requestedHeight=" + requestedHeight - + ", viewVisibility=" + viewVisibility - + "\nRelayout returning frame=" + outFrame - + ", surface=" + outSurfaceControl); + + ", requestedWidth=" + requestedWidth + + ", requestedHeight=" + requestedHeight + + ", viewVisibility=" + viewVisibility + + "\nRelayout returning frame=" + outFrame + + ", surface=" + outSurfaceControl); } - if (DEBUG || DEBUG_FOCUS) { - Slog.v(TAG_WM, "Relayout of " + win + ": focusMayChange=" + focusMayChange); - } + ProtoLog.v(WM_DEBUG_FOCUS, "Relayout of %s: focusMayChange=%b", + win, focusMayChange); result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0; if (DEBUG_LAYOUT) { - Slog.v(TAG_WM, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString()); + Slog.v(TAG_WM, + "Relayout complete " + win + ": outFrame=" + outFrame.toShortString()); } win.mInRelayout = false; @@ -2454,11 +2456,12 @@ public class WindowManagerService extends IWindowManager.Stub } if (surfaceController != null) { surfaceController.getSurfaceControl(outSurfaceControl); - if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " OUT SURFACE " + outSurfaceControl + ": copied"); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl); + } else { // For some reason there isn't a surface. Clear the // caller's object so they see the same state. - Slog.w(TAG_WM, "Failed to create surface control for " + win); + ProtoLog.w(WM_ERROR, "Failed to create surface control for %s", win); outSurfaceControl.release(); } @@ -2487,8 +2490,8 @@ public class WindowManagerService extends IWindowManager.Stub try { synchronized (mGlobalLock) { WindowState win = windowForClientLocked(session, client, false); - if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "finishDrawingWindow: " + win + " mDrawState=" - + (win != null ? win.mWinAnimator.drawStateToString() : "null")); + ProtoLog.d(WM_DEBUG_ADD_REMOVE, "finishDrawingWindow: %s mDrawState=%s", + win, (win != null ? win.mWinAnimator.drawStateToString() : "null")); if (win != null && win.mWinAnimator.finishDrawingLocked(postDrawTransaction)) { if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) { win.getDisplayContent().pendingLayoutChanges |= @@ -2513,9 +2516,8 @@ public class WindowManagerService extends IWindowManager.Stub == PackageManager.PERMISSION_GRANTED) { return true; } - final String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid() - + ", uid=" + Binder.getCallingUid() + " requires " + permission; - Slog.w(TAG_WM, msg); + ProtoLog.w(WM_ERROR, "Permission Denial: %s from pid=%d, uid=%d requires %s", + func, Binder.getCallingPid(), Binder.getCallingUid(), permission); return false; } @@ -2528,16 +2530,16 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final DisplayContent dc = getDisplayContentOrCreate(displayId, null /* token */); if (dc == null) { - Slog.w(TAG_WM, "addWindowToken: Attempted to add token: " + binder - + " for non-exiting displayId=" + displayId); + ProtoLog.w(WM_ERROR, "addWindowToken: Attempted to add token: %s" + + " for non-exiting displayId=%d", binder, displayId); return; } WindowToken token = dc.getWindowToken(binder); if (token != null) { - Slog.w(TAG_WM, "addWindowToken: Attempted to add binder token: " + binder - + " for already created window token: " + token - + " displayId=" + displayId); + ProtoLog.w(WM_ERROR, "addWindowToken: Attempted to add binder token: %s" + + " for already created window token: %s" + + " displayId=%d", binder, token, displayId); return; } if (type == TYPE_WALLPAPER) { @@ -2560,15 +2562,16 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final DisplayContent dc = mRoot.getDisplayContent(displayId); if (dc == null) { - Slog.w(TAG_WM, "removeWindowToken: Attempted to remove token: " + binder - + " for non-exiting displayId=" + displayId); + ProtoLog.w(WM_ERROR, "removeWindowToken: Attempted to remove token: %s" + + " for non-exiting displayId=%d", binder, displayId); return; } final WindowToken token = dc.removeWindowToken(binder); if (token == null) { - Slog.w(TAG_WM, - "removeWindowToken: Attempted to remove non-existing token: " + binder); + ProtoLog.w(WM_ERROR, + "removeWindowToken: Attempted to remove non-existing token: %s", + binder); return; } @@ -3208,14 +3211,11 @@ public class WindowManagerService extends IWindowManager.Stub public void enableScreenAfterBoot() { synchronized (mGlobalLock) { - if (DEBUG_BOOT) { - RuntimeException here = new RuntimeException("here"); - here.fillInStackTrace(); - Slog.i(TAG_WM, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled - + " mForceDisplayEnabled=" + mForceDisplayEnabled - + " mShowingBootMessages=" + mShowingBootMessages - + " mSystemBooted=" + mSystemBooted, here); - } + ProtoLog.i(WM_DEBUG_BOOT, "enableScreenAfterBoot: mDisplayEnabled=%b " + + "mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. " + + "%s", + mDisplayEnabled, mForceDisplayEnabled, mShowingBootMessages, mSystemBooted, + new RuntimeException("here").fillInStackTrace()); if (mSystemBooted) { return; } @@ -3239,14 +3239,11 @@ public class WindowManagerService extends IWindowManager.Stub } void enableScreenIfNeededLocked() { - if (DEBUG_BOOT) { - RuntimeException here = new RuntimeException("here"); - here.fillInStackTrace(); - Slog.i(TAG_WM, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled - + " mForceDisplayEnabled=" + mForceDisplayEnabled - + " mShowingBootMessages=" + mShowingBootMessages - + " mSystemBooted=" + mSystemBooted, here); - } + ProtoLog.i(WM_DEBUG_BOOT, "enableScreenIfNeededLocked: mDisplayEnabled=%b " + + "mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. " + + "%s", + mDisplayEnabled, mForceDisplayEnabled, mShowingBootMessages, mSystemBooted, + new RuntimeException("here").fillInStackTrace()); if (mDisplayEnabled) { return; } @@ -3261,7 +3258,7 @@ public class WindowManagerService extends IWindowManager.Stub if (mDisplayEnabled) { return; } - Slog.w(TAG_WM, "***** BOOT TIMEOUT: forcing display enabled"); + ProtoLog.w(WM_ERROR, "***** BOOT TIMEOUT: forcing display enabled"); mForceDisplayEnabled = true; } performEnableScreen(); @@ -3276,11 +3273,10 @@ public class WindowManagerService extends IWindowManager.Stub private void performEnableScreen() { synchronized (mGlobalLock) { - if (DEBUG_BOOT) Slog.i(TAG_WM, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled - + " mForceDisplayEnabled=" + mForceDisplayEnabled - + " mShowingBootMessages=" + mShowingBootMessages - + " mSystemBooted=" + mSystemBooted - + " mOnlyCore=" + mOnlyCore, + ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: mDisplayEnabled=%b" + + " mForceDisplayEnabled=%b" + " mShowingBootMessages=%b" + + " mSystemBooted=%b mOnlyCore=%b. %s", mDisplayEnabled, + mForceDisplayEnabled, mShowingBootMessages, mSystemBooted, mOnlyCore, new RuntimeException("here").fillInStackTrace()); if (mDisplayEnabled) { return; @@ -3310,14 +3306,14 @@ public class WindowManagerService extends IWindowManager.Stub } if (!mForceDisplayEnabled && !checkBootAnimationCompleteLocked()) { - if (DEBUG_BOOT) Slog.i(TAG_WM, "performEnableScreen: Waiting for anim complete"); + ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: Waiting for anim complete"); return; } try { IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger"); if (surfaceFlinger != null) { - Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!"); + ProtoLog.i(WM_ERROR, "******* TELLING SURFACE FLINGER WE ARE BOOTED!"); Parcel data = Parcel.obtain(); data.writeInterfaceToken("android.ui.ISurfaceComposer"); surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED @@ -3325,13 +3321,13 @@ public class WindowManagerService extends IWindowManager.Stub data.recycle(); } } catch (RemoteException ex) { - Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!"); + ProtoLog.e(WM_ERROR, "Boot completed: SurfaceFlinger is dead!"); } EventLog.writeEvent(EventLogTags.WM_BOOT_ANIMATION_DONE, SystemClock.uptimeMillis()); Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0); mDisplayEnabled = true; - if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG_WM, "******************** ENABLING SCREEN!"); + ProtoLog.i(WM_DEBUG_SCREEN_ON, "******************** ENABLING SCREEN!"); // Enable input dispatch. mInputManagerCallback.setEventDispatchingLw(mEventDispatchingEnabled); @@ -3353,24 +3349,21 @@ public class WindowManagerService extends IWindowManager.Stub mH.removeMessages(H.CHECK_IF_BOOT_ANIMATION_FINISHED); mH.sendEmptyMessageDelayed(H.CHECK_IF_BOOT_ANIMATION_FINISHED, BOOT_ANIMATION_POLL_INTERVAL); - if (DEBUG_BOOT) Slog.i(TAG_WM, "checkBootAnimationComplete: Waiting for anim complete"); + ProtoLog.i(WM_DEBUG_BOOT, "checkBootAnimationComplete: Waiting for anim complete"); return false; } - if (DEBUG_BOOT) Slog.i(TAG_WM, "checkBootAnimationComplete: Animation complete!"); + ProtoLog.i(WM_DEBUG_BOOT, "checkBootAnimationComplete: Animation complete!"); return true; } public void showBootMessage(final CharSequence msg, final boolean always) { boolean first = false; synchronized (mGlobalLock) { - if (DEBUG_BOOT) { - RuntimeException here = new RuntimeException("here"); - here.fillInStackTrace(); - Slog.i(TAG_WM, "showBootMessage: msg=" + msg + " always=" + always - + " mAllowBootMessages=" + mAllowBootMessages - + " mShowingBootMessages=" + mShowingBootMessages - + " mSystemBooted=" + mSystemBooted, here); - } + ProtoLog.i(WM_DEBUG_BOOT, "showBootMessage: msg=%s always=%b" + + " mAllowBootMessages=%b mShowingBootMessages=%b" + + " mSystemBooted=%b. %s", msg, always, mAllowBootMessages, + mShowingBootMessages, mSystemBooted, + new RuntimeException("here").fillInStackTrace()); if (!mAllowBootMessages) { return; } @@ -3392,14 +3385,11 @@ public class WindowManagerService extends IWindowManager.Stub } public void hideBootMessagesLocked() { - if (DEBUG_BOOT) { - RuntimeException here = new RuntimeException("here"); - here.fillInStackTrace(); - Slog.i(TAG_WM, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled - + " mForceDisplayEnabled=" + mForceDisplayEnabled - + " mShowingBootMessages=" + mShowingBootMessages - + " mSystemBooted=" + mSystemBooted, here); - } + ProtoLog.i(WM_DEBUG_BOOT, "hideBootMessagesLocked: mDisplayEnabled=%b" + + " mForceDisplayEnabled=%b mShowingBootMessages=%b" + + " mSystemBooted=%b. %s", mDisplayEnabled, mForceDisplayEnabled, + mShowingBootMessages, mSystemBooted, + new RuntimeException("here").fillInStackTrace()); if (mShowingBootMessages) { mShowingBootMessages = false; mPolicy.hideBootMessages(); @@ -3691,8 +3681,7 @@ public class WindowManagerService extends IWindowManager.Stub throw new SecurityException("Requires SET_ORIENTATION permission"); } - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "thawRotation: mRotation=" - + getDefaultDisplayRotation()); + ProtoLog.v(WM_DEBUG_ORIENTATION, "thawRotation: mRotation=%d", getDefaultDisplayRotation()); long origId = Binder.clearCallingIdentity(); try { @@ -3741,9 +3730,9 @@ public class WindowManagerService extends IWindowManager.Stub } private void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) { - if(DEBUG_ORIENTATION) Slog.v(TAG_WM, "updateRotationUnchecked:" - + " alwaysSendConfiguration=" + alwaysSendConfiguration - + " forceRelayout=" + forceRelayout); + ProtoLog.v(WM_DEBUG_ORIENTATION, "updateRotationUnchecked:" + + " alwaysSendConfiguration=%b forceRelayout=%b", + alwaysSendConfiguration, forceRelayout); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation"); @@ -3992,7 +3981,7 @@ public class WindowManagerService extends IWindowManager.Stub try { return mViewServer.start(); } catch (IOException e) { - Slog.w(TAG_WM, "View server did not start"); + ProtoLog.w(WM_ERROR, "View server did not start"); } } return false; @@ -4002,7 +3991,7 @@ public class WindowManagerService extends IWindowManager.Stub mViewServer = new ViewServer(this, port); return mViewServer.start(); } catch (IOException e) { - Slog.w(TAG_WM, "View server did not start"); + ProtoLog.w(WM_ERROR, "View server did not start"); } return false; } @@ -4232,7 +4221,8 @@ public class WindowManagerService extends IWindowManager.Stub } } catch (Exception e) { - Slog.w(TAG_WM, "Could not send command " + command + " with parameters " + parameters, e); + ProtoLog.w(WM_ERROR, "Could not send command %s with parameters %s. %s", command, + parameters, e); success = false; } finally { if (data != null) { @@ -4381,9 +4371,9 @@ public class WindowManagerService extends IWindowManager.Stub public boolean detectSafeMode() { if (!mInputManagerCallback.waitForInputDevicesReady( INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) { - Slog.w(TAG_WM, "Devices still not ready after waiting " - + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS - + " milliseconds before attempting to detect safe mode."); + ProtoLog.w(WM_ERROR, "Devices still not ready after waiting %d" + + " milliseconds before attempting to detect safe mode.", + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS); } if (Settings.Global.getInt( @@ -4411,14 +4401,14 @@ public class WindowManagerService extends IWindowManager.Stub } catch (IllegalArgumentException e) { } if (mSafeMode) { - Log.i(TAG_WM, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState - + " dpad=" + dpadState + " trackball=" + trackballState + ")"); + ProtoLog.i(WM_ERROR, "SAFE MODE ENABLED (menu=%d s=%d dpad=%d" + + " trackball=%d)", menuState, sState, dpadState, trackballState); // May already be set if (for instance) this process has crashed if (SystemProperties.getInt(ShutdownThread.RO_SAFEMODE_PROPERTY, 0) == 0) { SystemProperties.set(ShutdownThread.RO_SAFEMODE_PROPERTY, "1"); } } else { - Log.i(TAG_WM, "SAFE MODE not enabled"); + ProtoLog.i(WM_ERROR, "SAFE MODE not enabled"); } mPolicy.setSafeMode(mSafeMode); return mSafeMode; @@ -4577,10 +4567,11 @@ public class WindowManagerService extends IWindowManager.Stub return; } displayContent.mLastFocus = newFocus; - if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Focus moving from " + lastFocus + - " to " + newFocus + " displayId=" + displayContent.getDisplayId()); + ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Focus moving from %s" + + " to %s displayId=%d", lastFocus, newFocus, + displayContent.getDisplayId()); if (newFocus != null && lastFocus != null && !newFocus.isDisplayedLw()) { - if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Delaying loss of focus..."); + ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Delaying loss of focus..."); displayContent.mLosingFocus.add(lastFocus); lastFocus = null; } @@ -4594,13 +4585,13 @@ public class WindowManagerService extends IWindowManager.Stub } if (newFocus != null) { - if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Gaining focus: " + newFocus); + ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Gaining focus: %s", newFocus); newFocus.reportFocusChangedSerialized(true, mInTouchMode); notifyFocusChanged(); } if (lastFocus != null) { - if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Losing focus: " + lastFocus); + ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Losing focus: %s", lastFocus); lastFocus.reportFocusChangedSerialized(false, mInTouchMode); } break; @@ -4617,7 +4608,7 @@ public class WindowManagerService extends IWindowManager.Stub final int N = losers.size(); for (int i = 0; i < N; i++) { - if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Losing delayed focus: " + + ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Losing delayed focus: %s", losers.get(i)); losers.get(i).reportFocusChangedSerialized(false, mInTouchMode); } @@ -4700,9 +4691,9 @@ public class WindowManagerService extends IWindowManager.Stub case APP_FREEZE_TIMEOUT: { synchronized (mGlobalLock) { - Slog.w(TAG_WM, "App freeze timeout expired."); + ProtoLog.w(WM_ERROR, "App freeze timeout expired."); mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT; - for (int i = mAppFreezeListeners.size() - 1; i >=0 ; --i) { + for (int i = mAppFreezeListeners.size() - 1; i >= 0; --i) { mAppFreezeListeners.get(i).onAppFreezeTimeout(); } } @@ -4743,7 +4734,8 @@ public class WindowManagerService extends IWindowManager.Stub case WAITING_FOR_DRAWN_TIMEOUT: { Runnable callback = null; synchronized (mGlobalLock) { - Slog.w(TAG_WM, "Timeout waiting for drawn: undrawn=" + mWaitingForDrawn); + ProtoLog.w(WM_ERROR, "Timeout waiting for drawn: undrawn=%s", + mWaitingForDrawn); mWaitingForDrawn.clear(); callback = mWaitingForDrawnCallback; mWaitingForDrawnCallback = null; @@ -4817,7 +4809,7 @@ public class WindowManagerService extends IWindowManager.Stub case CHECK_IF_BOOT_ANIMATION_FINISHED: { final boolean bootAnimationComplete; synchronized (mGlobalLock) { - if (DEBUG_BOOT) Slog.i(TAG_WM, "CHECK_IF_BOOT_ANIMATION_FINISHED:"); + ProtoLog.i(WM_DEBUG_BOOT, "CHECK_IF_BOOT_ANIMATION_FINISHED:"); bootAnimationComplete = checkBootAnimationCompleteLocked(); } if (bootAnimationComplete) { @@ -5031,10 +5023,10 @@ public class WindowManagerService extends IWindowManager.Stub int width, height; try { width = Integer.parseInt(sizeStr.substring(0, pos)); - height = Integer.parseInt(sizeStr.substring(pos+1)); + height = Integer.parseInt(sizeStr.substring(pos + 1)); if (displayContent.mBaseDisplayWidth != width || displayContent.mBaseDisplayHeight != height) { - Slog.i(TAG_WM, "FORCED DISPLAY SIZE: " + width + "x" + height); + ProtoLog.i(WM_ERROR, "FORCED DISPLAY SIZE: %dx%d", width, height); displayContent.updateBaseDisplayMetrics(width, height, displayContent.mBaseDisplayDensity); changed = true; @@ -5055,7 +5047,7 @@ public class WindowManagerService extends IWindowManager.Stub int mode = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.DISPLAY_SCALING_FORCE, 0); if (displayContent.mDisplayScalingDisabled != (mode != 0)) { - Slog.i(TAG_WM, "FORCED DISPLAY SCALING DISABLED"); + ProtoLog.i(WM_ERROR, "FORCED DISPLAY SCALING DISABLED"); displayContent.mDisplayScalingDisabled = true; changed = true; } @@ -5235,7 +5227,7 @@ public class WindowManagerService extends IWindowManager.Stub throw new IllegalArgumentException( "Requested window " + client + " does not exist"); } - Slog.w(TAG_WM, "Failed looking up window callers=" + Debug.getCallers(3)); + ProtoLog.w(WM_ERROR, "Failed looking up window callers=%s", Debug.getCallers(3)); return null; } if (session != null && win.mSession != session) { @@ -5243,7 +5235,7 @@ public class WindowManagerService extends IWindowManager.Stub throw new IllegalArgumentException("Requested window " + client + " is in session " + win.mSession + ", not " + session); } - Slog.w(TAG_WM, "Failed looking up window callers=" + Debug.getCallers(3)); + ProtoLog.w(WM_ERROR, "Failed looking up window callers=%s", Debug.getCallers(3)); return null; } @@ -5255,7 +5247,7 @@ public class WindowManagerService extends IWindowManager.Stub // it frozen/off until this window draws at its new // orientation. if (!w.mToken.okToDisplay() && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) { - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Changing surface while display frozen: " + w); + ProtoLog.v(WM_DEBUG_ORIENTATION, "Changing surface while display frozen: %s", w); w.setOrientationChanging(true); w.mLastFreezeDuration = 0; mRoot.mOrientationChangeComplete = false; @@ -5275,22 +5267,22 @@ public class WindowManagerService extends IWindowManager.Stub } for (int j = mWaitingForDrawn.size() - 1; j >= 0; j--) { WindowState win = mWaitingForDrawn.get(j); - if (DEBUG_SCREEN_ON) Slog.i(TAG_WM, "Waiting for drawn " + win + - ": removed=" + win.mRemoved + " visible=" + win.isVisibleLw() + - " mHasSurface=" + win.mHasSurface + - " drawState=" + win.mWinAnimator.mDrawState); + ProtoLog.i(WM_DEBUG_SCREEN_ON, + "Waiting for drawn %s: removed=%b visible=%b mHasSurface=%b drawState=%d", + win, win.mRemoved, win.isVisibleLw(), win.mHasSurface, + win.mWinAnimator.mDrawState); if (win.mRemoved || !win.mHasSurface || !win.isVisibleByPolicy()) { // Window has been removed or hidden; no draw will now happen, so stop waiting. - if (DEBUG_SCREEN_ON) Slog.w(TAG_WM, "Aborted waiting for drawn: " + win); + ProtoLog.w(WM_DEBUG_SCREEN_ON, "Aborted waiting for drawn: %s", win); mWaitingForDrawn.remove(win); } else if (win.hasDrawnLw()) { // Window is now drawn (and shown). - if (DEBUG_SCREEN_ON) Slog.d(TAG_WM, "Window drawn win=" + win); + ProtoLog.d(WM_DEBUG_SCREEN_ON, "Window drawn win=%s", win); mWaitingForDrawn.remove(win); } } if (mWaitingForDrawn.isEmpty()) { - if (DEBUG_SCREEN_ON) Slog.d(TAG_WM, "All windows drawn!"); + ProtoLog.d(WM_DEBUG_SCREEN_ON, "All windows drawn!"); mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT); mH.sendEmptyMessage(H.ALL_WINDOWS_DRAWN); } @@ -5307,19 +5299,15 @@ public class WindowManagerService extends IWindowManager.Stub final boolean state = mHoldingScreenWakeLock.isHeld(); if (hold != state) { if (hold) { - if (DEBUG_KEEP_SCREEN_ON) { - Slog.d(TAG_KEEP_SCREEN_ON, "Acquiring screen wakelock due to " - + mRoot.mHoldScreenWindow); - } + ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "Acquiring screen wakelock due to %s", + mRoot.mHoldScreenWindow); mLastWakeLockHoldingWindow = mRoot.mHoldScreenWindow; mLastWakeLockObscuringWindow = null; mHoldingScreenWakeLock.acquire(); mPolicy.keepScreenOnStartedLw(); } else { - if (DEBUG_KEEP_SCREEN_ON) { - Slog.d(TAG_KEEP_SCREEN_ON, "Releasing screen wakelock, obscured by " - + mRoot.mObscuringWindow); - } + ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "Releasing screen wakelock, obscured by %s", + mRoot.mObscuringWindow); mLastWakeLockHoldingWindow = null; mLastWakeLockObscuringWindow = mRoot.mObscuringWindow; mPolicy.keepScreenOnStoppedLw(); @@ -5363,10 +5351,9 @@ public class WindowManagerService extends IWindowManager.Stub return; } - if (DEBUG_ORIENTATION) Slog.d(TAG_WM, - "startFreezingDisplayLocked: exitAnim=" - + exitAnim + " enterAnim=" + enterAnim - + " called by " + Debug.getCallers(8)); + ProtoLog.d(WM_DEBUG_ORIENTATION, + "startFreezingDisplayLocked: exitAnim=%d enterAnim=%d called by %s", + exitAnim, enterAnim, Debug.getCallers(8)); mScreenFrozenLock.acquire(); mDisplayFrozen = true; @@ -5392,7 +5379,7 @@ public class WindowManagerService extends IWindowManager.Stub mExitAnimId = exitAnim; mEnterAnimId = enterAnim; ScreenRotationAnimation screenRotationAnimation = - mAnimator.getScreenRotationAnimationLocked(mFrozenDisplayId); + displayContent.getRotationAnimation(); if (screenRotationAnimation != null) { screenRotationAnimation.kill(); } @@ -5404,8 +5391,7 @@ public class WindowManagerService extends IWindowManager.Stub screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent, displayContent.getDisplayRotation().isFixedToUserRotation(), isSecure, this); - mAnimator.setScreenRotationAnimationLocked(mFrozenDisplayId, - screenRotationAnimation); + displayContent.setRotationAnimation(screenRotationAnimation); } void stopFreezingDisplayLocked() { @@ -5419,17 +5405,17 @@ public class WindowManagerService extends IWindowManager.Stub if (waitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_ACTIVE || mClientFreezingScreen || numOpeningApps > 0) { - if (DEBUG_ORIENTATION) Slog.d(TAG_WM, - "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + waitingForConfig - + ", mAppsFreezingScreen=" + mAppsFreezingScreen - + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen - + ", mClientFreezingScreen=" + mClientFreezingScreen - + ", mOpeningApps.size()=" + numOpeningApps); + ProtoLog.d(WM_DEBUG_ORIENTATION, + "stopFreezingDisplayLocked: Returning mWaitingForConfig=%b, " + + "mAppsFreezingScreen=%d, mWindowsFreezingScreen=%d, " + + "mClientFreezingScreen=%b, mOpeningApps.size()=%d", + waitingForConfig, mAppsFreezingScreen, mWindowsFreezingScreen, + mClientFreezingScreen, numOpeningApps); return; } - if (DEBUG_ORIENTATION) Slog.d(TAG_WM, - "stopFreezingDisplayLocked: Unfreezing now"); + ProtoLog.d(WM_DEBUG_ORIENTATION, + "stopFreezingDisplayLocked: Unfreezing now"); // We must make a local copy of the displayId as it can be potentially overwritten later on @@ -5447,7 +5433,7 @@ public class WindowManagerService extends IWindowManager.Stub sb.append(" due to "); sb.append(mLastFinishedFreezeSource); } - Slog.i(TAG_WM, sb.toString()); + ProtoLog.i(WM_ERROR, "%s", sb.toString()); mH.removeMessages(H.APP_FREEZE_TIMEOUT); mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT); if (PROFILE_ORIENTATION) { @@ -5456,10 +5442,10 @@ public class WindowManagerService extends IWindowManager.Stub boolean updateRotation = false; - ScreenRotationAnimation screenRotationAnimation = - mAnimator.getScreenRotationAnimationLocked(displayId); + ScreenRotationAnimation screenRotationAnimation = displayContent == null ? null + : displayContent.getRotationAnimation(); if (screenRotationAnimation != null && screenRotationAnimation.hasScreenshot()) { - if (DEBUG_ORIENTATION) Slog.i(TAG_WM, "**** Dismissing screen rotation animation"); + ProtoLog.i(WM_DEBUG_ORIENTATION, "**** Dismissing screen rotation animation"); DisplayInfo displayInfo = displayContent.getDisplayInfo(); // Get rotation animation again, with new top window if (!displayContent.getDisplayRotation().validateRotationAnimation( @@ -5470,16 +5456,15 @@ public class WindowManagerService extends IWindowManager.Stub getTransitionAnimationScaleLocked(), displayInfo.logicalWidth, displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) { mTransaction.apply(); - scheduleAnimationLocked(); } else { screenRotationAnimation.kill(); - mAnimator.setScreenRotationAnimationLocked(displayId, null); + displayContent.setRotationAnimation(null); updateRotation = true; } } else { if (screenRotationAnimation != null) { screenRotationAnimation.kill(); - mAnimator.setScreenRotationAnimationLocked(displayId, null); + displayContent.setRotationAnimation(null); } updateRotation = true; } @@ -5503,7 +5488,7 @@ public class WindowManagerService extends IWindowManager.Stub mScreenFrozenLock.release(); if (updateRotation && displayContent != null) { - if (DEBUG_ORIENTATION) Slog.d(TAG_WM, "Performing post-rotate rotation"); + ProtoLog.d(WM_DEBUG_ORIENTATION, "Performing post-rotate rotation"); configChanged |= displayContent.updateRotationUnchecked(); } @@ -6316,17 +6301,20 @@ public class WindowManagerService extends IWindowManager.Stub /** * Hint to a token that its activity will relaunch, which will trigger removal and addition of * a window. + * * @param token Application token for which the activity will be relaunched. */ void setWillReplaceWindow(IBinder token, boolean animate) { final AppWindowToken appWindowToken = mRoot.getAppWindowToken(token); if (appWindowToken == null) { - Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token " + token); + ProtoLog.w(WM_ERROR, "Attempted to set replacing window on non-existing app token %s", + token); return; } if (!appWindowToken.hasContentToDisplay()) { - Slog.w(TAG_WM, "Attempted to set replacing window on app token with no content" - + token); + ProtoLog.w(WM_ERROR, + "Attempted to set replacing window on app token with no content %s", + token); return; } appWindowToken.setWillReplaceWindows(animate); @@ -6348,13 +6336,15 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final AppWindowToken appWindowToken = mRoot.getAppWindowToken(token); if (appWindowToken == null) { - Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token " - + token); + ProtoLog.w(WM_ERROR, + "Attempted to set replacing window on non-existing app token %s", + token); return; } if (!appWindowToken.hasContentToDisplay()) { - Slog.w(TAG_WM, "Attempted to set replacing window on app token with no content" - + token); + ProtoLog.w(WM_ERROR, + "Attempted to set replacing window on app token with no content %s", + token); return; } @@ -6374,14 +6364,14 @@ public class WindowManagerService extends IWindowManager.Stub * * If we're not replacing the window, clear the replace window settings of the app. * - * @param token Application token for the activity whose window might be replaced. + * @param token Application token for the activity whose window might be replaced. * @param replacing Whether the window is being replaced or not. */ void scheduleClearWillReplaceWindows(IBinder token, boolean replacing) { final AppWindowToken appWindowToken = mRoot.getAppWindowToken(token); if (appWindowToken == null) { - Slog.w(TAG_WM, "Attempted to reset replacing window on non-existing app token " - + token); + ProtoLog.w(WM_ERROR, "Attempted to reset replacing window on non-existing app token %s", + token); return; } if (replacing) { @@ -6570,7 +6560,7 @@ public class WindowManagerService extends IWindowManager.Stub } WindowState callingWin = windowForClientLocked(null, client, false); if (callingWin == null) { - Slog.w(TAG_WM, "Bad requesting window " + client); + ProtoLog.w(WM_ERROR, "Bad requesting window %s", client); return; } final DisplayContent displayContent = callingWin.getDisplayContent(); @@ -6587,7 +6577,7 @@ public class WindowManagerService extends IWindowManager.Stub windowUnderPointer.translateToWindowX(mouseX), windowUnderPointer.translateToWindowY(mouseY)); } catch (RemoteException e) { - Slog.w(TAG_WM, "unable to update pointer icon"); + ProtoLog.w(WM_ERROR, "unable to update pointer icon"); } } } @@ -6604,7 +6594,7 @@ public class WindowManagerService extends IWindowManager.Stub windowUnderPointer.translateToWindowX(latestX), windowUnderPointer.translateToWindowY(latestY)); } catch (RemoteException e) { - Slog.w(TAG_WM, "unable to restore pointer icon"); + ProtoLog.w(WM_ERROR, "unable to restore pointer icon"); } } else { InputManager.getInstance().setPointerIconType(PointerIcon.TYPE_DEFAULT); @@ -6634,7 +6624,7 @@ public class WindowManagerService extends IWindowManager.Stub try { final WindowState win = windowForClientLocked(null, client, false); if (win == null) { - Slog.w(TAG_WM, "Bad requesting window " + client); + ProtoLog.w(WM_ERROR, "Bad requesting window %s", client); return; } getDisplayContentOrCreate(displayId, null).reparentDisplayContent(win, sc); @@ -6659,7 +6649,7 @@ public class WindowManagerService extends IWindowManager.Stub try { final WindowState win = windowForClientLocked(null, client, false); if (win == null) { - Slog.w(TAG_WM, "Bad requesting window " + client); + ProtoLog.w(WM_ERROR, "Bad requesting window %s", client); return; } final DisplayContent displayContent = mRoot.getDisplayContent(displayId); @@ -6686,7 +6676,7 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final WindowState callingWin = windowForClientLocked(null, client, false); if (callingWin == null) { - Slog.w(TAG_WM, "Bad requesting window " + client); + ProtoLog.w(WM_ERROR, "Bad requesting window %s", client); return; } callingWin.updateTapExcludeRegion(regionId, region); @@ -6725,8 +6715,9 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final DisplayContent displayContent = mRoot.getDisplayContent(displayId); if (displayContent == null) { - Slog.w(TAG_WM, "Attempted to get windowing mode of a display that does not exist: " - + displayId); + ProtoLog.w(WM_ERROR, + "Attempted to get windowing mode of a display that does not exist: %d", + displayId); return WindowConfiguration.WINDOWING_MODE_UNDEFINED; } return mDisplayWindowSettings.getWindowingModeLocked(displayContent); @@ -6742,8 +6733,9 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null); if (displayContent == null) { - Slog.w(TAG_WM, "Attempted to set windowing mode to a display that does not exist: " - + displayId); + ProtoLog.w(WM_ERROR, + "Attempted to set windowing mode to a display that does not exist: %d", + displayId); return; } @@ -6778,8 +6770,9 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final DisplayContent displayContent = mRoot.getDisplayContent(displayId); if (displayContent == null) { - Slog.w(TAG_WM, "Attempted to get remove mode of a display that does not exist: " - + displayId); + ProtoLog.w(WM_ERROR, + "Attempted to get remove mode of a display that does not exist: %d", + displayId); return REMOVE_CONTENT_MODE_UNDEFINED; } return mDisplayWindowSettings.getRemoveContentModeLocked(displayContent); @@ -6795,8 +6788,9 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null); if (displayContent == null) { - Slog.w(TAG_WM, "Attempted to set remove mode to a display that does not exist: " - + displayId); + ProtoLog.w(WM_ERROR, + "Attempted to set remove mode to a display that does not exist: %d", + displayId); return; } @@ -6815,8 +6809,8 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final DisplayContent displayContent = mRoot.getDisplayContent(displayId); if (displayContent == null) { - Slog.w(TAG_WM, "Attempted to get flag of a display that does not exist: " - + displayId); + ProtoLog.w(WM_ERROR, "Attempted to get flag of a display that does not exist: %d", + displayId); return false; } return mDisplayWindowSettings.shouldShowWithInsecureKeyguardLocked(displayContent); @@ -6833,8 +6827,8 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null); if (displayContent == null) { - Slog.w(TAG_WM, "Attempted to set flag to a display that does not exist: " - + displayId); + ProtoLog.w(WM_ERROR, "Attempted to set flag to a display that does not exist: %d", + displayId); return; } @@ -6854,8 +6848,8 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final DisplayContent displayContent = mRoot.getDisplayContent(displayId); if (displayContent == null) { - Slog.w(TAG_WM, "Attempted to get system decors flag of a display that does " - + "not exist: " + displayId); + ProtoLog.w(WM_ERROR, "Attempted to get system decors flag of a display that does " + + "not exist: %d", displayId); return false; } if (displayContent.isUntrustedVirtualDisplay()) { @@ -6874,8 +6868,8 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null); if (displayContent == null) { - Slog.w(TAG_WM, "Attempted to set system decors flag to a display that does " - + "not exist: " + displayId); + ProtoLog.w(WM_ERROR, "Attempted to set system decors flag to a display that does " + + "not exist: %d", displayId); return; } if (displayContent.isUntrustedVirtualDisplay()) { @@ -6898,8 +6892,9 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final DisplayContent displayContent = mRoot.getDisplayContent(displayId); if (displayContent == null) { - Slog.w(TAG_WM, "Attempted to get IME flag of a display that does not exist: " - + displayId); + ProtoLog.w(WM_ERROR, + "Attempted to get IME flag of a display that does not exist: %d", + displayId); return false; } if (displayContent.isUntrustedVirtualDisplay()) { @@ -6919,8 +6914,9 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null); if (displayContent == null) { - Slog.w(TAG_WM, "Attempted to set IME flag to a display that does not exist: " - + displayId); + ProtoLog.w(WM_ERROR, + "Attempted to set IME flag to a display that does not exist: %d", + displayId); return; } if (displayContent.isUntrustedVirtualDisplay()) { @@ -7137,15 +7133,16 @@ public class WindowManagerService extends IWindowManager.Stub if (removeWindows) { final DisplayContent dc = mRoot.getDisplayContent(displayId); if (dc == null) { - Slog.w(TAG_WM, "removeWindowToken: Attempted to remove token: " + binder - + " for non-exiting displayId=" + displayId); + ProtoLog.w(WM_ERROR, "removeWindowToken: Attempted to remove token: %s" + + " for non-exiting displayId=%d", binder, displayId); return; } final WindowToken token = dc.removeWindowToken(binder); if (token == null) { - Slog.w(TAG_WM, "removeWindowToken: Attempted to remove non-existing token: " - + binder); + ProtoLog.w(WM_ERROR, + "removeWindowToken: Attempted to remove non-existing token: %s", + binder); return; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 0a65e3240885..d459f14564d0 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -90,20 +90,20 @@ import static com.android.server.wm.IdentifierProto.USER_ID; import static com.android.server.wm.MoveAnimationSpecProto.DURATION_MS; import static com.android.server.wm.MoveAnimationSpecProto.FROM; import static com.android.server.wm.MoveAnimationSpecProto.TO; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_RESIZE; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT; @@ -206,6 +206,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.KeyInterceptionInfo; import com.android.internal.util.ToBooleanFunction; import com.android.server.policy.WindowManagerPolicy; +import com.android.server.protolog.common.ProtoLog; import com.android.server.wm.LocalAnimationAdapter.AnimationSpec; import com.android.server.wm.utils.InsetUtils; import com.android.server.wm.utils.WmDisplayCutout; @@ -781,7 +782,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mSubLayer = mPolicy.getSubWindowLayerFromTypeLw(a.type); mIsChildWindow = true; - if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + parentWindow); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Adding %s to %s", this, parentWindow); parentWindow.addChild(this, sWindowSubLayerComparator); mLayoutAttached = mAttrs.type != @@ -1294,14 +1295,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP || configChanged || dragResizingChanged || mReportOrientationChanged) { - if (DEBUG_RESIZE || DEBUG_ORIENTATION) { - Slog.v(TAG_WM, "Resize reasons for w=" + this + ": " - + " " + mWindowFrames.getInsetsChangedInfo() - + " surfaceResized=" + winAnimator.mSurfaceResized - + " configChanged=" + configChanged - + " dragResizingChanged=" + dragResizingChanged - + " reportOrientationChanged=" + mReportOrientationChanged); - } + ProtoLog.v(WM_DEBUG_RESIZE, + "Resize reasons for w=%s: %s surfaceResized=%b configChanged=%b " + + "dragResizingChanged=%b reportOrientationChanged=%b", + this, mWindowFrames.getInsetsChangedInfo(), winAnimator.mSurfaceResized, + configChanged, dragResizingChanged, mReportOrientationChanged); // If it's a dead window left on screen, and the configuration changed, there is nothing // we can do about it. Remove the window now. @@ -1318,24 +1316,31 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // redrawn; to do that, we need to go through the process of getting informed by the // application when it has finished drawing. if (getOrientationChanging() || dragResizingChanged) { - if (DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) { - Slog.v(TAG_WM, "Orientation or resize start waiting for draw" + if (getOrientationChanging()) { + Slog.v(TAG_WM, "Orientation start waiting for draw" + ", mDrawState=DRAW_PENDING in " + this + ", surfaceController " + winAnimator.mSurfaceController); } + if (dragResizingChanged) { + ProtoLog.v(WM_DEBUG_RESIZE, + "Resize start waiting for draw, " + + "mDrawState=DRAW_PENDING in %s, surfaceController %s", + this, winAnimator.mSurfaceController); + } winAnimator.mDrawState = DRAW_PENDING; if (mAppToken != null) { mAppToken.clearAllDrawn(); } } if (!mWmService.mResizingWindows.contains(this)) { - if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG_WM, "Resizing window " + this); + ProtoLog.v(WM_DEBUG_RESIZE, "Resizing window %s", this); mWmService.mResizingWindows.add(this); } } else if (getOrientationChanging()) { if (isDrawnLw()) { - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Orientation not waiting for draw in " - + this + ", surfaceController " + winAnimator.mSurfaceController); + ProtoLog.v(WM_DEBUG_ORIENTATION, + "Orientation not waiting for draw in %s, surfaceController %s", this, + winAnimator.mSurfaceController); setOrientationChanging(false); mLastFreezeDuration = (int)(SystemClock.elapsedRealtime() - mWmService.mDisplayFreezeTime); @@ -1705,7 +1710,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP @Override void onMovedByResize() { - if (DEBUG_RESIZE) Slog.d(TAG, "onMovedByResize: Moving " + this); + ProtoLog.d(WM_DEBUG_RESIZE, "onMovedByResize: Moving %s", this); mMovedByResize = true; super.onMovedByResize(); } @@ -1779,7 +1784,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP void onResize() { final ArrayList<WindowState> resizingWindows = mWmService.mResizingWindows; if (mHasSurface && !isGoneForLayoutLw() && !resizingWindows.contains(this)) { - if (DEBUG_RESIZE) Slog.d(TAG, "onResize: Resizing " + this); + ProtoLog.d(WM_DEBUG_RESIZE, "onResize: Resizing %s", this); resizingWindows.add(this); } if (isGoneForLayoutLw()) { @@ -1922,8 +1927,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (mRemoved) { // Nothing to do. - if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, - "WS.removeImmediately: " + this + " Already removed..."); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, + "WS.removeImmediately: %s Already removed...", this); return; } @@ -1973,39 +1978,35 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP private void removeIfPossible(boolean keepVisibleDeadWindow) { mWindowRemovalAllowed = true; - if (DEBUG_ADD_REMOVE) Slog.v(TAG, - "removeIfPossible: " + this + " callers=" + Debug.getCallers(5)); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, + "removeIfPossible: %s callers=%s", this, Debug.getCallers(5)); final boolean startingWindow = mAttrs.type == TYPE_APPLICATION_STARTING; - if (startingWindow && DEBUG_STARTING_WINDOW) Slog.d(TAG_WM, - "Starting window removed " + this); - - if (DEBUG || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && isFocused()) { - Slog.v(TAG_WM, "Remove " + this + " client=" - + Integer.toHexString(System.identityHashCode(mClient.asBinder())) - + ", surfaceController=" + mWinAnimator.mSurfaceController + " Callers=" - + Debug.getCallers(5)); + if (startingWindow) { + ProtoLog.d(WM_DEBUG_STARTING_WINDOW, "Starting window removed %s", this); } + ProtoLog.v(WM_DEBUG_FOCUS, "Remove client=%x, surfaceController=%s Callers=%s", + System.identityHashCode(mClient.asBinder()), + mWinAnimator.mSurfaceController, + Debug.getCallers(5)); + + final long origId = Binder.clearCallingIdentity(); try { disposeInputChannel(); - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Remove " + this - + ": mSurfaceController=" + mWinAnimator.mSurfaceController - + " mAnimatingExit=" + mAnimatingExit - + " mRemoveOnExit=" + mRemoveOnExit - + " mHasSurface=" + mHasSurface - + " surfaceShowing=" + mWinAnimator.getShown() - + " animating=" + isAnimating() - + " app-animation=" - + (mAppToken != null ? mAppToken.isSelfAnimating() : "false") - + " mWillReplaceWindow=" + mWillReplaceWindow - + " inPendingTransaction=" - + (mAppToken != null ? mAppToken.inPendingTransaction : false) - + " mDisplayFrozen=" + mWmService.mDisplayFrozen - + " callers=" + Debug.getCallers(6)); + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "Remove %s: mSurfaceController=%s mAnimatingExit=%b mRemoveOnExit=%b " + + "mHasSurface=%b surfaceShowing=%b animating=%b app-animation=%b " + + "mWillReplaceWindow=%b inPendingTransaction=%b mDisplayFrozen=%b " + + "callers=%s", + this, mWinAnimator.mSurfaceController, mAnimatingExit, mRemoveOnExit, + mHasSurface, mWinAnimator.getShown(), isAnimating(), + mAppToken != null && mAppToken.isSelfAnimating(), mWillReplaceWindow, + mAppToken != null && mAppToken.inPendingTransaction, + mWmService.mDisplayFrozen, Debug.getCallers(6)); // Visibility of the removed window. Will be used later to update orientation later on. boolean wasVisible = false; @@ -2017,8 +2018,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (mWillReplaceWindow) { // This window is going to be replaced. We need to keep it around until the new one // gets added, then we will get rid of this one. - if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, - "Preserving " + this + " until the new one is " + "added"); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, + "Preserving %s until the new one is added", this); // TODO: We are overloading mAnimatingExit flag to prevent the window state from // been removed. We probably need another flag to indicate that window removal // should be deffered vs. overloading the flag that says we are playing an exit @@ -2032,8 +2033,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP wasVisible = isWinVisibleLw(); if (keepVisibleDeadWindow) { - if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, - "Not removing " + this + " because app died while it's visible"); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, + "Not removing %s because app died while it's visible", this); mAppDied = true; setDisplayLayoutNeeded(); @@ -2074,8 +2075,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (mWinAnimator.getShown() && mAnimatingExit && (!lastWindowIsStartingWindow || isAnimating)) { // The exit animation is running or should run... wait for it! - if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, - "Not removing " + this + " due to exit animation "); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, + "Not removing %s due to exit animation", this); setupWindowForRemoveOnExit(); if (mAppToken != null) { mAppToken.updateReportedVisibilityLocked(); @@ -2242,7 +2243,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } private void removeReplacedWindow() { - if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Removing replaced window: " + this); + ProtoLog.d(WM_DEBUG_ADD_REMOVE, "Removing replaced window: %s", this); mWillReplaceWindow = false; mAnimateReplacingWindow = false; mReplacingRemoveRequested = false; @@ -2398,7 +2399,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (!isVisibleByPolicy()) { mWinAnimator.hide("checkPolicyVisibilityChange"); if (isFocused()) { - if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, + ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "setAnimationLocked: setting mFocusMayChange true"); mWmService.mFocusMayChange = true; } @@ -2622,8 +2623,24 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP /** @return false if this window desires touch events. */ boolean cantReceiveTouchInput() { - return mAppToken != null && mAppToken.getTask() != null - && (mAppToken.getTask().mStack.shouldIgnoreInput() || mAppToken.hiddenRequested); + if (mAppToken == null || mAppToken.getTask() == null) { + return false; + } + + return mAppToken.getTask().mStack.shouldIgnoreInput() + || mAppToken.hiddenRequested + || isAnimatingToRecents(); + } + + /** + * Returns {@code true} if the window is animating to home as part of the recents animation. + */ + private boolean isAnimatingToRecents() { + final RecentsAnimationController recentsAnimationController = + mWmService.getRecentsAnimationController(); + return recentsAnimationController != null + && recentsAnimationController.isAnimatingTask(getTask()) + && !recentsAnimationController.isTargetApp(mAppToken); } @Override @@ -2721,7 +2738,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // we allow the display to be enabled now. mWmService.enableScreenIfNeededLocked(); if (isFocused) { - if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, + ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "WindowState.hideLw: setting mFocusMayChange true"); mWmService.mFocusMayChange = true; } @@ -2927,7 +2944,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (mHasSurface && !getOrientationChanging() && mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) { - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + this); + ProtoLog.v(WM_DEBUG_ORIENTATION, + "set mOrientationChanging of %s", this); setOrientationChanging(true); mWmService.mRoot.mOrientationChangeComplete = false; } @@ -2955,10 +2973,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } if (mDestroying) { - if (DEBUG_ADD_REMOVE) Slog.e(TAG_WM, "win=" + this - + " destroySurfaces: appStopped=" + appStopped - + " win.mWindowRemovalAllowed=" + mWindowRemovalAllowed - + " win.mRemoveOnExit=" + mRemoveOnExit); + ProtoLog.e(WM_DEBUG_ADD_REMOVE, "win=%s" + + " destroySurfaces: appStopped=%b" + + " win.mWindowRemovalAllowed=%b" + + " win.mRemoveOnExit=%b", this, appStopped, + mWindowRemovalAllowed, mRemoveOnExit); if (!cleanupOnResume || mRemoveOnExit) { destroySurfaceUnchecked(); } @@ -3226,16 +3245,19 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP void reportResized() { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wm.reportResized_" + getWindowTag()); try { - if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this - + ": " + mWindowFrames.mCompatFrame); + ProtoLog.v(WM_DEBUG_RESIZE, + "Reporting new frame to %s: %s", this, + mWindowFrames.mCompatFrame); final MergedConfiguration mergedConfiguration = new MergedConfiguration(mWmService.mRoot.getConfiguration(), getMergedOverrideConfiguration()); setLastReportedMergedConfiguration(mergedConfiguration); - if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == DRAW_PENDING) - Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING"); + if (mWinAnimator.mDrawState == DRAW_PENDING) { + ProtoLog.i(WM_DEBUG_ORIENTATION, + "Resizing %s WITH DRAW PENDING", this); + } final Rect frame = mWindowFrames.mCompatFrame; final Rect overscanInsets = mWindowFrames.mLastOverscanInsets; @@ -4378,9 +4400,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return; } - if (DEBUG || DEBUG_ADD_REMOVE) { - Slog.v(TAG, "Exit animation finished in " + this + ": remove=" + mRemoveOnExit); - } + ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Exit animation finished in %s: remove=%b", + this, mRemoveOnExit); mDestroying = true; diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index c676e723de71..3dcf6ecb5124 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -27,17 +27,18 @@ import static android.view.WindowManager.TRANSIT_NONE; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_DRAW; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW; +import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC; +import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER; @@ -67,6 +68,7 @@ import android.view.animation.Animation; import android.view.animation.AnimationUtils; import com.android.server.policy.WindowManagerPolicy; +import com.android.server.protolog.common.ProtoLog; import java.io.PrintWriter; @@ -312,19 +314,19 @@ class WindowStateAnimator { boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction) { final boolean startingWindow = mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; - if (DEBUG_STARTING_WINDOW && startingWindow) { - Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState=" - + drawStateToString()); + if (startingWindow) { + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Finishing drawing window %s: mDrawState=%s", + mWin, drawStateToString()); } boolean layoutNeeded = false; if (mDrawState == DRAW_PENDING) { - if (DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION) - Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + mWin + " in " - + mSurfaceController); - if (DEBUG_STARTING_WINDOW && startingWindow) { - Slog.v(TAG, "Draw state now committed in " + mWin); + ProtoLog.v(WM_DEBUG_DRAW, + "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s", mWin, + mSurfaceController); + if (startingWindow) { + ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Draw state now committed in %s", mWin); } mDrawState = COMMIT_DRAW_PENDING; layoutNeeded = true; @@ -385,7 +387,7 @@ class WindowStateAnimator { mSurfaceDestroyDeferred = true; return; } - if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "SET FREEZE LAYER", false); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SET FREEZE LAYER: %s", mWin); if (mSurfaceController != null) { // Our SurfaceControl is always at layer 0 within the parent Surface managed by // window-state. We want this old Surface to stay on top of the new one @@ -456,8 +458,9 @@ class WindowStateAnimator { w.setHasSurface(false); - if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG, - "createSurface " + this + ": mDrawState=DRAW_PENDING"); + if (DEBUG_ANIM) { + Slog.i(TAG, "createSurface " + this + ": mDrawState=DRAW_PENDING"); + } resetDrawState(); @@ -514,15 +517,10 @@ class WindowStateAnimator { w.setHasSurface(true); - if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { - Slog.i(TAG, " CREATE SURFACE " - + mSurfaceController + " IN SESSION " - + mSession.mSurfaceSession - + ": pid=" + mSession.mPid + " format=" - + attrs.format + " flags=0x" - + Integer.toHexString(flags) - + " / " + this); - } + ProtoLog.i(WM_SHOW_SURFACE_ALLOC, + " CREATE SURFACE %s IN SESSION %s: pid=%d format=%d flags=0x%x / %s", + mSurfaceController, mSession.mSurfaceSession, mSession.mPid, attrs.format, + flags, this); } catch (OutOfResourcesException e) { Slog.w(TAG, "OutOfResourcesException creating surface"); mService.mRoot.reclaimSomeSurfaceMemory(this, "create", true); @@ -616,17 +614,15 @@ class WindowStateAnimator { if (mSurfaceDestroyDeferred) { if (mSurfaceController != null && mPendingDestroySurface != mSurfaceController) { if (mPendingDestroySurface != null) { - if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { - WindowManagerService.logSurface(mWin, "DESTROY PENDING", true); - } + ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY PENDING: %s. %s", + mWin, new RuntimeException().fillInStackTrace()); mPendingDestroySurface.destroyNotInTransaction(); } mPendingDestroySurface = mSurfaceController; } } else { - if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { - WindowManagerService.logSurface(mWin, "DESTROY", true); - } + ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY: %s. %s", + mWin, new RuntimeException().fillInStackTrace()); destroySurface(); } // Don't hide wallpaper if we're deferring the surface destroy @@ -653,9 +649,8 @@ class WindowStateAnimator { void destroyDeferredSurfaceLocked() { try { if (mPendingDestroySurface != null) { - if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { - WindowManagerService.logSurface(mWin, "DESTROY PENDING", true); - } + ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY PENDING: %s. %s", + mWin, new RuntimeException().fillInStackTrace()); mPendingDestroySurface.destroyNotInTransaction(); // Don't hide wallpaper if we're destroying a deferred surface // after a surface mode change. @@ -673,9 +668,8 @@ class WindowStateAnimator { } void computeShownFrameLocked() { - final int displayId = mWin.getDisplayId(); final ScreenRotationAnimation screenRotationAnimation = - mAnimator.getScreenRotationAnimationLocked(displayId); + mWin.getDisplayContent().getRotationAnimation(); final boolean windowParticipatesInScreenRotationAnimation = !mWin.mForceSeamlesslyRotate; final boolean screenAnimation = screenRotationAnimation != null @@ -1089,9 +1083,7 @@ class WindowStateAnimator { // There is no need to wait for an animation change if our window is gone for layout // already as we'll never be visible. if (w.getOrientationChanging() && w.isGoneForLayoutLw()) { - if (DEBUG_ORIENTATION) { - Slog.v(TAG, "Orientation change skips hidden " + w); - } + ProtoLog.v(WM_DEBUG_ORIENTATION, "Orientation change skips hidden %s", w); w.setOrientationChanging(false); } return; @@ -1116,8 +1108,8 @@ class WindowStateAnimator { // before it has drawn for the new orientation. if (w.getOrientationChanging() && w.isGoneForLayoutLw()) { w.setOrientationChanging(false); - if (DEBUG_ORIENTATION) Slog.v(TAG, - "Orientation change skips hidden " + w); + ProtoLog.v(WM_DEBUG_ORIENTATION, + "Orientation change skips hidden %s", w); } } else if (mLastAlpha != mShownAlpha || mLastDsDx != mDsDx @@ -1135,13 +1127,10 @@ class WindowStateAnimator { mLastDtDy = mDtDy; w.mLastHScale = w.mHScale; w.mLastVScale = w.mVScale; - if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, - "controller=" + mSurfaceController + - "alpha=" + mShownAlpha - + " matrix=[" + mDsDx + "*" + w.mHScale - + "," + mDtDx + "*" + w.mVScale - + "][" + mDtDy + "*" + w.mHScale - + "," + mDsDy + "*" + w.mVScale + "]", false); + ProtoLog.i(WM_SHOW_TRANSACTIONS, + "SURFACE controller=%s alpha=%f matrix=[%f*%f,%f*%f][%f*%f,%f*%f]: %s", + mSurfaceController, mShownAlpha, mDsDx, w.mHScale, mDtDx, w.mVScale, + mDtDy, w.mHScale, mDsDy, w.mVScale, w); boolean prepared = mSurfaceController.prepareToShowInTransaction(mShownAlpha, @@ -1191,11 +1180,11 @@ class WindowStateAnimator { if (!w.isDrawnLw()) { mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE; mAnimator.mLastWindowFreezeSource = w; - if (DEBUG_ORIENTATION) Slog.v(TAG, - "Orientation continue waiting for draw in " + w); + ProtoLog.v(WM_DEBUG_ORIENTATION, + "Orientation continue waiting for draw in %s", w); } else { w.setOrientationChanging(false); - if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w); + ProtoLog.v(WM_DEBUG_ORIENTATION, "Orientation change complete in %s", w); } } diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index 6d813d106345..49f27a1b495d 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -21,10 +21,10 @@ import static android.view.Surface.SCALING_MODE_SCALE_TO_WINDOW; import static android.view.SurfaceControl.METADATA_OWNER_UID; import static android.view.SurfaceControl.METADATA_WINDOW_TYPE; +import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC; +import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC; -import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowSurfaceControllerProto.LAYER; @@ -40,6 +40,8 @@ import android.view.SurfaceControl; import android.view.SurfaceSession; import android.view.WindowContentFrameStats; +import com.android.server.protolog.common.ProtoLog; + import java.io.PrintWriter; class WindowSurfaceController { @@ -111,31 +113,22 @@ class WindowSurfaceController { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } - private void logSurface(String msg, RuntimeException where) { - String str = " SURFACE " + msg + ": " + title; - if (where != null) { - Slog.i(TAG, str, where); - } else { - Slog.i(TAG, str); - } - } - void reparentChildrenInTransaction(WindowSurfaceController other) { - if (SHOW_TRANSACTIONS) Slog.i(TAG, "REPARENT from: " + this + " to: " + other); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "REPARENT from: %s to: %s", this, other); if ((mSurfaceControl != null) && (other.mSurfaceControl != null)) { mSurfaceControl.reparentChildren(other.mSurfaceControl); } } void detachChildren() { - if (SHOW_TRANSACTIONS) Slog.i(TAG, "SEVER CHILDREN"); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "SEVER CHILDREN"); if (mSurfaceControl != null) { mSurfaceControl.detachChildren(); } } void hide(SurfaceControl.Transaction transaction, String reason) { - if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE HIDE ( %s ): %s", reason, title); mHiddenForOtherReasons = true; mAnimator.destroyPreservedSurfaceLocked(); @@ -157,9 +150,8 @@ class WindowSurfaceController { } void destroyNotInTransaction() { - if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { - Slog.i(TAG, "Destroying surface " + this + " called by " + Debug.getCallers(8)); - } + ProtoLog.i(WM_SHOW_SURFACE_ALLOC, + "Destroying surface %s called by %s", this, Debug.getCallers(8)); try { if (mSurfaceControl != null) { mTmpTransaction.remove(mSurfaceControl).apply(); @@ -173,8 +165,7 @@ class WindowSurfaceController { } void setCropInTransaction(Rect clipRect, boolean recoveringMemory) { - if (SHOW_TRANSACTIONS) logSurface( - "CROP " + clipRect.toShortString(), null); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE CROP %s: %s", clipRect.toShortString(), title); try { if (clipRect.width() > 0 && clipRect.height() > 0) { if (!clipRect.equals(mSurfaceCrop)) { @@ -198,8 +189,7 @@ class WindowSurfaceController { } void clearCropInTransaction(boolean recoveringMemory) { - if (SHOW_TRANSACTIONS) logSurface( - "CLEAR CROP", null); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE CLEAR CROP: %s", title); try { Rect clipRect = new Rect(0, 0, -1, -1); if (mSurfaceCrop.equals(clipRect)) { @@ -227,8 +217,8 @@ class WindowSurfaceController { mSurfaceY = top; try { - if (SHOW_TRANSACTIONS) logSurface( - "POS (setPositionInTransaction) @ (" + left + "," + top + ")", null); + ProtoLog.i(WM_SHOW_TRANSACTIONS, + "SURFACE POS (setPositionInTransaction) @ (%f,%f): %s", left, top, title); if (t == null) { mSurfaceControl.setPosition(left, top); @@ -264,8 +254,8 @@ class WindowSurfaceController { mLastDsdy = dsdy; try { - if (SHOW_TRANSACTIONS) logSurface( - "MATRIX [" + dsdx + "," + dtdx + "," + dtdy + "," + dsdy + "]", null); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE MATRIX [%f,%f,%f,%f]: %s", + dsdx, dtdx, dtdy, dsdy, title); if (t == null) { mSurfaceControl.setMatrix(dsdx, dtdx, dtdy, dsdy); } else { @@ -290,8 +280,7 @@ class WindowSurfaceController { mSurfaceH = height; try { - if (SHOW_TRANSACTIONS) logSurface( - "SIZE " + width + "x" + height, null); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SIZE %dx%d: %s", width, height, title); mSurfaceControl.setBufferSize(width, height); } catch (RuntimeException e) { // If something goes wrong with the surface (such @@ -350,8 +339,7 @@ class WindowSurfaceController { } void setOpaque(boolean isOpaque) { - if (SHOW_TRANSACTIONS) logSurface("isOpaque=" + isOpaque, - null); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isOpaque=%b: %s", isOpaque, title); if (mSurfaceControl == null) { return; @@ -367,8 +355,7 @@ class WindowSurfaceController { } void setSecure(boolean isSecure) { - if (SHOW_TRANSACTIONS) logSurface("isSecure=" + isSecure, - null); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isSecure=%b: %s", isSecure, title); if (mSurfaceControl == null) { return; @@ -384,9 +371,7 @@ class WindowSurfaceController { } void setColorSpaceAgnostic(boolean agnostic) { - if (SHOW_TRANSACTIONS) { - logSurface("isColorSpaceAgnostic=" + agnostic, null); - } + ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isColorSpaceAgnostic=%b: %s", agnostic, title); if (mSurfaceControl == null) { return; @@ -410,8 +395,7 @@ class WindowSurfaceController { } boolean showRobustlyInTransaction() { - if (SHOW_TRANSACTIONS) logSurface( - "SHOW (performLayout)", null); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SHOW (performLayout): %s", title); if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this + " during relayout"); mHiddenForOtherReasons = false; diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 8aee0f2a8308..fbfb0286db1e 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -19,9 +19,9 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_WINDOW_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; @@ -35,9 +35,10 @@ import static com.android.server.wm.WindowTokenProto.WINDOW_CONTAINER; import android.annotation.CallSuper; import android.os.Debug; import android.os.IBinder; -import android.util.Slog; import android.util.proto.ProtoOutputStream; +import com.android.server.protolog.common.ProtoLog; + import java.io.PrintWriter; import java.util.Comparator; @@ -135,8 +136,8 @@ class WindowToken extends WindowContainer<WindowState> { void removeAllWindowsIfPossible() { for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowState win = mChildren.get(i); - if (DEBUG_WINDOW_MOVEMENT) Slog.w(TAG_WM, - "removeAllWindowsIfPossible: removing win=" + win); + ProtoLog.w(WM_DEBUG_WINDOW_MOVEMENT, + "removeAllWindowsIfPossible: removing win=%s", win); win.removeIfPossible(); } } @@ -197,15 +198,15 @@ class WindowToken extends WindowContainer<WindowState> { } void addWindow(final WindowState win) { - if (DEBUG_FOCUS) Slog.d(TAG_WM, - "addWindow: win=" + win + " Callers=" + Debug.getCallers(5)); + ProtoLog.d(WM_DEBUG_FOCUS, + "addWindow: win=%s Callers=%s", win, Debug.getCallers(5)); if (win.isChildWindow()) { // Child windows are added to their parent windows. return; } if (!mChildren.contains(win)) { - if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + this); + ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Adding %s to %s", win, this); addChild(win, mWindowComparator); mWmService.mWindowsChanged = true; // TODO: Should we also be setting layout needed here and other places? diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index e93e17ae7a3c..de65002c2c31 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -804,7 +804,7 @@ public final class SystemServer { // Manages Overlay packages t.traceBegin("StartOverlayManagerService"); - mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer)); + mSystemServiceManager.startService(new OverlayManagerService(mSystemContext)); t.traceEnd(); t.traceBegin("StartSensorPrivacyService"); diff --git a/services/net/java/android/net/netlink/InetDiagMessage.java b/services/net/java/android/net/netlink/InetDiagMessage.java index af9e601da9ec..31a2556f2041 100644 --- a/services/net/java/android/net/netlink/InetDiagMessage.java +++ b/services/net/java/android/net/netlink/InetDiagMessage.java @@ -16,26 +16,23 @@ package android.net.netlink; -import static android.os.Process.INVALID_UID; import static android.net.netlink.NetlinkConstants.SOCK_DIAG_BY_FAMILY; import static android.net.netlink.NetlinkSocket.DEFAULT_RECV_BUFSIZE; import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP; import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST; +import static android.os.Process.INVALID_UID; import static android.system.OsConstants.AF_INET; import static android.system.OsConstants.AF_INET6; import static android.system.OsConstants.IPPROTO_UDP; import static android.system.OsConstants.NETLINK_INET_DIAG; -import android.os.Build; -import android.os.Process; +import android.net.util.SocketUtils; import android.system.ErrnoException; import android.util.Log; import java.io.FileDescriptor; +import java.io.IOException; import java.io.InterruptedIOException; -import java.net.DatagramSocket; -import java.net.DatagramSocket; -import java.net.InetAddress; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetSocketAddress; @@ -163,17 +160,25 @@ public class InetDiagMessage extends NetlinkMessage { */ public static int getConnectionOwnerUid(int protocol, InetSocketAddress local, InetSocketAddress remote) { + int uid = INVALID_UID; + FileDescriptor fd = null; try { - final FileDescriptor fd = NetlinkSocket.forProto(NETLINK_INET_DIAG); + fd = NetlinkSocket.forProto(NETLINK_INET_DIAG); NetlinkSocket.connectToKernel(fd); - - return lookupUid(protocol, local, remote, fd); - + uid = lookupUid(protocol, local, remote, fd); } catch (ErrnoException | SocketException | IllegalArgumentException | InterruptedIOException e) { Log.e(TAG, e.toString()); + } finally { + if (fd != null) { + try { + SocketUtils.closeSocket(fd); + } catch (IOException e) { + Log.e(TAG, e.toString()); + } + } } - return INVALID_UID; + return uid; } @Override diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java index f1142fd2f8f9..36e854ca77cd 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java @@ -46,7 +46,6 @@ import android.graphics.Point; import android.os.Handler; import android.os.Message; import android.os.RemoteException; -import android.util.Log; import android.view.Display; import android.view.InputDevice; import android.view.KeyEvent; @@ -55,6 +54,8 @@ import android.view.accessibility.AccessibilityEvent; import androidx.test.runner.AndroidJUnit4; +import com.android.server.accessibility.utils.MotionEventMatcher; + import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; @@ -761,56 +762,6 @@ public class MotionEventInjectorTest { return next; } - static class MotionEventMatcher extends TypeSafeMatcher<MotionEvent> { - long mDownTime; - long mEventTime; - long mActionMasked; - int mX; - int mY; - - MotionEventMatcher(long downTime, long eventTime, int actionMasked, int x, int y) { - mDownTime = downTime; - mEventTime = eventTime; - mActionMasked = actionMasked; - mX = x; - mY = y; - } - - MotionEventMatcher(MotionEvent event) { - this(event.getDownTime(), event.getEventTime(), event.getActionMasked(), - (int) event.getX(), (int) event.getY()); - } - - void offsetTimesBy(long timeOffset) { - mDownTime += timeOffset; - mEventTime += timeOffset; - } - - @Override - public boolean matchesSafely(MotionEvent event) { - if ((event.getDownTime() == mDownTime) && (event.getEventTime() == mEventTime) - && (event.getActionMasked() == mActionMasked) && ((int) event.getX() == mX) - && ((int) event.getY() == mY)) { - return true; - } - Log.e(LOG_TAG, "MotionEvent match failed"); - Log.e(LOG_TAG, "event.getDownTime() = " + event.getDownTime() - + ", expected " + mDownTime); - Log.e(LOG_TAG, "event.getEventTime() = " + event.getEventTime() - + ", expected " + mEventTime); - Log.e(LOG_TAG, "event.getActionMasked() = " + event.getActionMasked() - + ", expected " + mActionMasked); - Log.e(LOG_TAG, "event.getX() = " + event.getX() + ", expected " + mX); - Log.e(LOG_TAG, "event.getY() = " + event.getY() + ", expected " + mY); - return false; - } - - @Override - public void describeTo(Description description) { - description.appendText("Motion event matcher"); - } - } - private static class MotionEventActionMatcher extends TypeSafeMatcher<MotionEvent> { int mAction; diff --git a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java index 104aacb5ef79..4b1ec6fe032b 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java @@ -21,6 +21,7 @@ import static com.android.server.accessibility.gestures.TouchState.STATE_DELEGAT import static com.android.server.accessibility.gestures.TouchState.STATE_DRAGGING; import static com.android.server.accessibility.gestures.TouchState.STATE_TOUCH_EXPLORING; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; @@ -36,6 +37,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.server.accessibility.AccessibilityManagerService; import com.android.server.accessibility.EventStreamTransformation; +import com.android.server.accessibility.utils.MotionEventMatcher; import org.junit.Before; import org.junit.Rule; @@ -49,6 +51,7 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class TouchExplorerTest { + private static final String LOG_TAG = "TouchExplorerTest"; private static final int FLAG_1FINGER = 0x8000; private static final int FLAG_2FINGERS = 0x0100; private static final int FLAG_3FINGERS = 0x0200; @@ -86,7 +89,9 @@ public class TouchExplorerTest { @Override public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { + MotionEventMatcher lastEventMatcher = new MotionEventMatcher(mLastEvent); mEvents.add(0, event.copy()); + assertThat(rawEvent, lastEventMatcher); } @Override diff --git a/services/tests/servicestests/src/com/android/server/accessibility/utils/MotionEventMatcher.java b/services/tests/servicestests/src/com/android/server/accessibility/utils/MotionEventMatcher.java new file mode 100644 index 000000000000..2b6d385fed48 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/accessibility/utils/MotionEventMatcher.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 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. + */ + +package com.android.server.accessibility.utils; + +import android.util.Log; +import android.view.MotionEvent; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; + +/** + * This class compares two motion events using a subset of their attributes: actionMasked, downTime, + * eventTime, and location. If two events match they are considered to be effectively equal. + */ +public class MotionEventMatcher extends TypeSafeMatcher<MotionEvent> { + private static final String LOG_TAG = "MotionEventMatcher"; + long mDownTime; + long mEventTime; + long mActionMasked; + int mX; + int mY; + + MotionEventMatcher(long downTime, long eventTime, int actionMasked, int x, int y) { + mDownTime = downTime; + mEventTime = eventTime; + mActionMasked = actionMasked; + mX = x; + mY = y; + } + + public MotionEventMatcher(MotionEvent event) { + this( + event.getDownTime(), + event.getEventTime(), + event.getActionMasked(), + (int) event.getX(), + (int) event.getY()); + } + + void offsetTimesBy(long timeOffset) { + mDownTime += timeOffset; + mEventTime += timeOffset; + } + + @Override + public boolean matchesSafely(MotionEvent event) { + if ((event.getDownTime() == mDownTime) + && (event.getEventTime() == mEventTime) + && (event.getActionMasked() == mActionMasked) + && ((int) event.getX() == mX) + && ((int) event.getY() == mY)) { + return true; + } + Log.e(LOG_TAG, "MotionEvent match failed"); + Log.e(LOG_TAG, "event.getDownTime() = " + event.getDownTime() + ", expected " + mDownTime); + Log.e( + LOG_TAG, + "event.getEventTime() = " + event.getEventTime() + ", expected " + mEventTime); + Log.e( + LOG_TAG, + "event.getActionMasked() = " + + event.getActionMasked() + + ", expected " + + mActionMasked); + Log.e(LOG_TAG, "event.getX() = " + event.getX() + ", expected " + mX); + Log.e(LOG_TAG, "event.getY() = " + event.getY() + ", expected " + mY); + return false; + } + + @Override + public void describeTo(Description description) { + description.appendText("Motion event matcher"); + } +} diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsUpgradeTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsUpgradeTest.java index 70650de2a4b7..66d2baba2909 100644 --- a/services/tests/servicestests/src/com/android/server/appop/AppOpsUpgradeTest.java +++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsUpgradeTest.java @@ -89,11 +89,13 @@ public class AppOpsUpgradeTest { final int defaultModeOp2 = AppOpsManager.opToDefaultMode(op2); for(int i = 0; i < uidStates.size(); i++) { final AppOpsService.UidState uidState = uidStates.valueAt(i); - final int uidMode1 = uidState.hasOpMode(op1) ? uidState.getOpMode(op1) : defaultModeOp1; - final int uidMode2 = uidState.hasOpMode(op2) ? uidState.getOpMode(op2) : defaultModeOp2; - assertEquals(uidMode1, uidMode2); - if (uidMode1 != defaultModeOp1) { - numberOfNonDefaultOps++; + if (uidState.opModes != null) { + final int uidMode1 = uidState.opModes.get(op1, defaultModeOp1); + final int uidMode2 = uidState.opModes.get(op2, defaultModeOp2); + assertEquals(uidMode1, uidMode2); + if (uidMode1 != defaultModeOp1) { + numberOfNonDefaultOps++; + } } if (uidState.pkgOps == null) { continue; diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java index 3cdadd58486f..c566dfc4a23e 100644 --- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java +++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java @@ -444,7 +444,7 @@ public class OverlayManagerServiceImplTests { private Set<String> mIdmapFiles = new ArraySet<>(); DummyIdmapManager(DummyDeviceState state, DummyPackageManagerHelper packageManagerHelper) { - super(null, packageManagerHelper); + super(packageManagerHelper); mState = state; } diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java index e020945ebefc..819091c378b8 100644 --- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java @@ -27,13 +27,10 @@ import static org.mockito.Mockito.when; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ComponentParseUtils.ParsedActivity; -import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo; -import android.content.pm.parsing.PackageImpl; -import android.content.pm.parsing.ParsingPackage; +import android.content.pm.PackageParser; import android.os.Build; import android.os.Process; import android.permission.IPermissionManager; @@ -59,55 +56,45 @@ public class AppsFilterTest { @Mock AppsFilter.FeatureConfig mFeatureConfigMock; - private Map<String, AndroidPackage> mExisting = new ArrayMap<>(); + private Map<String, PackageParser.Package> mExisting = new ArrayMap<>(); - private static ParsingPackage pkg(String packageName) { - return PackageImpl.forParsing(packageName) - .setTargetSdkVersion(Build.VERSION_CODES.R); + private static PackageBuilder pkg(String packageName) { + return new PackageBuilder(packageName) + .setApplicationInfoTargetSdkVersion(Build.VERSION_CODES.R); } - private static ParsingPackage pkg(String packageName, Intent... queries) { - ParsingPackage pkg = pkg(packageName); - if (queries != null) { - for (Intent intent : queries) { - pkg.addQueriesIntent(intent); - } - } - return pkg; + private static PackageBuilder pkg(String packageName, Intent... queries) { + return pkg(packageName).setQueriesIntents(queries); } - private static ParsingPackage pkg(String packageName, String... queriesPackages) { - ParsingPackage pkg = pkg(packageName); - if (queriesPackages != null) { - for (String queryPackageName : queriesPackages) { - pkg.addQueriesPackage(queryPackageName); - } - } - return pkg; + private static PackageBuilder pkg(String packageName, String... queriesPackages) { + return pkg(packageName).setQueriesPackages(queriesPackages); } - private static ParsingPackage pkg(String packageName, IntentFilter... filters) { - ParsedActivity activity = new ParsedActivity(); - activity.setPackageName(packageName); + private static PackageBuilder pkg(String packageName, IntentFilter... filters) { + final PackageBuilder packageBuilder = pkg(packageName).addActivity( + pkg -> new PackageParser.ParseComponentArgs(pkg, new String[1], 0, 0, 0, 0, 0, 0, + new String[]{packageName}, 0, 0, 0), new ActivityInfo()); for (IntentFilter filter : filters) { - final ParsedActivityIntentInfo info = new ParsedActivityIntentInfo(packageName, null); - if (filter.countActions() > 0) { - filter.actionsIterator().forEachRemaining(info::addAction); - } - if (filter.countCategories() > 0) { - filter.actionsIterator().forEachRemaining(info::addAction); - } - if (filter.countDataAuthorities() > 0) { - filter.authoritiesIterator().forEachRemaining(info::addDataAuthority); - } - if (filter.countDataSchemes() > 0) { - filter.schemesIterator().forEachRemaining(info::addDataScheme); - } - activity.addIntent(info); + packageBuilder.addActivityIntentInfo(0 /* index */, activity -> { + final PackageParser.ActivityIntentInfo info = + new PackageParser.ActivityIntentInfo(activity); + if (filter.countActions() > 0) { + filter.actionsIterator().forEachRemaining(info::addAction); + } + if (filter.countCategories() > 0) { + filter.actionsIterator().forEachRemaining(info::addAction); + } + if (filter.countDataAuthorities() > 0) { + filter.authoritiesIterator().forEachRemaining(info::addDataAuthority); + } + if (filter.countDataSchemes() > 0) { + filter.schemesIterator().forEachRemaining(info::addDataScheme); + } + return info; + }); } - - return pkg(packageName) - .addActivity(activity); + return packageBuilder; } @Before @@ -119,7 +106,7 @@ public class AppsFilterTest { .checkPermission(anyString(), anyString(), anyInt())) .thenReturn(PackageManager.PERMISSION_DENIED); when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true); - when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))) + when(mFeatureConfigMock.packageIsEnabled(any(PackageParser.Package.class))) .thenReturn(true); } @@ -165,7 +152,7 @@ public class AppsFilterTest { PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build(); PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package", - new Intent("TEST_ACTION")).setTargetSdkVersion( + new Intent("TEST_ACTION")).setApplicationInfoTargetSdkVersion( Build.VERSION_CODES.P)).build(); assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0)); @@ -258,7 +245,7 @@ public class AppsFilterTest { @Test public void testNoQueries_FeatureOff_DoesntFilter() { - when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))) + when(mFeatureConfigMock.packageIsEnabled(any(PackageParser.Package.class))) .thenReturn(false); final AppsFilter appsFilter = new AppsFilter(mFeatureConfigMock, mPermissionManagerMock, @@ -314,15 +301,13 @@ public class AppsFilterTest { } private PackageSettingBuilder simulateAddPackage(AppsFilter filter, - ParsingPackage newPkgBuilder) { - AndroidPackage newPkg = newPkgBuilder - .hideAsParsed() - .hideAsFinal(); + PackageBuilder newPkgBuilder) { + PackageParser.Package newPkg = newPkgBuilder.build(); filter.addPackage(newPkg, mExisting); - mExisting.put(newPkg.getPackageName(), newPkg); + mExisting.put(newPkg.packageName, newPkg); return new PackageSettingBuilder() .setPackage(newPkg) - .setName(newPkg.getPackageName()) + .setName(newPkg.packageName) .setCodePath("/") .setResourcePath("/") .setPVersionCode(1L); diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java index 0273a1c5d86e..fec3267c2649 100644 --- a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java @@ -19,17 +19,17 @@ package com.android.server.pm; import android.content.pm.PackageParser; import android.content.pm.Signature; -import android.test.AndroidTestCase; import android.util.ArrayMap; import android.util.ArraySet; import android.util.LongSparseArray; - import com.android.internal.util.ArrayUtils; import java.io.File; import java.io.IOException; -import java.security.PublicKey; import java.security.cert.CertificateException; +import java.security.PublicKey; + +import android.test.AndroidTestCase; public class KeySetManagerServiceTest extends AndroidTestCase { @@ -39,7 +39,7 @@ public class KeySetManagerServiceTest extends AndroidTestCase { public PackageSetting generateFakePackageSetting(String name) { return new PackageSetting(name, name, new File(mContext.getCacheDir(), "fakeCodePath"), new File(mContext.getCacheDir(), "fakeResPath"), "", "", "", - "", 1, 0, 0, 0 /*sharedUserId*/, null /*usesStaticLibraries*/, + "", 1, 0, 0, null, null, 0 /*sharedUserId*/, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/); } diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java new file mode 100644 index 000000000000..c38672cfc93c --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 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. + */ + +package com.android.server.pm; + +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageParser; + +import com.android.internal.util.ArrayUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +class PackageBuilder { + final PackageParser.Package mPkg; + + PackageBuilder(String packageName) { + mPkg = new PackageParser.Package(packageName); + } + + PackageBuilder setApplicationInfoCodePath(String codePath) { + mPkg.applicationInfo.setCodePath(codePath); + return this; + } + + PackageBuilder setApplicationInfoResourcePath(String resourcePath) { + mPkg.applicationInfo.setResourcePath(resourcePath); + return this; + } + + PackageBuilder setCodePath(String codePath) { + mPkg.codePath = codePath; + return this; + } + + PackageBuilder setBaseCodePath(String baseCodePath) { + mPkg.baseCodePath = baseCodePath; + return this; + } + + PackageBuilder addUsesStaticLibrary(String name, long version) { + mPkg.usesStaticLibraries = ArrayUtils.add(mPkg.usesStaticLibraries, name); + mPkg.usesStaticLibrariesVersions = + ArrayUtils.appendLong(mPkg.usesStaticLibrariesVersions, version); + return this; + } + + PackageBuilder setApplicationInfoNativeLibraryRootDir(String dir) { + mPkg.applicationInfo.nativeLibraryRootDir = dir; + return this; + } + + PackageBuilder setStaticSharedLib(String staticSharedLibName, long staticSharedLibVersion) { + mPkg.staticSharedLibVersion = staticSharedLibVersion; + mPkg.staticSharedLibName = staticSharedLibName; + return this; + } + + PackageBuilder setManifestPackageName(String manifestPackageName) { + mPkg.manifestPackageName = manifestPackageName; + return this; + } + + PackageBuilder setVersionCodeMajor(int versionCodeMajor) { + mPkg.mVersionCodeMajor = versionCodeMajor; + return this; + } + + PackageBuilder setVersionCode(int versionCode) { + mPkg.mVersionCode = versionCode; + return this; + } + + PackageBuilder addSplitCodePath(String splitCodePath) { + mPkg.splitCodePaths = + ArrayUtils.appendElement(String.class, mPkg.splitCodePaths, splitCodePath); + return this; + } + + PackageBuilder setApplicationInfoVolumeUuid(String volumeUuid) { + mPkg.applicationInfo.volumeUuid = volumeUuid; + return this; + } + + PackageBuilder addLibraryName(String libraryName) { + mPkg.libraryNames = ArrayUtils.add(mPkg.libraryNames, libraryName); + return this; + } + + PackageBuilder setRealPackageName(String realPackageName) { + mPkg.mRealPackage = realPackageName; + return this; + } + + PackageBuilder setCpuAbiOVerride(String cpuAbiOverride) { + mPkg.cpuAbiOverride = cpuAbiOverride; + return this; + } + + PackageBuilder addPermissionRequest(String permissionName) { + mPkg.requestedPermissions.add(permissionName); + return this; + } + + PackageParser.Package build() { + return mPkg; + } + + public PackageBuilder addApplicationInfoFlag(int flag) { + mPkg.applicationInfo.flags |= flag; + return this; + } + + public PackageBuilder setApplicationInfoTargetSdkVersion(int versionCode) { + mPkg.applicationInfo.targetSdkVersion = versionCode; + return this; + } + + public PackageBuilder setQueriesIntents(Collection<Intent> queriesIntents) { + mPkg.mQueriesIntents = new ArrayList<>(queriesIntents); + return this; + } + + public PackageBuilder setQueriesIntents(Intent... intents) { + return setQueriesIntents(Arrays.asList(intents)); + } + + public PackageBuilder setQueriesPackages(Collection<String> queriesPackages) { + mPkg.mQueriesPackages = new ArrayList<>(queriesPackages); + return this; + } + + public PackageBuilder setQueriesPackages(String... queriesPackages) { + return setQueriesPackages(Arrays.asList(queriesPackages)); + } + + public PackageBuilder setForceQueryable(boolean forceQueryable) { + mPkg.mForceQueryable = forceQueryable; + return this; + } + + public interface ParseComponentArgsCreator { + PackageParser.ParseComponentArgs create(PackageParser.Package pkg); + } + + public PackageBuilder addActivity(ParseComponentArgsCreator argsCreator, ActivityInfo info) { + mPkg.activities.add(new PackageParser.Activity(argsCreator.create(mPkg), info)); + return this; + } + + public interface ActivityIntentInfoCreator { + PackageParser.ActivityIntentInfo create(PackageParser.Activity activity); + } + + public PackageBuilder addActivityIntentInfo( + int activityIndex, ActivityIntentInfoCreator creator) { + final PackageParser.Activity activity = mPkg.activities.get(activityIndex); + activity.intents.add(creator.create(activity)); + return this; + } +} diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java index 85840e135909..0a310d193675 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java @@ -87,7 +87,7 @@ public class PackageManagerServiceTest { setting = new PackageSetting("name", "realName", new File("codePath"), new File("resourcePath"), "legacyNativeLibraryPathString", "primaryCpuAbiString", "secondaryCpuAbiString", - "cpuAbiOverrideString", 0, 0, 0, 0, + "cpuAbiOverrideString", 0, 0, 0, "parentPackageName", null, 0, null, null); pri.populateUsers(new int[] { 1, 2, 3, 4, 5 diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java index 6836d3b6e21d..15032c5c5cbb 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java @@ -20,8 +20,8 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; +import static android.content.res.Resources.ID_NULL; -import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.notNullValue; @@ -75,10 +75,11 @@ import java.util.List; @RunWith(AndroidJUnit4.class) @SmallTest public class PackageManagerSettingsTests { + private static final String TAG = "PackageManagerSettingsTests"; + private static final String PACKAGE_NAME_1 = "com.android.app1"; private static final String PACKAGE_NAME_2 = "com.android.app2"; private static final String PACKAGE_NAME_3 = "com.android.app3"; - private static final String PACKAGE_NAME_1 = "com.android.app1"; - public static final String TAG = "PackageManagerSettingsTests"; + private static final int TEST_RESOURCE_ID = 2131231283; @Mock PermissionSettings mPermissionSettings; @@ -158,7 +159,7 @@ public class PackageManagerSettingsTests { assertThat(ps.getEnabled(1), is(COMPONENT_ENABLED_STATE_DEFAULT)); } - private PersistableBundle getPersistableBundle(String packageName, long longVal, + private static PersistableBundle createPersistableBundle(String packageName, long longVal, double doubleVal, boolean boolVal, String textVal) { final PersistableBundle bundle = new PersistableBundle(); bundle.putString(packageName + ".TEXT_VALUE", textVal); @@ -169,8 +170,8 @@ public class PackageManagerSettingsTests { } @Test - public void testReadPackageRestrictions_oldSuspendInfo() { - writePackageRestrictions_oldSuspendInfoXml(0); + public void testReadPackageRestrictions_noSuspendingPackage() { + writePackageRestrictions_noSuspendingPackageXml(0); final Object lock = new Object(); final Context context = InstrumentationRegistry.getTargetContext(); final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, lock); @@ -181,26 +182,61 @@ public class PackageManagerSettingsTests { final PackageSetting ps1 = settingsUnderTest.mPackages.get(PACKAGE_NAME_1); final PackageUserState packageUserState1 = ps1.readUserState(0); assertThat(packageUserState1.suspended, is(true)); - assertThat("android".equals(packageUserState1.suspendingPackage), is(true)); + assertThat(packageUserState1.suspendParams.size(), is(1)); + assertThat(packageUserState1.suspendParams.keyAt(0), is("android")); + assertThat(packageUserState1.suspendParams.valueAt(0), is(nullValue())); final PackageSetting ps2 = settingsUnderTest.mPackages.get(PACKAGE_NAME_2); final PackageUserState packageUserState2 = ps2.readUserState(0); assertThat(packageUserState2.suspended, is(false)); - assertThat(packageUserState2.suspendingPackage, is(nullValue())); + assertThat(packageUserState2.suspendParams, is(nullValue())); } @Test - public void testReadWritePackageRestrictions_newSuspendInfo() { + public void testReadPackageRestrictions_noSuspendParamsMap() { + writePackageRestrictions_noSuspendParamsMapXml(0); + final Object lock = new Object(); + final Context context = InstrumentationRegistry.getTargetContext(); + final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, lock); + settingsUnderTest.mPackages.put(PACKAGE_NAME_1, createPackageSetting(PACKAGE_NAME_1)); + settingsUnderTest.readPackageRestrictionsLPr(0); + + final PackageSetting ps1 = settingsUnderTest.mPackages.get(PACKAGE_NAME_1); + final PackageUserState packageUserState1 = ps1.readUserState(0); + assertThat(packageUserState1.suspended, is(true)); + assertThat(packageUserState1.suspendParams.size(), is(1)); + assertThat(packageUserState1.suspendParams.keyAt(0), is(PACKAGE_NAME_3)); + final PackageUserState.SuspendParams params = packageUserState1.suspendParams.valueAt(0); + assertThat(params, is(notNullValue())); + assertThat(params.appExtras.size(), is(1)); + assertThat(params.appExtras.getString("app_extra_string"), is("value")); + assertThat(params.launcherExtras.size(), is(1)); + assertThat(params.launcherExtras.getLong("launcher_extra_long"), is(4L)); + assertThat(params.dialogInfo, is(notNullValue())); + assertThat(params.dialogInfo.getDialogMessage(), is("Dialog Message")); + assertThat(params.dialogInfo.getTitleResId(), is(ID_NULL)); + assertThat(params.dialogInfo.getIconResId(), is(TEST_RESOURCE_ID)); + assertThat(params.dialogInfo.getNeutralButtonTextResId(), is(ID_NULL)); + assertThat(params.dialogInfo.getDialogMessageResId(), is(ID_NULL)); + } + + @Test + public void testReadWritePackageRestrictions_suspendInfo() { final Context context = InstrumentationRegistry.getTargetContext(); final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, new Object()); final PackageSetting ps1 = createPackageSetting(PACKAGE_NAME_1); final PackageSetting ps2 = createPackageSetting(PACKAGE_NAME_2); final PackageSetting ps3 = createPackageSetting(PACKAGE_NAME_3); - final PersistableBundle appExtras1 = getPersistableBundle( + final PersistableBundle appExtras1 = createPersistableBundle( PACKAGE_NAME_1, 1L, 0.01, true, "appString1"); - final PersistableBundle launcherExtras1 = getPersistableBundle( + final PersistableBundle appExtras2 = createPersistableBundle( + PACKAGE_NAME_2, 2L, 0.02, true, "appString2"); + + final PersistableBundle launcherExtras1 = createPersistableBundle( PACKAGE_NAME_1, 10L, 0.1, false, "launcherString1"); + final PersistableBundle launcherExtras2 = createPersistableBundle( + PACKAGE_NAME_2, 20L, 0.2, false, "launcherString2"); final SuspendDialogInfo dialogInfo1 = new SuspendDialogInfo.Builder() .setIcon(0x11220001) @@ -208,14 +244,23 @@ public class PackageManagerSettingsTests { .setMessage("1st message") .setNeutralButtonText(0x11220003) .build(); + final SuspendDialogInfo dialogInfo2 = new SuspendDialogInfo.Builder() + .setIcon(0x22220001) + .setTitle(0x22220002) + .setMessage("2nd message") + .setNeutralButtonText(0x22220003) + .build(); - ps1.setSuspended(true, "suspendingPackage1", dialogInfo1, appExtras1, launcherExtras1, 0); + ps1.addOrUpdateSuspension("suspendingPackage1", dialogInfo1, appExtras1, launcherExtras1, + 0); + ps1.addOrUpdateSuspension("suspendingPackage2", dialogInfo2, appExtras2, launcherExtras2, + 0); settingsUnderTest.mPackages.put(PACKAGE_NAME_1, ps1); - ps2.setSuspended(true, "suspendingPackage2", null, null, null, 0); + ps2.addOrUpdateSuspension("suspendingPackage3", null, appExtras1, null, 0); settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2); - ps3.setSuspended(false, "irrelevant", dialogInfo1, null, null, 0); + ps3.removeSuspension("irrelevant", 0); settingsUnderTest.mPackages.put(PACKAGE_NAME_3, ps3); settingsUnderTest.writePackageRestrictionsLPr(0); @@ -229,27 +274,39 @@ public class PackageManagerSettingsTests { final PackageUserState readPus1 = settingsUnderTest.mPackages.get(PACKAGE_NAME_1) .readUserState(0); assertThat(readPus1.suspended, is(true)); - assertThat(readPus1.suspendingPackage, equalTo("suspendingPackage1")); - assertThat(readPus1.dialogInfo, equalTo(dialogInfo1)); - assertThat(BaseBundle.kindofEquals(readPus1.suspendedAppExtras, appExtras1), is(true)); - assertThat(BaseBundle.kindofEquals(readPus1.suspendedLauncherExtras, launcherExtras1), + assertThat(readPus1.suspendParams.size(), is(2)); + + assertThat(readPus1.suspendParams.keyAt(0), is("suspendingPackage1")); + final PackageUserState.SuspendParams params11 = readPus1.suspendParams.valueAt(0); + assertThat(params11, is(notNullValue())); + assertThat(params11.dialogInfo, is(dialogInfo1)); + assertThat(BaseBundle.kindofEquals(params11.appExtras, appExtras1), is(true)); + assertThat(BaseBundle.kindofEquals(params11.launcherExtras, launcherExtras1), + is(true)); + + assertThat(readPus1.suspendParams.keyAt(1), is("suspendingPackage2")); + final PackageUserState.SuspendParams params12 = readPus1.suspendParams.valueAt(1); + assertThat(params12, is(notNullValue())); + assertThat(params12.dialogInfo, is(dialogInfo2)); + assertThat(BaseBundle.kindofEquals(params12.appExtras, appExtras2), is(true)); + assertThat(BaseBundle.kindofEquals(params12.launcherExtras, launcherExtras2), is(true)); final PackageUserState readPus2 = settingsUnderTest.mPackages.get(PACKAGE_NAME_2) .readUserState(0); assertThat(readPus2.suspended, is(true)); - assertThat(readPus2.suspendingPackage, equalTo("suspendingPackage2")); - assertThat(readPus2.dialogInfo, is(nullValue())); - assertThat(readPus2.suspendedAppExtras, is(nullValue())); - assertThat(readPus2.suspendedLauncherExtras, is(nullValue())); + assertThat(readPus2.suspendParams.size(), is(1)); + assertThat(readPus2.suspendParams.keyAt(0), is("suspendingPackage3")); + final PackageUserState.SuspendParams params21 = readPus2.suspendParams.valueAt(0); + assertThat(params21, is(notNullValue())); + assertThat(params21.dialogInfo, is(nullValue())); + assertThat(BaseBundle.kindofEquals(params21.appExtras, appExtras1), is(true)); + assertThat(params21.launcherExtras, is(nullValue())); final PackageUserState readPus3 = settingsUnderTest.mPackages.get(PACKAGE_NAME_3) .readUserState(0); assertThat(readPus3.suspended, is(false)); - assertThat(readPus3.suspendingPackage, is(nullValue())); - assertThat(readPus3.dialogInfo, is(nullValue())); - assertThat(readPus3.suspendedAppExtras, is(nullValue())); - assertThat(readPus3.suspendedLauncherExtras, is(nullValue())); + assertThat(readPus3.suspendParams, is(nullValue())); } @Test @@ -346,6 +403,10 @@ public class PackageManagerSettingsTests { private static final String PACKAGE_NAME = "com.android.bar"; private static final String REAL_PACKAGE_NAME = "com.android.foo"; + private static final String PARENT_PACKAGE_NAME = "com.android.bar.parent"; + private static final String CHILD_PACKAGE_NAME_01 = "com.android.bar.child01"; + private static final String CHILD_PACKAGE_NAME_02 = "com.android.bar.child02"; + private static final String CHILD_PACKAGE_NAME_03 = "com.android.bar.child03"; private static final File INITIAL_CODE_PATH = new File(InstrumentationRegistry.getContext().getFilesDir(), "com.android.bar-1"); private static final File UPDATED_CODE_PATH = @@ -355,6 +416,10 @@ public class PackageManagerSettingsTests { @Test public void testPackageStateCopy01() { + final List<String> childPackageNames = new ArrayList<>(); + childPackageNames.add(CHILD_PACKAGE_NAME_01); + childPackageNames.add(CHILD_PACKAGE_NAME_02); + childPackageNames.add(CHILD_PACKAGE_NAME_03); final PackageSetting origPkgSetting01 = new PackageSetting( PACKAGE_NAME, REAL_PACKAGE_NAME, @@ -367,6 +432,8 @@ public class PackageManagerSettingsTests { INITIAL_VERSION_CODE, ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_HAS_CODE, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED|ApplicationInfo.PRIVATE_FLAG_HIDDEN, + PARENT_PACKAGE_NAME, + childPackageNames, 0, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/); @@ -376,6 +443,10 @@ public class PackageManagerSettingsTests { @Test public void testPackageStateCopy02() { + final List<String> childPackageNames = new ArrayList<>(); + childPackageNames.add(CHILD_PACKAGE_NAME_01); + childPackageNames.add(CHILD_PACKAGE_NAME_02); + childPackageNames.add(CHILD_PACKAGE_NAME_03); final PackageSetting origPkgSetting01 = new PackageSetting( PACKAGE_NAME /*pkgName*/, REAL_PACKAGE_NAME /*realPkgName*/, @@ -388,6 +459,8 @@ public class PackageManagerSettingsTests { INITIAL_VERSION_CODE, ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_HAS_CODE, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED|ApplicationInfo.PRIVATE_FLAG_HIDDEN, + PARENT_PACKAGE_NAME, + childPackageNames, 0, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/); @@ -403,6 +476,8 @@ public class PackageManagerSettingsTests { UPDATED_VERSION_CODE, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, + null /*parentPkgName*/, + null /*childPkgNames*/, 0, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/); @@ -430,6 +505,7 @@ public class PackageManagerSettingsTests { "armeabi" /*secondaryCpuAbi*/, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, + null /*childPkgNames*/, UserManagerService.getInstance(), null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/); @@ -463,6 +539,7 @@ public class PackageManagerSettingsTests { "armeabi" /*secondaryCpuAbi*/, ApplicationInfo.FLAG_SYSTEM /*pkgFlags*/, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED /*pkgPrivateFlags*/, + null /*childPkgNames*/, UserManagerService.getInstance(), null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/); @@ -502,6 +579,7 @@ public class PackageManagerSettingsTests { "armeabi" /*secondaryCpuAbi*/, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, + null /*childPkgNames*/, UserManagerService.getInstance(), null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/); @@ -534,6 +612,8 @@ public class PackageManagerSettingsTests { false /*allowInstall*/, false /*instantApp*/, false /*virtualPreload*/, + null /*parentPkgName*/, + null /*childPkgNames*/, UserManagerService.getInstance(), null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/); @@ -573,6 +653,8 @@ public class PackageManagerSettingsTests { true /*allowInstall*/, false /*instantApp*/, false /*virtualPreload*/, + null /*parentPkgName*/, + null /*childPkgNames*/, UserManagerService.getInstance(), null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/); @@ -618,6 +700,8 @@ public class PackageManagerSettingsTests { false /*allowInstall*/, false /*instantApp*/, false /*virtualPreload*/, + null /*parentPkgName*/, + null /*childPkgNames*/, UserManagerService.getInstance(), null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/); @@ -660,6 +744,8 @@ public class PackageManagerSettingsTests { false /*allowInstall*/, false /*instantApp*/, false /*virtualPreload*/, + null /*parentPkgName*/, + null /*childPkgNames*/, UserManagerService.getInstance(), null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/); @@ -716,6 +802,9 @@ public class PackageManagerSettingsTests { private void verifySettingCopy(PackageSetting origPkgSetting, PackageSetting testPkgSetting) { assertThat(origPkgSetting, is(not(testPkgSetting))); assertThat(origPkgSetting.appId, is(testPkgSetting.appId)); + // different but equal objects + assertNotSame(origPkgSetting.childPackageNames, testPkgSetting.childPackageNames); + assertThat(origPkgSetting.childPackageNames, is(testPkgSetting.childPackageNames)); assertSame(origPkgSetting.codePath, testPkgSetting.codePath); assertThat(origPkgSetting.codePath, is(testPkgSetting.codePath)); assertSame(origPkgSetting.codePathString, testPkgSetting.codePathString); @@ -741,6 +830,8 @@ public class PackageManagerSettingsTests { // mOldCodePaths is _not_ copied // assertNotSame(origPkgSetting.mOldCodePaths, testPkgSetting.mOldCodePaths); // assertThat(origPkgSetting.mOldCodePaths, is(not(testPkgSetting.mOldCodePaths))); + assertSame(origPkgSetting.parentPackageName, testPkgSetting.parentPackageName); + assertThat(origPkgSetting.parentPackageName, is(testPkgSetting.parentPackageName)); assertSame(origPkgSetting.pkg, testPkgSetting.pkg); // No equals() method for this object // assertThat(origPkgSetting.pkg, is(testPkgSetting.pkg)); @@ -792,6 +883,8 @@ public class PackageManagerSettingsTests { INITIAL_VERSION_CODE, pkgFlags, 0 /*privateFlags*/, + null /*parentPackageName*/, + null /*childPackageNames*/, sharedUserId, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/); @@ -810,6 +903,8 @@ public class PackageManagerSettingsTests { INITIAL_VERSION_CODE, 0, 0 /*privateFlags*/, + null /*parentPackageName*/, + null /*childPackageNames*/, 0, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/); @@ -902,10 +997,10 @@ public class PackageManagerSettingsTests { + "</packages>").getBytes()); } - private void writePackageRestrictions_oldSuspendInfoXml(final int userId) { + private void writePackageRestrictions_noSuspendingPackageXml(final int userId) { writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/users/" + userId + "/package-restrictions.xml"), - ( "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" + ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" + "<package-restrictions>\n" + " <pkg name=\"" + PACKAGE_NAME_1 + "\" suspended=\"true\" />" + " <pkg name=\"" + PACKAGE_NAME_2 + "\" suspended=\"false\" />" @@ -917,6 +1012,30 @@ public class PackageManagerSettingsTests { .getBytes()); } + private void writePackageRestrictions_noSuspendParamsMapXml(final int userId) { + writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/users/" + + userId + "/package-restrictions.xml"), + ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" + + "<package-restrictions>\n" + + " <pkg name=\"" + PACKAGE_NAME_1 + "\" " + + " suspended=\"true\" suspending-package=\"" + PACKAGE_NAME_3 + "\">\n" + + " <suspended-dialog-info dialogMessage=\"Dialog Message\"" + + " iconResId=\"" + TEST_RESOURCE_ID + "\"/>\n" + + " <suspended-app-extras>\n" + + " <string name=\"app_extra_string\">value</string>\n" + + " </suspended-app-extras>\n" + + " <suspended-launcher-extras>\n" + + " <long name=\"launcher_extra_long\" value=\"4\" />\n" + + " </suspended-launcher-extras>\n" + + " </pkg>\n" + + " <preferred-activities />\n" + + " <persistent-preferred-activities />\n" + + " <crossProfile-intent-filters />\n" + + " <default-apps />\n" + + "</package-restrictions>\n") + .getBytes()); + } + private void writeStoppedPackagesXml() { writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages-stopped.xml"), ( "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java index 162092b5040a..e33d8ca66ed0 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java @@ -15,49 +15,35 @@ */ package com.android.server.pm; -import static org.junit.Assert.assertArrayEquals; +import static android.content.res.Resources.ID_NULL; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ConfigurationInfo; import android.content.pm.FeatureGroupInfo; import android.content.pm.FeatureInfo; -import android.content.pm.PackageInfo; +import android.content.pm.InstrumentationInfo; import android.content.pm.PackageParser; -import android.content.pm.PackageUserState; import android.content.pm.ProviderInfo; import android.content.pm.ServiceInfo; import android.content.pm.SharedLibraryInfo; import android.content.pm.Signature; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ComponentParseUtils; -import android.content.pm.parsing.ComponentParseUtils.ParsedActivity; -import android.content.pm.parsing.ComponentParseUtils.ParsedComponent; -import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation; -import android.content.pm.parsing.ComponentParseUtils.ParsedIntentInfo; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermission; -import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup; -import android.content.pm.parsing.ComponentParseUtils.ParsedProvider; -import android.content.pm.parsing.ComponentParseUtils.ParsedService; -import android.content.pm.parsing.PackageImpl; -import android.content.pm.parsing.PackageInfoUtils; -import android.content.pm.parsing.ParsedPackage; -import android.content.pm.parsing.ParsingPackage; import android.os.Bundle; import android.os.Parcel; import android.platform.test.annotations.Presubmit; +import android.util.ArrayMap; import android.util.ArraySet; import androidx.test.filters.MediumTest; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.internal.util.ArrayUtils; - import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -71,7 +57,6 @@ import java.lang.reflect.Field; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -79,9 +64,6 @@ import java.util.Set; @RunWith(AndroidJUnit4.class) @MediumTest public class PackageParserTest { - // TODO(b/135203078): Update this test with all fields and validate equality. Initial change - // was just migrating to new interfaces. Consider adding actual equals() methods. - @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder(); @@ -97,12 +79,12 @@ public class PackageParserTest { @Test public void testParse_noCache() throws Exception { PackageParser pp = new CachePackageNameParser(); - ParsedPackage pkg = pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */, + PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */); assertNotNull(pkg); pp.setCacheDir(mTmpDir); - pkg = pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */, + pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */); assertNotNull(pkg); @@ -117,27 +99,27 @@ public class PackageParserTest { pp.setCacheDir(mTmpDir); // The first parse will write this package to the cache. - pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */); + pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */); // Now attempt to parse the package again, should return the // cached result. - ParsedPackage pkg = pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */, + PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */); - assertEquals("cache_android", pkg.getPackageName()); + assertEquals("cache_android", pkg.packageName); // Try again, with useCaches == false, shouldn't return the parsed // result. - pkg = pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */); - assertEquals("android", pkg.getPackageName()); + pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */); + assertEquals("android", pkg.packageName); // We haven't set a cache directory here : the parse should still succeed, // just not using the cached results. pp = new CachePackageNameParser(); - pkg = pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */); - assertEquals("android", pkg.getPackageName()); + pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */); + assertEquals("android", pkg.packageName); - pkg = pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */); - assertEquals("android", pkg.getPackageName()); + pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */); + assertEquals("android", pkg.packageName); } @Test @@ -145,14 +127,14 @@ public class PackageParserTest { PackageParser pp = new PackageParser(); pp.setCacheDir(mTmpDir); - ParsedPackage pkg = pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */, - true /* useCaches */); + PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, + true /* useCaches */); Parcel p = Parcel.obtain(); pkg.writeToParcel(p, 0 /* flags */); p.setDataPosition(0); - ParsedPackage deserialized = new PackageImpl(p); + PackageParser.Package deserialized = new PackageParser.Package(p); assertPackagesEqual(pkg, deserialized); } @@ -161,164 +143,154 @@ public class PackageParserTest { @SmallTest @Presubmit public void test_roundTripKnownFields() throws Exception { - ParsingPackage pkg = PackageImpl.forParsing("foo"); + PackageParser.Package pkg = new PackageParser.Package("foo"); setKnownFields(pkg); Parcel p = Parcel.obtain(); pkg.writeToParcel(p, 0 /* flags */); p.setDataPosition(0); - ParsedPackage deserialized = new PackageImpl(p); + PackageParser.Package deserialized = new PackageParser.Package(p); assertAllFieldsExist(deserialized); } @Test public void test_stringInterning() throws Exception { - ParsingPackage pkg = PackageImpl.forParsing("foo"); + PackageParser.Package pkg = new PackageParser.Package("foo"); setKnownFields(pkg); Parcel p = Parcel.obtain(); pkg.writeToParcel(p, 0 /* flags */); p.setDataPosition(0); - ParsingPackage deserialized = new PackageImpl(p); + PackageParser.Package deserialized = new PackageParser.Package(p); p.setDataPosition(0); - ParsingPackage deserialized2 = new PackageImpl(p); - - assertSame(deserialized.getPackageName(), deserialized2.getPackageName()); - assertSame(deserialized.getPermission(), - deserialized2.getPermission()); - assertSame(deserialized.getRequestedPermissions().get(0), - deserialized2.getRequestedPermissions().get(0)); - - List<String> protectedBroadcastsOne = new ArrayList<>(1); - protectedBroadcastsOne.addAll(deserialized.getProtectedBroadcasts()); - - List<String> protectedBroadcastsTwo = new ArrayList<>(1); - protectedBroadcastsTwo.addAll(deserialized2.getProtectedBroadcasts()); - - assertSame(protectedBroadcastsOne.get(0), protectedBroadcastsTwo.get(0)); - - assertSame(deserialized.getUsesLibraries().get(0), - deserialized2.getUsesLibraries().get(0)); - assertSame(deserialized.getUsesOptionalLibraries().get(0), - deserialized2.getUsesOptionalLibraries().get(0)); - assertSame(deserialized.getVersionName(), deserialized2.getVersionName()); - assertSame(deserialized.getSharedUserId(), deserialized2.getSharedUserId()); + PackageParser.Package deserialized2 = new PackageParser.Package(p); + + assertSame(deserialized.packageName, deserialized2.packageName); + assertSame(deserialized.applicationInfo.permission, + deserialized2.applicationInfo.permission); + assertSame(deserialized.requestedPermissions.get(0), + deserialized2.requestedPermissions.get(0)); + assertSame(deserialized.protectedBroadcasts.get(0), + deserialized2.protectedBroadcasts.get(0)); + assertSame(deserialized.usesLibraries.get(0), + deserialized2.usesLibraries.get(0)); + assertSame(deserialized.usesOptionalLibraries.get(0), + deserialized2.usesOptionalLibraries.get(0)); + assertSame(deserialized.mVersionName, deserialized2.mVersionName); + assertSame(deserialized.mSharedUserId, deserialized2.mSharedUserId); } + /** * A trivial subclass of package parser that only caches the package name, and throws away * all other information. */ public static class CachePackageNameParser extends PackageParser { @Override - public byte[] toCacheEntry(ParsedPackage pkg) { - return ("cache_" + pkg.getPackageName()).getBytes(StandardCharsets.UTF_8); + public byte[] toCacheEntry(Package pkg) { + return ("cache_" + pkg.packageName).getBytes(StandardCharsets.UTF_8); } @Override - public ParsedPackage fromCacheEntry(byte[] cacheEntry) { - return PackageImpl.forParsing(new String(cacheEntry, StandardCharsets.UTF_8)) - .hideAsParsed(); + public Package fromCacheEntry(byte[] cacheEntry) { + return new Package(new String(cacheEntry, StandardCharsets.UTF_8)); } } // NOTE: The equality assertions below are based on code autogenerated by IntelliJ. - public static void assertPackagesEqual(AndroidPackage a, AndroidPackage b) { - assertEquals(a.getBaseRevisionCode(), b.getBaseRevisionCode()); - assertEquals(a.isBaseHardwareAccelerated(), b.isBaseHardwareAccelerated()); - assertEquals(a.getVersionCode(), b.getVersionCode()); - assertEquals(a.getSharedUserLabel(), b.getSharedUserLabel()); - assertEquals(a.getPreferredOrder(), b.getPreferredOrder()); - assertEquals(a.getInstallLocation(), b.getInstallLocation()); - assertEquals(a.isCoreApp(), b.isCoreApp()); - assertEquals(a.isRequiredForAllUsers(), b.isRequiredForAllUsers()); - assertEquals(a.getCompileSdkVersion(), b.getCompileSdkVersion()); - assertEquals(a.getCompileSdkVersionCodeName(), b.getCompileSdkVersionCodeName()); - assertEquals(a.isUse32BitAbi(), b.isUse32BitAbi()); - assertEquals(a.getPackageName(), b.getPackageName()); - assertArrayEquals(a.getSplitNames(), b.getSplitNames()); - assertEquals(a.getVolumeUuid(), b.getVolumeUuid()); - assertEquals(a.getCodePath(), b.getCodePath()); - assertEquals(a.getBaseCodePath(), b.getBaseCodePath()); - assertArrayEquals(a.getSplitCodePaths(), b.getSplitCodePaths()); - assertArrayEquals(a.getSplitRevisionCodes(), b.getSplitRevisionCodes()); - assertArrayEquals(a.getSplitFlags(), b.getSplitFlags()); - - PackageInfo aInfo = PackageInfoUtils.generate(a, new int[]{}, 0, 0, 0, - Collections.emptySet(), new PackageUserState(), 0); - PackageInfo bInfo = PackageInfoUtils.generate(b, new int[]{}, 0, 0, 0, - Collections.emptySet(), new PackageUserState(), 0); - assertApplicationInfoEqual(aInfo.applicationInfo, bInfo.applicationInfo); - - assertEquals(ArrayUtils.size(a.getPermissions()), ArrayUtils.size(b.getPermissions())); - for (int i = 0; i < ArrayUtils.size(a.getPermissions()); ++i) { - assertPermissionsEqual(a.getPermissions().get(i), b.getPermissions().get(i)); + public static void assertPackagesEqual(PackageParser.Package a, PackageParser.Package b) { + assertEquals(a.baseRevisionCode, b.baseRevisionCode); + assertEquals(a.baseHardwareAccelerated, b.baseHardwareAccelerated); + assertEquals(a.mVersionCode, b.mVersionCode); + assertEquals(a.mSharedUserLabel, b.mSharedUserLabel); + assertEquals(a.mPreferredOrder, b.mPreferredOrder); + assertEquals(a.installLocation, b.installLocation); + assertEquals(a.coreApp, b.coreApp); + assertEquals(a.mRequiredForAllUsers, b.mRequiredForAllUsers); + assertEquals(a.mCompileSdkVersion, b.mCompileSdkVersion); + assertEquals(a.mCompileSdkVersionCodename, b.mCompileSdkVersionCodename); + assertEquals(a.use32bitAbi, b.use32bitAbi); + assertEquals(a.packageName, b.packageName); + assertTrue(Arrays.equals(a.splitNames, b.splitNames)); + assertEquals(a.volumeUuid, b.volumeUuid); + assertEquals(a.codePath, b.codePath); + assertEquals(a.baseCodePath, b.baseCodePath); + assertTrue(Arrays.equals(a.splitCodePaths, b.splitCodePaths)); + assertTrue(Arrays.equals(a.splitRevisionCodes, b.splitRevisionCodes)); + assertTrue(Arrays.equals(a.splitFlags, b.splitFlags)); + assertTrue(Arrays.equals(a.splitPrivateFlags, b.splitPrivateFlags)); + assertApplicationInfoEqual(a.applicationInfo, b.applicationInfo); + + assertEquals(a.permissions.size(), b.permissions.size()); + for (int i = 0; i < a.permissions.size(); ++i) { + assertPermissionsEqual(a.permissions.get(i), b.permissions.get(i)); + assertSame(a.permissions.get(i).owner, a); + assertSame(b.permissions.get(i).owner, b); } - assertEquals(ArrayUtils.size(a.getPermissionGroups()), - ArrayUtils.size(b.getPermissionGroups())); - for (int i = 0; i < a.getPermissionGroups().size(); ++i) { - assertPermissionGroupsEqual(a.getPermissionGroups().get(i), - b.getPermissionGroups().get(i)); + assertEquals(a.permissionGroups.size(), b.permissionGroups.size()); + for (int i = 0; i < a.permissionGroups.size(); ++i) { + assertPermissionGroupsEqual(a.permissionGroups.get(i), b.permissionGroups.get(i)); } - assertEquals(ArrayUtils.size(a.getActivities()), ArrayUtils.size(b.getActivities())); - for (int i = 0; i < ArrayUtils.size(a.getActivities()); ++i) { - assertActivitiesEqual(a, a.getActivities().get(i), b, b.getActivities().get(i)); + assertEquals(a.activities.size(), b.activities.size()); + for (int i = 0; i < a.activities.size(); ++i) { + assertActivitiesEqual(a.activities.get(i), b.activities.get(i)); } - assertEquals(ArrayUtils.size(a.getReceivers()), ArrayUtils.size(b.getReceivers())); - for (int i = 0; i < ArrayUtils.size(a.getReceivers()); ++i) { - assertActivitiesEqual(a, a.getReceivers().get(i), b, b.getReceivers().get(i)); + assertEquals(a.receivers.size(), b.receivers.size()); + for (int i = 0; i < a.receivers.size(); ++i) { + assertActivitiesEqual(a.receivers.get(i), b.receivers.get(i)); } - assertEquals(ArrayUtils.size(a.getProviders()), ArrayUtils.size(b.getProviders())); - for (int i = 0; i < ArrayUtils.size(a.getProviders()); ++i) { - assertProvidersEqual(a, a.getProviders().get(i), b, b.getProviders().get(i)); + assertEquals(a.providers.size(), b.providers.size()); + for (int i = 0; i < a.providers.size(); ++i) { + assertProvidersEqual(a.providers.get(i), b.providers.get(i)); } - assertEquals(ArrayUtils.size(a.getServices()), ArrayUtils.size(b.getServices())); - for (int i = 0; i < ArrayUtils.size(a.getServices()); ++i) { - assertServicesEqual(a, a.getServices().get(i), b, b.getServices().get(i)); + assertEquals(a.services.size(), b.services.size()); + for (int i = 0; i < a.services.size(); ++i) { + assertServicesEqual(a.services.get(i), b.services.get(i)); } - assertEquals(ArrayUtils.size(a.getInstrumentations()), - ArrayUtils.size(b.getInstrumentations())); - for (int i = 0; i < ArrayUtils.size(a.getInstrumentations()); ++i) { - assertInstrumentationEqual(a.getInstrumentations().get(i), - b.getInstrumentations().get(i)); + assertEquals(a.instrumentation.size(), b.instrumentation.size()); + for (int i = 0; i < a.instrumentation.size(); ++i) { + assertInstrumentationEqual(a.instrumentation.get(i), b.instrumentation.get(i)); } - assertEquals(a.getRequestedPermissions(), b.getRequestedPermissions()); - assertEquals(a.getProtectedBroadcasts(), b.getProtectedBroadcasts()); - assertEquals(a.getLibraryNames(), b.getLibraryNames()); - assertEquals(a.getUsesLibraries(), b.getUsesLibraries()); - assertEquals(a.getUsesOptionalLibraries(), b.getUsesOptionalLibraries()); - assertArrayEquals(a.getUsesLibraryFiles(), b.getUsesLibraryFiles()); - assertEquals(a.getOriginalPackages(), b.getOriginalPackages()); - assertEquals(a.getRealPackage(), b.getRealPackage()); - assertEquals(a.getAdoptPermissions(), b.getAdoptPermissions()); - assertBundleApproximateEquals(a.getAppMetaData(), b.getAppMetaData()); - assertEquals(a.getVersionName(), b.getVersionName()); - assertEquals(a.getSharedUserId(), b.getSharedUserId()); - assertArrayEquals(a.getSigningDetails().signatures, b.getSigningDetails().signatures); - assertArrayEquals(a.getLastPackageUsageTimeInMills(), b.getLastPackageUsageTimeInMills()); - assertEquals(a.getRestrictedAccountType(), b.getRestrictedAccountType()); - assertEquals(a.getRequiredAccountType(), b.getRequiredAccountType()); - assertEquals(a.getOverlayTarget(), b.getOverlayTarget()); - assertEquals(a.getOverlayTargetName(), b.getOverlayTargetName()); - assertEquals(a.getOverlayCategory(), b.getOverlayCategory()); - assertEquals(a.getOverlayPriority(), b.getOverlayPriority()); - assertEquals(a.isOverlayIsStatic(), b.isOverlayIsStatic()); - assertEquals(a.getSigningDetails().publicKeys, b.getSigningDetails().publicKeys); - assertEquals(a.getUpgradeKeySets(), b.getUpgradeKeySets()); - assertEquals(a.getKeySetMapping(), b.getKeySetMapping()); - assertEquals(a.getCpuAbiOverride(), b.getCpuAbiOverride()); - assertArrayEquals(a.getRestrictUpdateHash(), b.getRestrictUpdateHash()); + assertEquals(a.requestedPermissions, b.requestedPermissions); + assertEquals(a.protectedBroadcasts, b.protectedBroadcasts); + assertEquals(a.parentPackage, b.parentPackage); + assertEquals(a.childPackages, b.childPackages); + assertEquals(a.libraryNames, b.libraryNames); + assertEquals(a.usesLibraries, b.usesLibraries); + assertEquals(a.usesOptionalLibraries, b.usesOptionalLibraries); + assertTrue(Arrays.equals(a.usesLibraryFiles, b.usesLibraryFiles)); + assertEquals(a.mOriginalPackages, b.mOriginalPackages); + assertEquals(a.mRealPackage, b.mRealPackage); + assertEquals(a.mAdoptPermissions, b.mAdoptPermissions); + assertBundleApproximateEquals(a.mAppMetaData, b.mAppMetaData); + assertEquals(a.mVersionName, b.mVersionName); + assertEquals(a.mSharedUserId, b.mSharedUserId); + assertTrue(Arrays.equals(a.mSigningDetails.signatures, b.mSigningDetails.signatures)); + assertTrue(Arrays.equals(a.mLastPackageUsageTimeInMills, b.mLastPackageUsageTimeInMills)); + assertEquals(a.mExtras, b.mExtras); + assertEquals(a.mRestrictedAccountType, b.mRestrictedAccountType); + assertEquals(a.mRequiredAccountType, b.mRequiredAccountType); + assertEquals(a.mOverlayTarget, b.mOverlayTarget); + assertEquals(a.mOverlayTargetName, b.mOverlayTargetName); + assertEquals(a.mOverlayCategory, b.mOverlayCategory); + assertEquals(a.mOverlayPriority, b.mOverlayPriority); + assertEquals(a.mOverlayIsStatic, b.mOverlayIsStatic); + assertEquals(a.mSigningDetails.publicKeys, b.mSigningDetails.publicKeys); + assertEquals(a.mUpgradeKeySets, b.mUpgradeKeySets); + assertEquals(a.mKeySetMapping, b.mKeySetMapping); + assertEquals(a.cpuAbiOverride, b.cpuAbiOverride); + assertTrue(Arrays.equals(a.restrictUpdateHash, b.restrictUpdateHash)); } private static void assertBundleApproximateEquals(Bundle a, Bundle b) { @@ -333,10 +305,10 @@ public class PackageParserTest { assertEquals(a.toString(), b.toString()); } - private static void assertComponentsEqual(ParsedComponent<?> a, - ParsedComponent<?> b) { + private static void assertComponentsEqual(PackageParser.Component<?> a, + PackageParser.Component<?> b) { assertEquals(a.className, b.className); - assertBundleApproximateEquals(a.getMetaData(), b.getMetaData()); + assertBundleApproximateEquals(a.metaData, b.metaData); assertEquals(a.getComponentName(), b.getComponentName()); if (a.intents != null && b.intents != null) { @@ -346,104 +318,80 @@ public class PackageParserTest { } for (int i = 0; i < a.intents.size(); ++i) { - ParsedIntentInfo aIntent = a.intents.get(i); - ParsedIntentInfo bIntent = b.intents.get(i); + PackageParser.IntentInfo aIntent = a.intents.get(i); + PackageParser.IntentInfo bIntent = b.intents.get(i); assertEquals(aIntent.hasDefault, bIntent.hasDefault); assertEquals(aIntent.labelRes, bIntent.labelRes); assertEquals(aIntent.nonLocalizedLabel, bIntent.nonLocalizedLabel); assertEquals(aIntent.icon, bIntent.icon); + assertEquals(aIntent.logo, bIntent.logo); + assertEquals(aIntent.banner, bIntent.banner); + assertEquals(aIntent.preferred, bIntent.preferred); } } - private static void assertPermissionsEqual(ParsedPermission a, - ParsedPermission b) { + private static void assertPermissionsEqual(PackageParser.Permission a, + PackageParser.Permission b) { assertComponentsEqual(a, b); assertEquals(a.tree, b.tree); // Verify basic flags in PermissionInfo to make sure they're consistent. We don't perform // a full structural equality here because the code that serializes them isn't parser // specific and is tested elsewhere. - assertEquals(a.getProtection(), b.getProtection()); - assertEquals(a.getGroup(), b.getGroup()); - assertEquals(a.flags, b.flags); + assertEquals(a.info.protectionLevel, b.info.protectionLevel); + assertEquals(a.info.group, b.info.group); + assertEquals(a.info.flags, b.info.flags); - if (a.parsedPermissionGroup != null && b.parsedPermissionGroup != null) { - assertPermissionGroupsEqual(a.parsedPermissionGroup, b.parsedPermissionGroup); - } else if (a.parsedPermissionGroup != null || b.parsedPermissionGroup != null) { + if (a.group != null && b.group != null) { + assertPermissionGroupsEqual(a.group, b.group); + } else if (a.group != null || b.group != null) { throw new AssertionError(); } } - private static void assertInstrumentationEqual(ParsedInstrumentation a, - ParsedInstrumentation b) { + private static void assertInstrumentationEqual(PackageParser.Instrumentation a, + PackageParser.Instrumentation b) { assertComponentsEqual(a, b); // Sanity check for InstrumentationInfo. - assertEquals(a.getTargetPackage(), b.getTargetPackage()); - assertEquals(a.getTargetProcesses(), b.getTargetProcesses()); - assertEquals(a.sourceDir, b.sourceDir); - assertEquals(a.publicSourceDir, b.publicSourceDir); + assertEquals(a.info.targetPackage, b.info.targetPackage); + assertEquals(a.info.targetProcesses, b.info.targetProcesses); + assertEquals(a.info.sourceDir, b.info.sourceDir); + assertEquals(a.info.publicSourceDir, b.info.publicSourceDir); } - private static void assertServicesEqual( - AndroidPackage aPkg, - ParsedService a, - AndroidPackage bPkg, - ParsedService b - ) { + private static void assertServicesEqual(PackageParser.Service a, PackageParser.Service b) { assertComponentsEqual(a, b); // Sanity check for ServiceInfo. - ServiceInfo aInfo = PackageInfoUtils.generateServiceInfo(aPkg, a, 0, new PackageUserState(), - 0); - ServiceInfo bInfo = PackageInfoUtils.generateServiceInfo(bPkg, b, 0, new PackageUserState(), - 0); - assertApplicationInfoEqual(aInfo.applicationInfo, bInfo.applicationInfo); - assertEquals(a.getName(), b.getName()); + assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo); + assertEquals(a.info.name, b.info.name); } - private static void assertProvidersEqual( - AndroidPackage aPkg, - ParsedProvider a, - AndroidPackage bPkg, - ParsedProvider b - ) { + private static void assertProvidersEqual(PackageParser.Provider a, PackageParser.Provider b) { assertComponentsEqual(a, b); // Sanity check for ProviderInfo - ProviderInfo aInfo = PackageInfoUtils.generateProviderInfo(aPkg, a, 0, - new PackageUserState(), 0); - ProviderInfo bInfo = PackageInfoUtils.generateProviderInfo(bPkg, b, 0, - new PackageUserState(), 0); - assertApplicationInfoEqual(aInfo.applicationInfo, bInfo.applicationInfo); - assertEquals(a.getName(), b.getName()); + assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo); + assertEquals(a.info.name, b.info.name); } - private static void assertActivitiesEqual( - AndroidPackage aPkg, - ParsedActivity a, - AndroidPackage bPkg, - ParsedActivity b - ) { + private static void assertActivitiesEqual(PackageParser.Activity a, PackageParser.Activity b) { assertComponentsEqual(a, b); // Sanity check for ActivityInfo. - ActivityInfo aInfo = PackageInfoUtils.generateActivityInfo(aPkg, a, 0, - new PackageUserState(), 0); - ActivityInfo bInfo = PackageInfoUtils.generateActivityInfo(bPkg, b, 0, - new PackageUserState(), 0); - assertApplicationInfoEqual(aInfo.applicationInfo, bInfo.applicationInfo); - assertEquals(a.getName(), b.getName()); + assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo); + assertEquals(a.info.name, b.info.name); } - private static void assertPermissionGroupsEqual(ParsedPermissionGroup a, - ParsedPermissionGroup b) { + private static void assertPermissionGroupsEqual(PackageParser.PermissionGroup a, + PackageParser.PermissionGroup b) { assertComponentsEqual(a, b); // Sanity check for PermissionGroupInfo. - assertEquals(a.getName(), b.getName()); - assertEquals(a.descriptionRes, b.descriptionRes); + assertEquals(a.info.name, b.info.name); + assertEquals(a.info.descriptionRes, b.info.descriptionRes); } private static void assertApplicationInfoEqual(ApplicationInfo a, ApplicationInfo that) { @@ -476,11 +424,11 @@ public class PackageParserTest { assertEquals(a.scanPublicSourceDir, that.scanPublicSourceDir); assertEquals(a.sourceDir, that.sourceDir); assertEquals(a.publicSourceDir, that.publicSourceDir); - assertArrayEquals(a.splitSourceDirs, that.splitSourceDirs); - assertArrayEquals(a.splitPublicSourceDirs, that.splitPublicSourceDirs); - assertArrayEquals(a.resourceDirs, that.resourceDirs); + assertTrue(Arrays.equals(a.splitSourceDirs, that.splitSourceDirs)); + assertTrue(Arrays.equals(a.splitPublicSourceDirs, that.splitPublicSourceDirs)); + assertTrue(Arrays.equals(a.resourceDirs, that.resourceDirs)); assertEquals(a.seInfo, that.seInfo); - assertArrayEquals(a.sharedLibraryFiles, that.sharedLibraryFiles); + assertTrue(Arrays.equals(a.sharedLibraryFiles, that.sharedLibraryFiles)); assertEquals(a.dataDir, that.dataDir); assertEquals(a.deviceProtectedDataDir, that.deviceProtectedDataDir); assertEquals(a.credentialProtectedDataDir, that.credentialProtectedDataDir); @@ -491,93 +439,132 @@ public class PackageParserTest { assertEquals(a.secondaryCpuAbi, that.secondaryCpuAbi); } - public static void setKnownFields(ParsingPackage pkg) { - Bundle bundle = new Bundle(); - bundle.putString("key", "value"); - - ParsedPermission permission = new ParsedPermission(); - permission.parsedPermissionGroup = new ParsedPermissionGroup(); - - pkg.setBaseRevisionCode(100) - .setBaseHardwareAccelerated(true) - .setSharedUserLabel(100) - .setPreferredOrder(100) - .setInstallLocation(100) - .setRequiredForAllUsers(true) - .asSplit( - new String[]{"foo2"}, - new String[]{"foo6"}, - new int[]{100}, - null - ) - .setUse32BitAbi(true) - .setVolumeUuid("foo3") - .setCodePath("foo4") - .addPermission(permission) - .addPermissionGroup(new ParsedPermissionGroup()) - .addActivity(new ParsedActivity()) - .addReceiver(new ParsedActivity()) - .addProvider(new ParsedProvider()) - .addService(new ParsedService()) - .addInstrumentation(new ParsedInstrumentation()) - .addRequestedPermission("foo7") - .addImplicitPermission("foo25") - .addProtectedBroadcast("foo8") - .setStaticSharedLibName("foo23") - .setStaticSharedLibVersion(100) - .addUsesStaticLibrary("foo23") - .addUsesStaticLibraryCertDigests(new String[]{"digest"}) - .addUsesStaticLibraryVersion(100) - .addLibraryName("foo10") - .addUsesLibrary("foo11") - .addUsesOptionalLibrary("foo12") - .addOriginalPackage("foo14") - .setRealPackage("foo15") - .addAdoptPermission("foo16") - .setAppMetaData(bundle) - .setVersionName("foo17") - .setSharedUserId("foo18") - .setSigningDetails( - new PackageParser.SigningDetails( - new Signature[]{new Signature(new byte[16])}, - 2, - new ArraySet<>(), - null) - ) - .setRestrictedAccountType("foo19") - .setRequiredAccountType("foo20") - .setOverlayTarget("foo21") - .setOverlayPriority(100) - .setUpgradeKeySets(new ArraySet<>()) - .addPreferredActivityFilter( - new ComponentParseUtils.ParsedActivityIntentInfo("foo", "className")) - .addConfigPreference(new ConfigurationInfo()) - .addReqFeature(new FeatureInfo()) - .addFeatureGroup(new FeatureGroupInfo()) - .setCompileSdkVersionCodename("foo23") - .setCompileSdkVersion(100) - .setOverlayCategory("foo24") - .setOverlayIsStatic(true) - .setOverlayTargetName("foo26") - .setVisibleToInstantApps(true) - .setSplitHasCode(0, true) - .hideAsParsed() - .setBaseCodePath("foo5") - .setVersionCode(100) - .setCpuAbiOverride("foo22") - .setRestrictUpdateHash(new byte[16]) - .setVersionCodeMajor(100) - .setCoreApp(true) - .hideAsFinal() - .mutate() - .setUsesLibraryInfos(Arrays.asList( - new SharedLibraryInfo(null, null, null, null, 0L, 0, null, null, null) - )) - .setUsesLibraryFiles(new String[]{"foo13"}); + public static void setKnownFields(PackageParser.Package pkg) { + pkg.baseRevisionCode = 100; + pkg.baseHardwareAccelerated = true; + pkg.mVersionCode = 100; + pkg.mSharedUserLabel = 100; + pkg.mPreferredOrder = 100; + pkg.installLocation = 100; + pkg.coreApp = true; + pkg.mRequiredForAllUsers = true; + pkg.use32bitAbi = true; + pkg.packageName = "foo"; + pkg.splitNames = new String[] { "foo2" }; + pkg.volumeUuid = "foo3"; + pkg.codePath = "foo4"; + pkg.baseCodePath = "foo5"; + pkg.splitCodePaths = new String[] { "foo6" }; + pkg.splitRevisionCodes = new int[] { 100 }; + pkg.splitFlags = new int[] { 100 }; + pkg.splitPrivateFlags = new int[] { 100 }; + pkg.applicationInfo = new ApplicationInfo(); + + pkg.permissions.add(new PackageParser.Permission(pkg, (String) null)); + pkg.permissionGroups.add(new PackageParser.PermissionGroup(pkg, ID_NULL, ID_NULL, ID_NULL)); + + final PackageParser.ParseComponentArgs dummy = new PackageParser.ParseComponentArgs( + pkg, new String[1], 0, 0, 0, 0, 0, 0, null, 0, 0, 0); + + pkg.activities.add(new PackageParser.Activity(dummy, new ActivityInfo())); + pkg.receivers.add(new PackageParser.Activity(dummy, new ActivityInfo())); + pkg.providers.add(new PackageParser.Provider(dummy, new ProviderInfo())); + pkg.services.add(new PackageParser.Service(dummy, new ServiceInfo())); + pkg.instrumentation.add(new PackageParser.Instrumentation(dummy, new InstrumentationInfo())); + pkg.requestedPermissions.add("foo7"); + pkg.implicitPermissions.add("foo25"); + + pkg.protectedBroadcasts = new ArrayList<>(); + pkg.protectedBroadcasts.add("foo8"); + + pkg.parentPackage = new PackageParser.Package("foo9"); + + pkg.childPackages = new ArrayList<>(); + pkg.childPackages.add(new PackageParser.Package("bar")); + + pkg.staticSharedLibName = "foo23"; + pkg.staticSharedLibVersion = 100; + pkg.usesStaticLibraries = new ArrayList<>(); + pkg.usesStaticLibraries.add("foo23"); + pkg.usesStaticLibrariesCertDigests = new String[1][]; + pkg.usesStaticLibrariesCertDigests[0] = new String[] { "digest" }; + pkg.usesStaticLibrariesVersions = new long[] { 100 }; + + pkg.libraryNames = new ArrayList<>(); + pkg.libraryNames.add("foo10"); + + pkg.usesLibraries = new ArrayList<>(); + pkg.usesLibraries.add("foo11"); + + pkg.usesOptionalLibraries = new ArrayList<>(); + pkg.usesOptionalLibraries.add("foo12"); + + pkg.usesLibraryFiles = new String[] { "foo13"}; + + pkg.usesLibraryInfos = new ArrayList<>(); + pkg.usesLibraryInfos.add( + new SharedLibraryInfo(null, null, null, null, 0L, 0, null, null, null)); + + pkg.mOriginalPackages = new ArrayList<>(); + pkg.mOriginalPackages.add("foo14"); + + pkg.mRealPackage = "foo15"; + + pkg.mAdoptPermissions = new ArrayList<>(); + pkg.mAdoptPermissions.add("foo16"); + + pkg.mAppMetaData = new Bundle(); + pkg.mVersionName = "foo17"; + pkg.mSharedUserId = "foo18"; + pkg.mSigningDetails = + new PackageParser.SigningDetails( + new Signature[] { new Signature(new byte[16]) }, + 2, + new ArraySet<>(), + null); + pkg.mExtras = new Bundle(); + pkg.mRestrictedAccountType = "foo19"; + pkg.mRequiredAccountType = "foo20"; + pkg.mOverlayTarget = "foo21"; + pkg.mOverlayPriority = 100; + pkg.mUpgradeKeySets = new ArraySet<>(); + pkg.mKeySetMapping = new ArrayMap<>(); + pkg.cpuAbiOverride = "foo22"; + pkg.restrictUpdateHash = new byte[16]; + + pkg.preferredActivityFilters = new ArrayList<>(); + pkg.preferredActivityFilters.add(new PackageParser.ActivityIntentInfo( + new PackageParser.Activity(dummy, new ActivityInfo()))); + + pkg.configPreferences = new ArrayList<>(); + pkg.configPreferences.add(new ConfigurationInfo()); + + pkg.reqFeatures = new ArrayList<>(); + pkg.reqFeatures.add(new FeatureInfo()); + + pkg.featureGroups = new ArrayList<>(); + pkg.featureGroups.add(new FeatureGroupInfo()); + + pkg.mCompileSdkVersionCodename = "foo23"; + pkg.mCompileSdkVersion = 100; + pkg.mVersionCodeMajor = 100; + + pkg.mOverlayCategory = "foo24"; + pkg.mOverlayIsStatic = true; + pkg.mOverlayTargetName = "foo26"; + + pkg.baseHardwareAccelerated = true; + pkg.coreApp = true; + pkg.mRequiredForAllUsers = true; + pkg.visibleToInstantApps = true; + pkg.use32bitAbi = true; + pkg.mForceQueryable = true; + pkg.mQueriesPackages = new ArrayList<>(Arrays.asList("foo27")); + pkg.mQueriesIntents = new ArrayList<>(Arrays.asList(new Intent("foo28"))); } - private static void assertAllFieldsExist(ParsedPackage pkg) throws Exception { - Field[] fields = ParsedPackage.class.getDeclaredFields(); + private static void assertAllFieldsExist(PackageParser.Package pkg) throws Exception { + Field[] fields = PackageParser.Package.class.getDeclaredFields(); Set<String> nonSerializedFields = new HashSet<>(); nonSerializedFields.add("mExtras"); @@ -614,7 +601,7 @@ public class PackageParserTest { } else if (fieldType == boolean.class) { // boolean fields: Check that they're set to true. boolean value = (boolean) f.get(pkg); - assertTrue("Bad value for field: " + f, value); + assertEquals("Bad value for field: " + f, true, value); } else { // All other fields: Check that they're set. Object o = f.get(pkg); diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java index ca9e5b1efb58..06c6314ab907 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java @@ -16,11 +16,12 @@ package com.android.server.pm; +import android.content.pm.PackageParser; import android.content.pm.PackageUserState; -import android.content.pm.parsing.AndroidPackage; import android.util.SparseArray; import java.io.File; +import java.util.List; class PackageSettingBuilder { private String mName; @@ -34,14 +35,16 @@ class PackageSettingBuilder { private long mPVersionCode; private int mPkgFlags; private int mPrivateFlags; + private String mParentPackageName; + private List<String> mChildPackageNames; private int mSharedUserId; private String[] mUsesStaticLibraries; private long[] mUsesStaticLibrariesVersions; private String mVolumeUuid; private SparseArray<PackageUserState> mUserStates = new SparseArray<>(); - private AndroidPackage mPkg; + private PackageParser.Package mPkg; - public PackageSettingBuilder setPackage(AndroidPackage pkg) { + public PackageSettingBuilder setPackage(PackageParser.Package pkg) { this.mPkg = pkg; return this; } @@ -102,6 +105,16 @@ class PackageSettingBuilder { return this; } + public PackageSettingBuilder setParentPackageName(String parentPackageName) { + this.mParentPackageName = parentPackageName; + return this; + } + + public PackageSettingBuilder setChildPackageNames(List<String> childPackageNames) { + this.mChildPackageNames = childPackageNames; + return this; + } + public PackageSettingBuilder setSharedUserId(int sharedUserId) { this.mSharedUserId = sharedUserId; return this; @@ -135,8 +148,9 @@ class PackageSettingBuilder { final PackageSetting packageSetting = new PackageSetting(mName, mRealName, new File(mCodePath), new File(mResourcePath), mLegacyNativeLibraryPathString, mPrimaryCpuAbiString, mSecondaryCpuAbiString, - mCpuAbiOverrideString, mPVersionCode, mPkgFlags, mPrivateFlags, mSharedUserId, - mUsesStaticLibraries, mUsesStaticLibrariesVersions); + mCpuAbiOverrideString, mPVersionCode, mPkgFlags, mPrivateFlags, mParentPackageName, + mChildPackageNames, mSharedUserId, mUsesStaticLibraries, + mUsesStaticLibrariesVersions); packageSetting.pkg = mPkg; packageSetting.volumeUuid = this.mVolumeUuid; for (int i = 0; i < mUserStates.size(); i++) { diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java index 04e769d7dcfb..d3a77d3e80f1 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java @@ -16,8 +16,8 @@ package com.android.server.pm; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -467,7 +467,8 @@ public class PackageSignaturesTest { File appPath = new File("/data/app/app"); PackageSetting result = new PackageSetting("test.app", null, appPath, appPath, "/data/app/app", null, null, null, - 1, 940097092, 0, 0 /*userId*/, null, null); + 1, 940097092, 0, null, + null, 0 /*userId*/, null, null); return result; } } diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java index 8eaf35f6432f..fc5a0ba1af7b 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java @@ -26,6 +26,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageUserState; import android.content.pm.SuspendDialogInfo; import android.os.PersistableBundle; +import android.util.ArrayMap; import android.util.ArraySet; import androidx.test.filters.SmallTest; @@ -175,18 +176,43 @@ public class PackageUserStateTest { assertThat(testUserState03.equals(oldUserState), is(false)); } + private static PackageUserState.SuspendParams createSuspendParams(SuspendDialogInfo dialogInfo, + PersistableBundle appExtras, PersistableBundle launcherExtras) { + PackageUserState.SuspendParams obj = PackageUserState.SuspendParams.getInstanceOrNull( + dialogInfo, appExtras, launcherExtras); + return obj; + } + + private static PersistableBundle createPersistableBundle(String lKey, long lValue, String sKey, + String sValue, String dKey, double dValue) { + final PersistableBundle result = new PersistableBundle(3); + if (lKey != null) { + result.putLong("com.unit_test." + lKey, lValue); + } + if (sKey != null) { + result.putString("com.unit_test." + sKey, sValue); + } + if (dKey != null) { + result.putDouble("com.unit_test." + dKey, dValue); + } + return result; + } + @Test public void testPackageUserState05() { - PersistableBundle appExtras1 = new PersistableBundle(); - PersistableBundle appExtras2 = new PersistableBundle(); - appExtras1.putInt("appExtraId", 1); - appExtras2.putInt("appExtraId", 2); - PersistableBundle launcherExtras1 = new PersistableBundle(); - PersistableBundle launcherExtras2 = new PersistableBundle(); - launcherExtras1.putString("name", "launcherExtras1"); - launcherExtras2.putString("name", "launcherExtras2"); + final PersistableBundle appExtras1 = createPersistableBundle("appExtraId", 1, null, null, + null, 0); + final PersistableBundle appExtras2 = createPersistableBundle("appExtraId", 2, null, null, + null, 0); + + final PersistableBundle launcherExtras1 = createPersistableBundle(null, 0, "name", + "launcherExtras1", null, 0); + final PersistableBundle launcherExtras2 = createPersistableBundle(null, 0, "name", + "launcherExtras2", null, 0); + final String suspendingPackage1 = "package1"; final String suspendingPackage2 = "package2"; + final SuspendDialogInfo dialogInfo1 = new SuspendDialogInfo.Builder() .setMessage("dialogMessage1") .build(); @@ -194,38 +220,23 @@ public class PackageUserStateTest { .setMessage("dialogMessage2") .build(); + final ArrayMap<String, PackageUserState.SuspendParams> paramsMap1 = new ArrayMap<>(); + paramsMap1.put(suspendingPackage1, createSuspendParams(dialogInfo1, appExtras1, + launcherExtras1)); + final ArrayMap<String, PackageUserState.SuspendParams> paramsMap2 = new ArrayMap<>(); + paramsMap2.put(suspendingPackage2, createSuspendParams(dialogInfo2, + appExtras2, launcherExtras2)); + + final PackageUserState testUserState1 = new PackageUserState(); testUserState1.suspended = true; - testUserState1.suspendedAppExtras = appExtras1; - testUserState1.suspendedLauncherExtras = launcherExtras1; - testUserState1.suspendingPackage = suspendingPackage1; - testUserState1.dialogInfo = dialogInfo1; + testUserState1.suspendParams = paramsMap1; PackageUserState testUserState2 = new PackageUserState(testUserState1); assertThat(testUserState1.equals(testUserState2), is(true)); - testUserState2.suspendingPackage = suspendingPackage2; - assertThat(testUserState1.equals(testUserState2), is(false)); - - testUserState2 = new PackageUserState(testUserState1); - testUserState2.suspendedAppExtras = appExtras2; - assertThat(testUserState1.equals(testUserState2), is(false)); - - testUserState2 = new PackageUserState(testUserState1); - testUserState2.suspendedLauncherExtras = launcherExtras2; - assertThat(testUserState1.equals(testUserState2), is(false)); - - testUserState2 = new PackageUserState(testUserState1); - testUserState2.dialogInfo = dialogInfo2; + testUserState2.suspendParams = paramsMap2; + // Should not be equal since suspendParams maps are different assertThat(testUserState1.equals(testUserState2), is(false)); - - testUserState2 = new PackageUserState(testUserState1); - testUserState2.suspended = testUserState1.suspended = false; - // Everything is different but irrelevant if suspended is false - testUserState2.suspendingPackage = suspendingPackage2; - testUserState2.dialogInfo = dialogInfo2; - testUserState2.suspendedAppExtras = appExtras2; - testUserState2.suspendedLauncherExtras = launcherExtras2; - assertThat(testUserState1.equals(testUserState2), is(true)); } @Test @@ -243,4 +254,46 @@ public class PackageUserStateTest { assertThat(userState1.equals(userState2), is(false)); } + @Test + public void testPackageUserState07() { + final PersistableBundle appExtras1 = createPersistableBundle("appExtraId", 1, null, null, + null, 0); + final PersistableBundle appExtras2 = createPersistableBundle("appExtraId", 2, null, null, + null, 0); + + final PersistableBundle launcherExtras1 = createPersistableBundle(null, 0, "name", + "launcherExtras1", null, 0); + final PersistableBundle launcherExtras2 = createPersistableBundle(null, 0, "name", + "launcherExtras2", null, 0); + + final SuspendDialogInfo dialogInfo1 = new SuspendDialogInfo.Builder() + .setMessage("dialogMessage1") + .build(); + final SuspendDialogInfo dialogInfo2 = new SuspendDialogInfo.Builder() + .setMessage("dialogMessage2") + .build(); + + final PackageUserState.SuspendParams params1; + PackageUserState.SuspendParams params2; + params1 = createSuspendParams(dialogInfo1, appExtras1, launcherExtras1); + params2 = createSuspendParams(dialogInfo1, appExtras1, launcherExtras1); + // Everything is same + assertThat(params1.equals(params2), is(true)); + + params2 = createSuspendParams(dialogInfo2, appExtras1, launcherExtras1); + // DialogInfo is different + assertThat(params1.equals(params2), is(false)); + + params2 = createSuspendParams(dialogInfo1, appExtras2, launcherExtras1); + // app extras are different + assertThat(params1.equals(params2), is(false)); + + params2 = createSuspendParams(dialogInfo1, appExtras1, launcherExtras2); + // Launcher extras are different + assertThat(params1.equals(params2), is(false)); + + params2 = createSuspendParams(dialogInfo2, appExtras2, launcherExtras2); + // Everything is different + assertThat(params1.equals(params2), is(false)); + } } diff --git a/services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java index a0efc8a03719..41489dc42a6a 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java @@ -17,7 +17,6 @@ package com.android.server.pm; import android.content.pm.PackageParser; -import android.content.pm.parsing.ParsedPackage; import android.util.Log; import androidx.test.runner.AndroidJUnit4; @@ -75,7 +74,7 @@ public class ParallelPackageParserTest { } @Override - protected ParsedPackage parsePackage(PackageParser packageParser, File scanFile, + protected PackageParser.Package parsePackage(PackageParser packageParser, File scanFile, int parseFlags) throws PackageParser.PackageParserException { // Do not actually parse the package for testing return null; diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java b/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java index 11f154be688b..34a3f860496a 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java +++ b/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java @@ -16,13 +16,12 @@ package com.android.server.pm; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ParsedPackage; +import android.content.pm.PackageParser; import android.os.UserHandle; class ScanRequestBuilder { - private final ParsedPackage mPkg; - private AndroidPackage mOldPkg; + private final PackageParser.Package mPkg; + private PackageParser.Package mOldPkg; private SharedUserSetting mSharedUserSetting; private PackageSetting mPkgSetting; private PackageSetting mDisabledPkgSetting; @@ -33,11 +32,11 @@ class ScanRequestBuilder { private UserHandle mUser; private boolean mIsPlatformPackage; - ScanRequestBuilder(ParsedPackage pkg) { + ScanRequestBuilder(PackageParser.Package pkg) { this.mPkg = pkg; } - public ScanRequestBuilder setOldPkg(AndroidPackage oldPkg) { + public ScanRequestBuilder setOldPkg(PackageParser.Package oldPkg) { this.mOldPkg = oldPkg; return this; } diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java index 1f027a31fbe3..05905d94dda7 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java @@ -35,17 +35,13 @@ import static org.junit.Assert.assertNotSame; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.Manifest; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; +import android.content.pm.PackageParser; import android.content.pm.SharedLibraryInfo; -import android.content.pm.parsing.PackageImpl; -import android.content.pm.parsing.ParsedPackage; -import android.content.pm.parsing.ParsingPackage; -import android.content.res.TypedArray; import android.os.Environment; import android.os.UserHandle; import android.os.UserManagerInternal; @@ -62,7 +58,6 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import java.io.File; -import java.util.UUID; @RunWith(MockitoJUnitRunner.class) @Presubmit @@ -71,9 +66,6 @@ public class ScanTests { private static final String DUMMY_PACKAGE_NAME = "some.app.to.test"; - private static final UUID UUID_ONE = UUID.randomUUID(); - private static final UUID UUID_TWO = UUID.randomUUID(); - @Mock PackageAbiHelper mMockPackageAbiHelper; @Mock @@ -95,25 +87,25 @@ public class ScanTests { @Before public void setupDefaultAbiBehavior() throws Exception { when(mMockPackageAbiHelper.derivePackageAbi( - any(ParsedPackage.class), nullable(String.class), anyBoolean())) + any(PackageParser.Package.class), nullable(String.class), anyBoolean())) .thenReturn(new Pair<>( new PackageAbiHelper.Abis("derivedPrimary", "derivedSecondary"), new PackageAbiHelper.NativeLibraryPaths( "derivedRootDir", true, "derivedNativeDir", "derivedNativeDir2"))); when(mMockPackageAbiHelper.getNativeLibraryPaths( - any(ParsedPackage.class), any(File.class))) + any(PackageParser.Package.class), any(File.class))) .thenReturn(new PackageAbiHelper.NativeLibraryPaths( "getRootDir", true, "getNativeDir", "getNativeDir2" )); when(mMockPackageAbiHelper.getBundledAppAbis( - any(ParsedPackage.class))) + any(PackageParser.Package.class))) .thenReturn(new PackageAbiHelper.Abis("bundledPrimary", "bundledSecondary")); } @Test public void newInstallSimpleAllNominal() throws Exception { final PackageManagerService.ScanRequest scanRequest = - createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME)) + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) .addScanFlag(PackageManagerService.SCAN_NEW_INSTALL) .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP) .build(); @@ -131,7 +123,7 @@ public class ScanTests { when(mMockUserManager.getUserIds()).thenReturn(userIds); final PackageManagerService.ScanRequest scanRequest = - createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME)) + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) .setRealPkgName(null) .addScanFlag(PackageManagerService.SCAN_NEW_INSTALL) .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP) @@ -146,7 +138,7 @@ public class ScanTests { @Test public void installRealPackageName() throws Exception { final PackageManagerService.ScanRequest scanRequest = - createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME)) + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) .setRealPkgName("com.package.real") .build(); @@ -157,7 +149,7 @@ public class ScanTests { final PackageManagerService.ScanRequest scanRequestNoRealPkg = createBasicScanRequestBuilder( createBasicPackage(DUMMY_PACKAGE_NAME) - .setRealPackage("com.package.real")) + .setRealPackageName("com.package.real").build()) .build(); final PackageManagerService.ScanResult scanResultNoReal = executeScan(scanRequestNoRealPkg); @@ -173,7 +165,7 @@ public class ScanTests { .setSecondaryCpuAbiString("secondaryCpuAbi") .build(); final PackageManagerService.ScanRequest scanRequest = - createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME)) + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP) .setPkgSetting(pkgSetting) .build(); @@ -205,7 +197,7 @@ public class ScanTests { .build(); final PackageManagerService.ScanRequest scanRequest = - createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME)) + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) .setPkgSetting(existingPkgSetting) .build(); @@ -217,18 +209,17 @@ public class ScanTests { @Test public void installStaticSharedLibrary() throws Exception { - final ParsedPackage pkg = createBasicPackage("static.lib.pkg") - .setStaticSharedLibName("static.lib") - .setStaticSharedLibVersion(123L) - .hideAsParsed() - .setPackageName("static.lib.pkg.123") + final PackageParser.Package pkg = createBasicPackage("static.lib.pkg.123") + .setStaticSharedLib("static.lib", 123L) + .setManifestPackageName("static.lib.pkg") .setVersionCodeMajor(1) .setVersionCode(234) .setBaseCodePath("/some/path.apk") - .setSplitCodePaths(new String[] {"/some/other/path.apk"}); + .addSplitCodePath("/some/other/path.apk") + .build(); - final PackageManagerService.ScanRequest scanRequest = new ScanRequestBuilder(pkg) - .setUser(UserHandle.of(0)).build(); + final PackageManagerService.ScanRequest scanRequest = new ScanRequestBuilder( + pkg).setUser(UserHandle.of(0)).build(); final PackageManagerService.ScanResult scanResult = executeScan(scanRequest); @@ -249,14 +240,15 @@ public class ScanTests { @Test public void installDynamicLibraries() throws Exception { - final ParsedPackage pkg = createBasicPackage("dynamic.lib.pkg") + final PackageParser.Package pkg = createBasicPackage("dynamic.lib.pkg") + .setManifestPackageName("dynamic.lib.pkg") .addLibraryName("liba") .addLibraryName("libb") - .hideAsParsed() .setVersionCodeMajor(1) .setVersionCode(234) .setBaseCodePath("/some/path.apk") - .setSplitCodePaths(new String[] {"/some/other/path.apk"}); + .addSplitCodePath("/some/other/path.apk") + .build(); final PackageManagerService.ScanRequest scanRequest = new ScanRequestBuilder(pkg).setUser(UserHandle.of(0)).build(); @@ -298,15 +290,15 @@ public class ScanTests { .setVolumeUuid("someUuid") .build(); - final ParsedPackage basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME) - .hideAsParsed() - .setApplicationVolumeUuid(UUID_TWO.toString()); + final PackageParser.Package basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME) + .setApplicationInfoVolumeUuid("someNewUuid") + .build(); final PackageManagerService.ScanResult scanResult = executeScan( new ScanRequestBuilder(basicPackage).setPkgSetting(pkgSetting).build()); - assertThat(scanResult.pkgSetting.volumeUuid, is(UUID_TWO.toString())); + assertThat(scanResult.pkgSetting.volumeUuid, is("someNewUuid")); } @Test @@ -314,10 +306,10 @@ public class ScanTests { final PackageSetting pkgSetting = createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME).build(); - final ParsedPackage basicPackage = + final PackageParser.Package basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME) - .hideAsParsed() - .setCpuAbiOverride("testOverride"); + .setCpuAbiOVerride("testOverride") + .build(); final PackageManagerService.ScanResult scanResult = executeScan(new ScanRequestBuilder( @@ -334,9 +326,9 @@ public class ScanTests { final PackageSetting originalPkgSetting = createBasicPackageSettingBuilder("original.package").build(); - final ParsedPackage basicPackage = + final PackageParser.Package basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME) - .hideAsParsed(); + .build(); final PackageManagerService.ScanResult result = @@ -344,7 +336,7 @@ public class ScanTests { .setOriginalPkgSetting(originalPkgSetting) .build()); - assertThat(result.request.parsedPackage.getPackageName(), is("original.package")); + assertThat(result.request.pkg.packageName, is("original.package")); } @Test @@ -357,7 +349,7 @@ public class ScanTests { .build(); final PackageManagerService.ScanRequest scanRequest = - createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME)) + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) .setPkgSetting(existingPkgSetting) .addScanFlag(SCAN_AS_FULL_APP) .build(); @@ -378,7 +370,7 @@ public class ScanTests { .build(); final PackageManagerService.ScanRequest scanRequest = - createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME)) + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) .setPkgSetting(existingPkgSetting) .addScanFlag(SCAN_AS_INSTANT_APP) .build(); @@ -397,7 +389,7 @@ public class ScanTests { .build(); final PackageManagerService.ScanRequest scanRequest = - createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME)) + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) .setPkgSetting(existingPkgSetting) .setDisabledPkgSetting(existingPkgSetting) .addScanFlag(SCAN_NEW_INSTALL) @@ -405,14 +397,15 @@ public class ScanTests { final PackageManagerService.ScanResult scanResult = executeScan(scanRequest); - assertThat(scanResult.request.parsedPackage.getFlags(), + assertThat(scanResult.request.pkg.applicationInfo.flags, hasFlag(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)); } @Test public void factoryTestFlagSet() throws Exception { - final ParsingPackage basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME) - .addRequestedPermission(Manifest.permission.FACTORY_TEST); + final PackageParser.Package basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME) + .addPermissionRequest(Manifest.permission.FACTORY_TEST) + .build(); final PackageManagerService.ScanResult scanResult = PackageManagerService.scanPackageOnlyLI( createBasicScanRequestBuilder(basicPackage).build(), @@ -420,15 +413,15 @@ public class ScanTests { true /*isUnderFactoryTest*/, System.currentTimeMillis()); - assertThat(scanResult.request.parsedPackage.getFlags(), + assertThat(scanResult.request.pkg.applicationInfo.flags, hasFlag(ApplicationInfo.FLAG_FACTORY_TEST)); } @Test public void scanSystemApp_isOrphanedTrue() throws Exception { - final ParsedPackage pkg = createBasicPackage(DUMMY_PACKAGE_NAME) - .hideAsParsed() - .setSystem(true); + final PackageParser.Package pkg = createBasicPackage(DUMMY_PACKAGE_NAME) + .addApplicationInfoFlag(ApplicationInfo.FLAG_SYSTEM) + .build(); final PackageManagerService.ScanRequest scanRequest = createBasicScanRequestBuilder(pkg) @@ -483,29 +476,22 @@ public class ScanTests { .setResourcePath(createResourcePath(packageName)); } - private static ScanRequestBuilder createBasicScanRequestBuilder(ParsingPackage pkg) { - return new ScanRequestBuilder(pkg.hideAsParsed()) - .setUser(UserHandle.of(0)); - } - - private static ScanRequestBuilder createBasicScanRequestBuilder(ParsedPackage pkg) { + private static ScanRequestBuilder createBasicScanRequestBuilder(PackageParser.Package pkg) { return new ScanRequestBuilder(pkg) .setUser(UserHandle.of(0)); } - private static ParsingPackage createBasicPackage(String packageName) { - // TODO(b/135203078): Make this use PackageImpl.forParsing and separate the steps - return new PackageImpl(packageName, null, mock(TypedArray.class), false) + + private static PackageBuilder createBasicPackage(String packageName) { + return new PackageBuilder(packageName) .setCodePath("/data/tmp/randompath") .setApplicationInfoCodePath(createCodePath(packageName)) .setApplicationInfoResourcePath(createResourcePath(packageName)) - .setApplicationVolumeUuid(UUID_ONE.toString()) + .setApplicationInfoVolumeUuid("volumeUuid") .setBaseCodePath("/data/tmp/randompath/base.apk") - .addUsesStaticLibrary("some.static.library") - .addUsesStaticLibraryVersion(234L) - .addUsesStaticLibrary("some.other.static.library") - .addUsesStaticLibraryVersion(456L) - .setNativeLibraryRootDir("/data/tmp/randompath/base.apk:/lib") + .addUsesStaticLibrary("some.static.library", 234L) + .addUsesStaticLibrary("some.other.static.library", 456L) + .setApplicationInfoNativeLibraryRootDir("/data/tmp/randompath/base.apk:/lib") .setVersionCodeMajor(1) .setVersionCode(2345); } @@ -517,18 +503,20 @@ public class ScanTests { final PackageSetting pkgSetting = scanResult.pkgSetting; assertBasicPackageSetting(scanResult, packageName, isInstant, pkgSetting); - final ApplicationInfo applicationInfo = pkgSetting.pkg.toAppInfo(); + final ApplicationInfo applicationInfo = pkgSetting.pkg.applicationInfo; assertBasicApplicationInfo(scanResult, applicationInfo); + } private static void assertBasicPackageSetting(PackageManagerService.ScanResult scanResult, String packageName, boolean isInstant, PackageSetting pkgSetting) { - assertThat(pkgSetting.pkg.getPackageName(), is(packageName)); + assertThat(pkgSetting.pkg.packageName, is(packageName)); assertThat(pkgSetting.getInstantApp(0), is(isInstant)); assertThat(pkgSetting.usesStaticLibraries, arrayContaining("some.static.library", "some.other.static.library")); assertThat(pkgSetting.usesStaticLibrariesVersions, is(new long[]{234L, 456L})); - assertThat(pkgSetting.pkg, is(scanResult.request.parsedPackage)); + assertThat(pkgSetting.pkg, is(scanResult.request.pkg)); + assertThat(pkgSetting.pkg.mExtras, is(pkgSetting)); assertThat(pkgSetting.codePath, is(new File(createCodePath(packageName)))); assertThat(pkgSetting.resourcePath, is(new File(createResourcePath(packageName)))); assertThat(pkgSetting.versionCode, is(PackageInfo.composeLongVersionCode(1, 2345))); @@ -536,21 +524,20 @@ public class ScanTests { private static void assertBasicApplicationInfo(PackageManagerService.ScanResult scanResult, ApplicationInfo applicationInfo) { - assertThat(applicationInfo.processName, - is(scanResult.request.parsedPackage.getPackageName())); + assertThat(applicationInfo.processName, is(scanResult.request.pkg.packageName)); final int uid = applicationInfo.uid; assertThat(UserHandle.getUserId(uid), is(UserHandle.USER_SYSTEM)); final String calculatedCredentialId = Environment.getDataUserCePackageDirectory( applicationInfo.volumeUuid, UserHandle.USER_SYSTEM, - scanResult.request.parsedPackage.getPackageName()).getAbsolutePath(); + scanResult.request.pkg.packageName).getAbsolutePath(); assertThat(applicationInfo.credentialProtectedDataDir, is(calculatedCredentialId)); assertThat(applicationInfo.dataDir, is(applicationInfo.credentialProtectedDataDir)); } private static void assertAbiAndPathssDerived(PackageManagerService.ScanResult scanResult) { - final ApplicationInfo applicationInfo = scanResult.pkgSetting.pkg.toAppInfo(); + final ApplicationInfo applicationInfo = scanResult.pkgSetting.pkg.applicationInfo; assertThat(applicationInfo.primaryCpuAbi, is("derivedPrimary")); assertThat(applicationInfo.secondaryCpuAbi, is("derivedSecondary")); @@ -562,7 +549,7 @@ public class ScanTests { } private static void assertPathsNotDerived(PackageManagerService.ScanResult scanResult) { - final ApplicationInfo applicationInfo = scanResult.pkgSetting.pkg.toAppInfo(); + final ApplicationInfo applicationInfo = scanResult.pkgSetting.pkg.applicationInfo; assertThat(applicationInfo.nativeLibraryRootDir, is("getRootDir")); assertThat(scanResult.pkgSetting.legacyNativeLibraryPathString, is("getRootDir")); assertThat(applicationInfo.nativeLibraryRootRequiresIsa, is(true)); diff --git a/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java index ddda10ec19d5..f0b0328ff7d4 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java @@ -37,9 +37,8 @@ import static org.junit.Assert.fail; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageParser; import android.content.pm.UserInfo; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.PackageImpl; import android.os.Looper; import android.os.SystemProperties; import android.os.UserManager; @@ -221,10 +220,10 @@ public class UserSystemPackageInstallerTest { final UserSystemPackageInstaller uspi = new UserSystemPackageInstaller(null, pkgFlgMap); - final AndroidPackage pkg1 = PackageImpl.forParsing(packageName1).hideAsParsed().hideAsFinal(); - final AndroidPackage pkg2 = PackageImpl.forParsing(packageName2).hideAsParsed().hideAsFinal(); - final AndroidPackage pkg3 = PackageImpl.forParsing(packageName3).hideAsParsed().hideAsFinal(); - final AndroidPackage pkg4 = PackageImpl.forParsing(packageName4).hideAsParsed().hideAsFinal(); + final PackageParser.Package pkg1 = new PackageParser.Package(packageName1); + final PackageParser.Package pkg2 = new PackageParser.Package(packageName2); + final PackageParser.Package pkg3 = new PackageParser.Package(packageName3); + final PackageParser.Package pkg4 = new PackageParser.Package(packageName4); // No implicit whitelist, so only install pkg1. boolean implicit = false; diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java index 66a4946ecc20..3a55c2290157 100644 --- a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java @@ -22,11 +22,8 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.content.pm.ApplicationInfo; import android.content.pm.SharedLibraryInfo; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.PackageImpl; -import android.content.pm.parsing.ParsedPackage; -import android.content.pm.parsing.ParsingPackage; import android.util.SparseArray; import androidx.test.filters.SmallTest; @@ -54,18 +51,17 @@ public class DexoptUtilsTest { DelegateLastClassLoader.class.getName(); private static class TestData { - AndroidPackage pkg; + ApplicationInfo info; boolean[] pathsWithCode; } private TestData createMockApplicationInfo(String baseClassLoader, boolean addSplits, - boolean addSplitDependencies, boolean isolatedSplitLoading) { + boolean addSplitDependencies) { + ApplicationInfo ai = new ApplicationInfo(); String codeDir = "/data/app/mock.android.com"; - ParsingPackage parsingPackage = PackageImpl.forParsing("mock.android.com") - .setClassLoaderName(baseClassLoader); - - parsingPackage.setIsolatedSplitLoading(isolatedSplitLoading); - + ai.setBaseCodePath(codeDir + "/base.dex"); + ai.classLoaderName = baseClassLoader; + ai.privateFlags = ai.privateFlags | ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING; boolean[] pathsWithCode; if (!addSplits) { pathsWithCode = new boolean[] {true}; @@ -74,7 +70,7 @@ public class DexoptUtilsTest { Arrays.fill(pathsWithCode, true); pathsWithCode[7] = false; // config split - String[] splitCodePaths = new String[]{ + ai.setSplitCodePaths(new String[]{ codeDir + "/base-1.dex", codeDir + "/base-2.dex", codeDir + "/base-3.dex", @@ -82,51 +78,32 @@ public class DexoptUtilsTest { codeDir + "/base-5.dex", codeDir + "/base-6.dex", codeDir + "/config-split-7.dex", - codeDir + "/feature-no-deps.dex" - }; - - String[] splitNames = new String[splitCodePaths.length]; - int[] splitRevisionCodes = new int[splitCodePaths.length]; - SparseArray<int[]> splitDependencies = null; - + codeDir + "/feature-no-deps.dex"}); + + ai.splitClassLoaderNames = new String[]{ + DELEGATE_LAST_CLASS_LOADER_NAME, + DELEGATE_LAST_CLASS_LOADER_NAME, + PATH_CLASS_LOADER_NAME, + DEX_CLASS_LOADER_NAME, + PATH_CLASS_LOADER_NAME, + null, // A null class loader name should default to PathClassLoader. + null, // The config split gets a null class loader. + null}; // The feature split with no dependency and no specified class loader. if (addSplitDependencies) { - splitDependencies = new SparseArray<>(splitCodePaths.length); - splitDependencies.put(0, new int[] {-1}); // base has no dependency - splitDependencies.put(1, new int[] {2}); // split 1 depends on 2 - splitDependencies.put(2, new int[] {4}); // split 2 depends on 4 - splitDependencies.put(3, new int[] {4}); // split 3 depends on 4 - splitDependencies.put(4, new int[] {0}); // split 4 depends on base - splitDependencies.put(5, new int[] {0}); // split 5 depends on base - splitDependencies.put(6, new int[] {5}); // split 6 depends on 5 + ai.splitDependencies = new SparseArray<>(ai.splitClassLoaderNames.length + 1); + ai.splitDependencies.put(0, new int[] {-1}); // base has no dependency + ai.splitDependencies.put(1, new int[] {2}); // split 1 depends on 2 + ai.splitDependencies.put(2, new int[] {4}); // split 2 depends on 4 + ai.splitDependencies.put(3, new int[] {4}); // split 3 depends on 4 + ai.splitDependencies.put(4, new int[] {0}); // split 4 depends on base + ai.splitDependencies.put(5, new int[] {0}); // split 5 depends on base + ai.splitDependencies.put(6, new int[] {5}); // split 6 depends on 5 // Do not add the config split to the dependency list. // Do not add the feature split with no dependency to the dependency list. } - - parsingPackage - .asSplit( - splitNames, - splitCodePaths, - splitRevisionCodes, - splitDependencies - ) - .setSplitClassLoaderName(0, DELEGATE_LAST_CLASS_LOADER_NAME) - .setSplitClassLoaderName(1, DELEGATE_LAST_CLASS_LOADER_NAME) - .setSplitClassLoaderName(2, PATH_CLASS_LOADER_NAME) - .setSplitClassLoaderName(3, DEX_CLASS_LOADER_NAME) - .setSplitClassLoaderName(4, PATH_CLASS_LOADER_NAME) - // A null class loader name should default to PathClassLoader - .setSplitClassLoaderName(5, null) - // The config split gets a null class loader - .setSplitClassLoaderName(6, null) - // The feature split with no dependency and no specified class loader. - .setSplitClassLoaderName(7, null); } - - ParsedPackage parsedPackage = parsingPackage.hideAsParsed() - .setBaseCodePath(codeDir + "/base.dex"); - TestData data = new TestData(); - data.pkg = parsedPackage.hideAsFinal(); + data.info = ai; data.pathsWithCode = pathsWithCode; return data; } @@ -141,11 +118,11 @@ public class DexoptUtilsTest { @Test public void testSplitChain() { - TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, true, true); + TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, true); List<SharedLibraryInfo> sharedLibrary = createMockSharedLibrary(new String[] {"a.dex", "b.dex"}); String[] contexts = DexoptUtils.getClassLoaderContexts( - data.pkg, sharedLibrary, data.pathsWithCode); + data.info, sharedLibrary, data.pathsWithCode); assertEquals(9, contexts.length); assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]); @@ -162,11 +139,11 @@ public class DexoptUtilsTest { @Test public void testSplitChainNoSplitDependencies() { - TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, false, true); + TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, false); List<SharedLibraryInfo> sharedLibrary = createMockSharedLibrary(new String[] {"a.dex", "b.dex"}); String[] contexts = DexoptUtils.getClassLoaderContexts( - data.pkg, sharedLibrary, data.pathsWithCode); + data.info, sharedLibrary, data.pathsWithCode); assertEquals(9, contexts.length); assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]); @@ -190,9 +167,11 @@ public class DexoptUtilsTest { @Test public void testSplitChainNoIsolationNoSharedLibrary() { - TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, true, false); + TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, true); + data.info.privateFlags = data.info.privateFlags + & (~ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING); String[] contexts = DexoptUtils.getClassLoaderContexts( - data.pkg, null, data.pathsWithCode); + data.info, null, data.pathsWithCode); assertEquals(9, contexts.length); assertEquals("PCL[]", contexts[0]); @@ -213,9 +192,9 @@ public class DexoptUtilsTest { @Test public void testSplitChainNoSharedLibraries() { TestData data = createMockApplicationInfo( - DELEGATE_LAST_CLASS_LOADER_NAME, true, true, true); + DELEGATE_LAST_CLASS_LOADER_NAME, true, true); String[] contexts = DexoptUtils.getClassLoaderContexts( - data.pkg, null, data.pathsWithCode); + data.info, null, data.pathsWithCode); assertEquals(9, contexts.length); assertEquals("DLC[]", contexts[0]); @@ -232,11 +211,11 @@ public class DexoptUtilsTest { @Test public void testSplitChainWithNullPrimaryClassLoader() { // A null classLoaderName should mean PathClassLoader. - TestData data = createMockApplicationInfo(null, true, true, true); + TestData data = createMockApplicationInfo(null, true, true); List<SharedLibraryInfo> sharedLibrary = createMockSharedLibrary(new String[] {"a.dex", "b.dex"}); String[] contexts = DexoptUtils.getClassLoaderContexts( - data.pkg, sharedLibrary, data.pathsWithCode); + data.info, sharedLibrary, data.pathsWithCode); assertEquals(9, contexts.length); assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]); @@ -254,11 +233,11 @@ public class DexoptUtilsTest { @Test public void tesNoSplits() { - TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, false, false, true); + TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, false, false); List<SharedLibraryInfo> sharedLibrary = createMockSharedLibrary(new String[] {"a.dex", "b.dex"}); String[] contexts = DexoptUtils.getClassLoaderContexts( - data.pkg, sharedLibrary, data.pathsWithCode); + data.info, sharedLibrary, data.pathsWithCode); assertEquals(1, contexts.length); assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]); @@ -266,11 +245,11 @@ public class DexoptUtilsTest { @Test public void tesNoSplitsNullClassLoaderName() { - TestData data = createMockApplicationInfo(null, false, false, true); + TestData data = createMockApplicationInfo(null, false, false); List<SharedLibraryInfo> sharedLibrary = createMockSharedLibrary(new String[] {"a.dex", "b.dex"}); String[] contexts = DexoptUtils.getClassLoaderContexts( - data.pkg, sharedLibrary, data.pathsWithCode); + data.info, sharedLibrary, data.pathsWithCode); assertEquals(1, contexts.length); assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]); @@ -279,11 +258,11 @@ public class DexoptUtilsTest { @Test public void tesNoSplitDelegateLast() { TestData data = createMockApplicationInfo( - DELEGATE_LAST_CLASS_LOADER_NAME, false, false, true); + DELEGATE_LAST_CLASS_LOADER_NAME, false, false); List<SharedLibraryInfo> sharedLibrary = createMockSharedLibrary(new String[] {"a.dex", "b.dex"}); String[] contexts = DexoptUtils.getClassLoaderContexts( - data.pkg, sharedLibrary, data.pathsWithCode); + data.info, sharedLibrary, data.pathsWithCode); assertEquals(1, contexts.length); assertEquals("DLC[]{PCL[a.dex:b.dex]}", contexts[0]); @@ -291,9 +270,9 @@ public class DexoptUtilsTest { @Test public void tesNoSplitsNoSharedLibraries() { - TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, false, false, true); + TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, false, false); String[] contexts = DexoptUtils.getClassLoaderContexts( - data.pkg, null, data.pathsWithCode); + data.info, null, data.pathsWithCode); assertEquals(1, contexts.length); assertEquals("PCL[]", contexts[0]); @@ -302,9 +281,9 @@ public class DexoptUtilsTest { @Test public void tesNoSplitDelegateLastNoSharedLibraries() { TestData data = createMockApplicationInfo( - DELEGATE_LAST_CLASS_LOADER_NAME, false, false, true); + DELEGATE_LAST_CLASS_LOADER_NAME, false, false); String[] contexts = DexoptUtils.getClassLoaderContexts( - data.pkg, null, data.pathsWithCode); + data.info, null, data.pathsWithCode); assertEquals(1, contexts.length); assertEquals("DLC[]", contexts[0]); @@ -312,13 +291,13 @@ public class DexoptUtilsTest { @Test public void testContextWithNoCode() { - TestData data = createMockApplicationInfo(null, true, false, true); + TestData data = createMockApplicationInfo(null, true, false); Arrays.fill(data.pathsWithCode, false); List<SharedLibraryInfo> sharedLibrary = createMockSharedLibrary(new String[] {"a.dex", "b.dex"}); String[] contexts = DexoptUtils.getClassLoaderContexts( - data.pkg, sharedLibrary, data.pathsWithCode); + data.info, sharedLibrary, data.pathsWithCode); assertEquals(9, contexts.length); assertEquals(null, contexts[0]); @@ -333,12 +312,12 @@ public class DexoptUtilsTest { @Test public void testContextBaseNoCode() { - TestData data = createMockApplicationInfo(null, true, true, true); + TestData data = createMockApplicationInfo(null, true, true); data.pathsWithCode[0] = false; List<SharedLibraryInfo> sharedLibrary = createMockSharedLibrary(new String[] {"a.dex", "b.dex"}); String[] contexts = DexoptUtils.getClassLoaderContexts( - data.pkg, sharedLibrary, data.pathsWithCode); + data.info, sharedLibrary, data.pathsWithCode); assertEquals(9, contexts.length); assertEquals(null, contexts[0]); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java index dcab78ede287..3d872237d8d4 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java @@ -16,9 +16,10 @@ package com.android.server.notification; -import static junit.framework.Assert.assertEquals; +import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertNull; +import static junit.framework.TestCase.assertTrue; import android.app.NotificationManager.Policy; import android.content.ComponentName; @@ -52,18 +53,18 @@ public class ZenModeConfigTest extends UiServiceTestCase { @Test public void testPriorityOnlyMutingAllNotifications() { - ZenModeConfig config = getMutedNotificationsConfig(); - assertEquals(true, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); + ZenModeConfig config = getMutedRingerConfig(); + assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); config.allowReminders = true; - assertEquals(false, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); + assertFalse(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); config.allowReminders = false; config.areChannelsBypassingDnd = true; - assertEquals(false, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); + assertFalse(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); config.areChannelsBypassingDnd = false; - assertEquals(true, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); + assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); } @Test @@ -106,26 +107,26 @@ public class ZenModeConfigTest extends UiServiceTestCase { @Test public void testPriorityOnlyMutingAll() { ZenModeConfig config = getMutedAllConfig(); - assertEquals(true, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); - assertEquals(true, ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); + assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); + assertTrue(ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); config.allowReminders = true; - assertEquals(false, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); - assertEquals(false, ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); + assertFalse(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); + assertFalse(ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); config.allowReminders = false; config.areChannelsBypassingDnd = true; - assertEquals(false, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); - assertEquals(false, ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); + assertFalse(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); + assertFalse(ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); config.areChannelsBypassingDnd = false; config.allowAlarms = true; - assertEquals(true, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); - assertEquals(false, ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); + assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); + assertFalse(ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); config.allowAlarms = false; - assertEquals(true, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); - assertEquals(true, ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); + assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); + assertTrue(ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); } @Test @@ -200,14 +201,14 @@ public class ZenModeConfigTest extends UiServiceTestCase { assertEquals(rule.zenMode, fromXml.zenMode); } - private ZenModeConfig getMutedNotificationsConfig() { + private ZenModeConfig getMutedRingerConfig() { ZenModeConfig config = new ZenModeConfig(); - // Allow alarms, media, and system + // Allow alarms, media config.allowAlarms = true; config.allowMedia = true; - config.allowSystem = true; - // All notification sounds are not allowed + // All sounds that respect the ringer are not allowed + config.allowSystem = false; config.allowCalls = false; config.allowRepeatCallers = false; config.allowMessages = false; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index 89364500fd80..99771b91ee2a 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -487,7 +487,6 @@ public class ZenModeHelperTest extends UiServiceTestCase { public void testRingerAffectedStreamsPriorityOnly() { // in priority only mode: // ringtone, notification and system streams are affected by ringer mode - // UNLESS ringer is muted due to all the other priority only dnd sounds being muted mZenModeHelperSpy.mConfig.allowAlarms = true; mZenModeHelperSpy.mConfig.allowReminders = true; mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; @@ -503,8 +502,9 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) == 0); assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) == 0); - // special case: if ringer is muted (since all notification sounds cannot bypass) - // then system stream is not affected by ringer mode + // even when ringer is muted (since all ringer sounds cannot bypass DND), + // system stream is still affected by ringer mode + mZenModeHelperSpy.mConfig.allowSystem = false; mZenModeHelperSpy.mConfig.allowReminders = false; mZenModeHelperSpy.mConfig.allowCalls = false; mZenModeHelperSpy.mConfig.allowMessages = false; @@ -519,7 +519,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION)) != 0); assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM)) - == 0); + != 0); assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) == 0); assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) == 0); } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java index 6c78f6f0443f..69cc9b256b83 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java @@ -24,11 +24,9 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.clearInvocations; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.wm.ActivityStackSupervisor.ON_TOP; @@ -49,6 +47,7 @@ import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; import org.junit.Test; +import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.concurrent.CompletableFuture; @@ -62,6 +61,7 @@ import java.util.concurrent.TimeUnit; */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class ActivityDisplayTests extends ActivityTestsBase { @Test @@ -142,30 +142,24 @@ public class ActivityDisplayTests extends ActivityTestsBase { // Create a display which supports system decoration and allows reparenting stacks to // another display when the display is removed. final ActivityDisplay display = createNewActivityDisplay(); - spyOn(display); doReturn(false).when(display).shouldDestroyContentOnRemove(); doReturn(true).when(display).supportsSystemDecorations(); mRootActivityContainer.addChild(display, ActivityDisplay.POSITION_TOP); // Put home stack on the display. - final ActivityStack homeStack = display.createStack( - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP); - final TaskRecord task = new TaskBuilder(mSupervisor).setStack(homeStack).build(); - new ActivityBuilder(mService).setTask(task).build(); - display.removeChild(homeStack); - final ActivityStack spiedHomeStack = spy(homeStack); - display.addChild(spiedHomeStack, ActivityDisplay.POSITION_TOP); - reset(spiedHomeStack); + final ActivityStack homeStack = new StackBuilder(mRootActivityContainer) + .setDisplay(display).setActivityType(ACTIVITY_TYPE_HOME).build(); // Put a finishing standard activity which will be reparented. final ActivityStack stack = createFullscreenStackWithSimpleActivityAt(display); stack.topRunningActivityLocked().makeFinishingLocked(); + clearInvocations(homeStack); display.remove(); // The removed display should have no focused stack and its home stack should never resume. assertNull(display.getFocusedStack()); - verify(spiedHomeStack, never()).resumeTopActivityUncheckedLocked(any(), any()); + verify(homeStack, never()).resumeTopActivityUncheckedLocked(any(), any()); } private ActivityStack createFullscreenStackWithSimpleActivityAt(ActivityDisplay display) { diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 30c8eb36f34a..50203dfc043a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -103,8 +103,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.invocation.InvocationOnMock; -import java.util.concurrent.TimeUnit; - /** * Tests for the {@link ActivityRecord} class. * @@ -646,7 +644,7 @@ public class ActivityRecordTests extends ActivityTestsBase { // The override configuration should be reset and the activity's process will be killed. assertFalse(mActivity.inSizeCompatMode()); verify(mActivity).restartProcessIfVisible(); - mLockRule.runWithScissors(mService.mH, () -> { }, TimeUnit.SECONDS.toMillis(3)); + waitHandlerIdle(mService.mH); verify(mService.mAmInternal).killProcess( eq(mActivity.app.mName), eq(mActivity.app.mUid), anyString()); } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java index 9583b8acb14a..9e1df913b22c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java @@ -44,6 +44,7 @@ import androidx.test.filters.MediumTest; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for the {@link ActivityStackSupervisor} class. @@ -53,6 +54,7 @@ import org.junit.Test; */ @MediumTest @Presubmit +@RunWith(WindowTestRunner.class) public class ActivityStackSupervisorTests extends ActivityTestsBase { private ActivityStack mFullscreenStack; @@ -79,32 +81,28 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase { /** * Ensures that waiting results are notified of launches. */ - @SuppressWarnings("SynchronizeOnNonFinalField") @Test public void testReportWaitingActivityLaunchedIfNeeded() { final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true) .setStack(mFullscreenStack).build(); - // #notifyAll will be called on the ActivityManagerService. we must hold the object lock - // when this happens. - synchronized (mService.mGlobalLock) { - final WaitResult taskToFrontWait = new WaitResult(); - mSupervisor.mWaitingActivityLaunched.add(taskToFrontWait); - mSupervisor.reportWaitingActivityLaunchedIfNeeded(firstActivity, START_TASK_TO_FRONT); - - assertThat(mSupervisor.mWaitingActivityLaunched).isEmpty(); - assertEquals(taskToFrontWait.result, START_TASK_TO_FRONT); - assertNull(taskToFrontWait.who); - - final WaitResult deliverToTopWait = new WaitResult(); - mSupervisor.mWaitingActivityLaunched.add(deliverToTopWait); - mSupervisor.reportWaitingActivityLaunchedIfNeeded(firstActivity, - START_DELIVERED_TO_TOP); - - assertThat(mSupervisor.mWaitingActivityLaunched).isEmpty(); - assertEquals(deliverToTopWait.result, START_DELIVERED_TO_TOP); - assertEquals(deliverToTopWait.who, firstActivity.mActivityComponent); - } + final WaitResult taskToFrontWait = new WaitResult(); + mSupervisor.mWaitingActivityLaunched.add(taskToFrontWait); + // #notifyAll will be called on the ActivityTaskManagerService#mGlobalLock. The lock is hold + // implicitly by WindowManagerGlobalLockRule. + mSupervisor.reportWaitingActivityLaunchedIfNeeded(firstActivity, START_TASK_TO_FRONT); + + assertThat(mSupervisor.mWaitingActivityLaunched).isEmpty(); + assertEquals(taskToFrontWait.result, START_TASK_TO_FRONT); + assertNull(taskToFrontWait.who); + + final WaitResult deliverToTopWait = new WaitResult(); + mSupervisor.mWaitingActivityLaunched.add(deliverToTopWait); + mSupervisor.reportWaitingActivityLaunchedIfNeeded(firstActivity, START_DELIVERED_TO_TOP); + + assertThat(mSupervisor.mWaitingActivityLaunched).isEmpty(); + assertEquals(deliverToTopWait.result, START_DELIVERED_TO_TOP); + assertEquals(deliverToTopWait.who, firstActivity.mActivityComponent); } /** diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index 2a8b4c88c000..c2a05c243540 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -67,6 +67,7 @@ import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for the {@link ActivityStack} class. @@ -76,6 +77,7 @@ import org.junit.Test; */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class ActivityStackTests extends ActivityTestsBase { private ActivityDisplay mDefaultDisplay; private ActivityStack mStack; diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java index a7bbe6e4cf02..5e4c96582d02 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java @@ -38,6 +38,7 @@ import com.android.server.wm.ActivityStarter.Factory; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import java.util.Random; @@ -49,6 +50,7 @@ import java.util.Random; */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class ActivityStartControllerTests extends ActivityTestsBase { private ActivityStartController mController; private Factory mFactory; diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java index 350114c792bf..4165052fa675 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java @@ -175,8 +175,8 @@ public class ActivityStartInterceptorTest { .build(); when(mPackageManagerInternal.getSuspendingPackage(TEST_PACKAGE_NAME, TEST_USER_ID)) .thenReturn(suspendingPackage); - when(mPackageManagerInternal.getSuspendedDialogInfo(TEST_PACKAGE_NAME, TEST_USER_ID)) - .thenReturn(dialogInfo); + when(mPackageManagerInternal.getSuspendedDialogInfo(TEST_PACKAGE_NAME, suspendingPackage, + TEST_USER_ID)).thenReturn(dialogInfo); // THEN calling intercept returns true assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index 1f672c0c95f3..78f3f7953d8d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -753,7 +753,7 @@ public class ActivityStarterTests extends ActivityTestsBase { false /* mockGetLaunchStack */); // Create a secondary display at bottom. - final TestActivityDisplay secondaryDisplay = spy(createNewActivityDisplay()); + final TestActivityDisplay secondaryDisplay = createNewActivityDisplay(); mRootActivityContainer.addChild(secondaryDisplay, POSITION_BOTTOM); final ActivityStack stack = secondaryDisplay.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); @@ -791,7 +791,7 @@ public class ActivityStarterTests extends ActivityTestsBase { false /* mockGetLaunchStack */); // Create a secondary display with an activity. - final TestActivityDisplay secondaryDisplay = spy(createNewActivityDisplay()); + final TestActivityDisplay secondaryDisplay = createNewActivityDisplay(); mRootActivityContainer.addChild(secondaryDisplay, POSITION_TOP); final ActivityRecord singleTaskActivity = createSingleTaskActivityOn( secondaryDisplay.createStack(WINDOWING_MODE_FULLSCREEN, diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java index 297aa7eab169..7b7e6e70cd80 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java @@ -26,6 +26,7 @@ import androidx.test.filters.MediumTest; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for the {@link ActivityTaskManagerService} class. @@ -34,6 +35,7 @@ import org.junit.Test; * atest WmTests:ActivityTaskManagerServiceTests */ @MediumTest +@RunWith(WindowTestRunner.class) public class ActivityTaskManagerServiceTests extends ActivityTestsBase { @Before diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java index d311dfc60675..f4d1cbfa5387 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java @@ -40,31 +40,17 @@ import android.content.pm.ApplicationInfo; import android.content.res.Configuration; import android.os.UserHandle; import android.service.voice.IVoiceInteractionSession; -import android.testing.DexmakerShareClassLoaderRule; import android.view.DisplayInfo; import com.android.server.AttributeCache; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Rule; /** * A base class to handle common operations in activity related unit tests. */ -class ActivityTestsBase { - - @Rule - public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule = - new DexmakerShareClassLoaderRule(); - - @Rule - public final SystemServicesTestRule mSystemServicesTestRule = new SystemServicesTestRule(); - - @WindowTestRunner.MethodWrapperRule - public final WindowManagerGlobalLockRule mLockRule = - new WindowManagerGlobalLockRule(mSystemServicesTestRule); - +class ActivityTestsBase extends SystemServiceTestsBase { final Context mContext = getInstrumentation().getTargetContext(); ActivityTaskManagerService mService; diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java index 629a95453054..61dbd67c3fe8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java @@ -42,6 +42,7 @@ import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for change transitions @@ -51,6 +52,7 @@ import org.junit.Test; */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class AppChangeTransitionTests extends WindowTestsBase { private TaskStack mStack; diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java index e71c8f47a69f..605d52045d50 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java @@ -36,6 +36,7 @@ import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; /** * Build/Install/Run: @@ -43,6 +44,7 @@ import org.junit.Test; */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class AppTransitionControllerTest extends WindowTestsBase { private AppTransitionController mAppTransitionController; @@ -55,73 +57,63 @@ public class AppTransitionControllerTest extends WindowTestsBase { @Test @FlakyTest(bugId = 131005232) public void testTranslucentOpen() { - synchronized (mWm.mGlobalLock) { - final AppWindowToken behind = createAppWindowToken(mDisplayContent, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); - final AppWindowToken translucentOpening = createAppWindowToken(mDisplayContent, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); - translucentOpening.setOccludesParent(false); - translucentOpening.setHidden(true); - mDisplayContent.mOpeningApps.add(behind); - mDisplayContent.mOpeningApps.add(translucentOpening); - assertEquals(WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_OPEN, - mAppTransitionController.maybeUpdateTransitToTranslucentAnim( - TRANSIT_TASK_OPEN)); - } + final AppWindowToken behind = createAppWindowToken(mDisplayContent, + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); + final AppWindowToken translucentOpening = createAppWindowToken(mDisplayContent, + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); + translucentOpening.setOccludesParent(false); + translucentOpening.setHidden(true); + mDisplayContent.mOpeningApps.add(behind); + mDisplayContent.mOpeningApps.add(translucentOpening); + assertEquals(WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_OPEN, + mAppTransitionController.maybeUpdateTransitToTranslucentAnim(TRANSIT_TASK_OPEN)); } @Test @FlakyTest(bugId = 131005232) public void testTranslucentClose() { - synchronized (mWm.mGlobalLock) { - final AppWindowToken behind = createAppWindowToken(mDisplayContent, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); - final AppWindowToken translucentClosing = createAppWindowToken(mDisplayContent, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); - translucentClosing.setOccludesParent(false); - mDisplayContent.mClosingApps.add(translucentClosing); - assertEquals(WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE, - mAppTransitionController.maybeUpdateTransitToTranslucentAnim( - TRANSIT_TASK_CLOSE)); - } + final AppWindowToken behind = createAppWindowToken(mDisplayContent, + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); + final AppWindowToken translucentClosing = createAppWindowToken(mDisplayContent, + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); + translucentClosing.setOccludesParent(false); + mDisplayContent.mClosingApps.add(translucentClosing); + assertEquals(WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE, + mAppTransitionController.maybeUpdateTransitToTranslucentAnim(TRANSIT_TASK_CLOSE)); } @Test @FlakyTest(bugId = 131005232) public void testChangeIsNotOverwritten() { - synchronized (mWm.mGlobalLock) { - final AppWindowToken behind = createAppWindowToken(mDisplayContent, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); - final AppWindowToken translucentOpening = createAppWindowToken(mDisplayContent, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); - translucentOpening.setOccludesParent(false); - translucentOpening.setHidden(true); - mDisplayContent.mOpeningApps.add(behind); - mDisplayContent.mOpeningApps.add(translucentOpening); - assertEquals(TRANSIT_TASK_CHANGE_WINDOWING_MODE, - mAppTransitionController.maybeUpdateTransitToTranslucentAnim( - TRANSIT_TASK_CHANGE_WINDOWING_MODE)); - } + final AppWindowToken behind = createAppWindowToken(mDisplayContent, + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); + final AppWindowToken translucentOpening = createAppWindowToken(mDisplayContent, + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); + translucentOpening.setOccludesParent(false); + translucentOpening.setHidden(true); + mDisplayContent.mOpeningApps.add(behind); + mDisplayContent.mOpeningApps.add(translucentOpening); + assertEquals(TRANSIT_TASK_CHANGE_WINDOWING_MODE, + mAppTransitionController.maybeUpdateTransitToTranslucentAnim( + TRANSIT_TASK_CHANGE_WINDOWING_MODE)); } @Test @FlakyTest(bugId = 131005232) public void testTransitWithinTask() { - synchronized (mWm.mGlobalLock) { - final AppWindowToken opening = createAppWindowToken(mDisplayContent, - WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD); - opening.setOccludesParent(false); - final AppWindowToken closing = createAppWindowToken(mDisplayContent, - WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD); - closing.setOccludesParent(false); - Task task = opening.getTask(); - mDisplayContent.mOpeningApps.add(opening); - mDisplayContent.mClosingApps.add(closing); - assertFalse(mAppTransitionController.isTransitWithinTask(TRANSIT_ACTIVITY_OPEN, task)); - closing.getTask().removeChild(closing); - task.addChild(closing, 0); - assertTrue(mAppTransitionController.isTransitWithinTask(TRANSIT_ACTIVITY_OPEN, task)); - assertFalse(mAppTransitionController.isTransitWithinTask(TRANSIT_TASK_OPEN, task)); - } + final AppWindowToken opening = createAppWindowToken(mDisplayContent, + WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD); + opening.setOccludesParent(false); + final AppWindowToken closing = createAppWindowToken(mDisplayContent, + WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD); + closing.setOccludesParent(false); + final Task task = opening.getTask(); + mDisplayContent.mOpeningApps.add(opening); + mDisplayContent.mClosingApps.add(closing); + assertFalse(mAppTransitionController.isTransitWithinTask(TRANSIT_ACTIVITY_OPEN, task)); + closing.getTask().removeChild(closing); + task.addChild(closing, 0); + assertTrue(mAppTransitionController.isTransitWithinTask(TRANSIT_ACTIVITY_OPEN, task)); + assertFalse(mAppTransitionController.isTransitWithinTask(TRANSIT_TASK_OPEN, task)); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java index 45e68902e123..49e4c78551cb 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java @@ -31,7 +31,6 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -55,6 +54,7 @@ import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; /** * Test class for {@link AppTransition}. @@ -64,16 +64,13 @@ import org.junit.Test; */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class AppTransitionTests extends WindowTestsBase { private DisplayContent mDc; @Before public void setUp() throws Exception { - synchronized (mWm.mGlobalLock) { - // Hold the lock to protect the stubbing from being accessed by other threads. - spyOn(mWm.mRoot); - doNothing().when(mWm.mRoot).performSurfacePlacement(anyBoolean()); - } + doNothing().when(mWm.mRoot).performSurfacePlacement(anyBoolean()); mDc = mWm.getDefaultDisplayContentLocked(); } diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java index b8f8e21d64ac..aacdeb21c52b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java @@ -17,8 +17,8 @@ package com.android.server.wm; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; - import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; + import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -26,12 +26,12 @@ import android.graphics.GraphicBuffer; import android.graphics.PixelFormat; import android.platform.test.annotations.Presubmit; import android.view.Surface; -import android.view.SurfaceControl; import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import org.junit.Test; +import org.junit.runner.RunWith; /** * Test class for {@link TaskSnapshotSurface}. @@ -42,6 +42,7 @@ import org.junit.Test; */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class AppWindowThumbnailTest extends WindowTestsBase { private AppWindowThumbnail buildThumbnail() { final GraphicBuffer buffer = GraphicBuffer.create(1, 1, PixelFormat.RGBA_8888, diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java index 70d9b5fedbcb..8957486b2dfe 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java @@ -37,6 +37,7 @@ import com.android.server.wm.WindowTestUtils.TestAppWindowToken; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -50,6 +51,7 @@ import org.mockito.MockitoAnnotations; */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class AppWindowTokenAnimationTests extends WindowTestsBase { private TestAppWindowToken mToken; diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java index 1f634b11d173..d528e415d75d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java @@ -62,6 +62,7 @@ import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mockito; /** @@ -72,6 +73,7 @@ import org.mockito.Mockito; */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class AppWindowTokenTests extends WindowTestsBase { TaskStack mStack; @@ -324,40 +326,36 @@ public class AppWindowTokenTests extends WindowTestsBase { @Test public void testReportOrientationChangeOnVisibilityChange() { - synchronized (mWm.mGlobalLock) { - mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); + mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); - mDisplayContent.getDisplayRotation().setFixedToUserRotation( - DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED); + mDisplayContent.getDisplayRotation().setFixedToUserRotation( + DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED); - doReturn(Configuration.ORIENTATION_LANDSCAPE).when(mToken.mActivityRecord) - .getRequestedConfigurationOrientation(); + doReturn(Configuration.ORIENTATION_LANDSCAPE).when(mToken.mActivityRecord) + .getRequestedConfigurationOrientation(); - mTask.mTaskRecord = Mockito.mock(TaskRecord.class, RETURNS_DEEP_STUBS); - mToken.commitVisibility(null, false /* visible */, TRANSIT_UNSET, - true /* performLayout */, false /* isVoiceInteraction */); - } + mTask.mTaskRecord = Mockito.mock(TaskRecord.class, RETURNS_DEEP_STUBS); + mToken.commitVisibility(null /* lp */, false /* visible */, TRANSIT_UNSET, + true /* performLayout */, false /* isVoiceInteraction */); verify(mTask.mTaskRecord).onConfigurationChanged(any(Configuration.class)); } @Test public void testReportOrientationChangeOnOpeningClosingAppChange() { - synchronized (mWm.mGlobalLock) { - mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); + mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); - mDisplayContent.getDisplayRotation().setFixedToUserRotation( - DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED); - mDisplayContent.getDisplayInfo().state = Display.STATE_ON; - mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_CLOSE, - false /* alwaysKeepCurrent */, 0 /* flags */, true /* forceOverride */); + mDisplayContent.getDisplayRotation().setFixedToUserRotation( + DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED); + mDisplayContent.getDisplayInfo().state = Display.STATE_ON; + mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_CLOSE, + false /* alwaysKeepCurrent */, 0 /* flags */, true /* forceOverride */); - doReturn(Configuration.ORIENTATION_LANDSCAPE).when(mToken.mActivityRecord) - .getRequestedConfigurationOrientation(); + doReturn(Configuration.ORIENTATION_LANDSCAPE).when(mToken.mActivityRecord) + .getRequestedConfigurationOrientation(); - mTask.mTaskRecord = Mockito.mock(TaskRecord.class, RETURNS_DEEP_STUBS); - mToken.setVisibility(false, false); - } + mTask.mTaskRecord = Mockito.mock(TaskRecord.class, RETURNS_DEEP_STUBS); + mToken.setVisibility(false /* visible */, false /* deferHidingClient */); verify(mTask.mTaskRecord).onConfigurationChanged(any(Configuration.class)); } diff --git a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java index bb574ceed4e0..2e85897b6fee 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java @@ -22,6 +22,8 @@ import static android.app.AppOpsManager.OP_ASSIST_SCREENSHOT; import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE; import static android.graphics.Bitmap.Config.ARGB_8888; +import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; + import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; @@ -71,7 +73,7 @@ import java.util.concurrent.TimeUnit; */ @MediumTest @Presubmit -public class AssistDataRequesterTest extends ActivityTestsBase { +public class AssistDataRequesterTest { private static final String TAG = AssistDataRequesterTest.class.getSimpleName(); @@ -111,8 +113,9 @@ public class AssistDataRequesterTest extends ActivityTestsBase { mHandler = new Handler(Looper.getMainLooper()); mCallbacksLock = new Object(); mCallbacks = new Callbacks(); - mDataRequester = new AssistDataRequester(mContext, mWm, mAppOpsManager, mCallbacks, - mCallbacksLock, OP_ASSIST_STRUCTURE, OP_ASSIST_SCREENSHOT); + mDataRequester = new AssistDataRequester(getInstrumentation().getTargetContext(), mWm, + mAppOpsManager, mCallbacks, mCallbacksLock, OP_ASSIST_STRUCTURE, + OP_ASSIST_SCREENSHOT); mDataRequester.mActivityTaskManager = mAtm; // Gate the continuation of the assist data callbacks until we are ready within the tests mGate = new CountDownLatch(1); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 44f3ee4130e0..ae4074275b97 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -47,7 +47,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.same; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; @@ -72,7 +71,6 @@ import android.metrics.LogMaker; import android.os.SystemClock; import android.platform.test.annotations.Presubmit; import android.util.DisplayMetrics; -import android.util.MutableBoolean; import android.view.DisplayCutout; import android.view.Gravity; import android.view.ISystemGestureExclusionListener; @@ -88,6 +86,7 @@ import com.android.internal.logging.nano.MetricsProto; import com.android.server.wm.utils.WmDisplayCutout; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; @@ -105,6 +104,7 @@ import java.util.List; */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class DisplayContentTests extends WindowTestsBase { @Test @@ -435,78 +435,70 @@ public class DisplayContentTests extends WindowTestsBase { @Test public void testDisplayCutout_rot0() { - synchronized (mWm.getWindowManagerLock()) { - final DisplayContent dc = createNewDisplay(); - dc.mInitialDisplayWidth = 200; - dc.mInitialDisplayHeight = 400; - Rect r = new Rect(80, 0, 120, 10); - final DisplayCutout cutout = new WmDisplayCutout( - fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_TOP), null) - .computeSafeInsets(200, 400).getDisplayCutout(); - - dc.mInitialDisplayCutout = cutout; - dc.getDisplayRotation().setRotation(Surface.ROTATION_0); - dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo. - - assertEquals(cutout, dc.getDisplayInfo().displayCutout); - } + final DisplayContent dc = createNewDisplay(); + dc.mInitialDisplayWidth = 200; + dc.mInitialDisplayHeight = 400; + final Rect r = new Rect(80, 0, 120, 10); + final DisplayCutout cutout = new WmDisplayCutout( + fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_TOP), null) + .computeSafeInsets(200, 400).getDisplayCutout(); + + dc.mInitialDisplayCutout = cutout; + dc.getDisplayRotation().setRotation(Surface.ROTATION_0); + dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo. + + assertEquals(cutout, dc.getDisplayInfo().displayCutout); } @Test public void testDisplayCutout_rot90() { - synchronized (mWm.getWindowManagerLock()) { - // Prevent mInitialDisplayCutout from being updated from real display (e.g. null - // if the device has no cutout). - final DisplayContent dc = createDisplayNoUpdateDisplayInfo(); - // Rotation may use real display info to compute bound, so here also uses the - // same width and height. - final int displayWidth = dc.mInitialDisplayWidth; - final int displayHeight = dc.mInitialDisplayHeight; - final int cutoutWidth = 40; - final int cutoutHeight = 10; - final int left = (displayWidth - cutoutWidth) / 2; - final int top = 0; - final int right = (displayWidth + cutoutWidth) / 2; - final int bottom = cutoutHeight; - - final Rect r1 = new Rect(left, top, right, bottom); - final DisplayCutout cutout = new WmDisplayCutout( - fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom, BOUNDS_POSITION_TOP), - null) - .computeSafeInsets(displayWidth, displayHeight).getDisplayCutout(); - - dc.mInitialDisplayCutout = cutout; - dc.getDisplayRotation().setRotation(Surface.ROTATION_90); - dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo. - - // ----o---------- ------------- - // | | | | | - // | ------o | o--- - // | | | | - // | | -> | | - // | | ---o - // | | | - // | | ------------- - final Rect r = new Rect(top, left, bottom, right); - assertEquals(new WmDisplayCutout( - fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_LEFT), null) - .computeSafeInsets(displayHeight, displayWidth) - .getDisplayCutout(), dc.getDisplayInfo().displayCutout); - } + // Prevent mInitialDisplayCutout from being updated from real display (e.g. null + // if the device has no cutout). + final DisplayContent dc = createDisplayNoUpdateDisplayInfo(); + // Rotation may use real display info to compute bound, so here also uses the + // same width and height. + final int displayWidth = dc.mInitialDisplayWidth; + final int displayHeight = dc.mInitialDisplayHeight; + final int cutoutWidth = 40; + final int cutoutHeight = 10; + final int left = (displayWidth - cutoutWidth) / 2; + final int top = 0; + final int right = (displayWidth + cutoutWidth) / 2; + final int bottom = cutoutHeight; + + final Rect r1 = new Rect(left, top, right, bottom); + final DisplayCutout cutout = new WmDisplayCutout( + fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom, BOUNDS_POSITION_TOP), null) + .computeSafeInsets(displayWidth, displayHeight).getDisplayCutout(); + + dc.mInitialDisplayCutout = cutout; + dc.getDisplayRotation().setRotation(Surface.ROTATION_90); + dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo. + + // ----o---------- ------------- + // | | | | | + // | ------o | o--- + // | | | | + // | | -> | | + // | | ---o + // | | | + // | | ------------- + final Rect r = new Rect(top, left, bottom, right); + assertEquals(new WmDisplayCutout( + fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_LEFT), null) + .computeSafeInsets(displayHeight, displayWidth).getDisplayCutout(), + dc.getDisplayInfo().displayCutout); } @Test public void testLayoutSeq_assignedDuringLayout() { - synchronized (mWm.getWindowManagerLock()) { - - final DisplayContent dc = createNewDisplay(); - final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w"); + final DisplayContent dc = createNewDisplay(); + final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w"); - dc.setLayoutNeeded(); - dc.performLayout(true /* initial */, false /* updateImeWindows */); + dc.setLayoutNeeded(); + dc.performLayout(true /* initial */, false /* updateImeWindows */); - assertThat(win.mLayoutSeq, is(dc.mLayoutSeq)); - } + assertThat(win.mLayoutSeq, is(dc.mLayoutSeq)); } @Test @@ -751,7 +743,7 @@ public class DisplayContentTests extends WindowTestsBase { win.setHasSurface(true); dc.updateSystemGestureExclusion(); - final MutableBoolean invoked = new MutableBoolean(false); + final boolean[] invoked = { false }; final ISystemGestureExclusionListener.Stub verifier = new ISystemGestureExclusionListener.Stub() { @Override @@ -760,7 +752,7 @@ public class DisplayContentTests extends WindowTestsBase { Region expected = Region.obtain(); expected.set(10, 20, 30, 40); assertEquals(expected, actual); - invoked.value = true; + invoked[0] = true; } }; try { @@ -768,7 +760,7 @@ public class DisplayContentTests extends WindowTestsBase { } finally { dc.unregisterSystemGestureExclusionListener(verifier); } - assertTrue("SystemGestureExclusionListener was not invoked", invoked.value); + assertTrue("SystemGestureExclusionListener was not invoked", invoked[0]); } @Test @@ -826,30 +818,28 @@ public class DisplayContentTests extends WindowTestsBase { @Test public void testCalculateSystemGestureExclusion_immersiveStickyLegacyWindow() throws Exception { - synchronized (mWm.mGlobalLock) { - mWm.mSystemGestureExcludedByPreQStickyImmersive = true; + mWm.mSystemGestureExcludedByPreQStickyImmersive = true; - final DisplayContent dc = createNewDisplay(); - final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win"); - win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR; - win.getAttrs().layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; - win.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION; - win.getAttrs().subtreeSystemUiVisibility = win.mSystemUiVisibility = - SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION - | SYSTEM_UI_FLAG_IMMERSIVE_STICKY; - win.mAppToken.mTargetSdk = P; + final DisplayContent dc = createNewDisplay(); + final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win"); + win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR; + win.getAttrs().layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; + win.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION; + win.getAttrs().subtreeSystemUiVisibility = win.mSystemUiVisibility = + SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION + | SYSTEM_UI_FLAG_IMMERSIVE_STICKY; + win.mAppToken.mTargetSdk = P; - dc.setLayoutNeeded(); - dc.performLayout(true /* initial */, false /* updateImeWindows */); + dc.setLayoutNeeded(); + dc.performLayout(true /* initial */, false /* updateImeWindows */); - win.setHasSurface(true); + win.setHasSurface(true); - final Region expected = Region.obtain(); - expected.set(dc.getBounds()); - assertEquals(expected, calculateSystemGestureExclusion(dc)); + final Region expected = Region.obtain(); + expected.set(dc.getBounds()); + assertEquals(expected, calculateSystemGestureExclusion(dc)); - win.setHasSurface(false); - } + win.setHasSurface(false); } @Test @@ -860,7 +850,7 @@ public class DisplayContentTests extends WindowTestsBase { Configuration newConfig = new Configuration(); newConfig.orientation = Configuration.ORIENTATION_PORTRAIT; - final DisplayContent displayContent = spy(createNewDisplay()); + final DisplayContent displayContent = createNewDisplay(); Mockito.doReturn(mockLogger).when(displayContent).getMetricsLogger(); Mockito.doReturn(oldConfig).doReturn(newConfig).when(displayContent).getConfiguration(); @@ -886,9 +876,7 @@ public class DisplayContentTests extends WindowTestsBase { } private void updateFocusedWindow() { - synchronized (mWm.mGlobalLock) { - mWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false); - } + mWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false /* updateInputWindows */); } /** @@ -896,7 +884,7 @@ public class DisplayContentTests extends WindowTestsBase { * the values set by test. */ private DisplayContent createDisplayNoUpdateDisplayInfo() { - final DisplayContent displayContent = spy(createNewDisplay()); + final DisplayContent displayContent = createNewDisplay(); doNothing().when(displayContent).updateDisplayInfo(); return displayContent; } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java index de184b84857b..2a3731a2e483 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java @@ -63,9 +63,11 @@ import com.android.server.wm.utils.WmDisplayCutout; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { private DisplayFrames mFrames; @@ -118,458 +120,415 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { @Test public void layoutWindowLw_appDrawsBars() { - synchronized (mWm.mGlobalLock) { - mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; - addWindow(mWindow); - - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - - assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); - assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); - assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0); - } + mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; + addWindow(mWindow); + + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + + assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); + assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); + assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0); } @Test public void layoutWindowLw_appWontDrawBars() { - synchronized (mWm.mGlobalLock) { - mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; - addWindow(mWindow); - - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - - assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getDecorFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT); - } + mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; + addWindow(mWindow); + + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + + assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getDecorFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT); } @Test public void layoutWindowLw_appWontDrawBars_forceStatusAndNav() throws Exception { - synchronized (mWm.mGlobalLock) { - mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; - mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS; - addWindow(mWindow); - - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - - assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); - assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); - assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0); - } + mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; + mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS; + addWindow(mWindow); + + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + + assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); + assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); + assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0); } @Test public void layoutWindowLw_keyguardDialog_hideNav() { - synchronized (mWm.mGlobalLock) { - mWindow.mAttrs.type = TYPE_KEYGUARD_DIALOG; - mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; - mWindow.mAttrs.systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; - addWindow(mWindow); - - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* uiMode */); - mDisplayPolicy.layoutWindowLw(mWindow, null /* attached */, mFrames); - - assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); - assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); - assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0); - } + mWindow.mAttrs.type = TYPE_KEYGUARD_DIALOG; + mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; + mWindow.mAttrs.systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; + addWindow(mWindow); + + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* uiMode */); + mDisplayPolicy.layoutWindowLw(mWindow, null /* attached */, mFrames); + + assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); + assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); + assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0); } @Test public void layoutWindowLw_withDisplayCutout() { - synchronized (mWm.mGlobalLock) { - addDisplayCutout(); + addDisplayCutout(); - addWindow(mWindow); + addWindow(mWindow); - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); - assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); - assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0); - } + assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); + assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); + assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0); } @Test public void layoutWindowLw_withDisplayCutout_never() { - synchronized (mWm.mGlobalLock) { - addDisplayCutout(); + addDisplayCutout(); - mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER; - addWindow(mWindow); + mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER; + addWindow(mWindow); - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0); - assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); - assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0); - } + assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0); + assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); + assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0); } @Test public void layoutWindowLw_withDisplayCutout_layoutFullscreen() { - synchronized (mWm.mGlobalLock) { - addDisplayCutout(); + addDisplayCutout(); - mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; - addWindow(mWindow); + mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + addWindow(mWindow); - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); - assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); - assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0); - } + assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); + assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); + assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0); } @Test public void layoutWindowLw_withDisplayCutout_fullscreen() { - synchronized (mWm.mGlobalLock) { - addDisplayCutout(); + addDisplayCutout(); - mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN; - addWindow(mWindow); + mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN; + addWindow(mWindow); - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0); - assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); - assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0); - } + assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0); + assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); + assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0); } @Test public void layoutWindowLw_withDisplayCutout_fullscreenInCutout() { - synchronized (mWm.mGlobalLock) { - addDisplayCutout(); - - mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN; - mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; - addWindow(mWindow); - - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - - assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); - assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); - assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0); - } + addDisplayCutout(); + + mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN; + mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; + addWindow(mWindow); + + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + + assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); + assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); + assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0); } @Test public void layoutWindowLw_withDisplayCutout_landscape() { - synchronized (mWm.mGlobalLock) { - addDisplayCutout(); - setRotation(ROTATION_90); - addWindow(mWindow); - - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - - assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0); - assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); - assertInsetBy(mWindow.getContentFrameLw(), - DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); - assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0); - assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0); - } + addDisplayCutout(); + setRotation(ROTATION_90); + addWindow(mWindow); + + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + + assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0); + assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); + assertInsetBy(mWindow.getContentFrameLw(), + DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); + assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0); + assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0); } @Test public void layoutWindowLw_withDisplayCutout_seascape() { - synchronized (mWm.mGlobalLock) { - addDisplayCutout(); - setRotation(ROTATION_270); - addWindow(mWindow); - - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - - assertInsetBy(mWindow.getParentFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0); - assertInsetBy(mWindow.getStableFrameLw(), NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0); - assertInsetBy(mWindow.getContentFrameLw(), - NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0); - assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0); - assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0); - } + addDisplayCutout(); + setRotation(ROTATION_270); + addWindow(mWindow); + + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + + assertInsetBy(mWindow.getParentFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0); + assertInsetBy(mWindow.getStableFrameLw(), NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0); + assertInsetBy(mWindow.getContentFrameLw(), + NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0); + assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0); + assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0); } @Test public void layoutWindowLw_withDisplayCutout_fullscreen_landscape() { - synchronized (mWm.mGlobalLock) { - addDisplayCutout(); - setRotation(ROTATION_90); - - mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; - addWindow(mWindow); - - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - - assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0); - assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); - assertInsetBy(mWindow.getContentFrameLw(), - DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); - assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0); - } + addDisplayCutout(); + setRotation(ROTATION_90); + + mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + addWindow(mWindow); + + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + + assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0); + assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); + assertInsetBy(mWindow.getContentFrameLw(), + DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); + assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0); } @Test public void layoutWindowLw_withDisplayCutout_floatingInScreen() { - synchronized (mWm.mGlobalLock) { - addDisplayCutout(); + addDisplayCutout(); - mWindow.mAttrs.flags = FLAG_LAYOUT_IN_SCREEN; - mWindow.mAttrs.type = TYPE_APPLICATION_OVERLAY; - mWindow.mAttrs.width = DISPLAY_WIDTH; - mWindow.mAttrs.height = DISPLAY_HEIGHT; - addWindow(mWindow); + mWindow.mAttrs.flags = FLAG_LAYOUT_IN_SCREEN; + mWindow.mAttrs.type = TYPE_APPLICATION_OVERLAY; + mWindow.mAttrs.width = DISPLAY_WIDTH; + mWindow.mAttrs.height = DISPLAY_HEIGHT; + addWindow(mWindow); - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - } + assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); } @Test public void layoutWindowLw_withDisplayCutout_fullscreenInCutout_landscape() { - synchronized (mWm.mGlobalLock) { - addDisplayCutout(); - setRotation(ROTATION_90); - - mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; - mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; - addWindow(mWindow); - - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - - assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0); - assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); - assertInsetBy(mWindow.getContentFrameLw(), - DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); - assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0); - } + addDisplayCutout(); + setRotation(ROTATION_90); + + mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; + addWindow(mWindow); + + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + + assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0); + assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); + assertInsetBy(mWindow.getContentFrameLw(), + DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); + assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0); } @Test public void layoutWindowLw_withForwardInset_SoftInputAdjustResize() { - synchronized (mWm.mGlobalLock) { - mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_RESIZE; - addWindow(mWindow); - - final int forwardedInsetBottom = 50; - mDisplayPolicy.setForwardedInsets(Insets.of(0, 0, 0, forwardedInsetBottom)); - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - - assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0); - assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getContentFrameLw(), - STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT + forwardedInsetBottom); - assertInsetByTopBottom(mWindow.getVisibleFrameLw(), - STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT + forwardedInsetBottom); - assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0); - assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0); - } + mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_RESIZE; + addWindow(mWindow); + + final int forwardedInsetBottom = 50; + mDisplayPolicy.setForwardedInsets(Insets.of(0, 0, 0, forwardedInsetBottom)); + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + + assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0); + assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getContentFrameLw(), + STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT + forwardedInsetBottom); + assertInsetByTopBottom(mWindow.getVisibleFrameLw(), + STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT + forwardedInsetBottom); + assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0); + assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0); } @Test public void layoutWindowLw_withForwardInset_SoftInputAdjustNothing() { - synchronized (mWm.mGlobalLock) { - mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_NOTHING; - addWindow(mWindow); - - final int forwardedInsetBottom = 50; - mDisplayPolicy.setForwardedInsets(Insets.of(0, 0, 0, forwardedInsetBottom)); - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - - assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0); - assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0); - assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0); - } + mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_NOTHING; + addWindow(mWindow); + + final int forwardedInsetBottom = 50; + mDisplayPolicy.setForwardedInsets(Insets.of(0, 0, 0, forwardedInsetBottom)); + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + + assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0); + assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0); + assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0); } @Test public void layoutHint_appWindow() { - synchronized (mWm.mGlobalLock) { - // Initialize DisplayFrames - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - - final Rect outFrame = new Rect(); - final Rect outContentInsets = new Rect(); - final Rect outStableInsets = new Rect(); - final Rect outOutsets = new Rect(); - final DisplayCutout.ParcelableWrapper outDisplayCutout = - new DisplayCutout.ParcelableWrapper(); - - mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, null, mFrames, - false /* floatingStack */, outFrame, outContentInsets, outStableInsets, - outOutsets, outDisplayCutout); - - assertThat(outFrame, is(mFrames.mUnrestricted)); - assertThat(outContentInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT))); - assertThat(outStableInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT))); - assertThat(outOutsets, is(new Rect())); - assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper())); - } + // Initialize DisplayFrames + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + + final Rect outFrame = new Rect(); + final Rect outContentInsets = new Rect(); + final Rect outStableInsets = new Rect(); + final Rect outOutsets = new Rect(); + final DisplayCutout.ParcelableWrapper outDisplayCutout = + new DisplayCutout.ParcelableWrapper(); + + mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, null, mFrames, + false /* floatingStack */, outFrame, outContentInsets, outStableInsets, + outOutsets, outDisplayCutout); + + assertThat(outFrame, is(mFrames.mUnrestricted)); + assertThat(outContentInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT))); + assertThat(outStableInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT))); + assertThat(outOutsets, is(new Rect())); + assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper())); } @Test public void layoutHint_appWindowInTask() { - synchronized (mWm.mGlobalLock) { - // Initialize DisplayFrames - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - - final Rect taskBounds = new Rect(100, 100, 200, 200); - - final Rect outFrame = new Rect(); - final Rect outContentInsets = new Rect(); - final Rect outStableInsets = new Rect(); - final Rect outOutsets = new Rect(); - final DisplayCutout.ParcelableWrapper outDisplayCutout = - new DisplayCutout.ParcelableWrapper(); - - mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames, - false /* floatingStack */, outFrame, outContentInsets, outStableInsets, - outOutsets, outDisplayCutout); - - assertThat(outFrame, is(taskBounds)); - assertThat(outContentInsets, is(new Rect())); - assertThat(outStableInsets, is(new Rect())); - assertThat(outOutsets, is(new Rect())); - assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper())); - } + // Initialize DisplayFrames + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + + final Rect taskBounds = new Rect(100, 100, 200, 200); + + final Rect outFrame = new Rect(); + final Rect outContentInsets = new Rect(); + final Rect outStableInsets = new Rect(); + final Rect outOutsets = new Rect(); + final DisplayCutout.ParcelableWrapper outDisplayCutout = + new DisplayCutout.ParcelableWrapper(); + + mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames, + false /* floatingStack */, outFrame, outContentInsets, outStableInsets, + outOutsets, outDisplayCutout); + + assertThat(outFrame, is(taskBounds)); + assertThat(outContentInsets, is(new Rect())); + assertThat(outStableInsets, is(new Rect())); + assertThat(outOutsets, is(new Rect())); + assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper())); } @Test public void layoutHint_appWindowInTask_outsideContentFrame() { - synchronized (mWm.mGlobalLock) { - // Initialize DisplayFrames - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - - // Task is in the nav bar area (usually does not happen, but this is similar enough to - // the possible overlap with the IME) - final Rect taskBounds = new Rect(100, mFrames.mContent.bottom + 1, - 200, mFrames.mContent.bottom + 10); - - final Rect outFrame = new Rect(); - final Rect outContentInsets = new Rect(); - final Rect outStableInsets = new Rect(); - final Rect outOutsets = new Rect(); - final DisplayCutout.ParcelableWrapper outDisplayCutout = - new DisplayCutout.ParcelableWrapper(); - - mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames, - true /* floatingStack */, outFrame, outContentInsets, outStableInsets, - outOutsets, outDisplayCutout); - - assertThat(outFrame, is(taskBounds)); - assertThat(outContentInsets, is(new Rect())); - assertThat(outStableInsets, is(new Rect())); - assertThat(outOutsets, is(new Rect())); - assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper())); - } + // Initialize DisplayFrames + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + + // Task is in the nav bar area (usually does not happen, but this is similar enough to + // the possible overlap with the IME) + final Rect taskBounds = new Rect(100, mFrames.mContent.bottom + 1, + 200, mFrames.mContent.bottom + 10); + + final Rect outFrame = new Rect(); + final Rect outContentInsets = new Rect(); + final Rect outStableInsets = new Rect(); + final Rect outOutsets = new Rect(); + final DisplayCutout.ParcelableWrapper outDisplayCutout = + new DisplayCutout.ParcelableWrapper(); + + mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames, + true /* floatingStack */, outFrame, outContentInsets, outStableInsets, + outOutsets, outDisplayCutout); + + assertThat(outFrame, is(taskBounds)); + assertThat(outContentInsets, is(new Rect())); + assertThat(outStableInsets, is(new Rect())); + assertThat(outOutsets, is(new Rect())); + assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper())); } @Test public void forceShowSystemBars_clearsSystemUIFlags() { - synchronized (mWm.mGlobalLock) { - mDisplayPolicy.mLastSystemUiFlags |= SYSTEM_UI_FLAG_FULLSCREEN; - mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; - mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; - mWindow.mSystemUiVisibility = SYSTEM_UI_FLAG_FULLSCREEN; - mDisplayPolicy.setForceShowSystemBars(true); - addWindow(mWindow); - - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - // triggers updateSystemUiVisibilityLw which will reset the flags as needed - int finishPostLayoutPolicyLw = mDisplayPolicy.focusChangedLw(mWindow, mWindow); - - assertEquals(WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT, finishPostLayoutPolicyLw); - assertEquals(0, mDisplayPolicy.mLastSystemUiFlags); - assertEquals(0, mWindow.mAttrs.systemUiVisibility); - assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - } + mDisplayPolicy.mLastSystemUiFlags |= SYSTEM_UI_FLAG_FULLSCREEN; + mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; + mWindow.mSystemUiVisibility = SYSTEM_UI_FLAG_FULLSCREEN; + mDisplayPolicy.setForceShowSystemBars(true); + addWindow(mWindow); + + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + // triggers updateSystemUiVisibilityLw which will reset the flags as needed + int finishPostLayoutPolicyLw = mDisplayPolicy.focusChangedLw(mWindow, mWindow); + + assertEquals(WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT, finishPostLayoutPolicyLw); + assertEquals(0, mDisplayPolicy.mLastSystemUiFlags); + assertEquals(0, mWindow.mAttrs.systemUiVisibility); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); } @Test public void testScreenDecorWindows() { - synchronized (mWm.mGlobalLock) { - final WindowState decorWindow = createWindow(null, TYPE_APPLICATION_OVERLAY, - "decorWindow"); - decorWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE; - decorWindow.mAttrs.privateFlags |= PRIVATE_FLAG_IS_SCREEN_DECOR; - addWindow(decorWindow); - addWindow(mWindow); - - // Decor on top - updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, TOP); - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - assertInsetByTopBottom(mWindow.getContentFrameLw(), DECOR_WINDOW_INSET, NAV_BAR_HEIGHT); - - // Decor on bottom - updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, BOTTOM); - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, - DECOR_WINDOW_INSET); - - // Decor on the left - updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, LEFT); - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - assertInsetBy(mWindow.getContentFrameLw(), DECOR_WINDOW_INSET, STATUS_BAR_HEIGHT, 0, - NAV_BAR_HEIGHT); - - // Decor on the right - updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, RIGHT); - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - assertInsetBy(mWindow.getContentFrameLw(), 0, STATUS_BAR_HEIGHT, DECOR_WINDOW_INSET, - NAV_BAR_HEIGHT); - - // Decor not allowed as inset - updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, DECOR_WINDOW_INSET, TOP); - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - } + final WindowState decorWindow = createWindow(null, TYPE_APPLICATION_OVERLAY, "decorWindow"); + decorWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE; + decorWindow.mAttrs.privateFlags |= PRIVATE_FLAG_IS_SCREEN_DECOR; + addWindow(decorWindow); + addWindow(mWindow); + + // Decor on top + updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, TOP); + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + assertInsetByTopBottom(mWindow.getContentFrameLw(), DECOR_WINDOW_INSET, NAV_BAR_HEIGHT); + + // Decor on bottom + updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, BOTTOM); + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, + DECOR_WINDOW_INSET); + + // Decor on the left + updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, LEFT); + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + assertInsetBy(mWindow.getContentFrameLw(), DECOR_WINDOW_INSET, STATUS_BAR_HEIGHT, 0, + NAV_BAR_HEIGHT); + + // Decor on the right + updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, RIGHT); + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + assertInsetBy(mWindow.getContentFrameLw(), 0, STATUS_BAR_HEIGHT, DECOR_WINDOW_INSET, + NAV_BAR_HEIGHT); + + // Decor not allowed as inset + updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, DECOR_WINDOW_INSET, TOP); + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); } private void updateDecorWindow(WindowState decorWindow, int width, int height, int gravity) { diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java index 3ead97795954..e699b526e848 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java @@ -54,9 +54,11 @@ import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import org.junit.Test; +import org.junit.runner.RunWith; @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class DisplayPolicyTests extends WindowTestsBase { private WindowState createOpaqueFullscreen(boolean hasLightNavBar) { @@ -225,13 +227,10 @@ public class DisplayPolicyTests extends WindowTestsBase { final WindowState activity = createApplicationWindow(); final WindowState toast = createToastWindow(); - synchronized (mWm.mGlobalLock) { - policy.adjustWindowParamsLw( - toast, toast.mAttrs, 0 /* callingPid */, 0 /* callingUid */); + policy.adjustWindowParamsLw(toast, toast.mAttrs, 0 /* callingPid */, 0 /* callingUid */); - assertTrue(policy.canToastShowWhenLocked(0 /* callingUid */)); - assertNotEquals(0, toast.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED); - } + assertTrue(policy.canToastShowWhenLocked(0 /* callingUid */)); + assertNotEquals(0, toast.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED); } private WindowState createToastWindow() { diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java index 059ff3d70660..bd17bf26d70d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java @@ -238,18 +238,58 @@ public class DisplayRotationTests { } @Test - public void testReturnsUserRotation_UserRotationLocked_CompatibleAppRequest() + public void testReturnsLandscape_UserRotationLockedSeascape_AppRequestsLandscape() throws Exception { mBuilder.build(); - configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false, false); + configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false /* isCar */, + false /* isTv */); freezeRotation(Surface.ROTATION_180); - assertEquals(Surface.ROTATION_180, mTarget.rotationForOrientation( + assertEquals(Surface.ROTATION_0, mTarget.rotationForOrientation( ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, Surface.ROTATION_90)); } @Test + public void testReturnsSeascape_UserRotationLockedSeascape_AppRequestsSeascape() + throws Exception { + mBuilder.build(); + configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false /* isCar */, + false /* isTv */); + + freezeRotation(Surface.ROTATION_180); + + assertEquals(Surface.ROTATION_180, mTarget.rotationForOrientation( + ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE, Surface.ROTATION_90)); + } + + @Test + public void testReturnsPortrait_UserRotationLockedPortrait_AppRequestsPortrait() + throws Exception { + mBuilder.build(); + configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false /* isCar */, + false /* isTv */); + + freezeRotation(Surface.ROTATION_270); + + assertEquals(Surface.ROTATION_270, mTarget.rotationForOrientation( + ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, Surface.ROTATION_0)); + } + + @Test + public void testReturnsUpsideDown_UserRotationLockedUpsideDown_AppRequestsUpsideDown() + throws Exception { + mBuilder.build(); + configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false /* isCar */, + false /* isTv */); + + freezeRotation(Surface.ROTATION_90); + + assertEquals(Surface.ROTATION_90, mTarget.rotationForOrientation( + ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT, Surface.ROTATION_0)); + } + + @Test public void testReturnsSideways_UserRotationLocked_IncompatibleAppRequest() throws Exception { mBuilder.build(); diff --git a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java index bb80e5e4ddde..9d3c866d3ae7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java @@ -23,7 +23,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static org.junit.Assert.assertNotNull; @@ -51,6 +50,7 @@ import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.runner.RunWith; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -59,10 +59,11 @@ import java.util.concurrent.TimeUnit; * Tests for the {@link DragDropController} class. * * Build/Install/Run: - * atest FrameworksServicesTests:DragDropControllerTests + * atest WmTests:DragDropControllerTests */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class DragDropControllerTests extends WindowTestsBase { private static final int TIMEOUT_MS = 3000; private TestDragDropController mTarget; @@ -123,30 +124,25 @@ public class DragDropControllerTests extends WindowTestsBase { @Before public void setUp() throws Exception { mTarget = new TestDragDropController(mWm, mWm.mH.getLooper()); - mDisplayContent = spy(mDisplayContent); mWindow = createDropTargetWindow("Drag test window", 0); doReturn(mWindow).when(mDisplayContent).getTouchableWinAtPointLocked(0, 0); when(mWm.mInputManager.transferTouchFocus(any(), any())).thenReturn(true); - synchronized (mWm.mGlobalLock) { - mWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow); - } + mWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow); } @After public void tearDown() throws Exception { final CountDownLatch latch; - synchronized (mWm.mGlobalLock) { - if (!mTarget.dragDropActiveLocked()) { - return; - } - if (mToken != null) { - mTarget.cancelDragAndDrop(mToken, false); - } - latch = new CountDownLatch(1); - mTarget.setOnClosedCallbackLocked(latch::countDown); + if (!mTarget.dragDropActiveLocked()) { + return; + } + if (mToken != null) { + mTarget.cancelDragAndDrop(mToken, false); } - assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + latch = new CountDownLatch(1); + mTarget.setOnClosedCallbackLocked(latch::countDown); + assertTrue(awaitInWmLock(() -> latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS))); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java index f792b0db6cb5..5236b5d0e07f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -66,15 +66,17 @@ import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; /** * Build/Install/Run: - * atest FrameworksServicesTests:RecentsAnimationControllerTest + * atest WmTests:RecentsAnimationControllerTest */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class RecentsAnimationControllerTest extends WindowTestsBase { @Mock SurfaceControl mMockLeash; @@ -88,12 +90,8 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - synchronized (mWm.mGlobalLock) { - // Hold the lock to protect the stubbing from being accessed by other threads. - spyOn(mWm.mRoot); - doNothing().when(mWm.mRoot).performSurfacePlacement(anyBoolean()); - doReturn(mDisplayContent).when(mWm.mRoot).getDisplayContent(anyInt()); - } + doNothing().when(mWm.mRoot).performSurfacePlacement(anyBoolean()); + doReturn(mDisplayContent).when(mWm.mRoot).getDisplayContent(anyInt()); when(mMockRunner.asBinder()).thenReturn(new Binder()); mController = spy(new RecentsAnimationController(mWm, mMockRunner, mAnimationCallbacks, DEFAULT_DISPLAY)); diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java index db105ddc956d..afe18c332b9d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java @@ -31,6 +31,7 @@ import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for RootWindowContainer. @@ -40,6 +41,7 @@ import org.junit.Test; */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class RootWindowContainerTests extends WindowTestsBase { private static final int FAKE_CALLING_UID = 667; @@ -91,18 +93,16 @@ public class RootWindowContainerTests extends WindowTestsBase { @Test public void testUpdateDefaultDisplayWindowingModeOnSettingsRetrieved() { - synchronized (mWm.mGlobalLock) { - assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN, - mWm.getDefaultDisplayContentLocked().getWindowingMode()); + assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN, + mWm.getDefaultDisplayContentLocked().getWindowingMode()); - mWm.mIsPc = true; - mWm.mAtmService.mSupportsFreeformWindowManagement = true; + mWm.mIsPc = true; + mWm.mAtmService.mSupportsFreeformWindowManagement = true; - mWm.mRoot.onSettingsRetrieved(); + mWm.mRoot.onSettingsRetrieved(); - assertEquals(WindowConfiguration.WINDOWING_MODE_FREEFORM, - mWm.getDefaultDisplayContentLocked().getWindowingMode()); - } + assertEquals(WindowConfiguration.WINDOWING_MODE_FREEFORM, + mWm.getDefaultDisplayContentLocked().getWindowingMode()); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java index 3e316f674dbf..8326ad8bdefe 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java @@ -35,6 +35,7 @@ import androidx.test.filters.MediumTest; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import java.util.ArrayList; @@ -44,6 +45,7 @@ import java.util.ArrayList; */ @MediumTest @Presubmit +@RunWith(WindowTestRunner.class) public class RunningTasksTest extends ActivityTestsBase { private static final ArraySet<Integer> PROFILE_IDS = new ArraySet<>(); diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java new file mode 100644 index 000000000000..d1b6f6f3f4cf --- /dev/null +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 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. + */ + +package com.android.server.wm; + +import android.os.Handler; +import android.testing.DexmakerShareClassLoaderRule; + +import org.junit.Rule; + +import java.util.concurrent.Callable; + +/** The base class which provides the common rule for test classes under wm package. */ +class SystemServiceTestsBase { + @Rule + public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule = + new DexmakerShareClassLoaderRule(); + @Rule + public final SystemServicesTestRule mSystemServicesTestRule = new SystemServicesTestRule(); + + @WindowTestRunner.MethodWrapperRule + public final WindowManagerGlobalLockRule mLockRule = + new WindowManagerGlobalLockRule(mSystemServicesTestRule); + + /** Waits until the main handler for WM has processed all messages. */ + void waitUntilHandlersIdle() { + mLockRule.waitForLocked(mSystemServicesTestRule::waitUntilWindowManagerHandlersIdle); + } + + boolean waitHandlerIdle(Handler handler) { + return waitHandlerIdle(handler, 0 /* timeout */); + } + + boolean waitHandlerIdle(Handler handler, long timeout) { + return runWithScissors(handler, () -> { }, timeout); + } + + boolean runWithScissors(Handler handler, Runnable r, long timeout) { + return mLockRule.runWithScissors(handler, r, timeout); + } + + /** It is used when we want to wait for a result inside {@link WindowManagerGlobalLock}. */ + <T> T awaitInWmLock(Callable<T> callable) { + return mLockRule.waitForLocked(callable); + } +} diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java index 5a4d3991bedd..ef9821b92201 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java @@ -18,7 +18,6 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; -import static android.os.Process.THREAD_PRIORITY_DEFAULT; import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader; import static android.view.Display.DEFAULT_DISPLAY; @@ -36,7 +35,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSess import static com.android.dx.mockito.inline.extended.ExtendedMockito.nullable; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; -import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.app.ActivityManagerInternal; import android.app.AppOpsManager; @@ -68,11 +66,12 @@ import com.android.server.AnimationThread; import com.android.server.DisplayThread; import com.android.server.LocalServices; import com.android.server.LockGuard; -import com.android.server.ServiceThread; +import com.android.server.UiThread; import com.android.server.Watchdog; import com.android.server.am.ActivityManagerService; import com.android.server.appop.AppOpsService; import com.android.server.display.color.ColorDisplayService; +import com.android.server.firewall.IntentFirewall; import com.android.server.input.InputManagerService; import com.android.server.pm.UserManagerService; import com.android.server.policy.PermissionPolicyInternal; @@ -105,13 +104,13 @@ public class SystemServicesTestRule implements TestRule { private Context mContext; private StaticMockitoSession mMockitoSession; - ServiceThread mHandlerThread; private ActivityManagerService mAmService; private ActivityTaskManagerService mAtmService; private WindowManagerService mWmService; private TestWindowManagerPolicy mWMPolicy; private WindowState.PowerManagerWrapper mPowerManagerWrapper; private InputManagerService mImService; + private InputChannel mInputChannel; /** * Spied {@link SurfaceControl.Transaction} class than can be used to verify calls. */ @@ -147,10 +146,6 @@ public class SystemServicesTestRule implements TestRule { } private void setUpSystemCore() { - mHandlerThread = new ServiceThread( - "WmTestsThread", THREAD_PRIORITY_DEFAULT, true /* allowIo */); - mHandlerThread.start(); - doReturn(mock(Watchdog.class)).when(Watchdog::getInstance); mContext = getInstrumentation().getTargetContext(); @@ -181,6 +176,11 @@ public class SystemServicesTestRule implements TestRule { final AppOpsManager aom = mock(AppOpsManager.class); doReturn(aom).when(mContext).getSystemService(eq(Context.APP_OPS_SERVICE)); + // Prevent "WakeLock finalized while still held: SCREEN_FROZEN". + final PowerManager pm = mock(PowerManager.class); + doReturn(pm).when(mContext).getSystemService(eq(Context.POWER_SERVICE)); + doReturn(mock(PowerManager.WakeLock.class)).when(pm).newWakeLock(anyInt(), anyString()); + // DisplayManagerInternal final DisplayManagerInternal dmi = mock(DisplayManagerInternal.class); doReturn(dmi).when(() -> LocalServices.getService(eq(DisplayManagerInternal.class))); @@ -214,11 +214,11 @@ public class SystemServicesTestRule implements TestRule { // InputManagerService mImService = mock(InputManagerService.class); - // InputChannel is final and can't be mocked. - final InputChannel[] input = InputChannel.openInputChannelPair(TAG_WM); - if (input != null && input.length > 1) { - doReturn(input[1]).when(mImService).monitorInput(anyString(), anyInt()); - } + // InputChannel cannot be mocked because it may pass to InputEventReceiver. + final InputChannel[] inputChannels = InputChannel.openInputChannelPair(TAG); + inputChannels[0].dispose(); + mInputChannel = inputChannels[1]; + doReturn(mInputChannel).when(mImService).monitorInput(anyString(), anyInt()); // StatusBarManagerInternal final StatusBarManagerInternal sbmi = mock(StatusBarManagerInternal.class); @@ -227,8 +227,7 @@ public class SystemServicesTestRule implements TestRule { private void setUpActivityTaskManagerService() { // ActivityManagerService - mAmService = new ActivityManagerService( - new AMTestInjector(mContext, mHandlerThread), mHandlerThread); + mAmService = new ActivityManagerService(new AMTestInjector(mContext), null /* thread */); spyOn(mAmService); doReturn(mock(IPackageManager.class)).when(mAmService).getPackageManager(); doNothing().when(mAmService).grantImplicitAccess( @@ -246,6 +245,15 @@ public class SystemServicesTestRule implements TestRule { doNothing().when(amInternal).startProcess( any(), any(), anyBoolean(), anyBoolean(), any(), any()); doNothing().when(amInternal).updateOomLevelsForDisplay(anyInt()); + doNothing().when(amInternal).broadcastGlobalConfigurationChanged(anyInt(), anyBoolean()); + doNothing().when(amInternal).cleanUpServices(anyInt(), any(), any()); + doReturn(UserHandle.USER_SYSTEM).when(amInternal).getCurrentUserId(); + doReturn(TEST_USER_PROFILE_IDS).when(amInternal).getCurrentProfileIds(); + doReturn(true).when(amInternal).isCurrentProfile(anyInt()); + doReturn(true).when(amInternal).isUserRunning(anyInt(), anyInt()); + doReturn(true).when(amInternal).hasStartedUserState(anyInt()); + doReturn(false).when(amInternal).shouldConfirmCredentials(anyInt()); + doReturn(false).when(amInternal).isActivityStartsLoggingEnabled(); LocalServices.addService(ActivityManagerInternal.class, amInternal); mAtmService = new TestActivityTaskManagerService(mContext, mAmService); @@ -289,7 +297,6 @@ public class SystemServicesTestRule implements TestRule { } private void tearDown() { - waitUntilWindowManagerHandlersIdle(); // Unregister display listener from root to avoid issues with subsequent tests. mContext.getSystemService(DisplayManager.class) .unregisterDisplayListener(mAtmService.mRootActivityContainer); @@ -297,37 +304,23 @@ public class SystemServicesTestRule implements TestRule { // a static object, so we need to clean it up in tearDown(), even though we didn't set up // in tests. DeviceConfig.removeOnPropertiesChangedListener(mWmService.mPropertiesChangedListener); - mWmService = null; - mWMPolicy = null; - mPowerManagerWrapper = null; - - tearDownLocalServices(); - tearDownSystemCore(); + waitUntilWindowManagerHandlersIdle(); // Needs to explicitly dispose current static threads because there could be messages // scheduled at a later time, and all mocks are invalid when it's executed. DisplayThread.dispose(); AnimationThread.dispose(); + UiThread.dispose(); + mInputChannel.dispose(); + + tearDownLocalServices(); // Reset priority booster because animation thread has been changed. WindowManagerService.sThreadPriorityBooster = new WindowManagerThreadPriorityBooster(); + mMockitoSession.finishMocking(); Mockito.framework().clearInlineMocks(); } - private void tearDownSystemCore() { - if (mMockitoSession != null) { - mMockitoSession.finishMocking(); - mMockitoSession = null; - } - - if (mHandlerThread != null) { - // Make sure there are no running messages and then quit the thread so the next test - // won't be affected. - mHandlerThread.getThreadHandler().runWithScissors(mHandlerThread::quit, - 0 /* timeout */); - } - } - private static void tearDownLocalServices() { LocalServices.removeServiceForTest(DisplayManagerInternal.class); LocalServices.removeServiceForTest(PowerManagerInternal.class); @@ -375,7 +368,6 @@ public class SystemServicesTestRule implements TestRule { waitHandlerIdle(wm.mH); waitHandlerIdle(wm.mAnimationHandler); waitHandlerIdle(SurfaceAnimationThread.getHandler()); - waitHandlerIdle(mHandlerThread.getThreadHandler()); } private void waitHandlerIdle(Handler handler) { @@ -435,8 +427,12 @@ public class SystemServicesTestRule implements TestRule { ams.mActivityTaskManager = this; ams.mAtmInternal = mInternal; onActivityManagerInternalAdded(); - initialize( - ams.mIntentFirewall, ams.mPendingIntentController, mHandlerThread.getLooper()); + + final IntentFirewall intentFirewall = mock(IntentFirewall.class); + doReturn(true).when(intentFirewall).checkStartActivity( + any(), anyInt(), anyInt(), nullable(String.class), any()); + initialize(intentFirewall, null /* intentController */, + DisplayThread.getHandler().getLooper()); spyOn(getLifecycleManager()); spyOn(getLockTaskController()); spyOn(getTaskChangeNotificationController()); @@ -493,11 +489,9 @@ public class SystemServicesTestRule implements TestRule { // TODO: Can we just mock this? private static class AMTestInjector extends ActivityManagerService.Injector { - private ServiceThread mHandlerThread; - AMTestInjector(Context context, ServiceThread handlerThread) { + AMTestInjector(Context context) { super(context); - mHandlerThread = handlerThread; } @Override @@ -512,7 +506,7 @@ public class SystemServicesTestRule implements TestRule { @Override public Handler getUiHandler(ActivityManagerService service) { - return mHandlerThread.getThreadHandler(); + return UiThread.getHandler(); } @Override diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java index eb351b63a469..2ac5f7d94560 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java @@ -22,7 +22,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static org.junit.Assert.assertFalse; @@ -38,6 +37,7 @@ import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for the {@link TaskPositioningController} class. @@ -47,6 +47,7 @@ import org.junit.Test; */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class TaskPositioningControllerTests extends WindowTestsBase { private static final int TIMEOUT_MS = 1000; @@ -64,30 +65,23 @@ public class TaskPositioningControllerTests extends WindowTestsBase { mWindow = createWindow(null, TYPE_BASE_APPLICATION, "window"); mWindow.mInputChannel = new InputChannel(); - synchronized (mWm.mGlobalLock) { - mWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow); - spyOn(mDisplayContent); - doReturn(mock(InputMonitor.class)).when(mDisplayContent).getInputMonitor(); - } + mWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow); + doReturn(mock(InputMonitor.class)).when(mDisplayContent).getInputMonitor(); } @Test public void testStartAndFinishPositioning() { - synchronized (mWm.mGlobalLock) { - assertFalse(mTarget.isPositioningLocked()); - assertNull(mTarget.getDragWindowHandleLocked()); - } + assertFalse(mTarget.isPositioningLocked()); + assertNull(mTarget.getDragWindowHandleLocked()); assertTrue(mTarget.startMovingTask(mWindow.mClient, 0, 0)); - synchronized (mWm.mGlobalLock) { - assertTrue(mTarget.isPositioningLocked()); - assertNotNull(mTarget.getDragWindowHandleLocked()); - } + assertTrue(mTarget.isPositioningLocked()); + assertNotNull(mTarget.getDragWindowHandleLocked()); mTarget.finishTaskPositioning(); // Wait until the looper processes finishTaskPositioning. - assertTrue(mWm.mH.runWithScissors(() -> { }, TIMEOUT_MS)); + assertTrue(waitHandlerIdle(mWm.mH, TIMEOUT_MS)); assertFalse(mTarget.isPositioningLocked()); assertNull(mTarget.getDragWindowHandleLocked()); @@ -96,21 +90,17 @@ public class TaskPositioningControllerTests extends WindowTestsBase { @FlakyTest(bugId = 129507487) @Test public void testFinishPositioningWhenAppRequested() { - synchronized (mWm.mGlobalLock) { - assertFalse(mTarget.isPositioningLocked()); - assertNull(mTarget.getDragWindowHandleLocked()); - } + assertFalse(mTarget.isPositioningLocked()); + assertNull(mTarget.getDragWindowHandleLocked()); assertTrue(mTarget.startMovingTask(mWindow.mClient, 0, 0)); - synchronized (mWm.mGlobalLock) { - assertTrue(mTarget.isPositioningLocked()); - assertNotNull(mTarget.getDragWindowHandleLocked()); - } + assertTrue(mTarget.isPositioningLocked()); + assertNotNull(mTarget.getDragWindowHandleLocked()); mTarget.finishTaskPositioning(mWindow.mClient); // Wait until the looper processes finishTaskPositioning. - assertTrue(mWm.mH.runWithScissors(() -> { }, TIMEOUT_MS)); + assertTrue(waitHandlerIdle(mWm.mH, TIMEOUT_MS)); assertFalse(mTarget.isPositioningLocked()); assertNull(mTarget.getDragWindowHandleLocked()); @@ -118,10 +108,8 @@ public class TaskPositioningControllerTests extends WindowTestsBase { @Test public void testHandleTapOutsideTask() { - synchronized (mWm.mGlobalLock) { - assertFalse(mTarget.isPositioningLocked()); - assertNull(mTarget.getDragWindowHandleLocked()); - } + assertFalse(mTarget.isPositioningLocked()); + assertNull(mTarget.getDragWindowHandleLocked()); final DisplayContent content = mock(DisplayContent.class); when(content.findTaskForResizePoint(anyInt(), anyInt())).thenReturn(mWindow.getTask()); @@ -129,16 +117,14 @@ public class TaskPositioningControllerTests extends WindowTestsBase { mTarget.handleTapOutsideTask(content, 0, 0); // Wait until the looper processes finishTaskPositioning. - assertTrue(mWm.mH.runWithScissors(() -> { }, TIMEOUT_MS)); + assertTrue(waitHandlerIdle(mWm.mH, TIMEOUT_MS)); - synchronized (mWm.mGlobalLock) { - assertTrue(mTarget.isPositioningLocked()); - assertNotNull(mTarget.getDragWindowHandleLocked()); - } + assertTrue(mTarget.isPositioningLocked()); + assertNotNull(mTarget.getDragWindowHandleLocked()); mTarget.finishTaskPositioning(); // Wait until the looper processes finishTaskPositioning. - assertTrue(mWm.mH.runWithScissors(() -> { }, TIMEOUT_MS)); + assertTrue(waitHandlerIdle(mWm.mH, TIMEOUT_MS)); assertFalse(mTarget.isPositioningLocked()); assertNull(mTarget.getDragWindowHandleLocked()); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java index c83401b2eb65..d3588a269bbc 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java @@ -51,7 +51,6 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import android.app.ActivityManager; @@ -78,6 +77,7 @@ import com.android.server.wm.utils.WmDisplayCutout; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mockito; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -98,6 +98,7 @@ import java.util.ArrayList; */ @MediumTest @Presubmit +@RunWith(WindowTestRunner.class) public class TaskRecordTests extends ActivityTestsBase { private static final String TASK_TAG = "task"; diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java index 74ccccca43bb..5a0f7ed89cd0 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java @@ -32,15 +32,17 @@ import androidx.test.filters.SmallTest; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for the {@link DisplayContent.TaskStackContainers} container in {@link DisplayContent}. * * Build/Install/Run: - * atest FrameworksServicesTests:TaskStackContainersTests + * atest WmTests:TaskStackContainersTests */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class TaskStackContainersTests extends WindowTestsBase { private TaskStack mPinnedStack; diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java index 70ed62a4a11e..87713cb0181c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java @@ -34,15 +34,17 @@ import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for the {@link TaskStack} class. * * Build/Install/Run: - * atest FrameworksServicesTests:TaskStackTests + * atest WmTests:TaskStackTests */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class TaskStackTests extends WindowTestsBase { @Test @@ -149,7 +151,6 @@ public class TaskStackTests extends WindowTestsBase { // After removing, the task will be isolated. assertNull(task.getParent()); assertEquals(0, task.getChildCount()); - assertNull(task.getController()); } @Test @@ -176,13 +177,8 @@ public class TaskStackTests extends WindowTestsBase { public void testStackOutset() { final TaskStack stack = createTaskStackOnDisplay(mDisplayContent); final int stackOutset = 10; - // Clear the handler and hold the lock for mock, to prevent multi-thread issue. - waitUntilHandlersIdle(); - synchronized (mWm.mGlobalLock) { - spyOn(stack); - - doReturn(stackOutset).when(stack).getStackOutset(); - } + spyOn(stack); + doReturn(stackOutset).when(stack).getStackOutset(); final Rect stackBounds = new Rect(200, 200, 800, 1000); // Update surface position and size by the given bounds. diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java index 41842010d3a3..16fdf94cabbd 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java @@ -29,15 +29,17 @@ import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; import org.junit.Test; +import org.junit.runner.RunWith; /** * Test class for {@link Task}. * * Build/Install/Run: - * atest FrameworksServicesTests:TaskTests + * atest WmTests:TaskTests */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class TaskTests extends WindowTestsBase { @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java index a91daf0c7647..2e86178f4a10 100644 --- a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java @@ -24,15 +24,17 @@ import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; /** * Test class for {@link AppTransition}. * * Build/Install/Run: - * atest FrameworksServicesTests:UnknownAppVisibilityControllerTest + * atest WmTests:UnknownAppVisibilityControllerTest */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class UnknownAppVisibilityControllerTest extends WindowTestsBase { @Before @@ -48,7 +50,7 @@ public class UnknownAppVisibilityControllerTest extends WindowTestsBase { mDisplayContent.mUnknownAppVisibilityController.notifyRelayouted(token); // Make sure our handler processed the message. - mWm.mH.runWithScissors(() -> { }, 0); + waitHandlerIdle(mWm.mH); assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved()); } @@ -64,7 +66,7 @@ public class UnknownAppVisibilityControllerTest extends WindowTestsBase { mDisplayContent.mUnknownAppVisibilityController.notifyRelayouted(token2); // Make sure our handler processed the message. - mWm.mH.runWithScissors(() -> { }, 0); + waitHandlerIdle(mWm.mH); assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved()); } diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java index 6249bde3cea6..14d8a9ddab67 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java @@ -30,6 +30,7 @@ import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for the {@link WallpaperController} class. @@ -39,37 +40,36 @@ import org.junit.Test; */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class WallpaperControllerTests extends WindowTestsBase { @Test public void testWallpaperScreenshot() { WindowSurfaceController windowSurfaceController = mock(WindowSurfaceController.class); - synchronized (mWm.mGlobalLock) { - // No wallpaper - final DisplayContent dc = createNewDisplay(); - assertFalse(dc.mWallpaperController.canScreenshotWallpaper()); + // No wallpaper + final DisplayContent dc = createNewDisplay(); + assertFalse(dc.mWallpaperController.canScreenshotWallpaper()); - // No wallpaper WSA Surface - WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class), - true, dc, true /* ownerCanManageAppTokens */); - WindowState wallpaperWindow = createWindow(null /* parent */, TYPE_WALLPAPER, - wallpaperWindowToken, "wallpaperWindow"); - assertFalse(dc.mWallpaperController.canScreenshotWallpaper()); + // No wallpaper WSA Surface + WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class), + true, dc, true /* ownerCanManageAppTokens */); + WindowState wallpaperWindow = createWindow(null /* parent */, TYPE_WALLPAPER, + wallpaperWindowToken, "wallpaperWindow"); + assertFalse(dc.mWallpaperController.canScreenshotWallpaper()); - // Wallpaper with not visible WSA surface. - wallpaperWindow.mWinAnimator.mSurfaceController = windowSurfaceController; - wallpaperWindow.mWinAnimator.mLastAlpha = 1; - assertFalse(dc.mWallpaperController.canScreenshotWallpaper()); + // Wallpaper with not visible WSA surface. + wallpaperWindow.mWinAnimator.mSurfaceController = windowSurfaceController; + wallpaperWindow.mWinAnimator.mLastAlpha = 1; + assertFalse(dc.mWallpaperController.canScreenshotWallpaper()); - when(windowSurfaceController.getShown()).thenReturn(true); + when(windowSurfaceController.getShown()).thenReturn(true); - // Wallpaper with WSA alpha set to 0. - wallpaperWindow.mWinAnimator.mLastAlpha = 0; - assertFalse(dc.mWallpaperController.canScreenshotWallpaper()); + // Wallpaper with WSA alpha set to 0. + wallpaperWindow.mWinAnimator.mLastAlpha = 0; + assertFalse(dc.mWallpaperController.canScreenshotWallpaper()); - // Wallpaper window with WSA Surface - wallpaperWindow.mWinAnimator.mLastAlpha = 1; - assertTrue(dc.mWallpaperController.canScreenshotWallpaper()); - } + // Wallpaper window with WSA Surface + wallpaperWindow.mWinAnimator.mLastAlpha = 1; + assertTrue(dc.mWallpaperController.canScreenshotWallpaper()); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java deleted file mode 100644 index fc7863524240..000000000000 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2016 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.server.wm; - -import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; -import static android.content.res.Configuration.EMPTY; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import android.content.res.Configuration; -import android.platform.test.annotations.Presubmit; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; - -/** - * Test class for {@link WindowContainerController}. - * - * Build/Install/Run: - * atest WmTests:WindowContainerControllerTests - */ -@SmallTest -@Presubmit -public class WindowContainerControllerTests extends WindowTestsBase { - - @Test - public void testCreation() { - final WindowContainerController controller = new WindowContainerController<>(null, mWm); - final WindowContainer container = new WindowContainer(mWm); - - container.setController(controller); - assertEquals(controller, container.getController()); - assertEquals(controller.mContainer, container); - } - - @Test - public void testSetContainer() { - final WindowContainerController controller = new WindowContainerController<>(null, mWm); - final WindowContainer container = new WindowContainer(mWm); - - controller.setContainer(container); - assertEquals(controller.mContainer, container); - - // Assert we can't change the container to another one once set - boolean gotException = false; - try { - controller.setContainer(new WindowContainer(mWm)); - } catch (IllegalArgumentException e) { - gotException = true; - } - assertTrue(gotException); - - // Assert that we can set the container to null. - controller.setContainer(null); - assertNull(controller.mContainer); - } - - @Test - public void testRemoveContainer() { - final WindowContainerController controller = new WindowContainerController<>(null, mWm); - final WindowContainer container = new WindowContainer(mWm); - - controller.setContainer(container); - assertEquals(controller.mContainer, container); - - controller.removeContainer(); - assertNull(controller.mContainer); - } - - @Test - public void testOnOverrideConfigurationChanged() { - final WindowContainerController controller = new WindowContainerController<>(null, mWm); - final WindowContainer container = new WindowContainer(mWm); - - controller.setContainer(container); - assertEquals(controller.mContainer, container); - assertEquals(EMPTY, container.getRequestedOverrideConfiguration()); - - final Configuration config = new Configuration(); - config.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM); - config.windowConfiguration.setAppBounds(10, 10, 10, 10); - - // Assert that the config change through the controller is propagated to the container. - controller.onRequestedOverrideConfigurationChanged(config); - assertEquals(config, container.getRequestedOverrideConfiguration()); - - // Assert the container configuration isn't changed after removal from the controller. - controller.removeContainer(); - controller.onRequestedOverrideConfigurationChanged(EMPTY); - assertEquals(config, container.getRequestedOverrideConfiguration()); - } -} diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java index 921f105d1d25..8117ff601a8f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java @@ -216,44 +216,6 @@ public class WindowContainerTests extends WindowTestsBase { } @Test - public void testRemoveImmediately_WithController() { - final WindowContainer container = new WindowContainer(mWm); - final WindowContainerController controller = new WindowContainerController<>(null, mWm); - - container.setController(controller); - assertEquals(controller, container.getController()); - assertEquals(container, controller.mContainer); - - container.removeImmediately(); - assertNull(container.getController()); - assertNull(controller.mContainer); - } - - @Test - public void testSetController() { - final WindowContainerController controller = new WindowContainerController<>(null, mWm); - final WindowContainer container = new WindowContainer(mWm); - - container.setController(controller); - assertEquals(controller, container.getController()); - assertEquals(container, controller.mContainer); - - // Assert we can't change the controller to another one once set - boolean gotException = false; - try { - container.setController(new WindowContainerController<>(null, mWm)); - } catch (IllegalArgumentException e) { - gotException = true; - } - assertTrue(gotException); - - // Assert that we can set the controller to null. - container.setController(null); - assertNull(container.getController()); - assertNull(controller.mContainer); - } - - @Test public void testAddChildByIndex() { final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm); final TestWindowContainer root = builder.setLayer(0).build(); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java index 60cefe858c54..3563febb46f8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java @@ -43,16 +43,18 @@ import com.android.server.wm.utils.WmDisplayCutout; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mockito; /** * Tests for the {@link WindowState#computeFrameLw} method and other window frame machinery. * * Build/Install/Run: - * atest FrameworksServicesTests:WindowFrameTests + * atest WmTests:WindowFrameTests */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class WindowFrameTests extends WindowTestsBase { private final IWindow mIWindow = new TestIWindow(); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerGlobalLockRule.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerGlobalLockRule.java index e0c314fd572e..c5f13e05843b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerGlobalLockRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerGlobalLockRule.java @@ -27,6 +27,9 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -59,34 +62,41 @@ class WindowManagerGlobalLockRule implements WindowTestRunner.MethodWrapper { return base; } - void waitUntilHandlersIdle() { - if (!mIsLocked) { - mSystemServicesTestRule.waitUntilWindowManagerHandlersIdle(); - return; - } - - waitForLocked(mSystemServicesTestRule::waitUntilWindowManagerHandlersIdle); + boolean runWithScissors(Handler handler, Runnable r, long timeout) { + return waitForLocked(() -> handler.runWithScissors(r, timeout)); } - void runWithScissors(Handler handler, Runnable r, long timeout) { - if (!mIsLocked) { - handler.runWithScissors(r, timeout); - return; - } - - waitForLocked(() -> handler.runWithScissors(r, timeout)); + void waitForLocked(Runnable r) { + waitForLocked(() -> { + r.run(); + return null; + }); } /** * If the test holds the lock, we need to invoke {@link Object#wait} to release it so other * threads won't be blocked when we are waiting. */ - private void waitForLocked(Runnable r) { + <T> T waitForLocked(Callable<T> callable) { + if (!mIsLocked) { + try { + return callable.call(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + final Object lock = mSystemServicesTestRule.getWindowManagerService().mGlobalLock; final AtomicBoolean done = new AtomicBoolean(false); + final List<T> result = Arrays.asList((T) null); + final Exception[] exception = { null }; AsyncTask.SERIAL_EXECUTOR.execute(() -> { - r.run(); + try { + result.set(0, callable.call()); + } catch (Exception e) { + exception[0] = e; + } synchronized (lock) { lock.notifyAll(); done.set(true); @@ -101,6 +111,11 @@ class WindowManagerGlobalLockRule implements WindowTestRunner.MethodWrapper { } } } + if (exception[0] != null) { + throw new RuntimeException(exception[0]); + } + + return result.get(0); } /** Wraps methods annotated with {@link org.junit.Test}. */ diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java index 8c56ffaa6314..cc90ca1e2556 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java @@ -26,13 +26,13 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; import android.content.pm.ApplicationInfo; import android.platform.test.annotations.Presubmit; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mockito; @@ -43,6 +43,7 @@ import org.mockito.Mockito; * atest WmTests:WindowProcessControllerTests */ @Presubmit +@RunWith(WindowTestRunner.class) public class WindowProcessControllerTests extends ActivityTestsBase { WindowProcessController mWpc; @@ -97,7 +98,7 @@ public class WindowProcessControllerTests extends ActivityTestsBase { public void testSetRunningRecentsAnimation() { mWpc.setRunningRecentsAnimation(true); mWpc.setRunningRecentsAnimation(false); - mService.mH.runWithScissors(() -> {}, 0); + waitHandlerIdle(mService.mH); InOrder orderVerifier = Mockito.inOrder(mMockListener); orderVerifier.verify(mMockListener).setRunningRemoteAnimation(eq(true)); @@ -108,7 +109,7 @@ public class WindowProcessControllerTests extends ActivityTestsBase { public void testSetRunningRemoteAnimation() { mWpc.setRunningRemoteAnimation(true); mWpc.setRunningRemoteAnimation(false); - mService.mH.runWithScissors(() -> {}, 0); + waitHandlerIdle(mService.mH); InOrder orderVerifier = Mockito.inOrder(mMockListener); orderVerifier.verify(mMockListener).setRunningRemoteAnimation(eq(true)); @@ -122,7 +123,7 @@ public class WindowProcessControllerTests extends ActivityTestsBase { mWpc.setRunningRecentsAnimation(false); mWpc.setRunningRemoteAnimation(false); - mService.mH.runWithScissors(() -> {}, 0); + waitHandlerIdle(mService.mH); InOrder orderVerifier = Mockito.inOrder(mMockListener); orderVerifier.verify(mMockListener, times(3)).setRunningRemoteAnimation(eq(true)); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index f41f126593de..0503d74b38d5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -57,6 +57,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; import android.graphics.Insets; import android.graphics.Matrix; @@ -547,4 +548,29 @@ public class WindowStateTests extends WindowTestsBase { assertEquals(OFFSET_SUM, values[Matrix.MTRANS_X], 0f); assertEquals(0f, values[Matrix.MTRANS_Y], 0f); } + + @Test + public void testCantReceiveTouchDuringRecentsAnimation() { + final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0"); + + // Mock active recents animation + RecentsAnimationController recentsController = mock(RecentsAnimationController.class); + when(recentsController.isAnimatingTask(win0.mAppToken.getTask())).thenReturn(true); + mWm.setRecentsAnimationController(recentsController); + assertTrue(win0.cantReceiveTouchInput()); + } + + @Test + public void testCantReceiveTouchWhenAppTokenHiddenRequested() { + final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0"); + win0.mAppToken.hiddenRequested = true; + assertTrue(win0.cantReceiveTouchInput()); + } + + @Test + public void testCantReceiveTouchWhenShouldIgnoreInput() { + final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0"); + win0.mAppToken.getStack().setAdjustedForMinimizedDock(1 /* Any non 0 value works */); + assertTrue(win0.cantReceiveTouchInput()); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 8930e5ac42f8..c574b0fd33b2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -42,7 +42,6 @@ import static org.mockito.Mockito.mock; import android.content.Context; import android.content.res.Configuration; -import android.testing.DexmakerShareClassLoaderRule; import android.util.Log; import android.view.Display; import android.view.DisplayInfo; @@ -55,7 +54,6 @@ import com.android.server.AttributeCache; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Rule; import java.util.HashSet; import java.util.LinkedList; @@ -65,7 +63,7 @@ import java.util.LinkedList; * * Make sure any requests to WM hold the WM lock if needed b/73966377 */ -class WindowTestsBase { +class WindowTestsBase extends SystemServiceTestsBase { private static final String TAG = WindowTestsBase.class.getSimpleName(); WindowManagerService mWm; @@ -92,16 +90,6 @@ class WindowTestsBase { */ Transaction mTransaction; - @Rule - public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule = - new DexmakerShareClassLoaderRule(); - @Rule - public final SystemServicesTestRule mSystemServicesTestRule = new SystemServicesTestRule(); - - @WindowTestRunner.MethodWrapperRule - public final WindowManagerGlobalLockRule mLockRule = - new WindowManagerGlobalLockRule(mSystemServicesTestRule); - @BeforeClass public static void setUpOnceBase() { AttributeCache.init(getInstrumentation().getTargetContext()); @@ -205,13 +193,6 @@ class WindowTestsBase { } } - /** - * Waits until the main handler for WM has processed all messages. - */ - void waitUntilHandlersIdle() { - mLockRule.waitUntilHandlersIdle(); - } - private WindowToken createWindowToken( DisplayContent dc, int windowingMode, int activityType, int type) { synchronized (mWm.mGlobalLock) { diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java index 2105ab003e0e..63b50b5a9b2b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java @@ -47,6 +47,7 @@ import androidx.test.filters.SmallTest; import org.junit.After; import org.junit.Test; +import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.HashMap; @@ -61,6 +62,7 @@ import java.util.function.Function; */ @SmallTest @Presubmit +@RunWith(WindowTestRunner.class) public class ZOrderingTests extends WindowTestsBase { private static class LayerRecordingTransaction extends SurfaceControl.Transaction { diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index e3183e3a8344..59d07357ff56 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -977,7 +977,9 @@ public class UsageStatsService extends SystemService implements continue; } UserUsageStatsService service = mUserState.get(userId); - service.persistActiveStats(); + if (service != null) { + service.persistActiveStats(); + } mAppStandby.flushToDisk(userId); } mAppStandby.flushDurationsToDisk(); diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index 1822cee89eaa..5e71416a0510 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -19,6 +19,7 @@ package android.telecom; import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.net.Uri; import android.os.Build; @@ -119,6 +120,20 @@ public final class Call { public static final int STATE_PULLING_CALL = 11; /** + * The state of a call that is active with the network, but the audio from the call is + * being intercepted by an app on the local device. Telecom does not hold audio focus in this + * state, and the call will be invisible to the user except for a persistent notification. + */ + public static final int STATE_AUDIO_PROCESSING = 12; + + /** + * The state of a call that is being presented to the user after being in + * {@link #STATE_AUDIO_PROCESSING}. The call is still active with the network in this case, and + * Telecom will hold audio focus and play a ringtone if appropriate. + */ + public static final int STATE_SIMULATED_RINGING = 13; + + /** * The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call * extras. Used to pass the phone accounts to display on the front end to the user in order to * select phone accounts to (for example) place a call. @@ -1479,6 +1494,49 @@ public final class Call { } /** + * Instructs Telecom to put the call into the background audio processing state. + * + * This method can be called either when the call is in {@link #STATE_RINGING} or + * {@link #STATE_ACTIVE}. After Telecom acknowledges the request by setting the call's state to + * {@link #STATE_AUDIO_PROCESSING}, your app may setup the audio paths with the audio stack in + * order to capture and play audio on the call stream. + * + * This method can only be called by the default dialer app. + * @hide + */ + @SystemApi + @TestApi + //@RequiresPermission(android.Manifest.permission.BACKGROUND_CALL_AUDIO) + public void enterBackgroundAudioProcessing() { + if (mState != STATE_ACTIVE && mState != STATE_RINGING) { + throw new IllegalStateException("Call must be active or ringing"); + } + mInCallAdapter.enterBackgroundAudioProcessing(mTelecomCallId); + } + + /** + * Instructs Telecom to come out of the background audio processing state requested by + * {@link #enterBackgroundAudioProcessing()} or from the call screening service. + * + * This method can only be called when the call is in {@link #STATE_AUDIO_PROCESSING}. + * + * @param shouldRing If true, Telecom will put the call into the + * {@link #STATE_SIMULATED_RINGING} state and notify other apps that there is + * a ringing call. Otherwise, the call will go into {@link #STATE_ACTIVE} + * immediately. + * @hide + */ + @SystemApi + @TestApi + //@RequiresPermission(android.Manifest.permission.BACKGROUND_CALL_AUDIO) + public void exitBackgroundAudioProcessing(boolean shouldRing) { + if (mState != STATE_AUDIO_PROCESSING) { + throw new IllegalStateException("Call must in the audio processing state"); + } + mInCallAdapter.exitBackgroundAudioProcessing(mTelecomCallId, shouldRing); + } + + /** * Instructs this {@code Call} to play a dual-tone multi-frequency signaling (DTMF) tone. * * Any other currently playing DTMF tone in the specified call is immediately stopped. diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java index e4f8d118e7df..0d97567ed213 100644 --- a/telecomm/java/android/telecom/CallScreeningService.java +++ b/telecomm/java/android/telecom/CallScreeningService.java @@ -18,6 +18,8 @@ package android.telecom; import android.annotation.NonNull; import android.annotation.SdkConstant; +import android.annotation.SystemApi; +import android.annotation.TestApi; import android.app.Service; import android.content.ComponentName; import android.content.Intent; @@ -136,23 +138,30 @@ public abstract class CallScreeningService extends Service { private final boolean mShouldSilenceCall; private final boolean mShouldSkipCallLog; private final boolean mShouldSkipNotification; + private final boolean mShouldScreenCallFurther; private CallResponse( boolean shouldDisallowCall, boolean shouldRejectCall, boolean shouldSilenceCall, boolean shouldSkipCallLog, - boolean shouldSkipNotification) { + boolean shouldSkipNotification, + boolean shouldScreenCallFurther) { if (!shouldDisallowCall && (shouldRejectCall || shouldSkipCallLog || shouldSkipNotification)) { throw new IllegalStateException("Invalid response state for allowed call."); } + if (shouldDisallowCall && shouldScreenCallFurther) { + throw new IllegalStateException("Invalid response state for allowed call."); + } + mShouldDisallowCall = shouldDisallowCall; mShouldRejectCall = shouldRejectCall; mShouldSkipCallLog = shouldSkipCallLog; mShouldSkipNotification = shouldSkipNotification; mShouldSilenceCall = shouldSilenceCall; + mShouldScreenCallFurther = shouldScreenCallFurther; } /* @@ -191,12 +200,22 @@ public abstract class CallScreeningService extends Service { return mShouldSkipNotification; } + /** + * @return Whether we should enter the {@link Call#STATE_AUDIO_PROCESSING} state to allow + * for further screening of the call. + * @hide + */ + public boolean getShouldScreenCallFurther() { + return mShouldScreenCallFurther; + } + public static class Builder { private boolean mShouldDisallowCall; private boolean mShouldRejectCall; private boolean mShouldSilenceCall; private boolean mShouldSkipCallLog; private boolean mShouldSkipNotification; + private boolean mShouldScreenCallFurther; /** * Sets whether the incoming call should be blocked. @@ -252,13 +271,32 @@ public abstract class CallScreeningService extends Service { return this; } + /** + * Sets whether to request background audio processing so that the in-call service can + * screen the call further. If set to {@code true}, {@link #setDisallowCall} should be + * called with {@code false}, and all other parameters in this builder will be ignored. + * + * This request will only be honored if the {@link CallScreeningService} shares the same + * uid as the default dialer app. Otherwise, the call will go through as usual. + * + * @param shouldScreenCallFurther Whether to request further call screening. + * @hide + */ + @SystemApi + @TestApi + public Builder setShouldScreenCallFurther(boolean shouldScreenCallFurther) { + mShouldScreenCallFurther = shouldScreenCallFurther; + return this; + } + public CallResponse build() { return new CallResponse( mShouldDisallowCall, mShouldRejectCall, mShouldSilenceCall, mShouldSkipCallLog, - mShouldSkipNotification); + mShouldSkipNotification, + mShouldScreenCallFurther); } } } diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java index 8678e33f68b6..261246818f1d 100644 --- a/telecomm/java/android/telecom/InCallAdapter.java +++ b/telecomm/java/android/telecom/InCallAdapter.java @@ -16,8 +16,8 @@ package android.telecom; -import android.net.Uri; import android.bluetooth.BluetoothDevice; +import android.net.Uri; import android.os.Bundle; import android.os.RemoteException; @@ -149,6 +149,26 @@ public final class InCallAdapter { } /** + * @see Call#enterBackgroundAudioProcessing() + */ + public void enterBackgroundAudioProcessing(String callId) { + try { + mAdapter.enterBackgroundAudioProcessing(callId); + } catch (RemoteException e) { + } + } + + /** + * @see Call#exitBackgroundAudioProcessing(boolean) + */ + public void exitBackgroundAudioProcessing(String callId, boolean shouldRing) { + try { + mAdapter.exitBackgroundAudioProcessing(callId, shouldRing); + } catch (RemoteException e) { + } + } + + /** * Request audio routing to a specific bluetooth device. Calling this method may result in * the device routing audio to a different bluetooth device than the one specified. A list of * available devices can be obtained via {@link CallAudioState#getSupportedBluetoothDevices()} diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 64092034e0b2..2bc20d51113a 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -33,6 +33,7 @@ import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; +import android.telephony.Annotation.CallState; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; @@ -1412,7 +1413,7 @@ public class TelecomManager { * @hide */ @SystemApi - public @TelephonyManager.CallState int getCallState() { + public @CallState int getCallState() { try { if (isServiceConnected()) { return getTelecomService().getCallState(); @@ -2059,12 +2060,13 @@ public class TelecomManager { /** * Handles {@link Intent#ACTION_CALL} intents trampolined from UserCallActivity. * @param intent The {@link Intent#ACTION_CALL} intent to handle. + * @param callingPackageProxy The original package that called this before it was trampolined. * @hide */ - public void handleCallIntent(Intent intent) { + public void handleCallIntent(Intent intent, String callingPackageProxy) { try { if (isServiceConnected()) { - getTelecomService().handleCallIntent(intent); + getTelecomService().handleCallIntent(intent, callingPackageProxy); } } catch (RemoteException e) { Log.e(TAG, "RemoteException handleCallIntent: " + e); diff --git a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl index 3ee3285793c4..83c8f62bb3db 100644 --- a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl +++ b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl @@ -30,6 +30,8 @@ oneway interface ICallScreeningAdapter { void silenceCall(String callId); + void screenCallFurther(String callId); + void disallowCall( String callId, boolean shouldReject, diff --git a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl index 57df5c1e548e..60745e40aa77 100644 --- a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl +++ b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl @@ -44,6 +44,10 @@ oneway interface IInCallAdapter { void setAudioRoute(int route, String bluetoothAddress); + void enterBackgroundAudioProcessing(String callId); + + void exitBackgroundAudioProcessing(String callId, boolean shouldRing); + void playDtmfTone(String callId, char digit); void stopDtmfTone(String callId); diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl index 704749844c19..6a1b78fb79cf 100644 --- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl +++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl @@ -282,6 +282,11 @@ interface ITelecomService { void acceptHandover(in Uri srcAddr, int videoState, in PhoneAccountHandle destAcct); /** + * @see TelecomServiceImpl#setTestEmergencyPhoneAccountPackageNameFilter + */ + void setTestEmergencyPhoneAccountPackageNameFilter(String packageName); + + /** * @see TelecomServiceImpl#isInEmergencyCall */ boolean isInEmergencyCall(); @@ -289,7 +294,7 @@ interface ITelecomService { /** * @see TelecomServiceImpl#handleCallIntent */ - void handleCallIntent(in Intent intent); + void handleCallIntent(in Intent intent, in String callingPackageProxy); void setTestDefaultCallRedirectionApp(String packageName); @@ -302,9 +307,9 @@ interface ITelecomService { void setTestAutoModeApp(String packageName); /** - * @see TelecomServiceImpl#setSystemDialerPackage + * @see TelecomServiceImpl#setSystemDialer */ - void setSystemDialerPackage(in String packageName); + void setSystemDialer(in ComponentName testComponentName); /** * @see TelecomServiceImpl#setTestDefaultDialer diff --git a/telephony/java/com/google/android/mms/ContentType.java b/telephony/common/com/google/android/mms/ContentType.java index 12e4b7e26e1e..12e4b7e26e1e 100644 --- a/telephony/java/com/google/android/mms/ContentType.java +++ b/telephony/common/com/google/android/mms/ContentType.java diff --git a/telephony/java/com/google/android/mms/InvalidHeaderValueException.java b/telephony/common/com/google/android/mms/InvalidHeaderValueException.java index 2836c3075b3b..2836c3075b3b 100644 --- a/telephony/java/com/google/android/mms/InvalidHeaderValueException.java +++ b/telephony/common/com/google/android/mms/InvalidHeaderValueException.java diff --git a/telephony/java/com/google/android/mms/MmsException.java b/telephony/common/com/google/android/mms/MmsException.java index 5be33ed1fac9..5be33ed1fac9 100644 --- a/telephony/java/com/google/android/mms/MmsException.java +++ b/telephony/common/com/google/android/mms/MmsException.java diff --git a/telephony/java/com/google/android/mms/package.html b/telephony/common/com/google/android/mms/package.html index c9f96a66ab3b..c9f96a66ab3b 100755 --- a/telephony/java/com/google/android/mms/package.html +++ b/telephony/common/com/google/android/mms/package.html diff --git a/telephony/java/com/google/android/mms/pdu/AcknowledgeInd.java b/telephony/common/com/google/android/mms/pdu/AcknowledgeInd.java index ae447d7a7417..ae447d7a7417 100644 --- a/telephony/java/com/google/android/mms/pdu/AcknowledgeInd.java +++ b/telephony/common/com/google/android/mms/pdu/AcknowledgeInd.java diff --git a/telephony/java/com/google/android/mms/pdu/Base64.java b/telephony/common/com/google/android/mms/pdu/Base64.java index 483fa7f9842e..483fa7f9842e 100644 --- a/telephony/java/com/google/android/mms/pdu/Base64.java +++ b/telephony/common/com/google/android/mms/pdu/Base64.java diff --git a/telephony/java/com/google/android/mms/pdu/CharacterSets.java b/telephony/common/com/google/android/mms/pdu/CharacterSets.java index 27da35e2d928..27da35e2d928 100644 --- a/telephony/java/com/google/android/mms/pdu/CharacterSets.java +++ b/telephony/common/com/google/android/mms/pdu/CharacterSets.java diff --git a/telephony/java/com/google/android/mms/pdu/DeliveryInd.java b/telephony/common/com/google/android/mms/pdu/DeliveryInd.java index 7093ac63338c..7093ac63338c 100644 --- a/telephony/java/com/google/android/mms/pdu/DeliveryInd.java +++ b/telephony/common/com/google/android/mms/pdu/DeliveryInd.java diff --git a/telephony/java/com/google/android/mms/pdu/EncodedStringValue.java b/telephony/common/com/google/android/mms/pdu/EncodedStringValue.java index 41662750842f..41662750842f 100644 --- a/telephony/java/com/google/android/mms/pdu/EncodedStringValue.java +++ b/telephony/common/com/google/android/mms/pdu/EncodedStringValue.java diff --git a/telephony/java/com/google/android/mms/pdu/GenericPdu.java b/telephony/common/com/google/android/mms/pdu/GenericPdu.java index ebf16ac7e632..ebf16ac7e632 100644 --- a/telephony/java/com/google/android/mms/pdu/GenericPdu.java +++ b/telephony/common/com/google/android/mms/pdu/GenericPdu.java diff --git a/telephony/java/com/google/android/mms/pdu/MultimediaMessagePdu.java b/telephony/common/com/google/android/mms/pdu/MultimediaMessagePdu.java index e108f7600baf..e108f7600baf 100644 --- a/telephony/java/com/google/android/mms/pdu/MultimediaMessagePdu.java +++ b/telephony/common/com/google/android/mms/pdu/MultimediaMessagePdu.java diff --git a/telephony/java/com/google/android/mms/pdu/NotificationInd.java b/telephony/common/com/google/android/mms/pdu/NotificationInd.java index b561bd4ab3a7..b561bd4ab3a7 100644 --- a/telephony/java/com/google/android/mms/pdu/NotificationInd.java +++ b/telephony/common/com/google/android/mms/pdu/NotificationInd.java diff --git a/telephony/java/com/google/android/mms/pdu/NotifyRespInd.java b/telephony/common/com/google/android/mms/pdu/NotifyRespInd.java index 3c70f86a0890..3c70f86a0890 100644 --- a/telephony/java/com/google/android/mms/pdu/NotifyRespInd.java +++ b/telephony/common/com/google/android/mms/pdu/NotifyRespInd.java diff --git a/telephony/java/com/google/android/mms/pdu/PduBody.java b/telephony/common/com/google/android/mms/pdu/PduBody.java index 51914e4110b0..51914e4110b0 100644 --- a/telephony/java/com/google/android/mms/pdu/PduBody.java +++ b/telephony/common/com/google/android/mms/pdu/PduBody.java diff --git a/telephony/java/com/google/android/mms/pdu/PduComposer.java b/telephony/common/com/google/android/mms/pdu/PduComposer.java index e24bf21a11b5..e24bf21a11b5 100644 --- a/telephony/java/com/google/android/mms/pdu/PduComposer.java +++ b/telephony/common/com/google/android/mms/pdu/PduComposer.java diff --git a/telephony/java/com/google/android/mms/pdu/PduContentTypes.java b/telephony/common/com/google/android/mms/pdu/PduContentTypes.java index 8551b2f9b693..8551b2f9b693 100644 --- a/telephony/java/com/google/android/mms/pdu/PduContentTypes.java +++ b/telephony/common/com/google/android/mms/pdu/PduContentTypes.java diff --git a/telephony/java/com/google/android/mms/pdu/PduHeaders.java b/telephony/common/com/google/android/mms/pdu/PduHeaders.java index b5244645fda1..b5244645fda1 100644 --- a/telephony/java/com/google/android/mms/pdu/PduHeaders.java +++ b/telephony/common/com/google/android/mms/pdu/PduHeaders.java diff --git a/telephony/java/com/google/android/mms/pdu/PduParser.java b/telephony/common/com/google/android/mms/pdu/PduParser.java index f48399410723..f48399410723 100755 --- a/telephony/java/com/google/android/mms/pdu/PduParser.java +++ b/telephony/common/com/google/android/mms/pdu/PduParser.java diff --git a/telephony/java/com/google/android/mms/pdu/PduPart.java b/telephony/common/com/google/android/mms/pdu/PduPart.java index 09b775118dc3..09b775118dc3 100644 --- a/telephony/java/com/google/android/mms/pdu/PduPart.java +++ b/telephony/common/com/google/android/mms/pdu/PduPart.java diff --git a/telephony/java/com/google/android/mms/pdu/PduPersister.java b/telephony/common/com/google/android/mms/pdu/PduPersister.java index 93f30657bf1b..93f30657bf1b 100755 --- a/telephony/java/com/google/android/mms/pdu/PduPersister.java +++ b/telephony/common/com/google/android/mms/pdu/PduPersister.java diff --git a/telephony/java/com/google/android/mms/pdu/QuotedPrintable.java b/telephony/common/com/google/android/mms/pdu/QuotedPrintable.java index 9d6535c72e90..9d6535c72e90 100644 --- a/telephony/java/com/google/android/mms/pdu/QuotedPrintable.java +++ b/telephony/common/com/google/android/mms/pdu/QuotedPrintable.java diff --git a/telephony/java/com/google/android/mms/pdu/ReadOrigInd.java b/telephony/common/com/google/android/mms/pdu/ReadOrigInd.java index e38c62dde622..e38c62dde622 100644 --- a/telephony/java/com/google/android/mms/pdu/ReadOrigInd.java +++ b/telephony/common/com/google/android/mms/pdu/ReadOrigInd.java diff --git a/telephony/java/com/google/android/mms/pdu/ReadRecInd.java b/telephony/common/com/google/android/mms/pdu/ReadRecInd.java index 9696bc259d00..9696bc259d00 100644 --- a/telephony/java/com/google/android/mms/pdu/ReadRecInd.java +++ b/telephony/common/com/google/android/mms/pdu/ReadRecInd.java diff --git a/telephony/java/com/google/android/mms/pdu/RetrieveConf.java b/telephony/common/com/google/android/mms/pdu/RetrieveConf.java index 03755af4189c..03755af4189c 100644 --- a/telephony/java/com/google/android/mms/pdu/RetrieveConf.java +++ b/telephony/common/com/google/android/mms/pdu/RetrieveConf.java diff --git a/telephony/java/com/google/android/mms/pdu/SendConf.java b/telephony/common/com/google/android/mms/pdu/SendConf.java index b85982791ada..b85982791ada 100644 --- a/telephony/java/com/google/android/mms/pdu/SendConf.java +++ b/telephony/common/com/google/android/mms/pdu/SendConf.java diff --git a/telephony/java/com/google/android/mms/pdu/SendReq.java b/telephony/common/com/google/android/mms/pdu/SendReq.java index c1b7f934c0f7..c1b7f934c0f7 100644 --- a/telephony/java/com/google/android/mms/pdu/SendReq.java +++ b/telephony/common/com/google/android/mms/pdu/SendReq.java diff --git a/telephony/java/com/google/android/mms/pdu/package.html b/telephony/common/com/google/android/mms/pdu/package.html index c9f96a66ab3b..c9f96a66ab3b 100755 --- a/telephony/java/com/google/android/mms/pdu/package.html +++ b/telephony/common/com/google/android/mms/pdu/package.html diff --git a/telephony/java/com/google/android/mms/util/AbstractCache.java b/telephony/common/com/google/android/mms/util/AbstractCache.java index ab5d48a4ce3d..ab5d48a4ce3d 100644 --- a/telephony/java/com/google/android/mms/util/AbstractCache.java +++ b/telephony/common/com/google/android/mms/util/AbstractCache.java diff --git a/telephony/java/com/google/android/mms/util/DownloadDrmHelper.java b/telephony/common/com/google/android/mms/util/DownloadDrmHelper.java index 118de465a518..118de465a518 100644 --- a/telephony/java/com/google/android/mms/util/DownloadDrmHelper.java +++ b/telephony/common/com/google/android/mms/util/DownloadDrmHelper.java diff --git a/telephony/java/com/google/android/mms/util/DrmConvertSession.java b/telephony/common/com/google/android/mms/util/DrmConvertSession.java index 0e8ec91f4ef6..0e8ec91f4ef6 100644 --- a/telephony/java/com/google/android/mms/util/DrmConvertSession.java +++ b/telephony/common/com/google/android/mms/util/DrmConvertSession.java diff --git a/telephony/java/com/google/android/mms/util/PduCache.java b/telephony/common/com/google/android/mms/util/PduCache.java index 94e38946f632..94e38946f632 100644 --- a/telephony/java/com/google/android/mms/util/PduCache.java +++ b/telephony/common/com/google/android/mms/util/PduCache.java diff --git a/telephony/java/com/google/android/mms/util/PduCacheEntry.java b/telephony/common/com/google/android/mms/util/PduCacheEntry.java index 1ecd1bf93e7f..1ecd1bf93e7f 100644 --- a/telephony/java/com/google/android/mms/util/PduCacheEntry.java +++ b/telephony/common/com/google/android/mms/util/PduCacheEntry.java diff --git a/telephony/java/com/google/android/mms/util/SqliteWrapper.java b/telephony/common/com/google/android/mms/util/SqliteWrapper.java index 2dd1dc11c2a9..2dd1dc11c2a9 100644 --- a/telephony/java/com/google/android/mms/util/SqliteWrapper.java +++ b/telephony/common/com/google/android/mms/util/SqliteWrapper.java diff --git a/telephony/java/com/google/android/mms/util/package.html b/telephony/common/com/google/android/mms/util/package.html index c9f96a66ab3b..c9f96a66ab3b 100755 --- a/telephony/java/com/google/android/mms/util/package.html +++ b/telephony/common/com/google/android/mms/util/package.html diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java new file mode 100644 index 000000000000..a884a7039d5b --- /dev/null +++ b/telephony/java/android/telephony/Annotation.java @@ -0,0 +1,472 @@ +package android.telephony; + +import android.annotation.IntDef; +import android.telephony.data.ApnSetting; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Telephony Annotations. + * Telephony sdk is a mainline module and others cannot reference hidden @IntDef. Moving some + * telephony annotations to a separate class to allow others statically link to it. + * + * @hide + */ +public class Annotation { + @IntDef(prefix = {"DATA_"}, value = { + TelephonyManager.DATA_ACTIVITY_NONE, + TelephonyManager.DATA_ACTIVITY_IN, + TelephonyManager.DATA_ACTIVITY_OUT, + TelephonyManager.DATA_ACTIVITY_INOUT, + TelephonyManager.DATA_ACTIVITY_DORMANT, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DataActivityType { + } + + @IntDef(prefix = {"DATA_"}, value = { + TelephonyManager.DATA_UNKNOWN, + TelephonyManager.DATA_DISCONNECTED, + TelephonyManager.DATA_CONNECTING, + TelephonyManager.DATA_CONNECTED, + TelephonyManager.DATA_SUSPENDED, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DataState { + } + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"RADIO_POWER_"}, + value = { + TelephonyManager.RADIO_POWER_OFF, + TelephonyManager.RADIO_POWER_ON, + TelephonyManager.RADIO_POWER_UNAVAILABLE, + }) + public @interface RadioPowerState { + } + + @IntDef({ + TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN, + TelephonyManager.SIM_ACTIVATION_STATE_ACTIVATING, + TelephonyManager.SIM_ACTIVATION_STATE_ACTIVATED, + TelephonyManager.SIM_ACTIVATION_STATE_DEACTIVATED, + TelephonyManager.SIM_ACTIVATION_STATE_RESTRICTED + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SimActivationState { + } + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SRVCC_STATE_"}, + value = { + TelephonyManager.SRVCC_STATE_HANDOVER_NONE, + TelephonyManager.SRVCC_STATE_HANDOVER_STARTED, + TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED, + TelephonyManager.SRVCC_STATE_HANDOVER_FAILED, + TelephonyManager.SRVCC_STATE_HANDOVER_CANCELED}) + public @interface SrvccState { + } + + @IntDef(prefix = {"CALL_STATE_"}, value = { + TelephonyManager.CALL_STATE_IDLE, + TelephonyManager.CALL_STATE_RINGING, + TelephonyManager.CALL_STATE_OFFHOOK + }) + @Retention(RetentionPolicy.SOURCE) + public @interface CallState { + } + + @IntDef({ + TelephonyManager.NETWORK_TYPE_UNKNOWN, + TelephonyManager.NETWORK_TYPE_GPRS, + TelephonyManager.NETWORK_TYPE_EDGE, + TelephonyManager.NETWORK_TYPE_UMTS, + TelephonyManager.NETWORK_TYPE_CDMA, + TelephonyManager.NETWORK_TYPE_EVDO_0, + TelephonyManager.NETWORK_TYPE_EVDO_A, + TelephonyManager.NETWORK_TYPE_1xRTT, + TelephonyManager.NETWORK_TYPE_HSDPA, + TelephonyManager.NETWORK_TYPE_HSUPA, + TelephonyManager.NETWORK_TYPE_HSPA, + TelephonyManager.NETWORK_TYPE_IDEN, + TelephonyManager.NETWORK_TYPE_EVDO_B, + TelephonyManager.NETWORK_TYPE_LTE, + TelephonyManager.NETWORK_TYPE_EHRPD, + TelephonyManager.NETWORK_TYPE_HSPAP, + TelephonyManager.NETWORK_TYPE_GSM, + TelephonyManager.NETWORK_TYPE_TD_SCDMA, + TelephonyManager.NETWORK_TYPE_IWLAN, + TelephonyManager.NETWORK_TYPE_LTE_CA, + TelephonyManager.NETWORK_TYPE_NR, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface NetworkType { + } + + @IntDef(flag = true, prefix = {"TYPE_"}, value = { + ApnSetting.TYPE_DEFAULT, + ApnSetting.TYPE_MMS, + ApnSetting.TYPE_SUPL, + ApnSetting.TYPE_DUN, + ApnSetting.TYPE_HIPRI, + ApnSetting.TYPE_FOTA, + ApnSetting.TYPE_IMS, + ApnSetting.TYPE_CBS, + ApnSetting.TYPE_IA, + ApnSetting.TYPE_EMERGENCY, + ApnSetting.TYPE_MCX + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ApnType { + } + + @IntDef(value = { + DataFailCause.NONE, + DataFailCause.OPERATOR_BARRED, + DataFailCause.NAS_SIGNALLING, + DataFailCause.LLC_SNDCP, + DataFailCause.INSUFFICIENT_RESOURCES, + DataFailCause.MISSING_UNKNOWN_APN, + DataFailCause.UNKNOWN_PDP_ADDRESS_TYPE, + DataFailCause.USER_AUTHENTICATION, + DataFailCause.ACTIVATION_REJECT_GGSN, + DataFailCause.ACTIVATION_REJECT_UNSPECIFIED, + DataFailCause.SERVICE_OPTION_NOT_SUPPORTED, + DataFailCause.SERVICE_OPTION_NOT_SUBSCRIBED, + DataFailCause.SERVICE_OPTION_OUT_OF_ORDER, + DataFailCause.NSAPI_IN_USE, + DataFailCause.REGULAR_DEACTIVATION, + DataFailCause.QOS_NOT_ACCEPTED, + DataFailCause.NETWORK_FAILURE, + DataFailCause.UMTS_REACTIVATION_REQ, + DataFailCause.FEATURE_NOT_SUPP, + DataFailCause.TFT_SEMANTIC_ERROR, + DataFailCause.TFT_SYTAX_ERROR, + DataFailCause.UNKNOWN_PDP_CONTEXT, + DataFailCause.FILTER_SEMANTIC_ERROR, + DataFailCause.FILTER_SYTAX_ERROR, + DataFailCause.PDP_WITHOUT_ACTIVE_TFT, + DataFailCause.ACTIVATION_REJECTED_BCM_VIOLATION, + DataFailCause.ONLY_IPV4_ALLOWED, + DataFailCause.ONLY_IPV6_ALLOWED, + DataFailCause.ONLY_SINGLE_BEARER_ALLOWED, + DataFailCause.ESM_INFO_NOT_RECEIVED, + DataFailCause.PDN_CONN_DOES_NOT_EXIST, + DataFailCause.MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED, + DataFailCause.COLLISION_WITH_NETWORK_INITIATED_REQUEST, + DataFailCause.ONLY_IPV4V6_ALLOWED, + DataFailCause.ONLY_NON_IP_ALLOWED, + DataFailCause.UNSUPPORTED_QCI_VALUE, + DataFailCause.BEARER_HANDLING_NOT_SUPPORTED, + DataFailCause.ACTIVE_PDP_CONTEXT_MAX_NUMBER_REACHED, + DataFailCause.UNSUPPORTED_APN_IN_CURRENT_PLMN, + DataFailCause.INVALID_TRANSACTION_ID, + DataFailCause.MESSAGE_INCORRECT_SEMANTIC, + DataFailCause.INVALID_MANDATORY_INFO, + DataFailCause.MESSAGE_TYPE_UNSUPPORTED, + DataFailCause.MSG_TYPE_NONCOMPATIBLE_STATE, + DataFailCause.UNKNOWN_INFO_ELEMENT, + DataFailCause.CONDITIONAL_IE_ERROR, + DataFailCause.MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE, + DataFailCause.PROTOCOL_ERRORS, + DataFailCause.APN_TYPE_CONFLICT, + DataFailCause.INVALID_PCSCF_ADDR, + DataFailCause.INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN, + DataFailCause.EMM_ACCESS_BARRED, + DataFailCause.EMERGENCY_IFACE_ONLY, + DataFailCause.IFACE_MISMATCH, + DataFailCause.COMPANION_IFACE_IN_USE, + DataFailCause.IP_ADDRESS_MISMATCH, + DataFailCause.IFACE_AND_POL_FAMILY_MISMATCH, + DataFailCause.EMM_ACCESS_BARRED_INFINITE_RETRY, + DataFailCause.AUTH_FAILURE_ON_EMERGENCY_CALL, + DataFailCause.INVALID_DNS_ADDR, + DataFailCause.INVALID_PCSCF_OR_DNS_ADDRESS, + DataFailCause.CALL_PREEMPT_BY_EMERGENCY_APN, + DataFailCause.UE_INITIATED_DETACH_OR_DISCONNECT, + DataFailCause.MIP_FA_REASON_UNSPECIFIED, + DataFailCause.MIP_FA_ADMIN_PROHIBITED, + DataFailCause.MIP_FA_INSUFFICIENT_RESOURCES, + DataFailCause.MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE, + DataFailCause.MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE, + DataFailCause.MIP_FA_REQUESTED_LIFETIME_TOO_LONG, + DataFailCause.MIP_FA_MALFORMED_REQUEST, + DataFailCause.MIP_FA_MALFORMED_REPLY, + DataFailCause.MIP_FA_ENCAPSULATION_UNAVAILABLE, + DataFailCause.MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE, + DataFailCause.MIP_FA_REVERSE_TUNNEL_UNAVAILABLE, + DataFailCause.MIP_FA_REVERSE_TUNNEL_IS_MANDATORY, + DataFailCause.MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED, + DataFailCause.MIP_FA_MISSING_NAI, + DataFailCause.MIP_FA_MISSING_HOME_AGENT, + DataFailCause.MIP_FA_MISSING_HOME_ADDRESS, + DataFailCause.MIP_FA_UNKNOWN_CHALLENGE, + DataFailCause.MIP_FA_MISSING_CHALLENGE, + DataFailCause.MIP_FA_STALE_CHALLENGE, + DataFailCause.MIP_HA_REASON_UNSPECIFIED, + DataFailCause.MIP_HA_ADMIN_PROHIBITED, + DataFailCause.MIP_HA_INSUFFICIENT_RESOURCES, + DataFailCause.MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE, + DataFailCause.MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE, + DataFailCause.MIP_HA_REGISTRATION_ID_MISMATCH, + DataFailCause.MIP_HA_MALFORMED_REQUEST, + DataFailCause.MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS, + DataFailCause.MIP_HA_REVERSE_TUNNEL_UNAVAILABLE, + DataFailCause.MIP_HA_REVERSE_TUNNEL_IS_MANDATORY, + DataFailCause.MIP_HA_ENCAPSULATION_UNAVAILABLE, + DataFailCause.CLOSE_IN_PROGRESS, + DataFailCause.NETWORK_INITIATED_TERMINATION, + DataFailCause.MODEM_APP_PREEMPTED, + DataFailCause.PDN_IPV4_CALL_DISALLOWED, + DataFailCause.PDN_IPV4_CALL_THROTTLED, + DataFailCause.PDN_IPV6_CALL_DISALLOWED, + DataFailCause.PDN_IPV6_CALL_THROTTLED, + DataFailCause.MODEM_RESTART, + DataFailCause.PDP_PPP_NOT_SUPPORTED, + DataFailCause.UNPREFERRED_RAT, + DataFailCause.PHYSICAL_LINK_CLOSE_IN_PROGRESS, + DataFailCause.APN_PENDING_HANDOVER, + DataFailCause.PROFILE_BEARER_INCOMPATIBLE, + DataFailCause.SIM_CARD_CHANGED, + DataFailCause.LOW_POWER_MODE_OR_POWERING_DOWN, + DataFailCause.APN_DISABLED, + DataFailCause.MAX_PPP_INACTIVITY_TIMER_EXPIRED, + DataFailCause.IPV6_ADDRESS_TRANSFER_FAILED, + DataFailCause.TRAT_SWAP_FAILED, + DataFailCause.EHRPD_TO_HRPD_FALLBACK, + DataFailCause.MIP_CONFIG_FAILURE, + DataFailCause.PDN_INACTIVITY_TIMER_EXPIRED, + DataFailCause.MAX_IPV4_CONNECTIONS, + DataFailCause.MAX_IPV6_CONNECTIONS, + DataFailCause.APN_MISMATCH, + DataFailCause.IP_VERSION_MISMATCH, + DataFailCause.DUN_CALL_DISALLOWED, + DataFailCause.INTERNAL_EPC_NONEPC_TRANSITION, + DataFailCause.INTERFACE_IN_USE, + DataFailCause.APN_DISALLOWED_ON_ROAMING, + DataFailCause.APN_PARAMETERS_CHANGED, + DataFailCause.NULL_APN_DISALLOWED, + DataFailCause.THERMAL_MITIGATION, + DataFailCause.DATA_SETTINGS_DISABLED, + DataFailCause.DATA_ROAMING_SETTINGS_DISABLED, + DataFailCause.DDS_SWITCHED, + DataFailCause.FORBIDDEN_APN_NAME, + DataFailCause.DDS_SWITCH_IN_PROGRESS, + DataFailCause.CALL_DISALLOWED_IN_ROAMING, + DataFailCause.NON_IP_NOT_SUPPORTED, + DataFailCause.PDN_NON_IP_CALL_THROTTLED, + DataFailCause.PDN_NON_IP_CALL_DISALLOWED, + DataFailCause.CDMA_LOCK, + DataFailCause.CDMA_INTERCEPT, + DataFailCause.CDMA_REORDER, + DataFailCause.CDMA_RELEASE_DUE_TO_SO_REJECTION, + DataFailCause.CDMA_INCOMING_CALL, + DataFailCause.CDMA_ALERT_STOP, + DataFailCause.CHANNEL_ACQUISITION_FAILURE, + DataFailCause.MAX_ACCESS_PROBE, + DataFailCause.CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION, + DataFailCause.NO_RESPONSE_FROM_BASE_STATION, + DataFailCause.REJECTED_BY_BASE_STATION, + DataFailCause.CONCURRENT_SERVICES_INCOMPATIBLE, + DataFailCause.NO_CDMA_SERVICE, + DataFailCause.RUIM_NOT_PRESENT, + DataFailCause.CDMA_RETRY_ORDER, + DataFailCause.ACCESS_BLOCK, + DataFailCause.ACCESS_BLOCK_ALL, + DataFailCause.IS707B_MAX_ACCESS_PROBES, + DataFailCause.THERMAL_EMERGENCY, + DataFailCause.CONCURRENT_SERVICES_NOT_ALLOWED, + DataFailCause.INCOMING_CALL_REJECTED, + DataFailCause.NO_SERVICE_ON_GATEWAY, + DataFailCause.NO_GPRS_CONTEXT, + DataFailCause.ILLEGAL_MS, + DataFailCause.ILLEGAL_ME, + DataFailCause.GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED, + DataFailCause.GPRS_SERVICES_NOT_ALLOWED, + DataFailCause.MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK, + DataFailCause.IMPLICITLY_DETACHED, + DataFailCause.PLMN_NOT_ALLOWED, + DataFailCause.LOCATION_AREA_NOT_ALLOWED, + DataFailCause.GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN, + DataFailCause.PDP_DUPLICATE, + DataFailCause.UE_RAT_CHANGE, + DataFailCause.CONGESTION, + DataFailCause.NO_PDP_CONTEXT_ACTIVATED, + DataFailCause.ACCESS_CLASS_DSAC_REJECTION, + DataFailCause.PDP_ACTIVATE_MAX_RETRY_FAILED, + DataFailCause.RADIO_ACCESS_BEARER_FAILURE, + DataFailCause.ESM_UNKNOWN_EPS_BEARER_CONTEXT, + DataFailCause.DRB_RELEASED_BY_RRC, + DataFailCause.CONNECTION_RELEASED, + DataFailCause.EMM_DETACHED, + DataFailCause.EMM_ATTACH_FAILED, + DataFailCause.EMM_ATTACH_STARTED, + DataFailCause.LTE_NAS_SERVICE_REQUEST_FAILED, + DataFailCause.DUPLICATE_BEARER_ID, + DataFailCause.ESM_COLLISION_SCENARIOS, + DataFailCause.ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK, + DataFailCause.ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER, + DataFailCause.ESM_BAD_OTA_MESSAGE, + DataFailCause.ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL, + DataFailCause.ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT, + DataFailCause.DS_EXPLICIT_DEACTIVATION, + DataFailCause.ESM_LOCAL_CAUSE_NONE, + DataFailCause.LTE_THROTTLING_NOT_REQUIRED, + DataFailCause.ACCESS_CONTROL_LIST_CHECK_FAILURE, + DataFailCause.SERVICE_NOT_ALLOWED_ON_PLMN, + DataFailCause.EMM_T3417_EXPIRED, + DataFailCause.EMM_T3417_EXT_EXPIRED, + DataFailCause.RRC_UPLINK_DATA_TRANSMISSION_FAILURE, + DataFailCause.RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER, + DataFailCause.RRC_UPLINK_CONNECTION_RELEASE, + DataFailCause.RRC_UPLINK_RADIO_LINK_FAILURE, + DataFailCause.RRC_UPLINK_ERROR_REQUEST_FROM_NAS, + DataFailCause.RRC_CONNECTION_ACCESS_STRATUM_FAILURE, + DataFailCause.RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS, + DataFailCause.RRC_CONNECTION_ACCESS_BARRED, + DataFailCause.RRC_CONNECTION_CELL_RESELECTION, + DataFailCause.RRC_CONNECTION_CONFIG_FAILURE, + DataFailCause.RRC_CONNECTION_TIMER_EXPIRED, + DataFailCause.RRC_CONNECTION_LINK_FAILURE, + DataFailCause.RRC_CONNECTION_CELL_NOT_CAMPED, + DataFailCause.RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE, + DataFailCause.RRC_CONNECTION_REJECT_BY_NETWORK, + DataFailCause.RRC_CONNECTION_NORMAL_RELEASE, + DataFailCause.RRC_CONNECTION_RADIO_LINK_FAILURE, + DataFailCause.RRC_CONNECTION_REESTABLISHMENT_FAILURE, + DataFailCause.RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER, + DataFailCause.RRC_CONNECTION_ABORT_REQUEST, + DataFailCause.RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR, + DataFailCause.NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH, + DataFailCause.NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH, + DataFailCause.ESM_PROCEDURE_TIME_OUT, + DataFailCause.INVALID_CONNECTION_ID, + DataFailCause.MAXIMIUM_NSAPIS_EXCEEDED, + DataFailCause.INVALID_PRIMARY_NSAPI, + DataFailCause.CANNOT_ENCODE_OTA_MESSAGE, + DataFailCause.RADIO_ACCESS_BEARER_SETUP_FAILURE, + DataFailCause.PDP_ESTABLISH_TIMEOUT_EXPIRED, + DataFailCause.PDP_MODIFY_TIMEOUT_EXPIRED, + DataFailCause.PDP_INACTIVE_TIMEOUT_EXPIRED, + DataFailCause.PDP_LOWERLAYER_ERROR, + DataFailCause.PDP_MODIFY_COLLISION, + DataFailCause.MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED, + DataFailCause.NAS_REQUEST_REJECTED_BY_NETWORK, + DataFailCause.RRC_CONNECTION_INVALID_REQUEST, + DataFailCause.RRC_CONNECTION_TRACKING_AREA_ID_CHANGED, + DataFailCause.RRC_CONNECTION_RF_UNAVAILABLE, + DataFailCause.RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE, + DataFailCause.RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE, + DataFailCause.RRC_CONNECTION_ABORTED_AFTER_HANDOVER, + DataFailCause.RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE, + DataFailCause.RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE, + DataFailCause.IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER, + DataFailCause.IMEI_NOT_ACCEPTED, + DataFailCause.EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED, + DataFailCause.EPS_SERVICES_NOT_ALLOWED_IN_PLMN, + DataFailCause.MSC_TEMPORARILY_NOT_REACHABLE, + DataFailCause.CS_DOMAIN_NOT_AVAILABLE, + DataFailCause.ESM_FAILURE, + DataFailCause.MAC_FAILURE, + DataFailCause.SYNCHRONIZATION_FAILURE, + DataFailCause.UE_SECURITY_CAPABILITIES_MISMATCH, + DataFailCause.SECURITY_MODE_REJECTED, + DataFailCause.UNACCEPTABLE_NON_EPS_AUTHENTICATION, + DataFailCause.CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED, + DataFailCause.NO_EPS_BEARER_CONTEXT_ACTIVATED, + DataFailCause.INVALID_EMM_STATE, + DataFailCause.NAS_LAYER_FAILURE, + DataFailCause.MULTIPLE_PDP_CALL_NOT_ALLOWED, + DataFailCause.EMBMS_NOT_ENABLED, + DataFailCause.IRAT_HANDOVER_FAILED, + DataFailCause.EMBMS_REGULAR_DEACTIVATION, + DataFailCause.TEST_LOOPBACK_REGULAR_DEACTIVATION, + DataFailCause.LOWER_LAYER_REGISTRATION_FAILURE, + DataFailCause.DATA_PLAN_EXPIRED, + DataFailCause.UMTS_HANDOVER_TO_IWLAN, + DataFailCause.EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY, + DataFailCause.EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE, + DataFailCause.EVDO_HDR_CHANGED, + DataFailCause.EVDO_HDR_EXITED, + DataFailCause.EVDO_HDR_NO_SESSION, + DataFailCause.EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL, + DataFailCause.EVDO_HDR_CONNECTION_SETUP_TIMEOUT, + DataFailCause.FAILED_TO_ACQUIRE_COLOCATED_HDR, + DataFailCause.OTASP_COMMIT_IN_PROGRESS, + DataFailCause.NO_HYBRID_HDR_SERVICE, + DataFailCause.HDR_NO_LOCK_GRANTED, + DataFailCause.DBM_OR_SMS_IN_PROGRESS, + DataFailCause.HDR_FADE, + DataFailCause.HDR_ACCESS_FAILURE, + DataFailCause.UNSUPPORTED_1X_PREV, + DataFailCause.LOCAL_END, + DataFailCause.NO_SERVICE, + DataFailCause.FADE, + DataFailCause.NORMAL_RELEASE, + DataFailCause.ACCESS_ATTEMPT_ALREADY_IN_PROGRESS, + DataFailCause.REDIRECTION_OR_HANDOFF_IN_PROGRESS, + DataFailCause.EMERGENCY_MODE, + DataFailCause.PHONE_IN_USE, + DataFailCause.INVALID_MODE, + DataFailCause.INVALID_SIM_STATE, + DataFailCause.NO_COLLOCATED_HDR, + DataFailCause.UE_IS_ENTERING_POWERSAVE_MODE, + DataFailCause.DUAL_SWITCH, + DataFailCause.PPP_TIMEOUT, + DataFailCause.PPP_AUTH_FAILURE, + DataFailCause.PPP_OPTION_MISMATCH, + DataFailCause.PPP_PAP_FAILURE, + DataFailCause.PPP_CHAP_FAILURE, + DataFailCause.PPP_CLOSE_IN_PROGRESS, + DataFailCause.LIMITED_TO_IPV4, + DataFailCause.LIMITED_TO_IPV6, + DataFailCause.VSNCP_TIMEOUT, + DataFailCause.VSNCP_GEN_ERROR, + DataFailCause.VSNCP_APN_UNATHORIZED, + DataFailCause.VSNCP_PDN_LIMIT_EXCEEDED, + DataFailCause.VSNCP_NO_PDN_GATEWAY_ADDRESS, + DataFailCause.VSNCP_PDN_GATEWAY_UNREACHABLE, + DataFailCause.VSNCP_PDN_GATEWAY_REJECT, + DataFailCause.VSNCP_INSUFFICIENT_PARAMETERS, + DataFailCause.VSNCP_RESOURCE_UNAVAILABLE, + DataFailCause.VSNCP_ADMINISTRATIVELY_PROHIBITED, + DataFailCause.VSNCP_PDN_ID_IN_USE, + DataFailCause.VSNCP_SUBSCRIBER_LIMITATION, + DataFailCause.VSNCP_PDN_EXISTS_FOR_THIS_APN, + DataFailCause.VSNCP_RECONNECT_NOT_ALLOWED, + DataFailCause.IPV6_PREFIX_UNAVAILABLE, + DataFailCause.HANDOFF_PREFERENCE_CHANGED, + DataFailCause.OEM_DCFAILCAUSE_1, + DataFailCause.OEM_DCFAILCAUSE_2, + DataFailCause.OEM_DCFAILCAUSE_3, + DataFailCause.OEM_DCFAILCAUSE_4, + DataFailCause.OEM_DCFAILCAUSE_5, + DataFailCause.OEM_DCFAILCAUSE_6, + DataFailCause.OEM_DCFAILCAUSE_7, + DataFailCause.OEM_DCFAILCAUSE_8, + DataFailCause.OEM_DCFAILCAUSE_9, + DataFailCause.OEM_DCFAILCAUSE_10, + DataFailCause.OEM_DCFAILCAUSE_11, + DataFailCause.OEM_DCFAILCAUSE_12, + DataFailCause.OEM_DCFAILCAUSE_13, + DataFailCause.OEM_DCFAILCAUSE_14, + DataFailCause.OEM_DCFAILCAUSE_15, + DataFailCause.REGISTRATION_FAIL, + DataFailCause.GPRS_REGISTRATION_FAIL, + DataFailCause.SIGNAL_LOST, + DataFailCause.PREF_RADIO_TECH_CHANGED, + DataFailCause.RADIO_POWER_OFF, + DataFailCause.TETHERED_CALL_ACTIVE, + DataFailCause.ERROR_UNSPECIFIED, + DataFailCause.UNKNOWN, + DataFailCause.RADIO_NOT_AVAILABLE, + DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER, + DataFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN, + DataFailCause.LOST_CONNECTION, + DataFailCause.RESET_BY_FRAMEWORK + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DataFailureCause { + } +} diff --git a/telephony/java/android/telephony/CallAttributes.java b/telephony/java/android/telephony/CallAttributes.java index 1c03d8089df7..cd830adf23b0 100644 --- a/telephony/java/android/telephony/CallAttributes.java +++ b/telephony/java/android/telephony/CallAttributes.java @@ -21,8 +21,8 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.TelephonyManager.NetworkType; +import android.telephony.Annotation.NetworkType; import java.util.Objects; /** diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java index ca264f738e1d..246bec7de59e 100644 --- a/telephony/java/android/telephony/DataFailCause.java +++ b/telephony/java/android/telephony/DataFailCause.java @@ -21,6 +21,7 @@ import android.annotation.SystemApi; import android.content.Context; import android.os.PersistableBundle; +import android.telephony.Annotation.DataFailureCause; import com.android.internal.util.ArrayUtils; import java.lang.annotation.Retention; @@ -968,355 +969,6 @@ public final class DataFailCause { */ public static final int HANDOVER_FAILED = 0x10006; - /** @hide */ - @IntDef(value = { - NONE, - OPERATOR_BARRED, - NAS_SIGNALLING, - LLC_SNDCP, - INSUFFICIENT_RESOURCES, - MISSING_UNKNOWN_APN, - UNKNOWN_PDP_ADDRESS_TYPE, - USER_AUTHENTICATION, - ACTIVATION_REJECT_GGSN, - ACTIVATION_REJECT_UNSPECIFIED, - SERVICE_OPTION_NOT_SUPPORTED, - SERVICE_OPTION_NOT_SUBSCRIBED, - SERVICE_OPTION_OUT_OF_ORDER, - NSAPI_IN_USE, - REGULAR_DEACTIVATION, - QOS_NOT_ACCEPTED, - NETWORK_FAILURE, - UMTS_REACTIVATION_REQ, - FEATURE_NOT_SUPP, - TFT_SEMANTIC_ERROR, - TFT_SYTAX_ERROR, - UNKNOWN_PDP_CONTEXT, - FILTER_SEMANTIC_ERROR, - FILTER_SYTAX_ERROR, - PDP_WITHOUT_ACTIVE_TFT, - ACTIVATION_REJECTED_BCM_VIOLATION, - ONLY_IPV4_ALLOWED, - ONLY_IPV6_ALLOWED, - ONLY_SINGLE_BEARER_ALLOWED, - ESM_INFO_NOT_RECEIVED, - PDN_CONN_DOES_NOT_EXIST, - MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED, - COLLISION_WITH_NETWORK_INITIATED_REQUEST, - ONLY_IPV4V6_ALLOWED, - ONLY_NON_IP_ALLOWED, - UNSUPPORTED_QCI_VALUE, - BEARER_HANDLING_NOT_SUPPORTED, - ACTIVE_PDP_CONTEXT_MAX_NUMBER_REACHED, - UNSUPPORTED_APN_IN_CURRENT_PLMN, - INVALID_TRANSACTION_ID, - MESSAGE_INCORRECT_SEMANTIC, - INVALID_MANDATORY_INFO, - MESSAGE_TYPE_UNSUPPORTED, - MSG_TYPE_NONCOMPATIBLE_STATE, - UNKNOWN_INFO_ELEMENT, - CONDITIONAL_IE_ERROR, - MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE, - PROTOCOL_ERRORS, - APN_TYPE_CONFLICT, - INVALID_PCSCF_ADDR, - INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN, - EMM_ACCESS_BARRED, - EMERGENCY_IFACE_ONLY, - IFACE_MISMATCH, - COMPANION_IFACE_IN_USE, - IP_ADDRESS_MISMATCH, - IFACE_AND_POL_FAMILY_MISMATCH, - EMM_ACCESS_BARRED_INFINITE_RETRY, - AUTH_FAILURE_ON_EMERGENCY_CALL, - INVALID_DNS_ADDR, - INVALID_PCSCF_OR_DNS_ADDRESS, - CALL_PREEMPT_BY_EMERGENCY_APN, - UE_INITIATED_DETACH_OR_DISCONNECT, - MIP_FA_REASON_UNSPECIFIED, - MIP_FA_ADMIN_PROHIBITED, - MIP_FA_INSUFFICIENT_RESOURCES, - MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE, - MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE, - MIP_FA_REQUESTED_LIFETIME_TOO_LONG, - MIP_FA_MALFORMED_REQUEST, - MIP_FA_MALFORMED_REPLY, - MIP_FA_ENCAPSULATION_UNAVAILABLE, - MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE, - MIP_FA_REVERSE_TUNNEL_UNAVAILABLE, - MIP_FA_REVERSE_TUNNEL_IS_MANDATORY, - MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED, - MIP_FA_MISSING_NAI, - MIP_FA_MISSING_HOME_AGENT, - MIP_FA_MISSING_HOME_ADDRESS, - MIP_FA_UNKNOWN_CHALLENGE, - MIP_FA_MISSING_CHALLENGE, - MIP_FA_STALE_CHALLENGE, - MIP_HA_REASON_UNSPECIFIED, - MIP_HA_ADMIN_PROHIBITED, - MIP_HA_INSUFFICIENT_RESOURCES, - MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE, - MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE, - MIP_HA_REGISTRATION_ID_MISMATCH, - MIP_HA_MALFORMED_REQUEST, - MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS, - MIP_HA_REVERSE_TUNNEL_UNAVAILABLE, - MIP_HA_REVERSE_TUNNEL_IS_MANDATORY, - MIP_HA_ENCAPSULATION_UNAVAILABLE, - CLOSE_IN_PROGRESS, - NETWORK_INITIATED_TERMINATION, - MODEM_APP_PREEMPTED, - PDN_IPV4_CALL_DISALLOWED, - PDN_IPV4_CALL_THROTTLED, - PDN_IPV6_CALL_DISALLOWED, - PDN_IPV6_CALL_THROTTLED, - MODEM_RESTART, - PDP_PPP_NOT_SUPPORTED, - UNPREFERRED_RAT, - PHYSICAL_LINK_CLOSE_IN_PROGRESS, - APN_PENDING_HANDOVER, - PROFILE_BEARER_INCOMPATIBLE, - SIM_CARD_CHANGED, - LOW_POWER_MODE_OR_POWERING_DOWN, - APN_DISABLED, - MAX_PPP_INACTIVITY_TIMER_EXPIRED, - IPV6_ADDRESS_TRANSFER_FAILED, - TRAT_SWAP_FAILED, - EHRPD_TO_HRPD_FALLBACK, - MIP_CONFIG_FAILURE, - PDN_INACTIVITY_TIMER_EXPIRED, - MAX_IPV4_CONNECTIONS, - MAX_IPV6_CONNECTIONS, - APN_MISMATCH, - IP_VERSION_MISMATCH, - DUN_CALL_DISALLOWED, - INTERNAL_EPC_NONEPC_TRANSITION, - INTERFACE_IN_USE, - APN_DISALLOWED_ON_ROAMING, - APN_PARAMETERS_CHANGED, - NULL_APN_DISALLOWED, - THERMAL_MITIGATION, - DATA_SETTINGS_DISABLED, - DATA_ROAMING_SETTINGS_DISABLED, - DDS_SWITCHED, - FORBIDDEN_APN_NAME, - DDS_SWITCH_IN_PROGRESS, - CALL_DISALLOWED_IN_ROAMING, - NON_IP_NOT_SUPPORTED, - PDN_NON_IP_CALL_THROTTLED, - PDN_NON_IP_CALL_DISALLOWED, - CDMA_LOCK, - CDMA_INTERCEPT, - CDMA_REORDER, - CDMA_RELEASE_DUE_TO_SO_REJECTION, - CDMA_INCOMING_CALL, - CDMA_ALERT_STOP, - CHANNEL_ACQUISITION_FAILURE, - MAX_ACCESS_PROBE, - CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION, - NO_RESPONSE_FROM_BASE_STATION, - REJECTED_BY_BASE_STATION, - CONCURRENT_SERVICES_INCOMPATIBLE, - NO_CDMA_SERVICE, - RUIM_NOT_PRESENT, - CDMA_RETRY_ORDER, - ACCESS_BLOCK, - ACCESS_BLOCK_ALL, - IS707B_MAX_ACCESS_PROBES, - THERMAL_EMERGENCY, - CONCURRENT_SERVICES_NOT_ALLOWED, - INCOMING_CALL_REJECTED, - NO_SERVICE_ON_GATEWAY, - NO_GPRS_CONTEXT, - ILLEGAL_MS, - ILLEGAL_ME, - GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED, - GPRS_SERVICES_NOT_ALLOWED, - MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK, - IMPLICITLY_DETACHED, - PLMN_NOT_ALLOWED, - LOCATION_AREA_NOT_ALLOWED, - GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN, - PDP_DUPLICATE, - UE_RAT_CHANGE, - CONGESTION, - NO_PDP_CONTEXT_ACTIVATED, - ACCESS_CLASS_DSAC_REJECTION, - PDP_ACTIVATE_MAX_RETRY_FAILED, - RADIO_ACCESS_BEARER_FAILURE, - ESM_UNKNOWN_EPS_BEARER_CONTEXT, - DRB_RELEASED_BY_RRC, - CONNECTION_RELEASED, - EMM_DETACHED, - EMM_ATTACH_FAILED, - EMM_ATTACH_STARTED, - LTE_NAS_SERVICE_REQUEST_FAILED, - DUPLICATE_BEARER_ID, - ESM_COLLISION_SCENARIOS, - ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK, - ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER, - ESM_BAD_OTA_MESSAGE, - ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL, - ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT, - DS_EXPLICIT_DEACTIVATION, - ESM_LOCAL_CAUSE_NONE, - LTE_THROTTLING_NOT_REQUIRED, - ACCESS_CONTROL_LIST_CHECK_FAILURE, - SERVICE_NOT_ALLOWED_ON_PLMN, - EMM_T3417_EXPIRED, - EMM_T3417_EXT_EXPIRED, - RRC_UPLINK_DATA_TRANSMISSION_FAILURE, - RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER, - RRC_UPLINK_CONNECTION_RELEASE, - RRC_UPLINK_RADIO_LINK_FAILURE, - RRC_UPLINK_ERROR_REQUEST_FROM_NAS, - RRC_CONNECTION_ACCESS_STRATUM_FAILURE, - RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS, - RRC_CONNECTION_ACCESS_BARRED, - RRC_CONNECTION_CELL_RESELECTION, - RRC_CONNECTION_CONFIG_FAILURE, - RRC_CONNECTION_TIMER_EXPIRED, - RRC_CONNECTION_LINK_FAILURE, - RRC_CONNECTION_CELL_NOT_CAMPED, - RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE, - RRC_CONNECTION_REJECT_BY_NETWORK, - RRC_CONNECTION_NORMAL_RELEASE, - RRC_CONNECTION_RADIO_LINK_FAILURE, - RRC_CONNECTION_REESTABLISHMENT_FAILURE, - RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER, - RRC_CONNECTION_ABORT_REQUEST, - RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR, - NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH, - NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH, - ESM_PROCEDURE_TIME_OUT, - INVALID_CONNECTION_ID, - MAXIMIUM_NSAPIS_EXCEEDED, - INVALID_PRIMARY_NSAPI, - CANNOT_ENCODE_OTA_MESSAGE, - RADIO_ACCESS_BEARER_SETUP_FAILURE, - PDP_ESTABLISH_TIMEOUT_EXPIRED, - PDP_MODIFY_TIMEOUT_EXPIRED, - PDP_INACTIVE_TIMEOUT_EXPIRED, - PDP_LOWERLAYER_ERROR, - PDP_MODIFY_COLLISION, - MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED, - NAS_REQUEST_REJECTED_BY_NETWORK, - RRC_CONNECTION_INVALID_REQUEST, - RRC_CONNECTION_TRACKING_AREA_ID_CHANGED, - RRC_CONNECTION_RF_UNAVAILABLE, - RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE, - RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE, - RRC_CONNECTION_ABORTED_AFTER_HANDOVER, - RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE, - RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE, - IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER, - IMEI_NOT_ACCEPTED, - EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED, - EPS_SERVICES_NOT_ALLOWED_IN_PLMN, - MSC_TEMPORARILY_NOT_REACHABLE, - CS_DOMAIN_NOT_AVAILABLE, - ESM_FAILURE, - MAC_FAILURE, - SYNCHRONIZATION_FAILURE, - UE_SECURITY_CAPABILITIES_MISMATCH, - SECURITY_MODE_REJECTED, - UNACCEPTABLE_NON_EPS_AUTHENTICATION, - CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED, - NO_EPS_BEARER_CONTEXT_ACTIVATED, - INVALID_EMM_STATE, - NAS_LAYER_FAILURE, - MULTIPLE_PDP_CALL_NOT_ALLOWED, - EMBMS_NOT_ENABLED, - IRAT_HANDOVER_FAILED, - EMBMS_REGULAR_DEACTIVATION, - TEST_LOOPBACK_REGULAR_DEACTIVATION, - LOWER_LAYER_REGISTRATION_FAILURE, - DATA_PLAN_EXPIRED, - UMTS_HANDOVER_TO_IWLAN, - EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY, - EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE, - EVDO_HDR_CHANGED, - EVDO_HDR_EXITED, - EVDO_HDR_NO_SESSION, - EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL, - EVDO_HDR_CONNECTION_SETUP_TIMEOUT, - FAILED_TO_ACQUIRE_COLOCATED_HDR, - OTASP_COMMIT_IN_PROGRESS, - NO_HYBRID_HDR_SERVICE, - HDR_NO_LOCK_GRANTED, - DBM_OR_SMS_IN_PROGRESS, - HDR_FADE, - HDR_ACCESS_FAILURE, - UNSUPPORTED_1X_PREV, - LOCAL_END, - NO_SERVICE, - FADE, - NORMAL_RELEASE, - ACCESS_ATTEMPT_ALREADY_IN_PROGRESS, - REDIRECTION_OR_HANDOFF_IN_PROGRESS, - EMERGENCY_MODE, - PHONE_IN_USE, - INVALID_MODE, - INVALID_SIM_STATE, - NO_COLLOCATED_HDR, - UE_IS_ENTERING_POWERSAVE_MODE, - DUAL_SWITCH, - PPP_TIMEOUT, - PPP_AUTH_FAILURE, - PPP_OPTION_MISMATCH, - PPP_PAP_FAILURE, - PPP_CHAP_FAILURE, - PPP_CLOSE_IN_PROGRESS, - LIMITED_TO_IPV4, - LIMITED_TO_IPV6, - VSNCP_TIMEOUT, - VSNCP_GEN_ERROR, - VSNCP_APN_UNATHORIZED, - VSNCP_PDN_LIMIT_EXCEEDED, - VSNCP_NO_PDN_GATEWAY_ADDRESS, - VSNCP_PDN_GATEWAY_UNREACHABLE, - VSNCP_PDN_GATEWAY_REJECT, - VSNCP_INSUFFICIENT_PARAMETERS, - VSNCP_RESOURCE_UNAVAILABLE, - VSNCP_ADMINISTRATIVELY_PROHIBITED, - VSNCP_PDN_ID_IN_USE, - VSNCP_SUBSCRIBER_LIMITATION, - VSNCP_PDN_EXISTS_FOR_THIS_APN, - VSNCP_RECONNECT_NOT_ALLOWED, - IPV6_PREFIX_UNAVAILABLE, - HANDOFF_PREFERENCE_CHANGED, - OEM_DCFAILCAUSE_1, - OEM_DCFAILCAUSE_2, - OEM_DCFAILCAUSE_3, - OEM_DCFAILCAUSE_4, - OEM_DCFAILCAUSE_5, - OEM_DCFAILCAUSE_6, - OEM_DCFAILCAUSE_7, - OEM_DCFAILCAUSE_8, - OEM_DCFAILCAUSE_9, - OEM_DCFAILCAUSE_10, - OEM_DCFAILCAUSE_11, - OEM_DCFAILCAUSE_12, - OEM_DCFAILCAUSE_13, - OEM_DCFAILCAUSE_14, - OEM_DCFAILCAUSE_15, - REGISTRATION_FAIL, - GPRS_REGISTRATION_FAIL, - SIGNAL_LOST, - PREF_RADIO_TECH_CHANGED, - RADIO_POWER_OFF, - TETHERED_CALL_ACTIVE, - ERROR_UNSPECIFIED, - UNKNOWN, - RADIO_NOT_AVAILABLE, - UNACCEPTABLE_NETWORK_PARAMETER, - CONNECTION_TO_DATACONNECTIONAC_BROKEN, - LOST_CONNECTION, - RESET_BY_FRAMEWORK - }) - @Retention(RetentionPolicy.SOURCE) - public @interface FailCause{} - private static final Map<Integer, String> sFailCauseMap; static { sFailCauseMap = new HashMap<>(); @@ -1737,7 +1389,8 @@ public final class DataFailCause { * * @hide */ - public static boolean isRadioRestartFailure(@NonNull Context context, @FailCause int cause, + public static boolean isRadioRestartFailure(@NonNull Context context, + @DataFailureCause int cause, int subId) { CarrierConfigManager configManager = (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE); @@ -1765,7 +1418,8 @@ public final class DataFailCause { } /** @hide */ - public static boolean isPermanentFailure(@NonNull Context context, @FailCause int failCause, + public static boolean isPermanentFailure(@NonNull Context context, + @DataFailureCause int failCause, int subId) { synchronized (sPermanentFailureCache) { @@ -1825,7 +1479,7 @@ public final class DataFailCause { } /** @hide */ - public static boolean isEventLoggable(@FailCause int dataFailCause) { + public static boolean isEventLoggable(@DataFailureCause int dataFailCause) { return (dataFailCause == OPERATOR_BARRED) || (dataFailCause == INSUFFICIENT_RESOURCES) || (dataFailCause == UNKNOWN_PDP_ADDRESS_TYPE) || (dataFailCause == USER_AUTHENTICATION) @@ -1845,13 +1499,13 @@ public final class DataFailCause { } /** @hide */ - public static String toString(@FailCause int dataFailCause) { + public static String toString(@DataFailureCause int dataFailCause) { int cause = getFailCause(dataFailCause); return (cause == UNKNOWN) ? "UNKNOWN(" + dataFailCause + ")" : sFailCauseMap.get(cause); } /** @hide */ - public static int getFailCause(@FailCause int failCause) { + public static int getFailCause(@DataFailureCause int failCause) { if (sFailCauseMap.containsKey(failCause)) { return failCause; } else { diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java index da4da79a39df..45deea206cfc 100644 --- a/telephony/java/android/telephony/MbmsDownloadSession.java +++ b/telephony/java/android/telephony/MbmsDownloadSession.java @@ -243,6 +243,7 @@ public class MbmsDownloadSession implements AutoCloseable { }; private AtomicReference<IMbmsDownloadService> mService = new AtomicReference<>(null); + private ServiceConnection mServiceConnection; private final InternalDownloadSessionCallback mInternalCallback; private final Map<DownloadStatusListener, InternalDownloadStatusListener> mInternalDownloadStatusListeners = new HashMap<>(); @@ -318,56 +319,66 @@ public class MbmsDownloadSession implements AutoCloseable { } private int bindAndInitialize() { - return MbmsUtils.startBinding(mContext, MBMS_DOWNLOAD_SERVICE_ACTION, - new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - IMbmsDownloadService downloadService = - IMbmsDownloadService.Stub.asInterface(service); - int result; - try { - result = downloadService.initialize(mSubscriptionId, mInternalCallback); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Service died before initialization"); - sIsInitialized.set(false); - return; - } catch (RuntimeException e) { - Log.e(LOG_TAG, "Runtime exception during initialization"); - sendErrorToApp( - MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, - e.toString()); - sIsInitialized.set(false); - return; - } - if (result == MbmsErrors.UNKNOWN) { - // Unbind and throw an obvious error - close(); - throw new IllegalStateException("Middleware must not return an" - + " unknown error code"); - } - if (result != MbmsErrors.SUCCESS) { - sendErrorToApp(result, "Error returned during initialization"); - sIsInitialized.set(false); - return; - } - try { - downloadService.asBinder().linkToDeath(mDeathRecipient, 0); - } catch (RemoteException e) { - sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, - "Middleware lost during initialization"); - sIsInitialized.set(false); - return; - } - mService.set(downloadService); - } + mServiceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + IMbmsDownloadService downloadService = + IMbmsDownloadService.Stub.asInterface(service); + int result; + try { + result = downloadService.initialize(mSubscriptionId, mInternalCallback); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Service died before initialization"); + sIsInitialized.set(false); + return; + } catch (RuntimeException e) { + Log.e(LOG_TAG, "Runtime exception during initialization"); + sendErrorToApp( + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + sIsInitialized.set(false); + return; + } + if (result == MbmsErrors.UNKNOWN) { + // Unbind and throw an obvious error + close(); + throw new IllegalStateException("Middleware must not return an" + + " unknown error code"); + } + if (result != MbmsErrors.SUCCESS) { + sendErrorToApp(result, "Error returned during initialization"); + sIsInitialized.set(false); + return; + } + try { + downloadService.asBinder().linkToDeath(mDeathRecipient, 0); + } catch (RemoteException e) { + sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Middleware lost during initialization"); + sIsInitialized.set(false); + return; + } + mService.set(downloadService); + } - @Override - public void onServiceDisconnected(ComponentName name) { - Log.w(LOG_TAG, "bindAndInitialize: Remote service disconnected"); - sIsInitialized.set(false); - mService.set(null); - } - }); + @Override + public void onServiceDisconnected(ComponentName name) { + Log.w(LOG_TAG, "bindAndInitialize: Remote service disconnected"); + sIsInitialized.set(false); + mService.set(null); + } + + @Override + public void onNullBinding(ComponentName name) { + Log.w(LOG_TAG, "bindAndInitialize: Remote service returned null"); + sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Middleware service binding returned null"); + sIsInitialized.set(false); + mService.set(null); + mContext.unbindService(this); + } + }; + return MbmsUtils.startBinding(mContext, MBMS_DOWNLOAD_SERVICE_ACTION, mServiceConnection); } /** @@ -965,17 +976,19 @@ public class MbmsDownloadSession implements AutoCloseable { public void close() { try { IMbmsDownloadService downloadService = mService.get(); - if (downloadService == null) { + if (downloadService == null || mServiceConnection == null) { Log.i(LOG_TAG, "Service already dead"); return; } downloadService.dispose(mSubscriptionId); + mContext.unbindService(mServiceConnection); } catch (RemoteException e) { // Ignore Log.i(LOG_TAG, "Remote exception while disposing of service"); } finally { mService.set(null); sIsInitialized.set(false); + mServiceConnection = null; mInternalCallback.stop(); } } diff --git a/telephony/java/android/telephony/MbmsGroupCallSession.java b/telephony/java/android/telephony/MbmsGroupCallSession.java index f1be31fa5477..d54071f28be9 100644 --- a/telephony/java/android/telephony/MbmsGroupCallSession.java +++ b/telephony/java/android/telephony/MbmsGroupCallSession.java @@ -80,6 +80,7 @@ public class MbmsGroupCallSession implements AutoCloseable { }; private InternalGroupCallSessionCallback mInternalCallback; + private ServiceConnection mServiceConnection; private Set<GroupCall> mKnownActiveGroupCalls = new ArraySet<>(); private final Context mContext; @@ -163,7 +164,7 @@ public class MbmsGroupCallSession implements AutoCloseable { public void close() { try { IMbmsGroupCallService groupCallService = mService.get(); - if (groupCallService == null) { + if (groupCallService == null || mServiceConnection == null) { // Ignore and return, assume already disposed. return; } @@ -172,11 +173,13 @@ public class MbmsGroupCallSession implements AutoCloseable { s.getCallback().stop(); } mKnownActiveGroupCalls.clear(); + mContext.unbindService(mServiceConnection); } catch (RemoteException e) { // Ignore for now } finally { mService.set(null); sIsInitialized.set(false); + mServiceConnection = null; mInternalCallback.stop(); } } @@ -244,59 +247,69 @@ public class MbmsGroupCallSession implements AutoCloseable { } private int bindAndInitialize() { - return MbmsUtils.startBinding(mContext, MBMS_GROUP_CALL_SERVICE_ACTION, - new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - IMbmsGroupCallService groupCallService = - IMbmsGroupCallService.Stub.asInterface(service); - int result; - try { - result = groupCallService.initialize(mInternalCallback, - mSubscriptionId); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Service died before initialization"); - mInternalCallback.onError( - MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, - e.toString()); - sIsInitialized.set(false); - return; - } catch (RuntimeException e) { - Log.e(LOG_TAG, "Runtime exception during initialization"); - mInternalCallback.onError( - MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, - e.toString()); - sIsInitialized.set(false); - return; - } - if (result == MbmsErrors.UNKNOWN) { - // Unbind and throw an obvious error - close(); - throw new IllegalStateException("Middleware must not return" - + " an unknown error code"); - } - if (result != MbmsErrors.SUCCESS) { - mInternalCallback.onError(result, - "Error returned during initialization"); - sIsInitialized.set(false); - return; - } - try { - groupCallService.asBinder().linkToDeath(mDeathRecipient, 0); - } catch (RemoteException e) { - mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST, - "Middleware lost during initialization"); - sIsInitialized.set(false); - return; - } - mService.set(groupCallService); - } + mServiceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + IMbmsGroupCallService groupCallService = + IMbmsGroupCallService.Stub.asInterface(service); + int result; + try { + result = groupCallService.initialize(mInternalCallback, + mSubscriptionId); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Service died before initialization"); + mInternalCallback.onError( + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + sIsInitialized.set(false); + return; + } catch (RuntimeException e) { + Log.e(LOG_TAG, "Runtime exception during initialization"); + mInternalCallback.onError( + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + sIsInitialized.set(false); + return; + } + if (result == MbmsErrors.UNKNOWN) { + // Unbind and throw an obvious error + close(); + throw new IllegalStateException("Middleware must not return" + + " an unknown error code"); + } + if (result != MbmsErrors.SUCCESS) { + mInternalCallback.onError(result, + "Error returned during initialization"); + sIsInitialized.set(false); + return; + } + try { + groupCallService.asBinder().linkToDeath(mDeathRecipient, 0); + } catch (RemoteException e) { + mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Middleware lost during initialization"); + sIsInitialized.set(false); + return; + } + mService.set(groupCallService); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + sIsInitialized.set(false); + mService.set(null); + } - @Override - public void onServiceDisconnected(ComponentName name) { - sIsInitialized.set(false); - mService.set(null); - } - }); + @Override + public void onNullBinding(ComponentName name) { + Log.w(LOG_TAG, "bindAndInitialize: Remote service returned null"); + mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Middleware service binding returned null"); + sIsInitialized.set(false); + mService.set(null); + mContext.unbindService(this); + } + }; + return MbmsUtils.startBinding(mContext, MBMS_GROUP_CALL_SERVICE_ACTION, mServiceConnection); } } diff --git a/telephony/java/android/telephony/MbmsStreamingSession.java b/telephony/java/android/telephony/MbmsStreamingSession.java index cd465d22d331..3fbbc03f0c67 100644 --- a/telephony/java/android/telephony/MbmsStreamingSession.java +++ b/telephony/java/android/telephony/MbmsStreamingSession.java @@ -82,6 +82,7 @@ public class MbmsStreamingSession implements AutoCloseable { }; private InternalStreamingSessionCallback mInternalCallback; + private ServiceConnection mServiceConnection; private Set<StreamingService> mKnownActiveStreamingServices = new ArraySet<>(); private final Context mContext; @@ -168,7 +169,7 @@ public class MbmsStreamingSession implements AutoCloseable { public void close() { try { IMbmsStreamingService streamingService = mService.get(); - if (streamingService == null) { + if (streamingService == null || mServiceConnection == null) { // Ignore and return, assume already disposed. return; } @@ -177,11 +178,13 @@ public class MbmsStreamingSession implements AutoCloseable { s.getCallback().stop(); } mKnownActiveStreamingServices.clear(); + mContext.unbindService(mServiceConnection); } catch (RemoteException e) { // Ignore for now } finally { mService.set(null); sIsInitialized.set(false); + mServiceConnection = null; mInternalCallback.stop(); } } @@ -286,59 +289,69 @@ public class MbmsStreamingSession implements AutoCloseable { } private int bindAndInitialize() { - return MbmsUtils.startBinding(mContext, MBMS_STREAMING_SERVICE_ACTION, - new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - IMbmsStreamingService streamingService = - IMbmsStreamingService.Stub.asInterface(service); - int result; - try { - result = streamingService.initialize(mInternalCallback, - mSubscriptionId); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Service died before initialization"); - sendErrorToApp( - MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, - e.toString()); - sIsInitialized.set(false); - return; - } catch (RuntimeException e) { - Log.e(LOG_TAG, "Runtime exception during initialization"); - sendErrorToApp( - MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, - e.toString()); - sIsInitialized.set(false); - return; - } - if (result == MbmsErrors.UNKNOWN) { - // Unbind and throw an obvious error - close(); - throw new IllegalStateException("Middleware must not return" - + " an unknown error code"); - } - if (result != MbmsErrors.SUCCESS) { - sendErrorToApp(result, "Error returned during initialization"); - sIsInitialized.set(false); - return; - } - try { - streamingService.asBinder().linkToDeath(mDeathRecipient, 0); - } catch (RemoteException e) { - sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, - "Middleware lost during initialization"); - sIsInitialized.set(false); - return; - } - mService.set(streamingService); - } + mServiceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + IMbmsStreamingService streamingService = + IMbmsStreamingService.Stub.asInterface(service); + int result; + try { + result = streamingService.initialize(mInternalCallback, + mSubscriptionId); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Service died before initialization"); + sendErrorToApp( + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + sIsInitialized.set(false); + return; + } catch (RuntimeException e) { + Log.e(LOG_TAG, "Runtime exception during initialization"); + sendErrorToApp( + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + sIsInitialized.set(false); + return; + } + if (result == MbmsErrors.UNKNOWN) { + // Unbind and throw an obvious error + close(); + throw new IllegalStateException("Middleware must not return" + + " an unknown error code"); + } + if (result != MbmsErrors.SUCCESS) { + sendErrorToApp(result, "Error returned during initialization"); + sIsInitialized.set(false); + return; + } + try { + streamingService.asBinder().linkToDeath(mDeathRecipient, 0); + } catch (RemoteException e) { + sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Middleware lost during initialization"); + sIsInitialized.set(false); + return; + } + mService.set(streamingService); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + sIsInitialized.set(false); + mService.set(null); + } - @Override - public void onServiceDisconnected(ComponentName name) { - sIsInitialized.set(false); - mService.set(null); - } - }); + @Override + public void onNullBinding(ComponentName name) { + Log.w(LOG_TAG, "bindAndInitialize: Remote service returned null"); + sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Middleware service binding returned null"); + sIsInitialized.set(false); + mService.set(null); + mContext.unbindService(this); + } + }; + return MbmsUtils.startBinding(mContext, MBMS_STREAMING_SERVICE_ACTION, mServiceConnection); } private void sendErrorToApp(int errorCode, String message) { diff --git a/telephony/java/android/telephony/MmsManager.java b/telephony/java/android/telephony/MmsManager.java new file mode 100644 index 000000000000..4bcf04691652 --- /dev/null +++ b/telephony/java/android/telephony/MmsManager.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 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. + */ + +package android.telephony; + +import android.app.ActivityThread; +import android.app.PendingIntent; +import android.net.Uri; +import android.os.Bundle; +import android.os.RemoteException; +import android.os.ServiceManager; + +import com.android.internal.telephony.IMms; + +/** + * Manages MMS operations such as sending multimedia messages. + * Get this object by calling the static method {@link #getInstance()}. + * @hide + */ +public class MmsManager { + private static final String TAG = "MmsManager"; + + /** Singleton object constructed during class initialization. */ + private static final MmsManager sInstance = new MmsManager(); + + /** + * Get the MmsManager singleton instance. + * + * @return the {@link MmsManager} singleton instance. + */ + public static MmsManager getInstance() { + return sInstance; + } + + /** + * Send an MMS message + * + * @param subId the subscription id + * @param contentUri the content Uri from which the message pdu will be read + * @param locationUrl the optional location url where message should be sent to + * @param configOverrides the carrier-specific messaging configuration values to override for + * sending the message. + * @param sentIntent if not NULL this <code>PendingIntent</code> is broadcast when the message + * is successfully sent, or failed + */ + public void sendMultimediaMessage(int subId, Uri contentUri, String locationUrl, + Bundle configOverrides, PendingIntent sentIntent) { + try { + final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); + if (iMms == null) { + return; + } + + iMms.sendMessage(subId, ActivityThread.currentPackageName(), contentUri, + locationUrl, configOverrides, sentIntent); + } catch (RemoteException e) { + // Ignore it + } + } + + /** + * Download an MMS message from carrier by a given location URL + * + * @param subId the subscription id + * @param locationUrl the location URL of the MMS message to be downloaded, usually obtained + * from the MMS WAP push notification + * @param contentUri the content uri to which the downloaded pdu will be written + * @param configOverrides the carrier-specific messaging configuration values to override for + * downloading the message. + * @param downloadedIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is downloaded, or the download is failed + * @throws IllegalArgumentException if locationUrl or contentUri is empty + */ + public void downloadMultimediaMessage(int subId, String locationUrl, Uri contentUri, + Bundle configOverrides, PendingIntent downloadedIntent) { + try { + final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); + if (iMms == null) { + return; + } + iMms.downloadMessage(subId, ActivityThread.currentPackageName(), + locationUrl, contentUri, configOverrides, downloadedIntent); + } catch (RemoteException e) { + // Ignore it + } + } + + /** + * Get carrier-dependent configuration values. + * + * @param subId the subscription id + * @return bundle key/values pairs of configuration values + */ + public Bundle getCarrierConfigValues(int subId) { + try { + IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); + if (iMms != null) { + return iMms.getCarrierConfigValues(subId); + } + } catch (RemoteException ex) { + // ignore it + } + return null; + } +} diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java index a76b8da09064..3e028715fd6d 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -24,8 +24,8 @@ import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; import android.telephony.AccessNetworkConstants.TransportType; -import android.telephony.TelephonyManager.NetworkType; +import android.telephony.Annotation.NetworkType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index 1e1e3daff3ec..57348979e8b1 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -28,6 +28,10 @@ import android.os.Bundle; import android.os.Handler; import android.os.HandlerExecutor; import android.os.Looper; +import android.telephony.Annotation.CallState; +import android.telephony.Annotation.RadioPowerState; +import android.telephony.Annotation.SimActivationState; +import android.telephony.Annotation.SrvccState; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; @@ -567,7 +571,7 @@ public class PhoneStateListener { * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an empty string will be * passed as an argument. */ - public void onCallStateChanged(@TelephonyManager.CallState int state, String phoneNumber) { + public void onCallStateChanged(@CallState int state, String phoneNumber) { // default implementation empty } @@ -773,7 +777,7 @@ public class PhoneStateListener { * @hide */ @SystemApi - public void onSrvccStateChanged(@TelephonyManager.SrvccState int srvccState) { + public void onSrvccStateChanged(@SrvccState int srvccState) { } @@ -791,7 +795,7 @@ public class PhoneStateListener { * @hide */ @SystemApi - public void onVoiceActivationStateChanged(@TelephonyManager.SimActivationState int state) { + public void onVoiceActivationStateChanged(@SimActivationState int state) { } /** @@ -807,7 +811,7 @@ public class PhoneStateListener { * @param state is the current SIM data activation state * @hide */ - public void onDataActivationStateChanged(@TelephonyManager.SimActivationState int state) { + public void onDataActivationStateChanged(@SimActivationState int state) { } /** @@ -964,7 +968,7 @@ public class PhoneStateListener { * @hide */ @SystemApi - public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) { + public void onRadioPowerStateChanged(@RadioPowerState int state) { // default implementation empty } @@ -1231,7 +1235,7 @@ public class PhoneStateListener { () -> mExecutor.execute(() -> psl.onPhoneCapabilityChanged(capability))); } - public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) { + public void onRadioPowerStateChanged(@RadioPowerState int state) { PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); if (psl == null) return; diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java index e1763ab44fba..4273f5a4a16e 100644 --- a/telephony/java/android/telephony/PhysicalChannelConfig.java +++ b/telephony/java/android/telephony/PhysicalChannelConfig.java @@ -19,8 +19,8 @@ package android.telephony; import android.annotation.IntDef; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.TelephonyManager.NetworkType; +import android.telephony.Annotation.NetworkType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java index 701a375a3039..f929649453b9 100644 --- a/telephony/java/android/telephony/PreciseCallState.java +++ b/telephony/java/android/telephony/PreciseCallState.java @@ -41,7 +41,7 @@ import java.util.Objects; * <li>Precise background call state. * </ul> * - * @see android.telephony.TelephonyManager.CallState which contains generic call states. + * @see android.telephony.Annotation.CallState which contains generic call states. * * @hide */ diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java index 90d443a6d8ee..257d634f1577 100644 --- a/telephony/java/android/telephony/PreciseDataConnectionState.java +++ b/telephony/java/android/telephony/PreciseDataConnectionState.java @@ -23,6 +23,10 @@ import android.annotation.UnsupportedAppUsage; import android.net.LinkProperties; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Annotation.ApnType; +import android.telephony.Annotation.DataFailureCause; +import android.telephony.Annotation.DataState; +import android.telephony.Annotation.NetworkType; import android.telephony.data.ApnSetting; import java.util.Objects; @@ -47,10 +51,10 @@ import java.util.Objects; @SystemApi public final class PreciseDataConnectionState implements Parcelable { - private @TelephonyManager.DataState int mState = TelephonyManager.DATA_UNKNOWN; - private @TelephonyManager.NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; - private @DataFailCause.FailCause int mFailCause = DataFailCause.NONE; - private @ApnSetting.ApnType int mAPNTypes = ApnSetting.TYPE_NONE; + private @DataState int mState = TelephonyManager.DATA_UNKNOWN; + private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; + private @DataFailureCause int mFailCause = DataFailCause.NONE; + private @ApnType int mAPNTypes = ApnSetting.TYPE_NONE; private String mAPN = ""; private LinkProperties mLinkProperties = null; @@ -60,11 +64,11 @@ public final class PreciseDataConnectionState implements Parcelable { * @hide */ @UnsupportedAppUsage - public PreciseDataConnectionState(@TelephonyManager.DataState int state, - @TelephonyManager.NetworkType int networkType, - @ApnSetting.ApnType int apnTypes, String apn, + public PreciseDataConnectionState(@DataState int state, + @NetworkType int networkType, + @ApnType int apnTypes, String apn, LinkProperties linkProperties, - @DataFailCause.FailCause int failCause) { + @DataFailureCause int failCause) { mState = state; mNetworkType = networkType; mAPNTypes = apnTypes; @@ -99,7 +103,7 @@ public final class PreciseDataConnectionState implements Parcelable { * Returns the state of data connection that supported the apn types returned by * {@link #getDataConnectionApnTypeBitMask()} */ - public @TelephonyManager.DataState int getDataConnectionState() { + public @DataState int getDataConnectionState() { return mState; } @@ -107,7 +111,7 @@ public final class PreciseDataConnectionState implements Parcelable { * Returns the network type associated with this data connection. * @hide */ - public @TelephonyManager.NetworkType int getDataConnectionNetworkType() { + public @NetworkType int getDataConnectionNetworkType() { return mNetworkType; } @@ -115,7 +119,7 @@ public final class PreciseDataConnectionState implements Parcelable { * Returns the data connection APN types supported by this connection and triggers * {@link PreciseDataConnectionState} change. */ - public @ApnSetting.ApnType int getDataConnectionApnTypeBitMask() { + public @ApnType int getDataConnectionApnTypeBitMask() { return mAPNTypes; } @@ -139,7 +143,7 @@ public final class PreciseDataConnectionState implements Parcelable { /** * Returns data connection fail cause, in case there was a failure. */ - public @DataFailCause.FailCause int getDataConnectionFailCause() { + public @Annotation.DataFailureCause int getDataConnectionFailCause() { return mFailCause; } diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index a985a6bd0787..c57512973c3d 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -29,6 +29,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.telephony.AccessNetworkConstants.AccessNetworkType; import android.telephony.AccessNetworkConstants.TransportType; +import android.telephony.Annotation.NetworkType; import android.telephony.NetworkRegistrationInfo.Domain; import android.telephony.NetworkRegistrationInfo.NRState; import android.text.TextUtils; @@ -1617,7 +1618,7 @@ public class ServiceState implements Parcelable { * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public @TelephonyManager.NetworkType int getDataNetworkType() { + public @NetworkType int getDataNetworkType() { final NetworkRegistrationInfo iwlanRegInfo = getNetworkRegistrationInfo( NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN); final NetworkRegistrationInfo wwanRegInfo = getNetworkRegistrationInfo( @@ -1644,7 +1645,7 @@ public class ServiceState implements Parcelable { /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public @TelephonyManager.NetworkType int getVoiceNetworkType() { + public @NetworkType int getVoiceNetworkType() { final NetworkRegistrationInfo regState = getNetworkRegistrationInfo( NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); if (regState != null) { diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 8c14cb444d89..71fcf23cb6ee 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -27,13 +27,11 @@ import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.app.PendingIntent; -import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.database.CursorWindow; import android.net.Uri; -import android.os.BaseBundle; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -45,7 +43,6 @@ import android.util.ArrayMap; import android.util.Log; import com.android.internal.telephony.IIntegerConsumer; -import com.android.internal.telephony.IMms; import com.android.internal.telephony.ISms; import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.SmsRawData; @@ -357,6 +354,68 @@ public final class SmsManager { true /* persistMessage*/, ActivityThread.currentPackageName()); } + /** + * Send a text based SMS with messaging options. + * + * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this + * manager on a multi-SIM device, this operation may fail sending the SMS message because no + * suitable default subscription could be found. In this case, if {@code sentIntent} is + * non-null, then the {@link PendingIntent} will be sent with an error code + * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the + * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions + * where this operation may fail. + * </p> + * + * @param destinationAddress the address to send the message to + * @param scAddress is the service center address or null to use + * the current default SMSC + * @param text the body of the message to send + * @param sentIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is successfully sent, or failed. + * The result code will be <code>Activity.RESULT_OK</code> for success, + * or one of these errors:<br> + * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> + * <code>RESULT_ERROR_RADIO_OFF</code><br> + * <code>RESULT_ERROR_NULL_PDU</code><br> + * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include + * the extra "errorCode" containing a radio technology specific value, + * generally only useful for troubleshooting.<br> + * The per-application based SMS control checks sentIntent. If sentIntent + * is NULL the caller will be checked against all unknown applications, + * which cause smaller number of SMS to be sent in checking period. + * @param deliveryIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is delivered to the recipient. The + * raw pdu of the status report is in the extended data ("pdu"). + * @param priority Priority level of the message + * Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1 + * --------------------------------- + * PRIORITY | Level of Priority + * --------------------------------- + * '00' | Normal + * '01' | Interactive + * '10' | Urgent + * '11' | Emergency + * ---------------------------------- + * Any Other values included Negative considered as Invalid Priority Indicator of the message. + * @param expectMore is a boolean to indicate the sending messages through same link or not. + * @param validityPeriod Validity Period of the message in mins. + * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1. + * Validity Period(Minimum) -> 5 mins + * Validity Period(Maximum) -> 635040 mins(i.e.63 weeks). + * Any Other values included Negative considered as Invalid Validity Period of the message. + * + * @throws IllegalArgumentException if destinationAddress or text are empty + * {@hide} + */ + @UnsupportedAppUsage + public void sendTextMessage( + String destinationAddress, String scAddress, String text, + PendingIntent sentIntent, PendingIntent deliveryIntent, + int priority, boolean expectMore, int validityPeriod) { + sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, + true /* persistMessage*/, priority, expectMore, validityPeriod); + } + private void sendTextMessageInternal(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, String packageName) { @@ -455,109 +514,6 @@ public final class SmsManager { false /* persistMessage */, ActivityThread.currentPackageName()); } - /** - * A variant of {@link SmsManager#sendTextMessage} that allows self to be the caller. This is - * for internal use only. - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier - * applications or the Telephony framework and will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the SMS being sent on the subscription associated with logical - * slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the - * correct subscription. - * </p> - * - * @param persistMessage whether to persist the sent message in the SMS app. the caller must be - * the Phone process if set to false. - * - * @hide - */ - public void sendTextMessageWithSelfPermissions( - String destinationAddress, String scAddress, String text, - PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage) { - if (TextUtils.isEmpty(destinationAddress)) { - throw new IllegalArgumentException("Invalid destinationAddress"); - } - - if (TextUtils.isEmpty(text)) { - throw new IllegalArgumentException("Invalid message body"); - } - - try { - ISms iSms = getISmsServiceOrThrow(); - iSms.sendTextForSubscriberWithSelfPermissions(getSubscriptionId(), - ActivityThread.currentPackageName(), - destinationAddress, - scAddress, text, sentIntent, deliveryIntent, persistMessage); - } catch (RemoteException ex) { - notifySmsGenericError(sentIntent); - } - } - - /** - * Send a text based SMS with messaging options. - * - * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this - * manager on a multi-SIM device, this operation may fail sending the SMS message because no - * suitable default subscription could be found. In this case, if {@code sentIntent} is - * non-null, then the {@link PendingIntent} will be sent with an error code - * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the - * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions - * where this operation may fail. - * </p> - * - * @param destinationAddress the address to send the message to - * @param scAddress is the service center address or null to use - * the current default SMSC - * @param text the body of the message to send - * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is successfully sent, or failed. - * The result code will be <code>Activity.RESULT_OK</code> for success, - * or one of these errors:<br> - * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> - * <code>RESULT_ERROR_RADIO_OFF</code><br> - * <code>RESULT_ERROR_NULL_PDU</code><br> - * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.<br> - * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applications, - * which cause smaller number of SMS to be sent in checking period. - * @param deliveryIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - * @param priority Priority level of the message - * Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1 - * --------------------------------- - * PRIORITY | Level of Priority - * --------------------------------- - * '00' | Normal - * '01' | Interactive - * '10' | Urgent - * '11' | Emergency - * ---------------------------------- - * Any Other values included Negative considered as Invalid Priority Indicator of the message. - * @param expectMore is a boolean to indicate the sending messages through same link or not. - * @param validityPeriod Validity Period of the message in mins. - * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1. - * Validity Period(Minimum) -> 5 mins - * Validity Period(Maximum) -> 635040 mins(i.e.63 weeks). - * Any Other values included Negative considered as Invalid Validity Period of the message. - * - * @throws IllegalArgumentException if destinationAddress or text are empty - * {@hide} - */ - @UnsupportedAppUsage - public void sendTextMessage( - String destinationAddress, String scAddress, String text, - PendingIntent sentIntent, PendingIntent deliveryIntent, - int priority, boolean expectMore, int validityPeriod) { - sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, - true /* persistMessage*/, priority, expectMore, validityPeriod); - } - private void sendTextMessageInternal( String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, @@ -1078,37 +1034,6 @@ public final class SmsManager { } /** - * Send a multi-part text based SMS without writing it into the SMS Provider. - * - * <p>Requires Permission: - * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or the calling app has carrier - * privileges. - * </p> - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use the Telephony - * framework and will never trigger an SMS disambiguation dialog. If this method is called on a - * device that has multiple active subscriptions, this {@link SmsManager} instance has been - * created with {@link #getDefault()}, and no user-defined default subscription is defined, the - * subscription ID associated with this message will be INVALID, which will result in the SMS - * being sent on the subscription associated with logical slot 0. Use - * {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the correct - * subscription. - * </p> - * - * @see #sendMultipartTextMessage(String, String, ArrayList, ArrayList, - * ArrayList, int, boolean, int) - * @hide - **/ - public void sendMultipartTextMessageWithoutPersisting( - String destinationAddress, String scAddress, List<String> parts, - List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, - int priority, boolean expectMore, int validityPeriod) { - sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents, - deliveryIntents, false /* persistMessage*/, priority, expectMore, - validityPeriod); - } - - /** * Send a data based SMS to a specific application port. * * <p class="note"><strong>Note:</strong> Using this method requires that your app has the @@ -1180,45 +1105,6 @@ public final class SmsManager { } /** - * A variant of {@link SmsManager#sendDataMessage} that allows self to be the caller. This is - * for internal use only. - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier - * applications or the Telephony framework and will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the SMS being sent on the subscription associated with logical - * slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the - * correct subscription. - * </p> - * - * @hide - */ - public void sendDataMessageWithSelfPermissions( - String destinationAddress, String scAddress, short destinationPort, - byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { - if (TextUtils.isEmpty(destinationAddress)) { - throw new IllegalArgumentException("Invalid destinationAddress"); - } - - if (data == null || data.length == 0) { - throw new IllegalArgumentException("Invalid message data"); - } - - try { - ISms iSms = getISmsServiceOrThrow(); - iSms.sendDataForSubscriberWithSelfPermissions(getSubscriptionId(), - ActivityThread.currentPackageName(), destinationAddress, scAddress, - destinationPort & 0xFFFF, data, sentIntent, deliveryIntent); - } catch (RemoteException e) { - Log.e(TAG, "sendDataMessageWithSelfPermissions: Couldn't send SMS - Exception: " - + e.getMessage()); - notifySmsGenericError(sentIntent); - } - } - - /** * Get the SmsManager associated with the default subscription id. The instance will always be * associated with the default subscription id, even if the default subscription id changes. * @@ -1650,100 +1536,6 @@ public final class SmsManager { /** * Enable reception of cell broadcast (SMS-CB) messages with the given - * message identifier and RAN type. The RAN type specify this message ID - * belong to 3GPP (GSM) or 3GPP2(CDMA).Note that if two different clients - * enable the same message identifier, they must both disable it for the device to stop - * receiving those messages. All received messages will be broadcast in an - * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED". - * Note: This call is blocking, callers may want to avoid calling it from - * the main thread of an application. - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier - * applications or the Telephony framework and will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the operation being completed on the subscription associated - * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the - * operation is performed on the correct subscription. - * </p> - * - * @param messageIdentifier Message identifier as specified in TS 23.041 (3GPP) - * or C.R1001-G (3GPP2) - * @param ranType the message format as defined in {@link SmsCbMessage] - * @return true if successful, false otherwise - * @see #disableCellBroadcast(int, int) - * - * {@hide} - */ - public boolean enableCellBroadcast(int messageIdentifier, - @android.telephony.SmsCbMessage.MessageFormat int ranType) { - boolean success = false; - - try { - ISms iSms = getISmsService(); - if (iSms != null) { - // If getSubscriptionId() returns INVALID or an inactive subscription, we will use - // the default phone internally. - success = iSms.enableCellBroadcastForSubscriber(getSubscriptionId(), - messageIdentifier, ranType); - } - } catch (RemoteException ex) { - // ignore it - } - - return success; - } - - /** - * Disable reception of cell broadcast (SMS-CB) messages with the given - * message identifier and RAN type. The RAN type specify this message ID - * belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients - * enable the same message identifier, they must both disable it for the - * device to stop receiving those messages. - * Note: This call is blocking, callers may want to avoid calling it from - * the main thread of an application. - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier - * applications or the Telephony framework and will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the operation being completed on the subscription associated - * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the - * operation is performed on the correct subscription. - * </p> - * - * @param messageIdentifier Message identifier as specified in TS 23.041 (3GPP) - * or C.R1001-G (3GPP2) - * @param ranType the message format as defined in {@link SmsCbMessage} - * @return true if successful, false otherwise - * - * @see #enableCellBroadcast(int, int) - * - * {@hide} - */ - public boolean disableCellBroadcast(int messageIdentifier, - @android.telephony.SmsCbMessage.MessageFormat int ranType) { - boolean success = false; - - try { - ISms iSms = getISmsService(); - if (iSms != null) { - // If getSubscriptionId() returns INVALID or an inactive subscription, we will use - // the default phone internally. - success = iSms.disableCellBroadcastForSubscriber(getSubscriptionId(), - messageIdentifier, ranType); - } - } catch (RemoteException ex) { - // ignore it - } - - return success; - } - - /** - * Enable reception of cell broadcast (SMS-CB) messages with the given * message identifier range and RAN type. The RAN type specifies if this message ID * belongs to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients enable * the same message identifier, they must both disable it for the device to stop @@ -2144,9 +1936,6 @@ public final class SmsManager { @SystemApi static public final int RESULT_REQUEST_NOT_SUPPORTED = 24; - - static private final String PHONE_PACKAGE_NAME = "com.android.phone"; - /** * Send an MMS message * @@ -2173,17 +1962,8 @@ public final class SmsManager { if (contentUri == null) { throw new IllegalArgumentException("Uri contentUri null"); } - try { - final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms == null) { - return; - } - - iMms.sendMessage(getSubscriptionId(), ActivityThread.currentPackageName(), contentUri, + MmsManager.getInstance().sendMultimediaMessage(getSubscriptionId(), contentUri, locationUrl, configOverrides, sentIntent); - } catch (RemoteException e) { - // Ignore it - } } /** @@ -2216,16 +1996,8 @@ public final class SmsManager { if (contentUri == null) { throw new IllegalArgumentException("Uri contentUri null"); } - try { - final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms == null) { - return; - } - iMms.downloadMessage(getSubscriptionId(), ActivityThread.currentPackageName(), - locationUrl, contentUri, configOverrides, downloadedIntent); - } catch (RemoteException e) { - // Ignore it - } + MmsManager.getInstance().downloadMultimediaMessage(getSubscriptionId(), locationUrl, + contentUri, configOverrides, downloadedIntent); } // MMS send/download failure result codes @@ -2243,434 +2015,17 @@ public final class SmsManager { /** Intent extra name for HTTP status code for MMS HTTP failure in integer type */ public static final String EXTRA_MMS_HTTP_STATUS = "android.telephony.extra.MMS_HTTP_STATUS"; - /** - * Import a text message into system's SMS store - * - * Only default SMS apps can import SMS - * - * @param address the destination(source) address of the sent(received) message - * @param type the type of the message - * @param text the message text - * @param timestampMillis the message timestamp in milliseconds - * @param seen if the message is seen - * @param read if the message is read - * @return the message URI, null if failed - * @hide - */ - public Uri importTextMessage(String address, int type, String text, long timestampMillis, - boolean seen, boolean read) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.importTextMessage(ActivityThread.currentPackageName(), - address, type, text, timestampMillis, seen, read); - } - } catch (RemoteException ex) { - // ignore it - } - return null; - } - /** Represents the received SMS message for importing {@hide} */ public static final int SMS_TYPE_INCOMING = 0; /** Represents the sent SMS message for importing {@hide} */ public static final int SMS_TYPE_OUTGOING = 1; - /** - * Import a multimedia message into system's MMS store. Only the following PDU type is - * supported: Retrieve.conf, Send.req, Notification.ind, Delivery.ind, Read-Orig.ind - * - * Only default SMS apps can import MMS - * - * @param contentUri the content uri from which to read the PDU of the message to import - * @param messageId the optional message id. Use null if not specifying - * @param timestampSecs the optional message timestamp. Use -1 if not specifying - * @param seen if the message is seen - * @param read if the message is read - * @return the message URI, null if failed - * @throws IllegalArgumentException if pdu is empty - * {@hide} - */ - public Uri importMultimediaMessage(Uri contentUri, String messageId, long timestampSecs, - boolean seen, boolean read) { - if (contentUri == null) { - throw new IllegalArgumentException("Uri contentUri null"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.importMultimediaMessage(ActivityThread.currentPackageName(), - contentUri, messageId, timestampSecs, seen, read); - } - } catch (RemoteException ex) { - // ignore it - } - return null; - } - - /** - * Delete a system stored SMS or MMS message - * - * Only default SMS apps can delete system stored SMS and MMS messages - * - * @param messageUri the URI of the stored message - * @return true if deletion is successful, false otherwise - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public boolean deleteStoredMessage(Uri messageUri) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.deleteStoredMessage(ActivityThread.currentPackageName(), messageUri); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - - /** - * Delete a system stored SMS or MMS thread - * - * Only default SMS apps can delete system stored SMS and MMS conversations - * - * @param conversationId the ID of the message conversation - * @return true if deletion is successful, false otherwise - * {@hide} - */ - public boolean deleteStoredConversation(long conversationId) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.deleteStoredConversation( - ActivityThread.currentPackageName(), conversationId); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - - /** - * Update the status properties of a system stored SMS or MMS message, e.g. - * the read status of a message, etc. - * - * @param messageUri the URI of the stored message - * @param statusValues a list of status properties in key-value pairs to update - * @return true if update is successful, false otherwise - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public boolean updateStoredMessageStatus(Uri messageUri, ContentValues statusValues) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.updateStoredMessageStatus(ActivityThread.currentPackageName(), - messageUri, statusValues); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - /** Message status property: whether the message has been seen. 1 means seen, 0 not {@hide} */ public static final String MESSAGE_STATUS_SEEN = "seen"; /** Message status property: whether the message has been read. 1 means read, 0 not {@hide} */ public static final String MESSAGE_STATUS_READ = "read"; /** - * Archive or unarchive a stored conversation - * - * @param conversationId the ID of the message conversation - * @param archived true to archive the conversation, false to unarchive - * @return true if update is successful, false otherwise - * {@hide} - */ - public boolean archiveStoredConversation(long conversationId, boolean archived) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.archiveStoredConversation(ActivityThread.currentPackageName(), - conversationId, archived); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - - /** - * Add a text message draft to system SMS store - * - * Only default SMS apps can add SMS draft - * - * @param address the destination address of message - * @param text the body of the message to send - * @return the URI of the stored draft message - * {@hide} - */ - public Uri addTextMessageDraft(String address, String text) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.addTextMessageDraft(ActivityThread.currentPackageName(), address, text); - } - } catch (RemoteException ex) { - // ignore it - } - return null; - } - - /** - * Add a multimedia message draft to system MMS store - * - * Only default SMS apps can add MMS draft - * - * @param contentUri the content uri from which to read the PDU data of the draft MMS - * @return the URI of the stored draft message - * @throws IllegalArgumentException if pdu is empty - * {@hide} - */ - public Uri addMultimediaMessageDraft(Uri contentUri) { - if (contentUri == null) { - throw new IllegalArgumentException("Uri contentUri null"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.addMultimediaMessageDraft(ActivityThread.currentPackageName(), - contentUri); - } - } catch (RemoteException ex) { - // ignore it - } - return null; - } - - /** - * Send a system stored text message. - * - * You can only send a failed text message or a draft text message. - * - * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this - * manager on a multi-SIM device, this operation may fail sending the SMS message because no - * suitable default subscription could be found. In this case, if {@code sentIntent} is - * non-null, then the {@link PendingIntent} will be sent with an error code - * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the - * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions - * where this operation may fail. - * </p> - * - * @param messageUri the URI of the stored message - * @param scAddress is the service center address or null to use the current default SMSC - * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is successfully sent, or failed. - * The result code will be <code>Activity.RESULT_OK</code> for success, - * or one of these errors:<br> - * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> - * <code>RESULT_ERROR_RADIO_OFF</code><br> - * <code>RESULT_ERROR_NULL_PDU</code><br> - * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.<br> - * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applications, - * which cause smaller number of SMS to be sent in checking period. - * @param deliveryIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - * - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public void sendStoredTextMessage(Uri messageUri, String scAddress, PendingIntent sentIntent, - PendingIntent deliveryIntent) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - final Context context = ActivityThread.currentApplication().getApplicationContext(); - resolveSubscriptionForOperation(new SubscriptionResolverResult() { - @Override - public void onSuccess(int subId) { - try { - ISms iSms = getISmsServiceOrThrow(); - iSms.sendStoredText(subId, ActivityThread.currentPackageName(), messageUri, - scAddress, sentIntent, deliveryIntent); - } catch (RemoteException e) { - Log.e(TAG, "sendStoredTextMessage: Couldn't send SMS - Exception: " - + e.getMessage()); - notifySmsGenericError(sentIntent); - } - } - @Override - public void onFailure() { - notifySmsErrorNoDefaultSet(context, sentIntent); - } - }); - } - - /** - * Send a system stored multi-part text message. - * - * You can only send a failed text message or a draft text message. - * The provided <code>PendingIntent</code> lists should match the part number of the - * divided text of the stored message by using <code>divideMessage</code> - * - * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this - * manager on a multi-SIM device, this operation may fail sending the SMS message because no - * suitable default subscription could be found. In this case, if {@code sentIntent} is - * non-null, then the {@link PendingIntent} will be sent with an error code - * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the - * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions - * where this operation may fail. - * </p> - * - * @param messageUri the URI of the stored message - * @param scAddress is the service center address or null to use - * the current default SMSC - * @param sentIntents if not null, an <code>ArrayList</code> of - * <code>PendingIntent</code>s (one for each message part) that is - * broadcast when the corresponding message part has been sent. - * The result code will be <code>Activity.RESULT_OK</code> for success, - * or one of these errors:<br> - * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> - * <code>RESULT_ERROR_RADIO_OFF</code><br> - * <code>RESULT_ERROR_NULL_PDU</code><br> - * For <code>RESULT_ERROR_GENERIC_FAILURE</code> each sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.<br> - * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applications, - * which cause smaller number of SMS to be sent in checking period. - * @param deliveryIntents if not null, an <code>ArrayList</code> of - * <code>PendingIntent</code>s (one for each message part) that is - * broadcast when the corresponding message part has been delivered - * to the recipient. The raw pdu of the status report is in the - * extended data ("pdu"). - * - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public void sendStoredMultipartTextMessage(Uri messageUri, String scAddress, - ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - final Context context = ActivityThread.currentApplication().getApplicationContext(); - resolveSubscriptionForOperation(new SubscriptionResolverResult() { - @Override - public void onSuccess(int subId) { - try { - ISms iSms = getISmsServiceOrThrow(); - iSms.sendStoredMultipartText(subId, ActivityThread.currentPackageName(), - messageUri, scAddress, sentIntents, deliveryIntents); - } catch (RemoteException e) { - Log.e(TAG, "sendStoredTextMessage: Couldn't send SMS - Exception: " - + e.getMessage()); - notifySmsGenericError(sentIntents); - } - } - @Override - public void onFailure() { - notifySmsErrorNoDefaultSet(context, sentIntents); - } - }); - } - - /** - * Send a system stored MMS message - * - * This is used for sending a previously sent, but failed-to-send, message or - * for sending a text message that has been stored as a draft. - * - * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the operation being completed on the subscription associated - * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the - * operation is performed on the correct subscription. - * </p> - * - * @param messageUri the URI of the stored message - * @param configOverrides the carrier-specific messaging configuration values to override for - * sending the message. - * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is successfully sent, or failed - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public void sendStoredMultimediaMessage(Uri messageUri, Bundle configOverrides, - PendingIntent sentIntent) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - iMms.sendStoredMessage( - getSubscriptionId(), ActivityThread.currentPackageName(), messageUri, - configOverrides, sentIntent); - } - } catch (RemoteException ex) { - // ignore it - } - } - - /** - * Turns on/off the flag to automatically write sent/received SMS/MMS messages into system - * - * When this flag is on, all SMS/MMS sent/received are stored by system automatically - * When this flag is off, only SMS/MMS sent by non-default SMS apps are stored by system - * automatically - * - * This flag can only be changed by default SMS apps - * - * @param enabled Whether to enable message auto persisting - * {@hide} - */ - public void setAutoPersisting(boolean enabled) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - iMms.setAutoPersisting(ActivityThread.currentPackageName(), enabled); - } - } catch (RemoteException ex) { - // ignore it - } - } - - /** - * Get the value of the flag to automatically write sent/received SMS/MMS messages into system - * - * When this flag is on, all SMS/MMS sent/received are stored by system automatically - * When this flag is off, only SMS/MMS sent by non-default SMS apps are stored by system - * automatically - * - * @return the current value of the auto persist flag - * {@hide} - */ - public boolean getAutoPersisting() { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.getAutoPersisting(); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - - /** * Get carrier-dependent configuration values. * * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier @@ -2686,15 +2041,7 @@ public final class SmsManager { * @return bundle key/values pairs of configuration values */ public Bundle getCarrierConfigValues() { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.getCarrierConfigValues(getSubscriptionId()); - } - } catch (RemoteException ex) { - // ignore it - } - return null; + return MmsManager.getInstance().getCarrierConfigValues(getSubscriptionId()); } /** @@ -2780,38 +2127,38 @@ public final class SmsManager { } /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * The prefixes is a list of prefix {@code String} separated by this delimiter. * @hide */ public static final String REGEX_PREFIX_DELIMITER = ","; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * The success status to be added into the intent to be sent to the calling package. * @hide */ public static final int RESULT_STATUS_SUCCESS = 0; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * The timeout status to be added into the intent to be sent to the calling package. * @hide */ public static final int RESULT_STATUS_TIMEOUT = 1; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * Intent extra key of the retrieved SMS message as a {@code String}. * @hide */ public static final String EXTRA_SMS_MESSAGE = "android.telephony.extra.SMS_MESSAGE"; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * Intent extra key of SMS retriever status, which indicates whether the request for the * coming SMS message is SUCCESS or TIMEOUT * @hide */ public static final String EXTRA_STATUS = "android.telephony.extra.STATUS"; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * [Optional] Intent extra key of the retrieved Sim card subscription Id if any. {@code int} * @hide */ @@ -2861,74 +2208,6 @@ public final class SmsManager { } } - /** - * Filters a bundle to only contain MMS config variables. - * - * This is for use with bundles returned by {@link CarrierConfigManager} which contain MMS - * config and unrelated config. It is assumed that all MMS_CONFIG_* keys are present in the - * supplied bundle. - * - * @param config a Bundle that contains MMS config variables and possibly more. - * @return a new Bundle that only contains the MMS_CONFIG_* keys defined above. - * @hide - */ - public static Bundle getMmsConfig(BaseBundle config) { - Bundle filtered = new Bundle(); - filtered.putBoolean(MMS_CONFIG_APPEND_TRANSACTION_ID, - config.getBoolean(MMS_CONFIG_APPEND_TRANSACTION_ID)); - filtered.putBoolean(MMS_CONFIG_MMS_ENABLED, config.getBoolean(MMS_CONFIG_MMS_ENABLED)); - filtered.putBoolean(MMS_CONFIG_GROUP_MMS_ENABLED, - config.getBoolean(MMS_CONFIG_GROUP_MMS_ENABLED)); - filtered.putBoolean(MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED, - config.getBoolean(MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED)); - filtered.putBoolean(MMS_CONFIG_ALIAS_ENABLED, config.getBoolean(MMS_CONFIG_ALIAS_ENABLED)); - filtered.putBoolean(MMS_CONFIG_ALLOW_ATTACH_AUDIO, - config.getBoolean(MMS_CONFIG_ALLOW_ATTACH_AUDIO)); - filtered.putBoolean(MMS_CONFIG_MULTIPART_SMS_ENABLED, - config.getBoolean(MMS_CONFIG_MULTIPART_SMS_ENABLED)); - filtered.putBoolean(MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED, - config.getBoolean(MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED)); - filtered.putBoolean(MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION, - config.getBoolean(MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION)); - filtered.putBoolean(MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES, - config.getBoolean(MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES)); - filtered.putBoolean(MMS_CONFIG_MMS_READ_REPORT_ENABLED, - config.getBoolean(MMS_CONFIG_MMS_READ_REPORT_ENABLED)); - filtered.putBoolean(MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED, - config.getBoolean(MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED)); - filtered.putBoolean(MMS_CONFIG_CLOSE_CONNECTION, - config.getBoolean(MMS_CONFIG_CLOSE_CONNECTION)); - filtered.putInt(MMS_CONFIG_MAX_MESSAGE_SIZE, config.getInt(MMS_CONFIG_MAX_MESSAGE_SIZE)); - filtered.putInt(MMS_CONFIG_MAX_IMAGE_WIDTH, config.getInt(MMS_CONFIG_MAX_IMAGE_WIDTH)); - filtered.putInt(MMS_CONFIG_MAX_IMAGE_HEIGHT, config.getInt(MMS_CONFIG_MAX_IMAGE_HEIGHT)); - filtered.putInt(MMS_CONFIG_RECIPIENT_LIMIT, config.getInt(MMS_CONFIG_RECIPIENT_LIMIT)); - filtered.putInt(MMS_CONFIG_ALIAS_MIN_CHARS, config.getInt(MMS_CONFIG_ALIAS_MIN_CHARS)); - filtered.putInt(MMS_CONFIG_ALIAS_MAX_CHARS, config.getInt(MMS_CONFIG_ALIAS_MAX_CHARS)); - filtered.putInt(MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD, - config.getInt(MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD)); - filtered.putInt(MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD, - config.getInt(MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD)); - filtered.putInt(MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE, - config.getInt(MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE)); - filtered.putInt(MMS_CONFIG_SUBJECT_MAX_LENGTH, - config.getInt(MMS_CONFIG_SUBJECT_MAX_LENGTH)); - filtered.putInt(MMS_CONFIG_HTTP_SOCKET_TIMEOUT, - config.getInt(MMS_CONFIG_HTTP_SOCKET_TIMEOUT)); - filtered.putString(MMS_CONFIG_UA_PROF_TAG_NAME, - config.getString(MMS_CONFIG_UA_PROF_TAG_NAME)); - filtered.putString(MMS_CONFIG_USER_AGENT, config.getString(MMS_CONFIG_USER_AGENT)); - filtered.putString(MMS_CONFIG_UA_PROF_URL, config.getString(MMS_CONFIG_UA_PROF_URL)); - filtered.putString(MMS_CONFIG_HTTP_PARAMS, config.getString(MMS_CONFIG_HTTP_PARAMS)); - filtered.putString(MMS_CONFIG_EMAIL_GATEWAY_NUMBER, - config.getString(MMS_CONFIG_EMAIL_GATEWAY_NUMBER)); - filtered.putString(MMS_CONFIG_NAI_SUFFIX, config.getString(MMS_CONFIG_NAI_SUFFIX)); - filtered.putBoolean(MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS, - config.getBoolean(MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS)); - filtered.putBoolean(MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER, - config.getBoolean(MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER)); - return filtered; - } - /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"SMS_CATEGORY_"}, diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index dcd35fdc4e16..a89328836e2a 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -53,7 +53,7 @@ import android.os.ParcelUuid; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; -import android.telephony.TelephonyManager.NetworkType; +import android.telephony.Annotation.NetworkType; import android.telephony.euicc.EuiccManager; import android.telephony.ims.ImsMmTelManager; import android.util.DisplayMetrics; @@ -2101,13 +2101,26 @@ public class SubscriptionManager { /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static boolean isValidSlotIndex(int slotIndex) { - return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getSimCount(); + return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getMaxPhoneCount(); } /** @hide */ @UnsupportedAppUsage public static boolean isValidPhoneId(int phoneId) { - return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getPhoneCount(); + return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getMaxPhoneCount(); + } + + /** + * When getPhoneCount and getMaxPhoneCount return different value, isValidPhoneId being true + * doesn't mean the phoneId has a corresponding active slot / logical modem. If a DSDS capable + * device is in single SIM mode, phoneId=1 is valid but not active. + * + * TODO: b/139642279 combine with SubscriptionManager#isValidPhoneId when phone objects + * are dynamically allocated instead of always based on getMaxPhoneCount. + * @hide + */ + public static boolean isActivePhoneId(int slotIndex) { + return slotIndex < TelephonyManager.getDefault().getPhoneCount(); } /** @hide */ diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 4f276bc845ca..1ff85b14c8bb 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -63,6 +63,12 @@ import android.telecom.InCallService; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; +import android.telephony.Annotation.ApnType; +import android.telephony.Annotation.CallState; +import android.telephony.Annotation.DataState; +import android.telephony.Annotation.NetworkType; +import android.telephony.Annotation.RadioPowerState; +import android.telephony.Annotation.SimActivationState; import android.telephony.VisualVoicemailService.VisualVoicemailTask; import android.telephony.data.ApnSetting; import android.telephony.emergency.EmergencyNumber; @@ -254,17 +260,6 @@ public class TelephonyManager { */ public static final int UNINITIALIZED_CARD_ID = -2; - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"SRVCC_STATE_"}, - value = { - SRVCC_STATE_HANDOVER_NONE, - SRVCC_STATE_HANDOVER_STARTED, - SRVCC_STATE_HANDOVER_COMPLETED, - SRVCC_STATE_HANDOVER_FAILED, - SRVCC_STATE_HANDOVER_CANCELED}) - public @interface SrvccState {} - private final Context mContext; private final int mSubId; @UnsupportedAppUsage @@ -404,7 +399,7 @@ public class TelephonyManager { * TODO: b/139642279 publicize and rename. * @hide */ - public static int getMaxPhoneCount() { + public int getMaxPhoneCount() { // TODO: b/139642279 when turning on this feature, remove dependency of // PROPERTY_REBOOT_REQUIRED_ON_MODEM_CHANGE and always return result based on // PROPERTY_MAX_ACTIVE_MODEMS. @@ -413,9 +408,9 @@ public class TelephonyManager { if (rebootRequired.equals("false")) { // If no reboot is required, return max possible active modems. return SystemProperties.getInt( - TelephonyProperties.PROPERTY_MAX_ACTIVE_MODEMS, getDefault().getPhoneCount()); + TelephonyProperties.PROPERTY_MAX_ACTIVE_MODEMS, getPhoneCount()); } else { - return getDefault().getPhoneCount(); + return getPhoneCount(); } } @@ -2538,33 +2533,6 @@ public class TelephonyManager { /** Max network type number. Update as new types are added. Don't add negative types. {@hide} */ public static final int MAX_NETWORK_TYPE = NETWORK_TYPE_NR; - /** @hide */ - @IntDef({ - NETWORK_TYPE_UNKNOWN, - NETWORK_TYPE_GPRS, - NETWORK_TYPE_EDGE, - NETWORK_TYPE_UMTS, - NETWORK_TYPE_CDMA, - NETWORK_TYPE_EVDO_0, - NETWORK_TYPE_EVDO_A, - NETWORK_TYPE_1xRTT, - NETWORK_TYPE_HSDPA, - NETWORK_TYPE_HSUPA, - NETWORK_TYPE_HSPA, - NETWORK_TYPE_IDEN, - NETWORK_TYPE_EVDO_B, - NETWORK_TYPE_LTE, - NETWORK_TYPE_EHRPD, - NETWORK_TYPE_HSPAP, - NETWORK_TYPE_GSM, - NETWORK_TYPE_TD_SCDMA, - NETWORK_TYPE_IWLAN, - NETWORK_TYPE_LTE_CA, - NETWORK_TYPE_NR, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface NetworkType{} - /** * Return the current data network type. * @@ -4611,17 +4579,6 @@ public class TelephonyManager { @SystemApi public static final int SIM_ACTIVATION_STATE_RESTRICTED = 4; - /** @hide */ - @IntDef({ - SIM_ACTIVATION_STATE_UNKNOWN, - SIM_ACTIVATION_STATE_ACTIVATING, - SIM_ACTIVATION_STATE_ACTIVATED, - SIM_ACTIVATION_STATE_DEACTIVATED, - SIM_ACTIVATION_STATE_RESTRICTED - }) - @Retention(RetentionPolicy.SOURCE) - public @interface SimActivationState{} - /** * Sets the voice activation state * @@ -5006,15 +4963,6 @@ public class TelephonyManager { */ public static final int CALL_STATE_OFFHOOK = 2; - /** @hide */ - @IntDef(prefix = { "CALL_STATE_" }, value = { - CALL_STATE_IDLE, - CALL_STATE_RINGING, - CALL_STATE_OFFHOOK - }) - @Retention(RetentionPolicy.SOURCE) - public @interface CallState{} - /** * Returns the state of all calls on the device. * <p> @@ -5095,17 +5043,6 @@ public class TelephonyManager { */ public static final int DATA_ACTIVITY_DORMANT = 0x00000004; - /** @hide */ - @IntDef(prefix = {"DATA_"}, value = { - DATA_ACTIVITY_NONE, - DATA_ACTIVITY_IN, - DATA_ACTIVITY_OUT, - DATA_ACTIVITY_INOUT, - DATA_ACTIVITY_DORMANT, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface DataActivityType{} - /** * Returns a constant indicating the type of activity on a data connection * (cellular). @@ -8321,15 +8258,6 @@ public class TelephonyManager { return false; } - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"RADIO_POWER_"}, - value = {RADIO_POWER_OFF, - RADIO_POWER_ON, - RADIO_POWER_UNAVAILABLE, - }) - public @interface RadioPowerState {} - /** * Radio explicitly powered off (e.g, airplane mode). * @hide @@ -11443,7 +11371,7 @@ public class TelephonyManager { * * @hide */ - public boolean isDataEnabledForApn(@ApnSetting.ApnType int apnType) { + public boolean isDataEnabledForApn(@ApnType int apnType) { String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; try { ITelephony service = getITelephony(); @@ -11464,7 +11392,7 @@ public class TelephonyManager { * * @hide */ - public boolean isApnMetered(@ApnSetting.ApnType int apnType) { + public boolean isApnMetered(@ApnType int apnType) { try { ITelephony service = getITelephony(); if (service != null) { diff --git a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java index 5f2f75da5c41..02429b5c2a2c 100644 --- a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java +++ b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java @@ -16,12 +16,19 @@ package android.telephony.cdma; +import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** - * CDMA Service Category Program Data from SCPT teleservice SMS. + * CDMA Service Category Program Data from SCPT (Service Category Programming Teleservice) SMS, + * as defined in 3GPP2 C.S0015-B section 4.5.19. + * <p> * The CellBroadcastReceiver app receives an Intent with action * {@link android.provider.Telephony.Sms.Intents#SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION} * containing an array of these objects to update its list of cell broadcast service categories @@ -29,6 +36,7 @@ import android.os.Parcelable; * * {@hide} */ +@SystemApi public final class CdmaSmsCbProgramData implements Parcelable { /** Delete the specified service category from the list of enabled categories. */ @@ -40,40 +48,83 @@ public final class CdmaSmsCbProgramData implements Parcelable { /** Clear all service categories from the list of enabled categories. */ public static final int OPERATION_CLEAR_CATEGORIES = 2; - /** Alert option: no alert. */ + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"OPERATION_"}, + value = { + OPERATION_DELETE_CATEGORY, + OPERATION_ADD_CATEGORY, + OPERATION_CLEAR_CATEGORIES, + }) + public @interface Operation {} + + // CMAS alert service category assignments, see 3GPP2 C.R1001 table 9.3.3-1 + /** Indicates a presidential-level alert */ + public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 0x1000; + + /** Indicates an extreme threat to life and property */ + public static final int CATEGORY_CMAS_EXTREME_THREAT = 0x1001; + + /** Indicates an severe threat to life and property */ + public static final int CATEGORY_CMAS_SEVERE_THREAT = 0x1002; + + /** Indicates an AMBER child abduction emergency */ + public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 0x1003; + + /** Indicates a CMAS test message */ + public static final int CATEGORY_CMAS_TEST_MESSAGE = 0x1004; + + /** The last reserved value of a CMAS service category according to 3GPP C.R1001 table + * 9.3.3-1. */ + public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 0x10ff; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"CATEGORY_"}, + value = { + CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT, + CATEGORY_CMAS_EXTREME_THREAT, + CATEGORY_CMAS_SEVERE_THREAT, + CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY, + CATEGORY_CMAS_TEST_MESSAGE, + CATEGORY_CMAS_LAST_RESERVED_VALUE, + }) + public @interface Category {} + + /** Alert option: no alert. @hide */ public static final int ALERT_OPTION_NO_ALERT = 0; - /** Alert option: default alert. */ + /** Alert option: default alert. @hide */ public static final int ALERT_OPTION_DEFAULT_ALERT = 1; - /** Alert option: vibrate alert once. */ + /** Alert option: vibrate alert once. @hide */ public static final int ALERT_OPTION_VIBRATE_ONCE = 2; - /** Alert option: vibrate alert - repeat. */ + /** Alert option: vibrate alert - repeat. @hide */ public static final int ALERT_OPTION_VIBRATE_REPEAT = 3; - /** Alert option: visual alert once. */ + /** Alert option: visual alert once. @hide */ public static final int ALERT_OPTION_VISUAL_ONCE = 4; - /** Alert option: visual alert - repeat. */ + /** Alert option: visual alert - repeat. @hide */ public static final int ALERT_OPTION_VISUAL_REPEAT = 5; - /** Alert option: low-priority alert once. */ + /** Alert option: low-priority alert once. @hide */ public static final int ALERT_OPTION_LOW_PRIORITY_ONCE = 6; - /** Alert option: low-priority alert - repeat. */ + /** Alert option: low-priority alert - repeat. @hide */ public static final int ALERT_OPTION_LOW_PRIORITY_REPEAT = 7; - /** Alert option: medium-priority alert once. */ + /** Alert option: medium-priority alert once. @hide */ public static final int ALERT_OPTION_MED_PRIORITY_ONCE = 8; - /** Alert option: medium-priority alert - repeat. */ + /** Alert option: medium-priority alert - repeat. @hide */ public static final int ALERT_OPTION_MED_PRIORITY_REPEAT = 9; - /** Alert option: high-priority alert once. */ + /** Alert option: high-priority alert once. @hide */ public static final int ALERT_OPTION_HIGH_PRIORITY_ONCE = 10; - /** Alert option: high-priority alert - repeat. */ + /** Alert option: high-priority alert - repeat. @hide */ public static final int ALERT_OPTION_HIGH_PRIORITY_REPEAT = 11; /** Service category operation (add/delete/clear). */ @@ -94,9 +145,12 @@ public final class CdmaSmsCbProgramData implements Parcelable { /** Name of service category. */ private final String mCategoryName; - /** Create a new CdmaSmsCbProgramData object with the specified values. */ - public CdmaSmsCbProgramData(int operation, int category, int language, int maxMessages, - int alertOption, @NonNull String categoryName) { + /** + * Create a new CdmaSmsCbProgramData object with the specified values. + * @hide + */ + public CdmaSmsCbProgramData(@Operation int operation, @Category int category, int language, + int maxMessages, int alertOption, @NonNull String categoryName) { mOperation = operation; mCategory = category; mLanguage = language; @@ -105,7 +159,10 @@ public final class CdmaSmsCbProgramData implements Parcelable { mCategoryName = categoryName; } - /** Create a new CdmaSmsCbProgramData object from a Parcel. */ + /** + * Create a new CdmaSmsCbProgramData object from a Parcel. + * @hide + */ CdmaSmsCbProgramData(Parcel in) { mOperation = in.readInt(); mCategory = in.readInt(); @@ -133,23 +190,28 @@ public final class CdmaSmsCbProgramData implements Parcelable { /** * Returns the service category operation, e.g. {@link #OPERATION_ADD_CATEGORY}. - * @return one of the {@code OPERATION_*} values + * + * @return the service category operation */ - public int getOperation() { + public @Operation int getOperation() { return mOperation; } /** - * Returns the CDMA service category to modify. + * Returns the CDMA service category to modify. See 3GPP2 C.S0015-B section 3.4.3.2 for more + * information on the service category. Currently only CMAS service categories 0x1000 through + * 0x10FF are supported. + * * @return a 16-bit CDMA service category value */ - public int getCategory() { + public @Category int getCategory() { return mCategory; } /** * Returns the CDMA language code for this service category. * @return one of the language values defined in BearerData.LANGUAGE_* + * @hide */ public int getLanguage() { return mLanguage; @@ -158,6 +220,7 @@ public final class CdmaSmsCbProgramData implements Parcelable { /** * Returns the maximum number of messages to store for this service category. * @return the maximum number of messages to store for this service category + * @hide */ public int getMaxMessages() { return mMaxMessages; @@ -166,6 +229,7 @@ public final class CdmaSmsCbProgramData implements Parcelable { /** * Returns the service category alert option, e.g. {@link #ALERT_OPTION_DEFAULT_ALERT}. * @return one of the {@code ALERT_OPTION_*} values + * @hide */ public int getAlertOption() { return mAlertOption; @@ -174,6 +238,7 @@ public final class CdmaSmsCbProgramData implements Parcelable { /** * Returns the service category name, in the language specified by {@link #getLanguage()}. * @return an optional service category name + * @hide */ @NonNull public String getCategoryName() { @@ -196,7 +261,10 @@ public final class CdmaSmsCbProgramData implements Parcelable { return 0; } - /** Creator for unparcelling objects. */ + /** + * Creator for unparcelling objects. + */ + @NonNull public static final Parcelable.Creator<CdmaSmsCbProgramData> CREATOR = new Parcelable.Creator<CdmaSmsCbProgramData>() { @Override diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index 116c05129a96..2161dcb9542f 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -26,6 +26,8 @@ import android.os.Parcel; import android.os.Parcelable; import android.provider.Telephony; import android.provider.Telephony.Carriers; +import android.telephony.Annotation.ApnType; +import android.telephony.Annotation.NetworkType; import android.telephony.Rlog; import android.telephony.ServiceState; import android.telephony.TelephonyManager; @@ -109,23 +111,6 @@ public class ApnSetting implements Parcelable { /** APN type for MCX (Mission Critical Service) where X can be PTT/Video/Data */ public static final int TYPE_MCX = ApnTypes.MCX; - /** @hide */ - @IntDef(flag = true, prefix = { "TYPE_" }, value = { - TYPE_DEFAULT, - TYPE_MMS, - TYPE_SUPL, - TYPE_DUN, - TYPE_HIPRI, - TYPE_FOTA, - TYPE_IMS, - TYPE_CBS, - TYPE_IA, - TYPE_EMERGENCY, - TYPE_MCX - }) - @Retention(RetentionPolicy.SOURCE) - public @interface ApnType {} - // Possible values for authentication types. /** No authentication type. */ public static final int AUTH_TYPE_NONE = 0; @@ -1425,7 +1410,7 @@ public class ApnSetting implements Parcelable { * * @hide */ - public boolean canSupportNetworkType(@TelephonyManager.NetworkType int networkType) { + public boolean canSupportNetworkType(@NetworkType int networkType) { // Do a special checking for GSM. In reality, GSM is a voice only network type and can never // be used for data. We allow it here because in some DSDS corner cases, on the non-DDS // sub, modem reports data rat unknown. In that case if voice is GSM and this APN supports diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java index 9170e88ce832..49625bbecf4f 100644 --- a/telephony/java/android/telephony/data/DataCallResponse.java +++ b/telephony/java/android/telephony/data/DataCallResponse.java @@ -24,8 +24,8 @@ import android.annotation.SystemApi; import android.net.LinkAddress; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Annotation.DataFailureCause; import android.telephony.DataFailCause; -import android.telephony.DataFailCause.FailCause; import android.telephony.data.ApnSetting.ProtocolType; import com.android.internal.annotations.VisibleForTesting; @@ -67,7 +67,7 @@ public final class DataCallResponse implements Parcelable { /** Indicates the data connection is active with physical link up. */ public static final int LINK_STATUS_ACTIVE = 2; - private final @FailCause int mCause; + private final @DataFailureCause int mCause; private final int mSuggestedRetryTime; private final int mId; private final @LinkStatus int mLinkStatus; @@ -103,7 +103,7 @@ public final class DataCallResponse implements Parcelable { * * @removed Use the {@link Builder()} instead. */ - public DataCallResponse(@FailCause int cause, int suggestedRetryTime, int id, + public DataCallResponse(@DataFailureCause int cause, int suggestedRetryTime, int id, @LinkStatus int linkStatus, @ProtocolType int protocolType, @Nullable String interfaceName, @Nullable List<LinkAddress> addresses, @@ -150,7 +150,7 @@ public final class DataCallResponse implements Parcelable { /** * @return Data call fail cause. {@link DataFailCause#NONE} indicates no error. */ - @FailCause + @DataFailureCause public int getCause() { return mCause; } /** @@ -314,7 +314,7 @@ public final class DataCallResponse implements Parcelable { * </code></pre> */ public static final class Builder { - private @FailCause int mCause; + private @DataFailureCause int mCause; private int mSuggestedRetryTime; @@ -348,7 +348,7 @@ public final class DataCallResponse implements Parcelable { * @param cause Data call fail cause. {@link DataFailCause#NONE} indicates no error. * @return The same instance of the builder. */ - public @NonNull Builder setCause(@FailCause int cause) { + public @NonNull Builder setCause(@DataFailureCause int cause) { mCause = cause; return this; } diff --git a/telephony/java/android/telephony/data/DataProfile.java b/telephony/java/android/telephony/data/DataProfile.java index 0d79ec98fcbb..30c209b28a4d 100644 --- a/telephony/java/android/telephony/data/DataProfile.java +++ b/telephony/java/android/telephony/data/DataProfile.java @@ -25,8 +25,8 @@ import android.annotation.SystemApi; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Annotation.ApnType; import android.telephony.TelephonyManager.NetworkTypeBitMask; -import android.telephony.data.ApnSetting.ApnType; import android.telephony.data.ApnSetting.AuthType; import android.text.TextUtils; diff --git a/telephony/java/android/telephony/data/QualifiedNetworksService.java b/telephony/java/android/telephony/data/QualifiedNetworksService.java index 0e1751d50949..e793979a61c9 100644 --- a/telephony/java/android/telephony/data/QualifiedNetworksService.java +++ b/telephony/java/android/telephony/data/QualifiedNetworksService.java @@ -27,8 +27,8 @@ import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.telephony.AccessNetworkConstants.AccessNetworkType; +import android.telephony.Annotation.ApnType; import android.telephony.Rlog; -import android.telephony.data.ApnSetting.ApnType; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; @@ -133,7 +133,7 @@ public abstract class QualifiedNetworksService extends Service { * service. * * @param apnTypes APN types of the qualified networks. This must be a bitmask combination - * of {@link ApnSetting.ApnType}. + * of {@link ApnType}. * @param qualifiedNetworkTypes List of network types which are qualified for data * connection setup for {@link @apnType} in the preferred order. Each element in the list * is a {@link AccessNetworkType}. An empty list indicates no networks are qualified diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java index 19d07242132b..16662652847d 100644 --- a/telephony/java/android/telephony/emergency/EmergencyNumber.java +++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java @@ -18,6 +18,7 @@ package android.telephony.emergency; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.TestApi; import android.hardware.radio.V1_4.EmergencyNumberSource; import android.hardware.radio.V1_4.EmergencyServiceCategory; import android.os.Parcel; @@ -184,6 +185,7 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu * * @hide */ + @TestApi public static final int EMERGENCY_NUMBER_SOURCE_TEST = 1 << 5; /** Bit-field which indicates the number is from the modem config. */ public static final int EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG = diff --git a/telephony/java/com/android/internal/telephony/SmsApplication.java b/telephony/java/com/android/internal/telephony/SmsApplication.java index f10398f09603..f4eae8ef4b2a 100644 --- a/telephony/java/com/android/internal/telephony/SmsApplication.java +++ b/telephony/java/com/android/internal/telephony/SmsApplication.java @@ -40,7 +40,6 @@ import android.os.UserHandle; import android.provider.Telephony; import android.provider.Telephony.Sms.Intents; import android.telephony.Rlog; -import android.telephony.SmsManager; import android.telephony.TelephonyManager; import android.util.Log; @@ -1045,9 +1044,6 @@ public final class SmsApplication { */ @UnsupportedAppUsage public static boolean shouldWriteMessageForPackage(String packageName, Context context) { - if (SmsManager.getDefault().getAutoPersisting()) { - return true; - } return !isDefaultSmsApplication(context, packageName); } diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java index 3440c651c8ea..2787b2451470 100644 --- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java @@ -18,6 +18,7 @@ package com.android.internal.telephony.cdma.sms; import android.annotation.UnsupportedAppUsage; +import android.telephony.cdma.CdmaSmsCbProgramData; public final class SmsEnvelope { /** @@ -55,12 +56,18 @@ public final class SmsEnvelope { //... // CMAS alert service category assignments, see 3GPP2 C.R1001 table 9.3.3-1 - public static final int SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 0x1000; - public static final int SERVICE_CATEGORY_CMAS_EXTREME_THREAT = 0x1001; - public static final int SERVICE_CATEGORY_CMAS_SEVERE_THREAT = 0x1002; - public static final int SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 0x1003; - public static final int SERVICE_CATEGORY_CMAS_TEST_MESSAGE = 0x1004; - public static final int SERVICE_CATEGORY_CMAS_LAST_RESERVED_VALUE = 0x10ff; + public static final int SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = + CdmaSmsCbProgramData.CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT; + public static final int SERVICE_CATEGORY_CMAS_EXTREME_THREAT = + CdmaSmsCbProgramData.CATEGORY_CMAS_EXTREME_THREAT; + public static final int SERVICE_CATEGORY_CMAS_SEVERE_THREAT = + CdmaSmsCbProgramData.CATEGORY_CMAS_SEVERE_THREAT; + public static final int SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = + CdmaSmsCbProgramData.CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY; + public static final int SERVICE_CATEGORY_CMAS_TEST_MESSAGE = + CdmaSmsCbProgramData.CATEGORY_CMAS_TEST_MESSAGE; + public static final int SERVICE_CATEGORY_CMAS_LAST_RESERVED_VALUE = + CdmaSmsCbProgramData.CATEGORY_CMAS_LAST_RESERVED_VALUE; /** * Provides the type of a SMS message like point to point, broadcast or acknowledge diff --git a/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java b/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java index 730b210f1529..fe1d9d26c7e7 100644 --- a/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java +++ b/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java @@ -92,5 +92,18 @@ public class BootImageProfileTest implements IDeviceTest { } assertTrue("Did not see framework.jar in " + res, sawFramework); assertTrue("Did not see services.jar in " + res, sawServices); + + + // Test the profile contents contain common methods for core-oj that would normally be AOT + // compiled. + res = mTestDevice.executeShellCommand("profman --dump-classes-and-methods --profile-file=" + + SYSTEM_SERVER_PROFILE + " --apk=/apex/com.android.art/javalib/core-oj.jar"); + boolean sawObjectInit = false; + for (String line : res.split("\n")) { + if (line.contains("Ljava/lang/Object;-><init>()V")) { + sawObjectInit = true; + } + } + assertTrue("Did not see Object.<init> in " + res, sawObjectInit); } } diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java index f0c5baad222b..66c7d06d6ff4 100644 --- a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java +++ b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java @@ -342,14 +342,14 @@ public final class SampleDataClass implements Parcelable { - // Code below generated by codegen v1.0.1. + // Code below generated by codegen v1.0.3. // // DO NOT MODIFY! + // CHECKSTYLE:OFF Generated code // // To regenerate run: // $ codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java - // - // CHECKSTYLE:OFF Generated code + @IntDef(prefix = "STATE_", value = { STATE_UNDEFINED, @@ -1798,8 +1798,8 @@ public final class SampleDataClass implements Parcelable { } @DataClass.Generated( - time = 1568235365376L, - codegenVersion = "1.0.1", + time = 1569956013899L, + codegenVersion = "1.0.3", sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java", inputSignatures = "public static final java.lang.String STATE_NAME_UNDEFINED\npublic static final java.lang.String STATE_NAME_ON\npublic static final java.lang.String STATE_NAME_OFF\npublic static final int STATE_UNDEFINED\npublic static final int STATE_ON\npublic static final int STATE_OFF\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate int mNum\nprivate int mNum2\nprivate int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient android.net.LinkAddress[] mLinkAddresses6\ntransient int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange(from=0L, to=6L) int mDayOfWeek\nprivate @android.annotation.Size(2L) @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange(from=0.0) float[] mCoords\nprivate static java.lang.String defaultName4()\nprivate int[] lazyInitTmpStorage()\npublic android.net.LinkAddress[] getLinkAddresses4()\nprivate boolean patternEquals(java.util.regex.Pattern)\nprivate int patternHashCode()\nprivate void onConstructed()\npublic void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)") @Deprecated diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java index 86f37fe1057e..c6bc8de3bb9e 100644 --- a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java +++ b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java @@ -74,14 +74,14 @@ public class SampleWithCustomBuilder { - // Code below generated by codegen v1.0.1. + // Code below generated by codegen v1.0.3. // // DO NOT MODIFY! + // CHECKSTYLE:OFF Generated code // // To regenerate run: // $ codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java - // - // CHECKSTYLE:OFF Generated code + @DataClass.Generated.Member /* package-private */ SampleWithCustomBuilder( @@ -176,8 +176,8 @@ public class SampleWithCustomBuilder { } @DataClass.Generated( - time = 1568235366386L, - codegenVersion = "1.0.1", + time = 1569956014908L, + codegenVersion = "1.0.3", sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java", inputSignatures = " long delayAmount\n @android.annotation.NonNull java.util.concurrent.TimeUnit delayUnit\n long creationTimestamp\nclass SampleWithCustomBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=true)\nabstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []") @Deprecated diff --git a/tests/net/java/android/net/netlink/InetDiagSocketTest.java b/tests/net/java/android/net/netlink/InetDiagSocketTest.java index 2adbb06babf1..46e27c1d3d3b 100644 --- a/tests/net/java/android/net/netlink/InetDiagSocketTest.java +++ b/tests/net/java/android/net/netlink/InetDiagSocketTest.java @@ -18,7 +18,6 @@ package android.net.netlink; import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP; import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST; -import static android.os.Process.INVALID_UID; import static android.system.OsConstants.AF_INET; import static android.system.OsConstants.AF_INET6; import static android.system.OsConstants.IPPROTO_TCP; @@ -28,6 +27,7 @@ import static android.system.OsConstants.SOCK_STREAM; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -152,9 +152,13 @@ public class InetDiagSocketTest { private void checkConnectionOwnerUid(int protocol, InetSocketAddress local, InetSocketAddress remote, boolean expectSuccess) { - final int expectedUid = expectSuccess ? Process.myUid() : INVALID_UID; final int uid = mCm.getConnectionOwnerUid(protocol, local, remote); - assertEquals(expectedUid, uid); + + if (expectSuccess) { + assertEquals(Process.myUid(), uid); + } else { + assertNotEquals(Process.myUid(), uid); + } } private int findLikelyFreeUdpPort(UdpConnection conn) throws Exception { @@ -165,11 +169,11 @@ public class InetDiagSocketTest { return localPort; } + /** + * Create a test connection for UDP and TCP sockets and verify that this + * {protocol, local, remote} socket result in receiving a valid UID. + */ public void checkGetConnectionOwnerUid(String to, String from) throws Exception { - /** - * For TCP connections, create a test connection and verify that this - * {protocol, local, remote} socket result in receiving a valid UID. - */ TcpConnection tcp = new TcpConnection(to, from); checkConnectionOwnerUid(tcp.protocol, tcp.local, tcp.remote, true); checkConnectionOwnerUid(IPPROTO_UDP, tcp.local, tcp.remote, false); @@ -177,20 +181,14 @@ public class InetDiagSocketTest { checkConnectionOwnerUid(tcp.protocol, tcp.local, new InetSocketAddress(0), false); tcp.close(); - /** - * For UDP connections, either a complete match {protocol, local, remote} or a - * partial match {protocol, local} should return a valid UID. - */ UdpConnection udp = new UdpConnection(to,from); checkConnectionOwnerUid(udp.protocol, udp.local, udp.remote, true); - checkConnectionOwnerUid(udp.protocol, udp.local, new InetSocketAddress(0), true); checkConnectionOwnerUid(IPPROTO_TCP, udp.local, udp.remote, false); checkConnectionOwnerUid(udp.protocol, new InetSocketAddress(findLikelyFreeUdpPort(udp)), udp.remote, false); udp.close(); } - @Ignore @Test public void testGetConnectionOwnerUid() throws Exception { checkGetConnectionOwnerUid("::", null); @@ -203,6 +201,17 @@ public class InetDiagSocketTest { checkGetConnectionOwnerUid("::1", "::1"); } + @Ignore("Times out on Marlin/Sailfish") + /* Verify fix for b/141603906 */ + @Test + public void testB141603906() throws Exception { + final InetSocketAddress src = new InetSocketAddress(0); + final InetSocketAddress dst = new InetSocketAddress(0); + for (int i = 1; i <= 100000; i++) { + mCm.getConnectionOwnerUid(IPPROTO_TCP, src, dst); + } + } + // Hexadecimal representation of InetDiagReqV2 request. private static final String INET_DIAG_REQ_V2_UDP_INET4_HEX = // struct nlmsghdr diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 9e21db76be84..5bfd647f0152 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -258,13 +258,13 @@ public class ConnectivityServiceTest { private static final String TAG = "ConnectivityServiceTest"; private static final int TIMEOUT_MS = 500; - private static final int TEST_LINGER_DELAY_MS = 250; + private static final int TEST_LINGER_DELAY_MS = 300; // Chosen to be less than the linger timeout. This ensures that we can distinguish between a // LOST callback that arrives immediately and a LOST callback that arrives after the linger // timeout. For this, our assertions should run fast enough to leave less than // (mService.mLingerDelayMs - TEST_CALLBACK_TIMEOUT_MS) between the time callbacks are // supposedly fired, and the time we call expectCallback. - private static final int TEST_CALLBACK_TIMEOUT_MS = 200; + private static final int TEST_CALLBACK_TIMEOUT_MS = 250; // Chosen to be less than TEST_CALLBACK_TIMEOUT_MS. This ensures that requests have time to // complete before callbacks are verified. private static final int TEST_REQUEST_TIMEOUT_MS = 150; @@ -1466,6 +1466,10 @@ public class ConnectivityServiceTest { * received. assertNoCallback may be called at any time. */ private class TestNetworkCallback extends TestableNetworkCallback { + TestNetworkCallback() { + super(TEST_CALLBACK_TIMEOUT_MS); + } + @Override public void assertNoCallback() { // TODO: better support this use case in TestableNetworkCallback diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp index 7966ba27ebd8..8a43bb4ede35 100644 --- a/tools/aapt2/Main.cpp +++ b/tools/aapt2/Main.cpp @@ -169,17 +169,12 @@ int MainImpl(int argc, char** argv) { aapt::text::Printer printer(&fout); aapt::StdErrDiagnostics diagnostics; - auto main_command = new aapt::MainCommand(&printer, &diagnostics); + aapt::MainCommand main_command(&printer, &diagnostics); // Add the daemon subcommand here so it cannot be called while executing the daemon - main_command->AddOptionalSubcommand( + main_command.AddOptionalSubcommand( aapt::util::make_unique<aapt::DaemonCommand>(&fout, &diagnostics)); - return main_command->Execute(args, &std::cerr); -} - -// TODO(b/141312058) stop leaks -extern "C" const char *__asan_default_options() { - return "detect_leaks=0"; + return main_command.Execute(args, &std::cerr); } int main(int argc, char** argv) { diff --git a/tools/codegen/src/com/android/codegen/Main.kt b/tools/codegen/src/com/android/codegen/Main.kt index ad5bb9e2e2e8..580467433756 100755 --- a/tools/codegen/src/com/android/codegen/Main.kt +++ b/tools/codegen/src/com/android/codegen/Main.kt @@ -136,7 +136,7 @@ fun main(args: Array<String>) { // // To regenerate run: // $ $cliExecutable ${cliArgs.dropLast(1).joinToString("") { "$it " }}$fileEscaped - / + """ if (FeatureFlag.CONST_DEFS()) generateConstDefs() diff --git a/tools/codegen/src/com/android/codegen/SharedConstants.kt b/tools/codegen/src/com/android/codegen/SharedConstants.kt index b2cc81391510..1e3973eaa022 100644 --- a/tools/codegen/src/com/android/codegen/SharedConstants.kt +++ b/tools/codegen/src/com/android/codegen/SharedConstants.kt @@ -1,7 +1,7 @@ package com.android.codegen const val CODEGEN_NAME = "codegen" -const val CODEGEN_VERSION = "1.0.1" +const val CODEGEN_VERSION = "1.0.3" const val CANONICAL_BUILDER_CLASS = "Builder" const val BASE_BUILDER_CLASS = "BaseBuilder" diff --git a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl new file mode 100644 index 000000000000..b83b594c8cb9 --- /dev/null +++ b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl @@ -0,0 +1,30 @@ +/** + * Copyright (c) 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. + */ + +package android.net.wifi; + +import android.net.wifi.WifiConfiguration; + +/** + * Communicates LOHS status back to the application process. + * + * @hide + */ +oneway interface ILocalOnlyHotspotCallback { + void onHotspotStarted(in WifiConfiguration config); + void onHotspotStopped(); + void onHotspotFailed(int reason); +} diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index a97a5a5ec593..b7e109463dab 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -26,6 +26,7 @@ import android.net.DhcpInfo; import android.net.Network; import android.net.wifi.IActionListener; import android.net.wifi.IDppCallback; +import android.net.wifi.ILocalOnlyHotspotCallback; import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.ISoftApCallback; import android.net.wifi.ITrafficStateCallback; @@ -138,11 +139,11 @@ interface IWifiManager boolean stopSoftAp(); - int startLocalOnlyHotspot(in Messenger messenger, in IBinder binder, String packageName); + int startLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback, String packageName); void stopLocalOnlyHotspot(); - void startWatchLocalOnlyHotspot(in Messenger messenger, in IBinder binder); + void startWatchLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback); void stopWatchLocalOnlyHotspot(); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 00895e846e82..5782f5b1ab31 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -45,10 +45,9 @@ import android.net.wifi.hotspot2.ProvisioningCallback; import android.os.Binder; import android.os.Build; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.IBinder; import android.os.Looper; -import android.os.Message; -import android.os.Messenger; import android.os.RemoteException; import android.os.ServiceManager; import android.os.WorkSource; @@ -1127,16 +1126,6 @@ public class WifiManager { private Looper mLooper; private boolean mVerboseLoggingEnabled = false; - /* LocalOnlyHotspot callback message types */ - /** @hide */ - public static final int HOTSPOT_STARTED = 0; - /** @hide */ - public static final int HOTSPOT_STOPPED = 1; - /** @hide */ - public static final int HOTSPOT_FAILED = 2; - /** @hide */ - public static final int HOTSPOT_OBSERVER_REGISTERED = 3; - private final Object mLock = new Object(); // lock guarding access to the following vars @GuardedBy("mLock") private LocalOnlyHotspotCallbackProxy mLOHSCallbackProxy; @@ -2730,6 +2719,13 @@ public class WifiManager { } } + private Executor executorForHandler(@Nullable Handler handler) { + if (handler == null) { + return mContext.getMainExecutor(); + } + return new HandlerExecutor(handler); + } + /** * Request a local only hotspot that an application can use to communicate between co-located * devices connected to the created WiFi hotspot. The network created by this method will not @@ -2787,21 +2783,20 @@ public class WifiManager { */ public void startLocalOnlyHotspot(LocalOnlyHotspotCallback callback, @Nullable Handler handler) { + Executor executor = executorForHandler(handler); synchronized (mLock) { - Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); LocalOnlyHotspotCallbackProxy proxy = - new LocalOnlyHotspotCallbackProxy(this, looper, callback); + new LocalOnlyHotspotCallbackProxy(this, executor, callback); try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { throw new RemoteException("Wifi service is not running"); } String packageName = mContext.getOpPackageName(); - int returnCode = iWifiManager.startLocalOnlyHotspot( - proxy.getMessenger(), new Binder(), packageName); + int returnCode = iWifiManager.startLocalOnlyHotspot(proxy, packageName); if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) { // Send message to the proxy to make sure we call back on the correct thread - proxy.notifyFailed(returnCode); + proxy.onHotspotFailed(returnCode); return; } mLOHSCallbackProxy = proxy; @@ -2879,16 +2874,16 @@ public class WifiManager { */ public void watchLocalOnlyHotspot(LocalOnlyHotspotObserver observer, @Nullable Handler handler) { + Executor executor = executorForHandler(handler); synchronized (mLock) { - Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); - mLOHSObserverProxy = new LocalOnlyHotspotObserverProxy(this, looper, observer); + mLOHSObserverProxy = + new LocalOnlyHotspotObserverProxy(this, executor, observer); try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { throw new RemoteException("Wifi service is not running"); } - iWifiManager.startWatchLocalOnlyHotspot( - mLOHSObserverProxy.getMessenger(), new Binder()); + iWifiManager.startWatchLocalOnlyHotspot(mLOHSObserverProxy); mLOHSObserverProxy.registered(); } catch (RemoteException e) { mLOHSObserverProxy = null; @@ -3446,82 +3441,58 @@ public class WifiManager { /** * Callback proxy for LocalOnlyHotspotCallback objects. */ - private static class LocalOnlyHotspotCallbackProxy { - private final Handler mHandler; + private static class LocalOnlyHotspotCallbackProxy extends ILocalOnlyHotspotCallback.Stub { private final WeakReference<WifiManager> mWifiManager; - private final Looper mLooper; - private final Messenger mMessenger; + private final Executor mExecutor; + private final LocalOnlyHotspotCallback mCallback; /** - * Constructs a {@link LocalOnlyHotspotCallback} using the specified looper. All callbacks - * will be delivered on the thread of the specified looper. + * Constructs a {@link LocalOnlyHotspotCallbackProxy} using the specified executor. All + * callbacks will run using the given executor. * * @param manager WifiManager - * @param looper Looper for delivering callbacks + * @param executor Executor for delivering callbacks. * @param callback LocalOnlyHotspotCallback to notify the calling application. */ - LocalOnlyHotspotCallbackProxy(WifiManager manager, Looper looper, - final LocalOnlyHotspotCallback callback) { + LocalOnlyHotspotCallbackProxy(WifiManager manager, Executor executor, + LocalOnlyHotspotCallback callback) { mWifiManager = new WeakReference<>(manager); - mLooper = looper; - - mHandler = new Handler(looper) { - @Override - public void handleMessage(Message msg) { - Log.d(TAG, "LocalOnlyHotspotCallbackProxy: handle message what: " - + msg.what + " msg: " + msg); - - WifiManager manager = mWifiManager.get(); - if (manager == null) { - Log.w(TAG, "LocalOnlyHotspotCallbackProxy: handle message post GC"); - return; - } + mExecutor = executor; + mCallback = callback; + } - switch (msg.what) { - case HOTSPOT_STARTED: - WifiConfiguration config = (WifiConfiguration) msg.obj; - if (config == null) { - Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null."); - callback.onFailed(LocalOnlyHotspotCallback.ERROR_GENERIC); - return; - } - callback.onStarted(manager.new LocalOnlyHotspotReservation(config)); - break; - case HOTSPOT_STOPPED: - Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped"); - callback.onStopped(); - break; - case HOTSPOT_FAILED: - int reasonCode = msg.arg1; - Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start. reason: " - + reasonCode); - callback.onFailed(reasonCode); - Log.w(TAG, "done with the callback..."); - break; - default: - Log.e(TAG, "LocalOnlyHotspotCallbackProxy unhandled message. type: " - + msg.what); - } - } - }; - mMessenger = new Messenger(mHandler); + @Override + public void onHotspotStarted(WifiConfiguration config) { + WifiManager manager = mWifiManager.get(); + if (manager == null) return; + + if (config == null) { + Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null."); + onHotspotFailed(LocalOnlyHotspotCallback.ERROR_GENERIC); + return; + } + final LocalOnlyHotspotReservation reservation = + manager.new LocalOnlyHotspotReservation(config); + mExecutor.execute(() -> mCallback.onStarted(reservation)); } - public Messenger getMessenger() { - return mMessenger; + @Override + public void onHotspotStopped() { + WifiManager manager = mWifiManager.get(); + if (manager == null) return; + + Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped"); + mExecutor.execute(() -> mCallback.onStopped()); } - /** - * Helper method allowing the the incoming application call to move the onFailed callback - * over to the desired callback thread. - * - * @param reason int representing the error type - */ - public void notifyFailed(int reason) throws RemoteException { - Message msg = Message.obtain(); - msg.what = HOTSPOT_FAILED; - msg.arg1 = reason; - mMessenger.send(msg); + @Override + public void onHotspotFailed(int reason) { + WifiManager manager = mWifiManager.get(); + if (manager == null) return; + + Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start. reason: " + + reason); + mExecutor.execute(() -> mCallback.onFailed(reason)); } } @@ -3589,69 +3560,57 @@ public class WifiManager { /** * Callback proxy for LocalOnlyHotspotObserver objects. */ - private static class LocalOnlyHotspotObserverProxy { - private final Handler mHandler; + private static class LocalOnlyHotspotObserverProxy extends ILocalOnlyHotspotCallback.Stub { private final WeakReference<WifiManager> mWifiManager; - private final Looper mLooper; - private final Messenger mMessenger; + private final Executor mExecutor; + private final LocalOnlyHotspotObserver mObserver; /** * Constructs a {@link LocalOnlyHotspotObserverProxy} using the specified looper. * All callbacks will be delivered on the thread of the specified looper. * * @param manager WifiManager - * @param looper Looper for delivering callbacks + * @param executor Executor for delivering callbacks * @param observer LocalOnlyHotspotObserver to notify the calling application. */ - LocalOnlyHotspotObserverProxy(WifiManager manager, Looper looper, + LocalOnlyHotspotObserverProxy(WifiManager manager, Executor executor, final LocalOnlyHotspotObserver observer) { mWifiManager = new WeakReference<>(manager); - mLooper = looper; - - mHandler = new Handler(looper) { - @Override - public void handleMessage(Message msg) { - Log.d(TAG, "LocalOnlyHotspotObserverProxy: handle message what: " - + msg.what + " msg: " + msg); - - WifiManager manager = mWifiManager.get(); - if (manager == null) { - Log.w(TAG, "LocalOnlyHotspotObserverProxy: handle message post GC"); - return; - } + mExecutor = executor; + mObserver = observer; + } - switch (msg.what) { - case HOTSPOT_OBSERVER_REGISTERED: - observer.onRegistered(manager.new LocalOnlyHotspotSubscription()); - break; - case HOTSPOT_STARTED: - WifiConfiguration config = (WifiConfiguration) msg.obj; - if (config == null) { - Log.e(TAG, "LocalOnlyHotspotObserverProxy: config cannot be null."); - return; - } - observer.onStarted(config); - break; - case HOTSPOT_STOPPED: - observer.onStopped(); - break; - default: - Log.e(TAG, "LocalOnlyHotspotObserverProxy unhandled message. type: " - + msg.what); - } - } - }; - mMessenger = new Messenger(mHandler); + public void registered() throws RemoteException { + WifiManager manager = mWifiManager.get(); + if (manager == null) return; + + mExecutor.execute(() -> + mObserver.onRegistered(manager.new LocalOnlyHotspotSubscription())); + } + + @Override + public void onHotspotStarted(WifiConfiguration config) { + WifiManager manager = mWifiManager.get(); + if (manager == null) return; + + if (config == null) { + Log.e(TAG, "LocalOnlyHotspotObserverProxy: config cannot be null."); + return; + } + mExecutor.execute(() -> mObserver.onStarted(config)); } - public Messenger getMessenger() { - return mMessenger; + @Override + public void onHotspotStopped() { + WifiManager manager = mWifiManager.get(); + if (manager == null) return; + + mExecutor.execute(() -> mObserver.onStopped()); } - public void registered() throws RemoteException { - Message msg = Message.obtain(); - msg.what = HOTSPOT_OBSERVER_REGISTERED; - mMessenger.send(msg); + @Override + public void onHotspotFailed(int reason) { + // do nothing } } diff --git a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java index e59516485112..8f3635fd2f04 100644 --- a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java +++ b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java @@ -20,8 +20,8 @@ import android.annotation.IntDef; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.TelephonyManager.NetworkType; +import android.telephony.Annotation.NetworkType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 2e82f4e8c23b..2b055d534f85 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -23,6 +23,7 @@ import android.net.DhcpInfo; import android.net.Network; import android.net.wifi.IActionListener; import android.net.wifi.IDppCallback; +import android.net.wifi.ILocalOnlyHotspotCallback; import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.IOnWifiUsabilityStatsListener; import android.net.wifi.ISoftApCallback; @@ -285,22 +286,34 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override + /** @deprecated replaced by {@link #startLocalOnlyHotspot(ILocalOnlyHotspotCallback, String)} */ + @Deprecated public int startLocalOnlyHotspot(Messenger messenger, IBinder binder, String packageName) { throw new UnsupportedOperationException(); } @Override - public void stopLocalOnlyHotspot() { + public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName) { throw new UnsupportedOperationException(); } @Override + public void stopLocalOnlyHotspot() { + throw new UnsupportedOperationException(); + } + + /** @deprecated replaced by {@link #startWatchLocalOnlyHotspot(ILocalOnlyHotspotCallback)} */ + @Deprecated public void startWatchLocalOnlyHotspot(Messenger messenger, IBinder binder) { throw new UnsupportedOperationException(); } @Override + public void startWatchLocalOnlyHotspot(ILocalOnlyHotspotCallback callback) { + throw new UnsupportedOperationException(); + } + + @Override public void stopWatchLocalOnlyHotspot() { throw new UnsupportedOperationException(); } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 7e7f00281529..885139b99b5f 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -16,9 +16,6 @@ package android.net.wifi; -import static android.net.wifi.WifiManager.HOTSPOT_FAILED; -import static android.net.wifi.WifiManager.HOTSPOT_STARTED; -import static android.net.wifi.WifiManager.HOTSPOT_STOPPED; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL; @@ -68,8 +65,6 @@ import android.os.Binder; import android.os.Build; import android.os.Handler; import android.os.IBinder; -import android.os.Message; -import android.os.Messenger; import android.os.RemoteException; import android.os.test.TestLooper; @@ -117,8 +112,6 @@ public class WifiManagerTest { private Handler mHandler; private TestLooper mLooper; private WifiManager mWifiManager; - private Messenger mWifiServiceMessenger; - final ArgumentCaptor<Messenger> mMessengerCaptor = ArgumentCaptor.forClass(Messenger.class); @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); @@ -128,7 +121,6 @@ public class WifiManagerTest { when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo); when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME); - mWifiServiceMessenger = new Messenger(mHandler); mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper()); verify(mWifiService).getVerboseLoggingLevel(); } @@ -178,7 +170,7 @@ public class WifiManagerTest { @Test public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); @@ -196,7 +188,7 @@ public class WifiManagerTest { public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); @@ -357,7 +349,7 @@ public class WifiManagerTest { mWifiManager.startLocalOnlyHotspot(callback, mHandler); verify(mWifiService) - .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString()); + .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString()); } /** @@ -368,7 +360,7 @@ public class WifiManagerTest { public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); doThrow(new SecurityException()).when(mWifiService) - .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString()); + .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString()); mWifiManager.startLocalOnlyHotspot(callback, mHandler); } @@ -380,7 +372,7 @@ public class WifiManagerTest { public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); doThrow(new IllegalStateException()).when(mWifiService) - .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString()); + .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString()); mWifiManager.startLocalOnlyHotspot(callback, mHandler); } @@ -390,12 +382,13 @@ public class WifiManagerTest { @Test public void testCorrectLooperIsUsedForHandler() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); verify(mContext, never()).getMainLooper(); + verify(mContext, never()).getMainExecutor(); } /** @@ -406,15 +399,15 @@ public class WifiManagerTest { public void testMainLooperIsUsedWhenHandlerNotProvided() throws Exception { // record thread from looper.getThread and check ids. TestLooper altLooper = new TestLooper(); - when(mContext.getMainLooper()).thenReturn(altLooper.getLooper()); + when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor()); TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, null); altLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); assertEquals(altLooper.getLooper().getThread().getId(), callback.mCallingThreadId); - verify(mContext).getMainLooper(); + verify(mContext).getMainExecutor(); } /** @@ -426,18 +419,17 @@ public class WifiManagerTest { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); TestLooper callbackLooper = new TestLooper(); Handler callbackHandler = new Handler(callbackLooper.getLooper()); - when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString())) + .thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(callback.mOnStartedCalled); assertEquals(null, callback.mRes); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STARTED; - msg.obj = mApConfig; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStarted(mApConfig); mLooper.dispatchAll(); callbackLooper.dispatchAll(); assertTrue(callback.mOnStartedCalled); @@ -453,17 +445,17 @@ public class WifiManagerTest { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); TestLooper callbackLooper = new TestLooper(); Handler callbackHandler = new Handler(callbackLooper.getLooper()); - when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString())) + .thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(callback.mOnStartedCalled); assertEquals(null, callback.mRes); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STARTED; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStarted(null); mLooper.dispatchAll(); callbackLooper.dispatchAll(); assertFalse(callback.mOnStartedCalled); @@ -478,16 +470,16 @@ public class WifiManagerTest { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); TestLooper callbackLooper = new TestLooper(); Handler callbackHandler = new Handler(callbackLooper.getLooper()); - when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString())) + .thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(callback.mOnStoppedCalled); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STOPPED; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStopped(); mLooper.dispatchAll(); callbackLooper.dispatchAll(); assertTrue(callback.mOnStoppedCalled); @@ -501,17 +493,16 @@ public class WifiManagerTest { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); TestLooper callbackLooper = new TestLooper(); Handler callbackHandler = new Handler(callbackLooper.getLooper()); - when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString())) + .thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); assertEquals(ERROR_NOT_SET, callback.mFailureReason); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_FAILED; - msg.arg1 = ERROR_NO_CHANNEL; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotFailed(ERROR_NO_CHANNEL); mLooper.dispatchAll(); callbackLooper.dispatchAll(); assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason); @@ -523,7 +514,7 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); @@ -539,7 +530,7 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(ERROR_TETHERING_DISALLOWED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); @@ -557,7 +548,7 @@ public class WifiManagerTest { public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); doThrow(new SecurityException()).when(mWifiService) - .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString()); + .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString()); try { mWifiManager.startLocalOnlyHotspot(callback, mHandler); } catch (SecurityException e) { @@ -577,7 +568,7 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); @@ -593,7 +584,7 @@ public class WifiManagerTest { @Test public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mWifiManager.cancelLocalOnlyHotspotRequest(); @@ -615,7 +606,7 @@ public class WifiManagerTest { @Test public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mWifiManager.cancelLocalOnlyHotspotRequest(); @@ -634,7 +625,7 @@ public class WifiManagerTest { @Test public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); @@ -654,7 +645,7 @@ public class WifiManagerTest { TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); mWifiManager.watchLocalOnlyHotspot(observer, mHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)); + verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); } /** @@ -665,7 +656,7 @@ public class WifiManagerTest { public void testStartWatchLocalOnlyHotspotThrowsSecurityException() throws Exception { TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); doThrow(new SecurityException()).when(mWifiService) - .startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)); + .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); mWifiManager.watchLocalOnlyHotspot(observer, mHandler); } @@ -677,7 +668,7 @@ public class WifiManagerTest { public void testStartWatchLocalOnlyHotspotThrowsIllegalStateException() throws Exception { TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); doThrow(new IllegalStateException()).when(mWifiService) - .startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)); + .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); mWifiManager.watchLocalOnlyHotspot(observer, mHandler); } @@ -822,6 +813,7 @@ public class WifiManagerTest { verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), anyInt()); verify(mContext, never()).getMainLooper(); + verify(mContext, never()).getMainExecutor(); } /** @@ -834,6 +826,7 @@ public class WifiManagerTest { mLooper.dispatchAll(); assertTrue(observer.mOnRegistered); verify(mContext, never()).getMainLooper(); + verify(mContext, never()).getMainExecutor(); } /** @@ -844,13 +837,13 @@ public class WifiManagerTest { public void testMainLooperIsUsedWhenHandlerNotProvidedForObserver() throws Exception { // record thread from looper.getThread and check ids. TestLooper altLooper = new TestLooper(); - when(mContext.getMainLooper()).thenReturn(altLooper.getLooper()); + when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor()); TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); mWifiManager.watchLocalOnlyHotspot(observer, null); altLooper.dispatchAll(); assertTrue(observer.mOnRegistered); assertEquals(altLooper.getLooper().getThread().getId(), observer.mCallingThreadId); - verify(mContext).getMainLooper(); + verify(mContext).getMainExecutor(); } /** @@ -865,8 +858,7 @@ public class WifiManagerTest { assertFalse(observer.mOnRegistered); assertEquals(null, observer.mSub); mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class)); + verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); // now trigger the callback observerLooper.dispatchAll(); mLooper.dispatchAll(); @@ -884,16 +876,14 @@ public class WifiManagerTest { TestLooper observerLooper = new TestLooper(); Handler observerHandler = new Handler(observerLooper.getLooper()); mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class)); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture()); observerLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(observer.mOnStartedCalled); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STARTED; - msg.obj = mApConfig; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStarted(mApConfig); mLooper.dispatchAll(); observerLooper.dispatchAll(); assertTrue(observer.mOnStartedCalled); @@ -910,15 +900,14 @@ public class WifiManagerTest { TestLooper observerLooper = new TestLooper(); Handler observerHandler = new Handler(observerLooper.getLooper()); mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class)); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture()); observerLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(observer.mOnStartedCalled); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STARTED; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStarted(null); mLooper.dispatchAll(); observerLooper.dispatchAll(); assertFalse(observer.mOnStartedCalled); @@ -936,15 +925,14 @@ public class WifiManagerTest { TestLooper observerLooper = new TestLooper(); Handler observerHandler = new Handler(observerLooper.getLooper()); mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class)); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture()); observerLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(observer.mOnStoppedCalled); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STOPPED; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStopped(); mLooper.dispatchAll(); observerLooper.dispatchAll(); assertTrue(observer.mOnStoppedCalled); @@ -1173,6 +1161,7 @@ i * Verify that a call to cancel WPS immediately returns a failure. Handler altHandler = new Handler(altLooper.getLooper()); mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, altHandler); verify(mContext, never()).getMainLooper(); + verify(mContext, never()).getMainExecutor(); verify(mWifiService).registerTrafficStateCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); |