diff options
446 files changed, 7571 insertions, 7002 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java index 361ebe55ccd8..227b8276abe1 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java @@ -18,28 +18,20 @@ package com.android.server.job.controllers; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; -import android.annotation.NonNull; import android.annotation.Nullable; import android.app.AlarmManager; import android.app.AlarmManager.OnAlarmListener; -import android.content.ContentResolver; import android.content.Context; -import android.database.ContentObserver; -import android.net.Uri; -import android.os.Handler; import android.os.Process; import android.os.UserHandle; import android.os.WorkSource; -import android.provider.Settings; import android.util.IndentingPrintWriter; -import android.util.KeyValueListParser; import android.util.Log; import android.util.Slog; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; -import com.android.server.job.ConstantsProto; import com.android.server.job.JobSchedulerService; import com.android.server.job.StateControllerProto; @@ -63,9 +55,6 @@ public final class TimeController extends StateController { /** Delay alarm tag for logging purposes */ private final String DELAY_TAG = "*job.delay*"; - private final Handler mHandler; - private final TcConstants mTcConstants; - private long mNextJobExpiredElapsedMillis; private long mNextDelayExpiredElapsedMillis; @@ -81,14 +70,6 @@ public final class TimeController extends StateController { mNextJobExpiredElapsedMillis = Long.MAX_VALUE; mNextDelayExpiredElapsedMillis = Long.MAX_VALUE; mChainedAttributionEnabled = mService.isChainedAttributionEnabled(); - - mHandler = new Handler(mContext.getMainLooper()); - mTcConstants = new TcConstants(mHandler); - } - - @Override - public void onSystemServicesReady() { - mTcConstants.start(mContext.getContentResolver()); } /** @@ -372,8 +353,7 @@ public final class TimeController extends StateController { /** * Set an alarm with the {@link android.app.AlarmManager} for the next time at which a job's * delay will expire. - * This alarm <b>will not</b> wake up the phone if - * {@link TcConstants#USE_NON_WAKEUP_ALARM_FOR_DELAY} is true. + * This alarm <b>will not</b> wake up the phone. */ private void setDelayExpiredAlarmLocked(long alarmTimeElapsedMillis, WorkSource ws) { alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis); @@ -381,10 +361,7 @@ public final class TimeController extends StateController { return; } mNextDelayExpiredElapsedMillis = alarmTimeElapsedMillis; - final int alarmType = - mTcConstants.USE_NON_WAKEUP_ALARM_FOR_DELAY - ? AlarmManager.ELAPSED_REALTIME : AlarmManager.ELAPSED_REALTIME_WAKEUP; - updateAlarmWithListenerLocked(DELAY_TAG, alarmType, + updateAlarmWithListenerLocked(DELAY_TAG, AlarmManager.ELAPSED_REALTIME, mNextDelayExpiredListener, mNextDelayExpiredElapsedMillis, ws); } @@ -443,80 +420,6 @@ public final class TimeController extends StateController { } }; - @VisibleForTesting - class TcConstants extends ContentObserver { - private ContentResolver mResolver; - private final KeyValueListParser mParser = new KeyValueListParser(','); - - private static final String KEY_USE_NON_WAKEUP_ALARM_FOR_DELAY = - "use_non_wakeup_delay_alarm"; - - private static final boolean DEFAULT_USE_NON_WAKEUP_ALARM_FOR_DELAY = true; - - /** - * Whether or not TimeController should skip setting wakeup alarms for jobs that aren't - * ready now. - */ - public boolean USE_NON_WAKEUP_ALARM_FOR_DELAY = DEFAULT_USE_NON_WAKEUP_ALARM_FOR_DELAY; - - /** - * Creates a content observer. - * - * @param handler The handler to run {@link #onChange} on, or null if none. - */ - TcConstants(Handler handler) { - super(handler); - } - - private void start(ContentResolver resolver) { - mResolver = resolver; - mResolver.registerContentObserver(Settings.Global.getUriFor( - Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS), false, this); - onChange(true, null); - } - - @Override - public void onChange(boolean selfChange, Uri uri) { - final String constants = Settings.Global.getString( - mResolver, Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS); - - try { - mParser.setString(constants); - } catch (Exception e) { - // Failed to parse the settings string, log this and move on with defaults. - Slog.e(TAG, "Bad jobscheduler time controller settings", e); - } - - USE_NON_WAKEUP_ALARM_FOR_DELAY = mParser.getBoolean( - KEY_USE_NON_WAKEUP_ALARM_FOR_DELAY, DEFAULT_USE_NON_WAKEUP_ALARM_FOR_DELAY); - // Intentionally not calling checkExpiredDelaysAndResetAlarm() here. There's no need to - // iterate through the entire list again for this constant change. The next delay alarm - // that is set will make use of the new constant value. - } - - private void dump(IndentingPrintWriter pw) { - pw.println(); - pw.println("TimeController:"); - pw.increaseIndent(); - pw.print(KEY_USE_NON_WAKEUP_ALARM_FOR_DELAY, - USE_NON_WAKEUP_ALARM_FOR_DELAY).println(); - pw.decreaseIndent(); - } - - private void dump(ProtoOutputStream proto) { - final long tcToken = proto.start(ConstantsProto.TIME_CONTROLLER); - proto.write(ConstantsProto.TimeController.USE_NON_WAKEUP_ALARM_FOR_DELAY, - USE_NON_WAKEUP_ALARM_FOR_DELAY); - proto.end(tcToken); - } - } - - @VisibleForTesting - @NonNull - TcConstants getTcConstants() { - return mTcConstants; - } - @Override public void dumpControllerStateLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate) { @@ -591,14 +494,4 @@ public final class TimeController extends StateController { proto.end(mToken); proto.end(token); } - - @Override - public void dumpConstants(IndentingPrintWriter pw) { - mTcConstants.dump(pw); - } - - @Override - public void dumpConstants(ProtoOutputStream proto) { - mTcConstants.dump(proto); - } } diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java index 24436ea5180b..f40f244e69e5 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -488,7 +488,7 @@ public class AppStandbyController implements AppStandbyInternal { mSystemServicesReady = true; // Offload to handler thread to avoid boot time impact. - mHandler.post(mInjector::updatePowerWhitelistCache); + mHandler.post(AppStandbyController.this::updatePowerWhitelistCache); boolean userFileExists; synchronized (mAppIdleLock) { @@ -1716,6 +1716,14 @@ public class AppStandbyController implements AppStandbyInternal { } } + private void updatePowerWhitelistCache() { + if (mInjector.getBootPhase() < PHASE_SYSTEM_SERVICES_READY) { + return; + } + mInjector.updatePowerWhitelistCache(); + postCheckIdleStates(UserHandle.USER_ALL); + } + private class PackageReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { @@ -2029,10 +2037,7 @@ public class AppStandbyController implements AppStandbyInternal { } } - private void updatePowerWhitelistCache() { - if (mBootPhase < PHASE_SYSTEM_SERVICES_READY) { - return; - } + void updatePowerWhitelistCache() { try { // Don't call out to DeviceIdleController with the lock held. final String[] whitelistedPkgs = @@ -2232,7 +2237,7 @@ public class AppStandbyController implements AppStandbyInternal { break; case PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED: if (mSystemServicesReady) { - mHandler.post(mInjector::updatePowerWhitelistCache); + mHandler.post(AppStandbyController.this::updatePowerWhitelistCache); } break; } diff --git a/apex/statsd/aidl/Android.bp b/apex/statsd/aidl/Android.bp index f66cf7c9e23c..04339e67d799 100644 --- a/apex/statsd/aidl/Android.bp +++ b/apex/statsd/aidl/Android.bp @@ -30,7 +30,6 @@ aidl_interface { "android/os/StatsDimensionsValueParcel.aidl", "android/util/StatsEventParcel.aidl", ], - host_supported: true, backend: { java: { enabled: false, // framework-statsd and service-statsd use framework-statsd-aidl-sources diff --git a/api/current.txt b/api/current.txt index 651cda564ee9..7119902b07d3 100644 --- a/api/current.txt +++ b/api/current.txt @@ -27905,6 +27905,7 @@ package android.media.audiofx { field public static final java.util.UUID EFFECT_TYPE_DYNAMICS_PROCESSING; field public static final java.util.UUID EFFECT_TYPE_ENV_REVERB; field public static final java.util.UUID EFFECT_TYPE_EQUALIZER; + field @NonNull public static final java.util.UUID EFFECT_TYPE_HAPTIC_GENERATOR; field public static final java.util.UUID EFFECT_TYPE_LOUDNESS_ENHANCER; field public static final java.util.UUID EFFECT_TYPE_NS; field public static final java.util.UUID EFFECT_TYPE_PRESET_REVERB; @@ -28257,6 +28258,13 @@ package android.media.audiofx { field public short numBands; } + public class HapticGenerator extends android.media.audiofx.AudioEffect implements java.lang.AutoCloseable { + method public void close(); + method @NonNull public static android.media.audiofx.HapticGenerator create(int); + method public static boolean isAvailable(); + method public int setEnabled(boolean); + } + public class LoudnessEnhancer extends android.media.audiofx.AudioEffect { ctor public LoudnessEnhancer(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.RuntimeException, java.lang.UnsupportedOperationException; method public float getTargetGain() throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException; diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt index 1803be384389..360e44ff055c 100644 --- a/api/module-lib-current.txt +++ b/api/module-lib-current.txt @@ -1,4 +1,12 @@ // Signature format: 2.0 +package android.app { + + public class AppOpsManager { + field public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage"; + } + +} + package android.content.rollback { public class RollbackManagerFrameworkInitializer { diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp index 878cef94b674..e21a6b288fb3 100644 --- a/cmds/idmap2/Android.bp +++ b/cmds/idmap2/Android.bp @@ -181,7 +181,6 @@ cc_binary { "idmap2/Dump.cpp", "idmap2/Lookup.cpp", "idmap2/Main.cpp", - "idmap2/Scan.cpp", ], target: { android: { diff --git a/cmds/idmap2/idmap2/Commands.h b/cmds/idmap2/idmap2/Commands.h index 69eea8d262d2..4099671066a2 100644 --- a/cmds/idmap2/idmap2/Commands.h +++ b/cmds/idmap2/idmap2/Commands.h @@ -26,6 +26,5 @@ android::idmap2::Result<android::idmap2::Unit> Create(const std::vector<std::str android::idmap2::Result<android::idmap2::Unit> CreateMultiple(const std::vector<std::string>& args); android::idmap2::Result<android::idmap2::Unit> Dump(const std::vector<std::string>& args); android::idmap2::Result<android::idmap2::Unit> Lookup(const std::vector<std::string>& args); -android::idmap2::Result<android::idmap2::Unit> Scan(const std::vector<std::string>& args); #endif // IDMAP2_IDMAP2_COMMANDS_H_ diff --git a/cmds/idmap2/idmap2/Main.cpp b/cmds/idmap2/idmap2/Main.cpp index fb093f0f22a4..aa6d0e76698f 100644 --- a/cmds/idmap2/idmap2/Main.cpp +++ b/cmds/idmap2/idmap2/Main.cpp @@ -53,8 +53,10 @@ void PrintUsage(const NameToFunctionMap& commands, std::ostream& out) { int main(int argc, char** argv) { SYSTRACE << "main"; const NameToFunctionMap commands = { - {"create", Create}, {"create-multiple", CreateMultiple}, {"dump", Dump}, {"lookup", Lookup}, - {"scan", Scan}, + {"create", Create}, + {"create-multiple", CreateMultiple}, + {"dump", Dump}, + {"lookup", Lookup}, }; if (argc <= 1) { PrintUsage(commands, std::cerr); diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp deleted file mode 100644 index 36250450cc74..000000000000 --- a/cmds/idmap2/idmap2/Scan.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/* - * 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. - */ - -#include <dirent.h> - -#include <fstream> -#include <memory> -#include <ostream> -#include <set> -#include <string> -#include <utility> -#include <vector> - -#include "Commands.h" -#include "android-base/properties.h" -#include "idmap2/CommandLineOptions.h" -#include "idmap2/CommandUtils.h" -#include "idmap2/FileUtils.h" -#include "idmap2/Idmap.h" -#include "idmap2/Policies.h" -#include "idmap2/PolicyUtils.h" -#include "idmap2/ResourceUtils.h" -#include "idmap2/Result.h" -#include "idmap2/SysTrace.h" -#include "idmap2/XmlParser.h" - -using android::idmap2::CommandLineOptions; -using android::idmap2::Error; -using android::idmap2::Idmap; -using android::idmap2::Result; -using android::idmap2::Unit; -using android::idmap2::policy::kPolicyOdm; -using android::idmap2::policy::kPolicyOem; -using android::idmap2::policy::kPolicyProduct; -using android::idmap2::policy::kPolicyPublic; -using android::idmap2::policy::kPolicySystem; -using android::idmap2::policy::kPolicyVendor; -using android::idmap2::utils::ExtractOverlayManifestInfo; -using android::idmap2::utils::FindFiles; -using android::idmap2::utils::OverlayManifestInfo; -using android::idmap2::utils::PoliciesToBitmaskResult; - -using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; - -namespace { - -struct InputOverlay { - bool operator<(InputOverlay const& rhs) const { - return priority < rhs.priority || (priority == rhs.priority && apk_path < rhs.apk_path); - } - - std::string apk_path; // NOLINT(misc-non-private-member-variables-in-classes) - std::string idmap_path; // NOLINT(misc-non-private-member-variables-in-classes) - int priority; // NOLINT(misc-non-private-member-variables-in-classes) - std::vector<std::string> policies; // NOLINT(misc-non-private-member-variables-in-classes) - bool ignore_overlayable; // NOLINT(misc-non-private-member-variables-in-classes) -}; - -bool VendorIsQOrLater() { - constexpr int kQSdkVersion = 29; - constexpr int kBase = 10; - std::string version_prop = android::base::GetProperty("ro.vndk.version", "29"); - int version = strtol(version_prop.data(), nullptr, kBase); - - // If the string cannot be parsed, it is a development sdk codename. - return version >= kQSdkVersion || version == 0; -} - -Result<std::unique_ptr<std::vector<std::string>>> FindApkFiles(const std::vector<std::string>& dirs, - bool recursive) { - SYSTRACE << "FindApkFiles " << dirs << " " << recursive; - const auto predicate = [](unsigned char type, const std::string& path) -> bool { - static constexpr size_t kExtLen = 4; // strlen(".apk") - return type == DT_REG && path.size() > kExtLen && - path.compare(path.size() - kExtLen, kExtLen, ".apk") == 0; - }; - // pass apk paths through a set to filter out duplicates - std::set<std::string> paths; - for (const auto& dir : dirs) { - const auto apk_paths = FindFiles(dir, recursive, predicate); - if (!apk_paths) { - return Error("failed to open directory %s", dir.c_str()); - } - paths.insert(apk_paths->cbegin(), apk_paths->cend()); - } - return std::make_unique<std::vector<std::string>>(paths.cbegin(), paths.cend()); -} - -std::vector<std::string> PoliciesForPath(const std::string& apk_path) { - // clang-format off - static const std::vector<std::pair<std::string, std::string>> values = { - {"/odm/", kPolicyOdm}, - {"/oem/", kPolicyOem}, - {"/product/", kPolicyProduct}, - {"/system/", kPolicySystem}, - {"/system_ext/", kPolicySystem}, - {"/vendor/", kPolicyVendor}, - }; - // clang-format on - - std::vector<std::string> fulfilled_policies = {kPolicyPublic}; - for (auto const& pair : values) { - if (apk_path.compare(0, pair.first.size(), pair.first) == 0) { - fulfilled_policies.emplace_back(pair.second); - break; - } - } - - return fulfilled_policies; -} - -} // namespace - -Result<Unit> Scan(const std::vector<std::string>& args) { - SYSTRACE << "Scan " << args; - std::vector<std::string> input_directories; - std::string target_package_name; - std::string target_apk_path; - std::string output_directory; - std::vector<std::string> override_policies; - bool recursive = false; - - const CommandLineOptions opts = - CommandLineOptions("idmap2 scan") - .MandatoryOption("--input-directory", "directory containing overlay apks to scan", - &input_directories) - .OptionalFlag("--recursive", "also scan subfolders of overlay-directory", &recursive) - .MandatoryOption("--target-package-name", "package name of target package", - &target_package_name) - .MandatoryOption("--target-apk-path", "path to target apk", &target_apk_path) - .MandatoryOption("--output-directory", - "directory in which to write artifacts (idmap files and overlays.list)", - &output_directory) - .OptionalOption( - "--override-policy", - "input: an overlayable policy this overlay fulfills " - "(if none or supplied, the overlays will not have their policies overriden", - &override_policies); - const auto opts_ok = opts.Parse(args); - if (!opts_ok) { - return opts_ok.GetError(); - } - - const auto apk_paths = FindApkFiles(input_directories, recursive); - if (!apk_paths) { - return Error(apk_paths.GetError(), "failed to find apk files"); - } - - std::vector<InputOverlay> interesting_apks; - for (const std::string& path : **apk_paths) { - Result<OverlayManifestInfo> overlay_info = - ExtractOverlayManifestInfo(path, /* assert_overlay */ false); - if (!overlay_info) { - return overlay_info.GetError(); - } - - if (!overlay_info->is_static) { - continue; - } - - if (overlay_info->target_package.empty() || - overlay_info->target_package != target_package_name) { - continue; - } - - if (overlay_info->priority < 0) { - 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; - } else { - fulfilled_policies = PoliciesForPath(path); - } - - bool ignore_overlayable = false; - if (std::find(fulfilled_policies.begin(), fulfilled_policies.end(), kPolicyVendor) != - fulfilled_policies.end() && - !VendorIsQOrLater()) { - // If the overlay is on a pre-Q vendor partition, do not enforce overlayable - // restrictions on this overlay because the pre-Q platform has no understanding of - // overlayable. - ignore_overlayable = true; - } - - std::string idmap_path = Idmap::CanonicalIdmapPathFor(output_directory, path); - - // Sort the static overlays in ascending priority order - InputOverlay input{path, idmap_path, overlay_info->priority, fulfilled_policies, - ignore_overlayable}; - interesting_apks.insert( - std::lower_bound(interesting_apks.begin(), interesting_apks.end(), input), input); - } - - std::stringstream stream; - for (const auto& overlay : interesting_apks) { - const auto policy_bitmask = PoliciesToBitmaskResult(overlay.policies); - if (!policy_bitmask) { - LOG(WARNING) << "failed to create idmap for overlay apk path \"" << overlay.apk_path - << "\": " << policy_bitmask.GetErrorMessage(); - continue; - } - - if (!Verify(overlay.idmap_path, target_apk_path, overlay.apk_path, *policy_bitmask, - !overlay.ignore_overlayable)) { - std::vector<std::string> create_args = {"--target-apk-path", target_apk_path, - "--overlay-apk-path", overlay.apk_path, - "--idmap-path", overlay.idmap_path}; - if (overlay.ignore_overlayable) { - create_args.emplace_back("--ignore-overlayable"); - } - - for (const std::string& policy : overlay.policies) { - create_args.emplace_back("--policy"); - create_args.emplace_back(policy); - } - - const auto create_ok = Create(create_args); - if (!create_ok) { - LOG(WARNING) << "failed to create idmap for overlay apk path \"" << overlay.apk_path - << "\": " << create_ok.GetError().GetMessage(); - continue; - } - } - - stream << overlay.idmap_path << std::endl; - } - - std::cout << stream.str(); - - return Unit{}; -} diff --git a/cmds/idmap2/include/idmap2/FileUtils.h b/cmds/idmap2/include/idmap2/FileUtils.h index 3f03236d5e1a..c4e0e1fd8ef0 100644 --- a/cmds/idmap2/include/idmap2/FileUtils.h +++ b/cmds/idmap2/include/idmap2/FileUtils.h @@ -17,27 +17,13 @@ #ifndef IDMAP2_INCLUDE_IDMAP2_FILEUTILS_H_ #define IDMAP2_INCLUDE_IDMAP2_FILEUTILS_H_ -#include <sys/types.h> - -#include <functional> -#include <memory> #include <string> -#include <vector> namespace android::idmap2::utils { constexpr const char* kIdmapCacheDir = "/data/resource-cache"; constexpr const mode_t kIdmapFilePermissionMask = 0133; // u=rw,g=r,o=r -typedef std::function<bool(unsigned char type /* DT_* from dirent.h */, const std::string& path)> - FindFilesPredicate; -std::unique_ptr<std::vector<std::string>> FindFiles(const std::string& root, bool recurse, - const FindFilesPredicate& predicate); - -std::unique_ptr<std::string> ReadFile(int fd); - -std::unique_ptr<std::string> ReadFile(const std::string& path); - bool UidHasWriteAccessToPath(uid_t uid, const std::string& path); } // namespace android::idmap2::utils diff --git a/cmds/idmap2/libidmap2/FileUtils.cpp b/cmds/idmap2/libidmap2/FileUtils.cpp index 3e8e32989a09..3af1f70ebe39 100644 --- a/cmds/idmap2/libidmap2/FileUtils.cpp +++ b/cmds/idmap2/libidmap2/FileUtils.cpp @@ -16,19 +16,7 @@ #include "idmap2/FileUtils.h" -#include <dirent.h> -#include <sys/types.h> -#include <unistd.h> - -#include <cerrno> -#include <climits> -#include <cstdlib> -#include <cstring> -#include <fstream> -#include <memory> #include <string> -#include <utility> -#include <vector> #include "android-base/file.h" #include "android-base/macros.h" @@ -37,54 +25,6 @@ namespace android::idmap2::utils { -std::unique_ptr<std::vector<std::string>> FindFiles(const std::string& root, bool recurse, - const FindFilesPredicate& predicate) { - DIR* dir = opendir(root.c_str()); - if (dir == nullptr) { - return nullptr; - } - std::unique_ptr<std::vector<std::string>> vector(new std::vector<std::string>()); - struct dirent* dirent; - while ((dirent = readdir(dir)) != nullptr) { - const std::string path = root + "/" + dirent->d_name; - if (predicate(dirent->d_type, path)) { - vector->push_back(path); - } - if (recurse && dirent->d_type == DT_DIR && strcmp(dirent->d_name, ".") != 0 && - strcmp(dirent->d_name, "..") != 0) { - auto sub_vector = FindFiles(path, recurse, predicate); - if (!sub_vector) { - closedir(dir); - return nullptr; - } - vector->insert(vector->end(), sub_vector->begin(), sub_vector->end()); - } - } - closedir(dir); - - return vector; -} - -std::unique_ptr<std::string> ReadFile(const std::string& path) { - std::unique_ptr<std::string> str(new std::string()); - std::ifstream fin(path); - str->append({std::istreambuf_iterator<char>(fin), std::istreambuf_iterator<char>()}); - fin.close(); - return str; -} - -std::unique_ptr<std::string> ReadFile(int fd) { - static constexpr const size_t kBufSize = 1024; - - std::unique_ptr<std::string> str(new std::string()); - char buf[kBufSize]; - ssize_t r; - while ((r = read(fd, buf, sizeof(buf))) > 0) { - str->append(buf, r); - } - return r == 0 ? std::move(str) : nullptr; -} - #ifdef __ANDROID__ bool UidHasWriteAccessToPath(uid_t uid, const std::string& path) { // resolve symlinks and relative paths; the directories must exist diff --git a/cmds/idmap2/tests/FileUtilsTests.cpp b/cmds/idmap2/tests/FileUtilsTests.cpp index 8af4037be954..5750ca1f49c5 100644 --- a/cmds/idmap2/tests/FileUtilsTests.cpp +++ b/cmds/idmap2/tests/FileUtilsTests.cpp @@ -14,73 +14,16 @@ * limitations under the License. */ -#include <dirent.h> -#include <fcntl.h> - -#include <set> #include <string> #include "TestHelpers.h" -#include "android-base/macros.h" #include "android-base/stringprintf.h" -#include "gmock/gmock.h" #include "gtest/gtest.h" #include "idmap2/FileUtils.h" #include "private/android_filesystem_config.h" -using ::testing::NotNull; - namespace android::idmap2::utils { -TEST(FileUtilsTests, FindFilesFindEverythingNonRecursive) { - const auto& root = GetTestDataPath(); - auto v = utils::FindFiles(root, false, - [](unsigned char type ATTRIBUTE_UNUSED, - const std::string& path ATTRIBUTE_UNUSED) -> bool { return true; }); - ASSERT_THAT(v, NotNull()); - ASSERT_EQ(v->size(), 7U); - ASSERT_EQ(std::set<std::string>(v->begin(), v->end()), std::set<std::string>({ - root + "/.", - root + "/..", - root + "/overlay", - root + "/target", - root + "/signature-overlay", - root + "/system-overlay", - root + "/system-overlay-invalid", - })); -} - -TEST(FileUtilsTests, FindFilesFindApkFilesRecursive) { - const auto& root = GetTestDataPath(); - auto v = utils::FindFiles(root, true, [](unsigned char type, const std::string& path) -> bool { - return type == DT_REG && path.size() > 4 && path.compare(path.size() - 4, 4, ".apk") == 0; - }); - ASSERT_THAT(v, NotNull()); - ASSERT_EQ(v->size(), 11U); - ASSERT_EQ(std::set<std::string>(v->begin(), v->end()), - std::set<std::string>( - {root + "/target/target.apk", root + "/target/target-no-overlayable.apk", - root + "/overlay/overlay.apk", root + "/overlay/overlay-no-name.apk", - root + "/overlay/overlay-no-name-static.apk", root + "/overlay/overlay-shared.apk", - root + "/overlay/overlay-static-1.apk", root + "/overlay/overlay-static-2.apk", - root + "/signature-overlay/signature-overlay.apk", - root + "/system-overlay/system-overlay.apk", - root + "/system-overlay-invalid/system-overlay-invalid.apk"})); -} - -TEST(FileUtilsTests, ReadFile) { - int pipefd[2]; - ASSERT_EQ(pipe2(pipefd, O_CLOEXEC), 0); - - ASSERT_EQ(write(pipefd[1], "foobar", 6), 6); - close(pipefd[1]); - - auto data = ReadFile(pipefd[0]); - ASSERT_THAT(data, NotNull()); - ASSERT_EQ(*data, "foobar"); - close(pipefd[0]); -} - #ifdef __ANDROID__ TEST(FileUtilsTests, UidHasWriteAccessToPath) { constexpr const char* tmp_path = "/data/local/tmp/test@idmap"; diff --git a/cmds/idmap2/tests/Idmap2BinaryTests.cpp b/cmds/idmap2/tests/Idmap2BinaryTests.cpp index d896cf9c11ba..61751b33dcba 100644 --- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp +++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp @@ -159,131 +159,6 @@ TEST_F(Idmap2BinaryTests, Dump) { unlink(GetIdmapPath().c_str()); } -TEST_F(Idmap2BinaryTests, Scan) { - SKIP_TEST_IF_CANT_EXEC_IDMAP2; - - const std::string overlay_static_no_name_apk_path = - GetTestDataPath() + "/overlay/overlay-no-name-static.apk"; - const std::string overlay_static_1_apk_path = GetTestDataPath() + "/overlay/overlay-static-1.apk"; - const std::string overlay_static_2_apk_path = GetTestDataPath() + "/overlay/overlay-static-2.apk"; - const std::string idmap_static_no_name_path = - Idmap::CanonicalIdmapPathFor(GetTempDirPath(), overlay_static_no_name_apk_path); - const std::string idmap_static_1_path = - Idmap::CanonicalIdmapPathFor(GetTempDirPath(), overlay_static_1_apk_path); - const std::string idmap_static_2_path = - Idmap::CanonicalIdmapPathFor(GetTempDirPath(), overlay_static_2_apk_path); - - // single input directory, recursive - // clang-format off - auto result = ExecuteBinary({"idmap2", - "scan", - "--input-directory", GetTestDataPath(), - "--recursive", - "--target-package-name", "test.target", - "--target-apk-path", GetTargetApkPath(), - "--output-directory", GetTempDirPath(), - "--override-policy", "public"}); - // clang-format on - ASSERT_THAT(result, NotNull()); - ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr; - std::stringstream expected; - expected << idmap_static_no_name_path << std::endl; - expected << idmap_static_1_path << std::endl; - expected << idmap_static_2_path << std::endl; - ASSERT_EQ(result->stdout, expected.str()); - - auto idmap_static_no_name_raw_string = utils::ReadFile(idmap_static_no_name_path); - auto idmap_static_no_name_raw_stream = std::istringstream(*idmap_static_no_name_raw_string); - auto idmap_static_no_name = Idmap::FromBinaryStream(idmap_static_no_name_raw_stream); - ASSERT_TRUE(idmap_static_no_name); - ASSERT_IDMAP(**idmap_static_no_name, GetTargetApkPath(), overlay_static_no_name_apk_path); - - auto idmap_static_1_raw_string = utils::ReadFile(idmap_static_1_path); - auto idmap_static_1_raw_stream = std::istringstream(*idmap_static_1_raw_string); - auto idmap_static_1 = Idmap::FromBinaryStream(idmap_static_1_raw_stream); - ASSERT_TRUE(idmap_static_1); - ASSERT_IDMAP(**idmap_static_1, GetTargetApkPath(), overlay_static_1_apk_path); - - auto idmap_static_2_raw_string = utils::ReadFile(idmap_static_2_path); - auto idmap_static_2_raw_stream = std::istringstream(*idmap_static_2_raw_string); - auto idmap_static_2 = Idmap::FromBinaryStream(idmap_static_2_raw_stream); - ASSERT_TRUE(idmap_static_2); - ASSERT_IDMAP(**idmap_static_2, GetTargetApkPath(), overlay_static_2_apk_path); - - unlink(idmap_static_no_name_path.c_str()); - unlink(idmap_static_2_path.c_str()); - unlink(idmap_static_1_path.c_str()); - - // multiple input directories, non-recursive - // clang-format off - result = ExecuteBinary({"idmap2", - "scan", - "--input-directory", GetTestDataPath() + "/target", - "--input-directory", GetTestDataPath() + "/overlay", - "--target-package-name", "test.target", - "--target-apk-path", GetTargetApkPath(), - "--output-directory", GetTempDirPath(), - "--override-policy", "public"}); - // clang-format on - ASSERT_THAT(result, NotNull()); - ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr; - ASSERT_EQ(result->stdout, expected.str()); - unlink(idmap_static_no_name_path.c_str()); - unlink(idmap_static_2_path.c_str()); - unlink(idmap_static_1_path.c_str()); - - // the same input directory given twice, but no duplicate entries - // clang-format off - result = ExecuteBinary({"idmap2", - "scan", - "--input-directory", GetTestDataPath(), - "--input-directory", GetTestDataPath(), - "--recursive", - "--target-package-name", "test.target", - "--target-apk-path", GetTargetApkPath(), - "--output-directory", GetTempDirPath(), - "--override-policy", "public"}); - // clang-format on - ASSERT_THAT(result, NotNull()); - ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr; - ASSERT_EQ(result->stdout, expected.str()); - unlink(idmap_static_no_name_path.c_str()); - unlink(idmap_static_2_path.c_str()); - unlink(idmap_static_1_path.c_str()); - - // no APKs in input-directory: ok, but no output - // clang-format off - result = ExecuteBinary({"idmap2", - "scan", - "--input-directory", GetTempDirPath(), - "--target-package-name", "test.target", - "--target-apk-path", GetTargetApkPath(), - "--output-directory", GetTempDirPath(), - "--override-policy", "public"}); - // clang-format on - ASSERT_THAT(result, NotNull()); - ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr; - ASSERT_EQ(result->stdout, ""); - - // the signature idmap failing to generate should not cause scanning to fail - // clang-format off - result = ExecuteBinary({"idmap2", - "scan", - "--input-directory", GetTestDataPath(), - "--recursive", - "--target-package-name", "test.target", - "--target-apk-path", GetTargetApkPath(), - "--output-directory", GetTempDirPath(), - "--override-policy", "public"}); - // clang-format on - ASSERT_THAT(result, NotNull()); - ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr; - ASSERT_EQ(result->stdout, expected.str()); - unlink(idmap_static_no_name_path.c_str()); - unlink(idmap_static_2_path.c_str()); - unlink(idmap_static_1_path.c_str()); -} - TEST_F(Idmap2BinaryTests, Lookup) { SKIP_TEST_IF_CANT_EXEC_IDMAP2; diff --git a/cmds/idmap2/valgrind.sh b/cmds/idmap2/valgrind.sh index b4ebab0c7ffe..84daeecdb21e 100755 --- a/cmds/idmap2/valgrind.sh +++ b/cmds/idmap2/valgrind.sh @@ -53,7 +53,5 @@ 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 1579715727ac..124f815f51f0 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -171,8 +171,7 @@ cc_library_static { export_generated_headers: ["statslog_statsdtest.h"], shared_libs: [ "libstatssocket", - "libstatspull", - ], + ] } cc_library_static { @@ -186,11 +185,7 @@ cc_library_static { ], shared_libs: [ "libstatssocket", - "libstatspull", - ], - export_shared_lib_headers: [ - "libstatspull", - ], + ] } // ========= diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index fc74fec45e47..e70eac88c769 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -586,7 +586,7 @@ message Atom { DataUsageBytesTransfer data_usage_bytes_transfer = 10082 [(module) = "framework", (truncate_timestamp) = true]; BytesTransferByTagAndMetered bytes_transfer_by_tag_and_metered = - 10083 [(module) = "framework"]; + 10083 [(module) = "framework", (truncate_timestamp) = true]; DNDModeProto dnd_mode_rule = 10084 [(module) = "framework"]; GeneralExternalStorageAccessStats general_external_storage_access_stats = 10085 [(module) = "mediaprovider"]; diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 3ca5f0deba1b..b40dd0053846 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -1461,8 +1461,12 @@ public class AppOpsManager { /** * AppOp granted to apps that we are started via {@code am instrument -e --no-isolated-storage} * + * <p>MediaProvider is the only component (outside of system server) that should care about this + * app op, hence {@code SystemApi.Client.MODULE_LIBRARIES}. + * * @hide */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage"; /** {@link #sAppOpsToNote} not initialized yet for this op */ diff --git a/core/java/android/app/QueuedWork.java b/core/java/android/app/QueuedWork.java index 82cc2c4daa0b..a1fcf53a2c37 100644 --- a/core/java/android/app/QueuedWork.java +++ b/core/java/android/app/QueuedWork.java @@ -80,7 +80,7 @@ public class QueuedWork { /** Work queued via {@link #queue} */ @GuardedBy("sLock") - private static final LinkedList<Runnable> sWork = new LinkedList<>(); + private static LinkedList<Runnable> sWork = new LinkedList<>(); /** If new work can be delayed or not */ @GuardedBy("sLock") @@ -252,8 +252,8 @@ public class QueuedWork { LinkedList<Runnable> work; synchronized (sLock) { - work = (LinkedList<Runnable>) sWork.clone(); - sWork.clear(); + work = sWork; + sWork = new LinkedList<>(); // Remove all msg-s as all work will be processed now getHandler().removeMessages(QueuedWorkHandler.MSG_RUN); diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 15a184f0e5ef..62c7b85fa62d 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -1573,7 +1573,6 @@ public final class AssetManager implements AutoCloseable { private static native long nativeAssetGetLength(long assetPtr); private static native long nativeAssetGetRemainingLength(long assetPtr); - private static native String[] nativeCreateIdmapsForStaticOverlaysTargetingAndroid(); private static native @Nullable Map nativeGetOverlayableMap(long ptr, @NonNull String packageName); private static native @Nullable String nativeGetOverlayablesToString(long ptr, diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java index 308718f3871b..885d137dd2fe 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -47,6 +47,7 @@ import android.view.Surface; import com.android.internal.R; import com.android.internal.os.SomeArgs; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -622,16 +623,16 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan */ @RequiresPermission(USE_BIOMETRIC_INTERNAL) @NonNull - public FaceSensorProperties getSensorProperties() { + public List<FaceSensorProperties> getSensorProperties() { try { if (mService == null || !mService.isHardwareDetected(mContext.getOpPackageName())) { - return new FaceSensorProperties(); + return new ArrayList<>(); } return mService.getSensorProperties(mContext.getOpPackageName()); } catch (RemoteException e) { e.rethrowFromSystemServer(); } - return new FaceSensorProperties(); + return new ArrayList<>(); } /** diff --git a/core/java/android/hardware/face/FaceSensorProperties.java b/core/java/android/hardware/face/FaceSensorProperties.java index 28c1d8772506..e3b2fbb6c614 100644 --- a/core/java/android/hardware/face/FaceSensorProperties.java +++ b/core/java/android/hardware/face/FaceSensorProperties.java @@ -25,23 +25,19 @@ import android.os.Parcelable; */ public class FaceSensorProperties implements Parcelable { + public final int sensorId; public final boolean supportsFaceDetection; /** - * Creates a SensorProperties class with safe default values - */ - public FaceSensorProperties() { - supportsFaceDetection = false; - } - - /** * Initializes SensorProperties with specified values */ - public FaceSensorProperties(boolean supportsFaceDetection) { + public FaceSensorProperties(int sensorId, boolean supportsFaceDetection) { + this.sensorId = sensorId; this.supportsFaceDetection = supportsFaceDetection; } protected FaceSensorProperties(Parcel in) { + sensorId = in.readInt(); supportsFaceDetection = in.readBoolean(); } @@ -65,6 +61,7 @@ public class FaceSensorProperties implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(sensorId); dest.writeBoolean(supportsFaceDetection); } } diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl index 5d5fe4e270a1..a9097d401349 100644 --- a/core/java/android/hardware/face/IFaceService.aidl +++ b/core/java/android/hardware/face/IFaceService.aidl @@ -28,6 +28,9 @@ import android.view.Surface; * @hide */ interface IFaceService { + // Retrieve static sensor properties for all face sensors + List<FaceSensorProperties> getSensorProperties(String opPackageName); + // Authenticate the given sessionId with a face void authenticate(IBinder token, long operationId, int userid, IFaceServiceReceiver receiver, String opPackageName); @@ -88,9 +91,6 @@ interface IFaceService { // Determine if a user has at least one enrolled face boolean hasEnrolledFaces(int userId, String opPackageName); - // Retrieve static sensor properties - FaceSensorProperties getSensorProperties(String opPackageName); - // Return the LockoutTracker status for the specified user int getLockoutModeForUser(int userId); diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index 8488454933da..e384da7574ad 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -50,6 +50,7 @@ import android.util.Slog; import android.view.Surface; import java.security.Signature; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; @@ -740,24 +741,6 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing * @hide */ @RequiresPermission(USE_BIOMETRIC_INTERNAL) - public boolean isUdfps() { - if (mService == null) { - Slog.w(TAG, "isUdfps: no fingerprint service"); - return false; - } - - try { - return mService.isUdfps(); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - return false; - } - - /** - * @hide - */ - @RequiresPermission(USE_BIOMETRIC_INTERNAL) public void setUdfpsOverlayController(IUdfpsOverlayController controller) { if (mService == null) { Slog.w(TAG, "setUdfpsOverlayController: no fingerprint service"); @@ -862,6 +845,24 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing } /** + * Get statically configured sensor properties. + * @hide + */ + @RequiresPermission(USE_BIOMETRIC_INTERNAL) + @NonNull + public List<FingerprintSensorProperties> getSensorProperties() { + try { + if (mService == null || !mService.isHardwareDetected(mContext.getOpPackageName())) { + return new ArrayList<>(); + } + return mService.getSensorProperties(mContext.getOpPackageName()); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + return new ArrayList<>(); + } + + /** * @hide */ public void addLockoutResetCallback(final LockoutResetCallback callback) { diff --git a/core/java/android/hardware/fingerprint/FingerprintSensorProperties.aidl b/core/java/android/hardware/fingerprint/FingerprintSensorProperties.aidl new file mode 100644 index 000000000000..83d853dd4048 --- /dev/null +++ b/core/java/android/hardware/fingerprint/FingerprintSensorProperties.aidl @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.fingerprint; + +parcelable FingerprintSensorProperties;
\ No newline at end of file diff --git a/core/java/android/hardware/fingerprint/FingerprintSensorProperties.java b/core/java/android/hardware/fingerprint/FingerprintSensorProperties.java new file mode 100644 index 000000000000..a774121c43f4 --- /dev/null +++ b/core/java/android/hardware/fingerprint/FingerprintSensorProperties.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.fingerprint; + +import android.annotation.IntDef; +import android.hardware.face.FaceSensorProperties; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Container for fingerprint sensor properties. + * @hide + */ +public class FingerprintSensorProperties implements Parcelable { + + public static final int TYPE_UNKNOWN = 0; + public static final int TYPE_REAR = 1; + public static final int TYPE_UDFPS = 2; + public static final int TYPE_POWER_BUTTON = 3; + + @IntDef({ + TYPE_UNKNOWN, + TYPE_REAR, + TYPE_UDFPS, + TYPE_POWER_BUTTON}) + @Retention(RetentionPolicy.SOURCE) + public @interface SensorType {} + + public final int sensorId; + public final @SensorType int sensorType; + + /** + * Initializes SensorProperties with specified values + */ + public FingerprintSensorProperties(int sensorId, @SensorType int sensorType) { + this.sensorId = sensorId; + this.sensorType = sensorType; + } + + protected FingerprintSensorProperties(Parcel in) { + sensorId = in.readInt(); + sensorType = in.readInt(); + } + + public static final Creator<FingerprintSensorProperties> CREATOR = + new Creator<FingerprintSensorProperties>() { + @Override + public FingerprintSensorProperties createFromParcel(Parcel in) { + return new FingerprintSensorProperties(in); + } + + @Override + public FingerprintSensorProperties[] newArray(int size) { + return new FingerprintSensorProperties[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(sensorId); + dest.writeInt(sensorType); + } +} diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl index 3604b5e8671d..f6069d81934f 100644 --- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl +++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl @@ -21,6 +21,7 @@ import android.hardware.fingerprint.IFingerprintClientActiveCallback; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.hardware.fingerprint.IUdfpsOverlayController; import android.hardware.fingerprint.Fingerprint; +import android.hardware.fingerprint.FingerprintSensorProperties; import android.view.Surface; import java.util.List; @@ -29,6 +30,9 @@ import java.util.List; * @hide */ interface IFingerprintService { + // Retrieve static sensor properties for all fingerprint sensors + List<FingerprintSensorProperties> getSensorProperties(String opPackageName); + // Authenticate the given sessionId with a fingerprint. This is protected by // USE_FINGERPRINT/USE_BIOMETRIC permission. This is effectively deprecated, since it only comes // through FingerprintManager now. @@ -122,9 +126,6 @@ interface IFingerprintService { // Notifies about a finger leaving the sensor area. void onFingerUp(); - // Returns whether the sensor is an under-display fingerprint sensor (UDFPS). - boolean isUdfps(); - // Sets the controller for managing the UDFPS overlay. void setUdfpsOverlayController(in IUdfpsOverlayController controller); } diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java index 38ba47ab3701..ff1bcf6b3c5e 100644 --- a/core/java/android/os/UserHandle.java +++ b/core/java/android/os/UserHandle.java @@ -538,7 +538,7 @@ public final class UserHandle implements Parcelable { UserHandle other = (UserHandle)obj; return mHandle == other.mHandle; } - } catch (ClassCastException e) { + } catch (ClassCastException ignore) { } return false; } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index e1d48860b1e2..500e476a7b80 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -11862,21 +11862,6 @@ public final class Settings { "job_scheduler_quota_controller_constants"; /** - * Job scheduler TimeController specific settings. - * This is encoded as a key=value list, separated by commas. Ex: - * - * "skip_not_ready_jobs=true5,other_key=2" - * - * <p> - * Type: string - * - * @hide - * @see com.android.server.job.JobSchedulerService.Constants - */ - public static final String JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS = - "job_scheduler_time_controller_constants"; - - /** * ShortcutManager specific settings. * This is encoded as a key=value list, separated by commas. Ex: * diff --git a/core/java/android/view/ImeFocusController.java b/core/java/android/view/ImeFocusController.java index ad43f9556d8d..92772c1d7a44 100644 --- a/core/java/android/view/ImeFocusController.java +++ b/core/java/android/view/ImeFocusController.java @@ -125,10 +125,10 @@ public final class ImeFocusController { final View viewForWindowFocus = focusedView != null ? focusedView : mViewRootImpl.mView; onViewFocusChanged(viewForWindowFocus, true); - // Starting new input when the next focused view is same as served view but the - // editor is not aligned with the same editor or editor is inactive. - final boolean nextFocusIsServedView = mServedView != null && mServedView == focusedView; - if (nextFocusIsServedView && !immDelegate.isSameEditorAndAcceptingText(focusedView)) { + // Starting new input when the next focused view is same as served view but the currently + // active connection (if any) is not associated with it. + final boolean nextFocusIsServedView = mServedView == viewForWindowFocus; + if (nextFocusIsServedView && !immDelegate.hasActiveConnection(viewForWindowFocus)) { forceFocus = true; } @@ -254,7 +254,7 @@ public final class ImeFocusController { void setCurrentRootView(ViewRootImpl rootView); boolean isCurrentRootView(ViewRootImpl rootView); boolean isRestartOnNextWindowFocus(boolean reset); - boolean isSameEditorAndAcceptingText(View view); + boolean hasActiveConnection(View view); } public View getServedView() { diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java index 492ab6f8a3d5..8c355202b63f 100644 --- a/core/java/android/view/WindowManagerPolicyConstants.java +++ b/core/java/android/view/WindowManagerPolicyConstants.java @@ -49,6 +49,13 @@ public interface WindowManagerPolicyConstants { int PRESENCE_INTERNAL = 1 << 0; int PRESENCE_EXTERNAL = 1 << 1; + // Alternate bars position values + int ALT_BAR_UNKNOWN = -1; + int ALT_BAR_LEFT = 1 << 0; + int ALT_BAR_RIGHT = 1 << 1; + int ALT_BAR_BOTTOM = 1 << 2; + int ALT_BAR_TOP = 1 << 3; + // Navigation bar position values int NAV_BAR_INVALID = -1; int NAV_BAR_LEFT = 1 << 0; diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java index 07fef76961f9..c5f2299e4f83 100644 --- a/core/java/android/view/inputmethod/EditorInfo.java +++ b/core/java/android/view/inputmethod/EditorInfo.java @@ -27,6 +27,7 @@ import android.os.LocaleList; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; +import android.text.Editable; import android.text.InputType; import android.text.TextUtils; import android.util.Printer; @@ -567,7 +568,8 @@ public class EditorInfo implements InputType, Parcelable { * editor wants to trim out the first 10 chars, subTextStart should be 10. */ public void setInitialSurroundingSubText(@NonNull CharSequence subText, int subTextStart) { - Objects.requireNonNull(subText); + CharSequence newSubText = Editable.Factory.getInstance().newEditable(subText); + Objects.requireNonNull(newSubText); // Swap selection start and end if necessary. final int subTextSelStart = initialSelStart > initialSelEnd @@ -575,7 +577,7 @@ public class EditorInfo implements InputType, Parcelable { final int subTextSelEnd = initialSelStart > initialSelEnd ? initialSelStart - subTextStart : initialSelEnd - subTextStart; - final int subTextLength = subText.length(); + final int subTextLength = newSubText.length(); // Unknown or invalid selection. if (subTextStart < 0 || subTextSelStart < 0 || subTextSelEnd > subTextLength) { mInitialSurroundingText = new InitialSurroundingText(); @@ -589,12 +591,12 @@ public class EditorInfo implements InputType, Parcelable { } if (subTextLength <= MEMORY_EFFICIENT_TEXT_LENGTH) { - mInitialSurroundingText = new InitialSurroundingText(subText, subTextSelStart, + mInitialSurroundingText = new InitialSurroundingText(newSubText, subTextSelStart, subTextSelEnd); return; } - trimLongSurroundingText(subText, subTextSelStart, subTextSelEnd); + trimLongSurroundingText(newSubText, subTextSelStart, subTextSelEnd); } /** diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 599a7c24e8aa..793d94097862 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -19,8 +19,8 @@ package android.view.inputmethod; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.Manifest.permission.WRITE_SECURE_SETTINGS; -import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR; -import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR; +import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION; +import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION; import android.annotation.DrawableRes; import android.annotation.NonNull; @@ -89,6 +89,7 @@ import com.android.internal.view.InputBindResult; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.lang.ref.WeakReference; import java.lang.reflect.Proxy; import java.util.Arrays; import java.util.Collections; @@ -610,14 +611,13 @@ public final class InputMethodManager { @Override public void startInputAsyncOnWindowFocusGain(View focusedView, @SoftInputModeFlags int softInputMode, int windowFlags, boolean forceNewFocus) { - final boolean forceNewFocus1 = forceNewFocus; final int startInputFlags = getStartInputFlags(focusedView, 0); final ImeFocusController controller = getFocusController(); if (controller == null) { return; } - if (controller.checkFocus(forceNewFocus1, false)) { + if (controller.checkFocus(forceNewFocus, false)) { // We need to restart input on the current focus view. This // should be done in conjunction with telling the system service // about the window gaining focus, to help make the transition @@ -633,15 +633,15 @@ public final class InputMethodManager { // we'll just do a window focus gain and call it a day. try { View servedView = controller.getServedView(); - boolean nextFocusSameEditor = servedView != null && servedView == focusedView - && isSameEditorAndAcceptingText(focusedView); + boolean nextFocusHasConnection = servedView != null && servedView == focusedView + && hasActiveConnection(focusedView); if (DEBUG) { Log.v(TAG, "Reporting focus gain, without startInput" - + ", nextFocusIsServedView=" + nextFocusSameEditor); + + ", nextFocusIsServedView=" + nextFocusHasConnection); } final int startInputReason = - nextFocusSameEditor ? WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR - : WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR; + nextFocusHasConnection ? WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION + : WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION; mService.startInputOrWindowGainedFocus( startInputReason, mClient, focusedView.getWindowToken(), startInputFlags, softInputMode, @@ -701,33 +701,24 @@ public final class InputMethodManager { } /** - * For {@link ImeFocusController} to check if the given focused view aligns with the same - * editor and the editor is active to accept the text input. + * Checks whether the active input connection (if any) is for the given view. * - * TODO(b/160968797): Remove this method and move mCurrentTextBoxAttritube to + * TODO(b/160968797): Remove this method and move mServedInputConnectionWrapper to * ImeFocusController. - * In the long-term, we should make mCurrentTextBoxAtrtribue as per-window base instance, - * so that we we can directly check if the current focused view aligned with the same editor - * in the window without using this checking. * - * Note that this method is only use for fixing start new input may ignored issue + * Note that this method is only intended for restarting input after focus gain * (e.g. b/160391516), DO NOT leverage this method to do another check. */ - public boolean isSameEditorAndAcceptingText(View view) { + @Override + public boolean hasActiveConnection(View view) { synchronized (mH) { - if (!hasServedByInputMethodLocked(view) || mCurrentTextBoxAttribute == null) { + if (!hasServedByInputMethodLocked(view)) { return false; } - final EditorInfo ic = mCurrentTextBoxAttribute; - // This sameEditor checking is based on using object hash comparison to check if - // some fields of the current EditorInfo (e.g. autoFillId, OpPackageName) the - // hash code is same as the given focused view. - final boolean sameEditor = view.onCheckIsTextEditor() && view.getId() == ic.fieldId - && view.getAutofillId() == ic.autofillId - && view.getContext().getOpPackageName() == ic.packageName; - return sameEditor && mServedInputConnectionWrapper != null - && mServedInputConnectionWrapper.isActive(); + return mServedInputConnectionWrapper != null + && mServedInputConnectionWrapper.isActive() + && mServedInputConnectionWrapper.mServedView.get() == view; } } } @@ -980,11 +971,13 @@ public final class InputMethodManager { private static class ControlledInputConnectionWrapper extends IInputConnectionWrapper { private final InputMethodManager mParentInputMethodManager; + private final WeakReference<View> mServedView; - public ControlledInputConnectionWrapper(final Looper mainLooper, final InputConnection conn, - final InputMethodManager inputMethodManager) { + ControlledInputConnectionWrapper(Looper mainLooper, InputConnection conn, + InputMethodManager inputMethodManager, View servedView) { super(mainLooper, conn); mParentInputMethodManager = inputMethodManager; + mServedView = new WeakReference<>(servedView); } @Override @@ -1007,6 +1000,7 @@ public final class InputMethodManager { + "connection=" + getInputConnection() + " finished=" + isFinished() + " mParentInputMethodManager.mActive=" + mParentInputMethodManager.mActive + + " mServedView=" + mServedView.get() + "}"; } } @@ -1187,7 +1181,8 @@ public final class InputMethodManager { mMainLooper = looper; mH = new H(looper); mDisplayId = displayId; - mIInputContext = new ControlledInputConnectionWrapper(looper, mDummyInputConnection, this); + mIInputContext = new ControlledInputConnectionWrapper(looper, mDummyInputConnection, this, + null); } /** @@ -1970,7 +1965,7 @@ public final class InputMethodManager { icHandler = ic.getHandler(); } servedContext = new ControlledInputConnectionWrapper( - icHandler != null ? icHandler.getLooper() : vh.getLooper(), ic, this); + icHandler != null ? icHandler.getLooper() : vh.getLooper(), ic, this, view); } else { servedContext = null; missingMethodFlags = 0; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index eaa4c573b0e4..6f14dfb89e6b 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -11003,17 +11003,18 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * not among the handles. */ boolean isFromPrimePointer(MotionEvent event, boolean fromHandleView) { + boolean res = true; if (mPrimePointerId == NO_POINTER_ID) { mPrimePointerId = event.getPointerId(0); mIsPrimePointerFromHandleView = fromHandleView; } else if (mPrimePointerId != event.getPointerId(0)) { - return mIsPrimePointerFromHandleView && fromHandleView; + res = mIsPrimePointerFromHandleView && fromHandleView; } if (event.getActionMasked() == MotionEvent.ACTION_UP || event.getActionMasked() == MotionEvent.ACTION_CANCEL) { mPrimePointerId = -1; } - return true; + return res; } @Override diff --git a/core/java/android/window/DisplayAreaOrganizer.java b/core/java/android/window/DisplayAreaOrganizer.java index 3daf6d371450..f035d36a0f71 100644 --- a/core/java/android/window/DisplayAreaOrganizer.java +++ b/core/java/android/window/DisplayAreaOrganizer.java @@ -68,6 +68,14 @@ public class DisplayAreaOrganizer extends WindowOrganizer { public static final int FEATURE_WINDOWED_MAGNIFICATION = FEATURE_SYSTEM_FIRST + 4; /** + * Display area that can be magnified in + * {@link Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN}. This is different from + * {@link #FEATURE_WINDOWED_MAGNIFICATION} that the whole display will be magnified. + * @hide + */ + public static final int FEATURE_FULLSCREEN_MAGNIFICATION = FEATURE_SYSTEM_FIRST + 5; + + /** * The last boundary of display area for system features */ public static final int FEATURE_SYSTEM_LAST = 10_000; diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index fbf050ad08f6..3a89dcd96487 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -3134,6 +3134,7 @@ public class ChooserActivity extends ResolverActivity implements // ends up disabled. That's because at some point the old tab's vertical scrolling is // disabled and the new tab's is enabled. For context, see b/159997845 setVerticalScrollEnabled(true); + mResolverDrawerLayout.scrollNestedScrollableChildBackToTop(); } @Override diff --git a/core/java/com/android/internal/inputmethod/InputMethodDebug.java b/core/java/com/android/internal/inputmethod/InputMethodDebug.java index 085cdfcf9462..37f68233db53 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodDebug.java +++ b/core/java/com/android/internal/inputmethod/InputMethodDebug.java @@ -46,10 +46,10 @@ public final class InputMethodDebug { return "UNSPECIFIED"; case StartInputReason.WINDOW_FOCUS_GAIN: return "WINDOW_FOCUS_GAIN"; - case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR: - return "WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR"; - case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR: - return "WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR"; + case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION: + return "WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION"; + case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION: + return "WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION"; case StartInputReason.APP_CALLED_RESTART_INPUT_API: return "APP_CALLED_RESTART_INPUT_API"; case StartInputReason.CHECK_FOCUS: diff --git a/core/java/com/android/internal/inputmethod/StartInputReason.java b/core/java/com/android/internal/inputmethod/StartInputReason.java index 946ce858c12d..2ba708dd9312 100644 --- a/core/java/com/android/internal/inputmethod/StartInputReason.java +++ b/core/java/com/android/internal/inputmethod/StartInputReason.java @@ -30,8 +30,8 @@ import java.lang.annotation.Retention; @IntDef(value = { StartInputReason.UNSPECIFIED, StartInputReason.WINDOW_FOCUS_GAIN, - StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR, - StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR, + StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION, + StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION, StartInputReason.APP_CALLED_RESTART_INPUT_API, StartInputReason.CHECK_FOCUS, StartInputReason.BOUND_TO_IMMS, @@ -54,13 +54,13 @@ public @interface StartInputReason { * view and its input connection remains. {@link android.view.inputmethod.InputMethodManager} * just reports this window focus change event to sync IME input target for system. */ - int WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR = 2; + int WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION = 2; /** * {@link android.view.Window} gained focus but there is no {@link android.view.View} that is * eligible to have IME focus. {@link android.view.inputmethod.InputMethodManager} just reports * this window focus change event for logging. */ - int WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR = 3; + int WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION = 3; /** * {@link android.view.inputmethod.InputMethodManager#restartInput(android.view.View)} is * either explicitly called by the application or indirectly called by some Framework class diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java index dc8d57ab709e..a2de0aff5dfa 100644 --- a/core/java/com/android/internal/widget/PointerLocationView.java +++ b/core/java/com/android/internal/widget/PointerLocationView.java @@ -371,7 +371,7 @@ public class PointerLocationView extends View implements InputDeviceListener, } if (haveLast) { canvas.drawLine(lastX, lastY, x, y, mPathPaint); - final Paint paint = ps.mTraceCurrent[i] ? mCurrentPointPaint : mPaint; + final Paint paint = ps.mTraceCurrent[i - 1] ? mCurrentPointPaint : mPaint; canvas.drawPoint(lastX, lastY, paint); drawn = true; } diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java index 3f708f84750c..90eeabb47e9a 100644 --- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java +++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java @@ -464,11 +464,7 @@ public class ResolverDrawerLayout extends ViewGroup { smoothScrollTo(mCollapsibleHeight + mUncollapsibleHeight, yvel); mDismissOnScrollerFinished = true; } else { - if (isNestedListChildScrolled()) { - mNestedListChild.smoothScrollToPosition(0); - } else if (isNestedRecyclerChildScrolled()) { - mNestedRecyclerChild.smoothScrollToPosition(0); - } + scrollNestedScrollableChildBackToTop(); smoothScrollTo(yvel < 0 ? 0 : mCollapsibleHeight, yvel); } } @@ -493,6 +489,17 @@ public class ResolverDrawerLayout extends ViewGroup { return handled; } + /** + * Scroll nested scrollable child back to top if it has been scrolled. + */ + public void scrollNestedScrollableChildBackToTop() { + if (isNestedListChildScrolled()) { + mNestedListChild.smoothScrollToPosition(0); + } else if (isNestedRecyclerChildScrolled()) { + mNestedRecyclerChild.smoothScrollToPosition(0); + } + } + private void onSecondaryPointerUp(MotionEvent ev) { final int pointerIndex = ev.getActionIndex(); final int pointerId = ev.getPointerId(pointerIndex); diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp index 792c00572318..bdb4544f4aae 100644 --- a/core/jni/android_hardware_input_InputWindowHandle.cpp +++ b/core/jni/android_hardware_input_InputWindowHandle.cpp @@ -16,20 +16,21 @@ #define LOG_TAG "InputWindowHandle" -#include <nativehelper/JNIHelp.h> -#include "core_jni_helpers.h" -#include "jni.h" -#include <android_runtime/AndroidRuntime.h> -#include <utils/threads.h> +#include "android_hardware_input_InputWindowHandle.h" #include <android/graphics/region.h> +#include <android_runtime/AndroidRuntime.h> +#include <binder/IPCThreadState.h> #include <gui/SurfaceControl.h> +#include <nativehelper/JNIHelp.h> #include <ui/Region.h> +#include <utils/threads.h> -#include "android_hardware_input_InputWindowHandle.h" #include "android_hardware_input_InputApplicationHandle.h" #include "android_util_Binder.h" -#include <binder/IPCThreadState.h> +#include "core_jni_helpers.h" +#include "input/InputWindow.h" +#include "jni.h" namespace android { @@ -113,10 +114,10 @@ bool NativeInputWindowHandle::updateInfo() { mInfo.name = getStringField(env, obj, gInputWindowHandleClassInfo.name, "<null>"); - mInfo.layoutParamsFlags = env->GetIntField(obj, - gInputWindowHandleClassInfo.layoutParamsFlags); - mInfo.layoutParamsType = env->GetIntField(obj, - gInputWindowHandleClassInfo.layoutParamsType); + mInfo.flags = Flags<InputWindowInfo::Flag>( + env->GetIntField(obj, gInputWindowHandleClassInfo.layoutParamsFlags)); + mInfo.type = static_cast<InputWindowInfo::Type>( + env->GetIntField(obj, gInputWindowHandleClassInfo.layoutParamsType)); mInfo.dispatchingTimeout = decltype(mInfo.dispatchingTimeout)( env->GetLongField(obj, gInputWindowHandleClassInfo.dispatchingTimeoutNanos)); mInfo.frameLeft = env->GetIntField(obj, @@ -157,8 +158,8 @@ bool NativeInputWindowHandle::updateInfo() { gInputWindowHandleClassInfo.ownerPid); mInfo.ownerUid = env->GetIntField(obj, gInputWindowHandleClassInfo.ownerUid); - mInfo.inputFeatures = env->GetIntField(obj, - gInputWindowHandleClassInfo.inputFeatures); + mInfo.inputFeatures = static_cast<InputWindowInfo::Feature>( + env->GetIntField(obj, gInputWindowHandleClassInfo.inputFeatures)); mInfo.displayId = env->GetIntField(obj, gInputWindowHandleClassInfo.displayId); mInfo.portalToDisplayId = env->GetIntField(obj, diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index e6881b3995a8..efca33aaf520 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -39,7 +39,6 @@ #include "androidfw/AssetManager2.h" #include "androidfw/AttributeResolution.h" #include "androidfw/MutexGuard.h" -#include "androidfw/PosixUtils.h" #include "androidfw/ResourceTypes.h" #include "androidfw/ResourceUtils.h" @@ -58,7 +57,6 @@ extern "C" int capget(cap_user_header_t hdrp, cap_user_data_t datap); extern "C" int capset(cap_user_header_t hdrp, const cap_user_data_t datap); using ::android::base::StringPrintf; -using ::android::util::ExecuteBinary; namespace android { @@ -114,88 +112,6 @@ constexpr inline static ApkAssetsCookie JavaCookieToApkAssetsCookie(jint cookie) return cookie > 0 ? static_cast<ApkAssetsCookie>(cookie - 1) : kInvalidCookie; } -static jobjectArray NativeCreateIdmapsForStaticOverlaysTargetingAndroid(JNIEnv* env, - jclass /*clazz*/) { - // --input-directory can be given multiple times, but idmap2 expects the directory to exist - std::vector<std::string> input_dirs; - struct stat st; - if (stat(AssetManager::VENDOR_OVERLAY_DIR, &st) == 0) { - input_dirs.push_back(AssetManager::VENDOR_OVERLAY_DIR); - } - - if (stat(AssetManager::PRODUCT_OVERLAY_DIR, &st) == 0) { - input_dirs.push_back(AssetManager::PRODUCT_OVERLAY_DIR); - } - - if (stat(AssetManager::SYSTEM_EXT_OVERLAY_DIR, &st) == 0) { - input_dirs.push_back(AssetManager::SYSTEM_EXT_OVERLAY_DIR); - } - - if (stat(AssetManager::ODM_OVERLAY_DIR, &st) == 0) { - input_dirs.push_back(AssetManager::ODM_OVERLAY_DIR); - } - - if (stat(AssetManager::OEM_OVERLAY_DIR, &st) == 0) { - input_dirs.push_back(AssetManager::OEM_OVERLAY_DIR); - } - - if (input_dirs.empty()) { - LOG(WARNING) << "no directories for idmap2 to scan"; - return env->NewObjectArray(0, g_stringClass, nullptr); - } - - if (access("/system/bin/idmap2", X_OK) == -1) { - PLOG(WARNING) << "unable to execute idmap2"; - return nullptr; - } - - std::vector<std::string> argv{"/system/bin/idmap2", - "scan", - "--recursive", - "--target-package-name", "android", - "--target-apk-path", "/system/framework/framework-res.apk", - "--output-directory", "/data/resource-cache"}; - - for (const auto& dir : input_dirs) { - argv.push_back("--input-directory"); - argv.push_back(dir); - } - - const auto result = ExecuteBinary(argv); - - if (!result) { - LOG(ERROR) << "failed to execute idmap2"; - return nullptr; - } - - if (result->status != 0) { - LOG(ERROR) << "idmap2: " << result->stderr; - return nullptr; - } - - std::vector<std::string> idmap_paths; - std::istringstream input(result->stdout); - std::string path; - while (std::getline(input, path)) { - idmap_paths.push_back(path); - } - - jobjectArray array = env->NewObjectArray(idmap_paths.size(), g_stringClass, nullptr); - if (array == nullptr) { - return nullptr; - } - for (size_t i = 0; i < idmap_paths.size(); i++) { - const std::string path = idmap_paths[i]; - jstring java_string = env->NewStringUTF(path.c_str()); - if (env->ExceptionCheck()) { - return nullptr; - } - env->SetObjectArrayElement(array, i, java_string); - env->DeleteLocalRef(java_string); - } - return array; -} - static jint CopyValue(JNIEnv* env, ApkAssetsCookie cookie, const Res_value& value, uint32_t ref, uint32_t type_spec_flags, ResTable_config* config, jobject out_typed_value) { env->SetIntField(out_typed_value, gTypedValueOffsets.mType, value.dataType); @@ -1563,8 +1479,6 @@ static const JNINativeMethod gAssetManagerMethods[] = { {"nativeAssetGetRemainingLength", "(J)J", (void*)NativeAssetGetRemainingLength}, // System/idmap related methods. - {"nativeCreateIdmapsForStaticOverlaysTargetingAndroid", "()[Ljava/lang/String;", - (void*)NativeCreateIdmapsForStaticOverlaysTargetingAndroid}, {"nativeGetOverlayableMap", "(JLjava/lang/String;)Ljava/util/Map;", (void*)NativeGetOverlayableMap}, {"nativeGetOverlayablesToString", "(JLjava/lang/String;)Ljava/lang/String;", diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index b7c5289043d6..c73441cbd4f9 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -101,6 +101,19 @@ #include "nativebridge/native_bridge.h" +/* Functions in the callchain during the fork shall not be protected with + Armv8.3-A Pointer Authentication, otherwise child will not be able to return. */ +#ifdef __ARM_FEATURE_PAC_DEFAULT +#ifdef __ARM_FEATURE_BTI_DEFAULT +#define NO_PAC_FUNC __attribute__((target("branch-protection=bti"))) +#else +#define NO_PAC_FUNC __attribute__((target("branch-protection=none"))) +#endif /* __ARM_FEATURE_BTI_DEFAULT */ +#else /* !__ARM_FEATURE_PAC_DEFAULT */ +#define NO_PAC_FUNC +#endif /* __ARM_FEATURE_PAC_DEFAULT */ + + namespace { // TODO (chriswailes): Add a function to initialize native Zygote data. @@ -1066,7 +1079,23 @@ static void ClearUsapTable() { gUsapPoolCount = 0; } +NO_PAC_FUNC +static void PAuthKeyChange(JNIEnv* env) { +#ifdef __aarch64__ + unsigned long int hwcaps = getauxval(AT_HWCAP); + if (hwcaps & HWCAP_PACA) { + const unsigned long key_mask = PR_PAC_APIAKEY | PR_PAC_APIBKEY | + PR_PAC_APDAKEY | PR_PAC_APDBKEY | PR_PAC_APGAKEY; + if (prctl(PR_PAC_RESET_KEYS, key_mask, 0, 0, 0) != 0) { + ALOGE("Failed to change the PAC keys: %s", strerror(errno)); + RuntimeAbort(env, __LINE__, "PAC key change failed."); + } + } +#endif +} + // Utility routine to fork a process from the zygote. +NO_PAC_FUNC static pid_t ForkCommon(JNIEnv* env, bool is_system_server, const std::vector<int>& fds_to_close, const std::vector<int>& fds_to_ignore, @@ -1117,6 +1146,7 @@ static pid_t ForkCommon(JNIEnv* env, bool is_system_server, } // The child process. + PAuthKeyChange(env); PreApplicationInit(); // Clean up any descriptors which must be closed immediately @@ -2052,6 +2082,7 @@ static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jcl PreApplicationInit(); } +NO_PAC_FUNC static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( JNIEnv* env, jclass, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, @@ -2104,6 +2135,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( return pid; } +NO_PAC_FUNC static jint com_android_internal_os_Zygote_nativeForkSystemServer( JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities, @@ -2175,6 +2207,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( * @param is_priority_fork Controls the nice level assigned to the newly created process * @return */ +NO_PAC_FUNC static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env, jclass, jint read_pipe_fd, diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto index 9bbe0caa9e98..ac143ac1a147 100644 --- a/core/proto/android/providers/settings/global.proto +++ b/core/proto/android/providers/settings/global.proto @@ -508,7 +508,7 @@ message GlobalSettingsProto { optional SettingProto job_scheduler_constants = 66 [ (android.privacy).dest = DEST_AUTOMATIC ]; optional SettingProto job_scheduler_quota_controller_constants = 149 [ (android.privacy).dest = DEST_AUTOMATIC ]; - optional SettingProto job_scheduler_time_controller_constants = 150 [ (android.privacy).dest = DEST_AUTOMATIC ]; + reserved 150; // job_scheduler_time_controller_constants optional SettingProto keep_profile_in_background = 67 [ (android.privacy).dest = DEST_AUTOMATIC ]; diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto index f2f20e3ac12e..76b7fc028a98 100644 --- a/core/proto/android/server/jobscheduler.proto +++ b/core/proto/android/server/jobscheduler.proto @@ -324,7 +324,7 @@ message ConstantsProto { // ready now. reserved 1; // skip_not_ready_jobs // Whether or not TimeController will use a non-wakeup alarm for delay constraints. - optional bool use_non_wakeup_alarm_for_delay = 2; + reserved 2; // use_non_wakeup_alarm_for_delay } optional TimeController time_controller = 25; diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 6640661d1c11..9ce214fdf3ab 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1792,8 +1792,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"በእርስዎ አስተዳዳሪ ተዘምኗል"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"በእርስዎ አስተዳዳሪ ተሰርዟል"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"እሺ"</string> - <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"የባትሪ ዕድሜን ለማራዘም፣ የባትሪ ቆጣቢ፦\n\n•ጨለማ ገጽታን ያበራል\n•የበስተጀርባ እንቅስቃሴን፣ አንዳንድ የሚታዩ ማሳመሪያዎችን፣ እና ሌሎች እንደ «Hey Google» ያሉ ባህሪያትን ያጠፋል ወይም ይገድባል\n\n"<annotation id="url">"የበለጠ ለመረዳት"</annotation></string> - <string name="battery_saver_description" msgid="8587408568232177204">"የባትሪ ዕድሜን ለማራዘም፣ የባትሪ ቆጣቢ፦\n\n•ጨለማ ገጽታን ያበራል\n•የበስተጀርባ እንቅስቃሴን፣ አንዳንድ የሚታዩ ማሳመሪያዎችን፣ እና ሌሎች እንደ «Hey Google» ያሉ ባህሪያትን ያጠፋል ወይም ይገድባል"</string> + <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"የባትሪ ዕድሜን ለማራዘም፣ የባትሪ ቆጣቢ፦\n\n•ጨለማ ገጽታን ያበራል\n•የበስተጀርባ እንቅስቃሴን፣ አንዳንድ የሚታዩ ማሳመሪያዎችን፣ እና ሌሎች እንደ «Hey Google» ያሉ ባህሪያትን ያጠፋል ወይም ይገድባል\n\n"<annotation id="url">"የበለጠ ለመረዳት"</annotation></string> + <string name="battery_saver_description" msgid="6794188153647295212">"የባትሪ ዕድሜን ለማራዘም የባትሪ ኃይል ቆጣቢ፦\n\n• ጨለማ ገጽታን ያበራል\n• የበስተጀርባ እንቅስቃሴን፣ አንዳንድ ምስላዊ ተጽዕኖዎችን እና ሌሎች እንደ «Hey Google» ያሉ ባህሪያትን ያጠፋል ወይም ይገድባል"</string> <string name="data_saver_description" msgid="4995164271550590517">"የውሂብ አጠቃቀም እንዲቀንስ ለማገዝ ውሂብ ቆጣቢ አንዳንድ መተግበሪያዎች ከበስተጀርባ ሆነው ውሂብ እንዳይልኩ ወይም እንዳይቀበሉ ይከለክላቸዋል። በአሁኑ ጊዜ እየተጠቀሙበት ያለ መተግበሪያ ውሂብ ሊደርስ ይችላል፣ ነገር ግን ባነሰ ተደጋጋሚነት ሊሆን ይችላል። ይሄ ማለት ለምሳሌ ምስሎችን መታ እስኪያደርጓቸው ድረስ ላይታዩ ይችላሉ ማለት ነው።"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ውሂብ ቆጣቢ ይጥፋ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"አብራ"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index ff70218e657a..2bcf9095cb04 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -1179,7 +1179,7 @@ <string name="noApplications" msgid="1186909265235544019">"Nijedna aplikacija ne može da obavlja ovu radnju."</string> <string name="aerr_application" msgid="4090916809370389109">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> je zaustavljena"</string> <string name="aerr_process" msgid="4268018696970966407">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> je zaustavljen"</string> - <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> se stalno zaustavlja(ju)"</string> + <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> se stalno zaustavlja"</string> <string name="aerr_process_repeated" msgid="1153152413537954974">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> se stalno zaustavlja"</string> <string name="aerr_restart" msgid="2789618625210505419">"Ponovo otvori aplikaciju"</string> <string name="aerr_report" msgid="3095644466849299308">"Pošaljite povratne informacije"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 9b2c093bd178..1ac213f01d6b 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -1792,10 +1792,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"আপনার প্রশাসক আপডেট করেছেন"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"আপনার প্রশাসক মুছে দিয়েছেন"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ঠিক আছে"</string> - <!-- no translation found for battery_saver_description_with_learn_more (4424488535318105801) --> - <skip /> - <!-- no translation found for battery_saver_description (6794188153647295212) --> - <skip /> + <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"ব্যাটারি আরও বেশিক্ষণ চালাতে, ব্যাটারি সেভার:\n\n• ডার্ক থিম চালু করে\n• ব্যাকগ্রাউন্ড অ্যাক্টিভিটি, কিছু ভিজ্যুয়াল এফেক্ট এবং “হ্যালো Google”-এর মতো অন্যান্য ফিচার বন্ধ বা সীমিত করে\n\n"<annotation id="url">"আরও জানুন"</annotation></string> + <string name="battery_saver_description" msgid="6794188153647295212">"ব্যাটারি আরও বেশিক্ষণ চালাতে, ব্যাটারি সেভার:\n\n• ডার্ক থিম চালু করে\n• ব্যাকগ্রাউন্ড অ্যাক্টিভিটি, কিছু ভিজ্যুয়াল এফেক্ট এবং “হ্যালো Google”-এর মতো অন্যান্য ফিচার বন্ধ অথবা সীমিত করে"</string> <string name="data_saver_description" msgid="4995164271550590517">"ডেটার ব্যবহার কমাতে সহায়তা করার জন্য, ডেটা সেভার ব্যাকগ্রাউন্ডে কিছু অ্যাপ্লিকেশনকে ডেটা পাঠাতে বা গ্রহণ করতে বাধা দেয়৷ আপনি বর্তমানে এমন একটি অ্যাপ্লিকেশন ব্যবহার করছেন যেটি ডেটা অ্যাক্সেস করতে পারে, তবে সেটি কমই করে৷ এর ফলে যা হতে পারে, উদাহরণস্বরূপ, আপনি ছবির উপর ট্যাপ না করা পর্যন্ত সেগুলি দেখানো হবে না৷"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ডেটা সেভার চালু করবেন?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"চালু করুন"</string> @@ -2042,7 +2040,7 @@ <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"দ্রুত সেটিংস"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"পাওয়ার ডায়লগ"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"লক স্ক্রিন"</string> - <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"স্ক্রিনশট"</string> + <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"স্ক্রিনশট নিন"</string> <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"অন-স্ক্রিন অ্যাক্সেসিবিলিটি শর্টকাট"</string> <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"অন-স্ক্রিন অ্যাক্সেসিবিলিটি শর্টকাট বেছে নেওয়ার বিকল্প"</string> <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"অ্যাক্সেসিবিলিটি শর্টকাট"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 6be331355766..f27441a667e7 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -2064,7 +2064,7 @@ <item quantity="few"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fajla</item> <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fajlova</item> </plurals> - <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Nijedna osoba nije preporučena za dijeljenje"</string> + <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Nema preporučenih osoba za dijeljenje"</string> <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista aplikacija"</string> <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Ovoj aplikaciji nije dato odobrenje za snimanje, ali može snimati zvuk putem ovog USB uređaja."</string> <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Početna stranica"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 0cc15d208233..296200f8004c 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1792,10 +1792,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Von deinem Administrator aktualisiert"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Von deinem Administrator gelöscht"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <!-- no translation found for battery_saver_description_with_learn_more (4424488535318105801) --> - <skip /> - <!-- no translation found for battery_saver_description (6794188153647295212) --> - <skip /> + <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"Der Energiesparmodus sorgt für eine längere Akkulaufzeit:\n\n• Das dunkle Design wird aktiviert\n• Hintergrundaktivitäten, einige optische Effekte und weitere Funktionen wie \"Ok Google\" werden abgeschaltet oder eingeschränkt\n\n"<annotation id="url">"Weitere Informationen"</annotation></string> + <string name="battery_saver_description" msgid="6794188153647295212">"Der Energiesparmodus sorgt für eine längere Akkulaufzeit:\n\n• Das dunkle Design wird aktiviert\n• Hintergrundaktivitäten, einige optische Effekte und weitere Funktionen wie \"Ok Google\" werden abgeschaltet oder eingeschränkt"</string> <string name="data_saver_description" msgid="4995164271550590517">"Der Datensparmodus verhindert zum einen, dass manche Apps im Hintergrund Daten senden oder empfangen, sodass weniger Daten verbraucht werden. Zum anderen werden die Datenzugriffe der gerade aktiven App eingeschränkt, was z. B. dazu führen kann, dass Bilder erst angetippt werden müssen, bevor sie sichtbar werden."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Datensparmodus aktivieren?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Aktivieren"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 8d5aea9e427e..815daaa5d7ae 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -1159,8 +1159,8 @@ <string name="noApplications" msgid="1186909265235544019">"Yksikään sovellus ei voi suorittaa tätä toimintoa."</string> <string name="aerr_application" msgid="4090916809370389109">"<xliff:g id="APPLICATION">%1$s</xliff:g> pysähtyi."</string> <string name="aerr_process" msgid="4268018696970966407">"<xliff:g id="PROCESS">%1$s</xliff:g> pysähtyi."</string> - <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> pysähtyy toistuvasti."</string> - <string name="aerr_process_repeated" msgid="1153152413537954974">"<xliff:g id="PROCESS">%1$s</xliff:g> pysähtyy toistuvasti."</string> + <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> pysähtyy toistuvasti"</string> + <string name="aerr_process_repeated" msgid="1153152413537954974">"<xliff:g id="PROCESS">%1$s</xliff:g> pysähtyy toistuvasti"</string> <string name="aerr_restart" msgid="2789618625210505419">"Avaa sovellus uudelleen"</string> <string name="aerr_report" msgid="3095644466849299308">"Lähetä palautetta"</string> <string name="aerr_close" msgid="3398336821267021852">"Sulje"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 7410c667dc8e..be17cfd03115 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -854,7 +854,7 @@ <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"રોકો"</string> <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"રીવાઇન્ડ કરો"</string> <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"ઝડપી ફોરવર્ડ કરો"</string> - <string name="emergency_calls_only" msgid="3057351206678279851">"ફક્ત કટોકટીના કૉલ્સ"</string> + <string name="emergency_calls_only" msgid="3057351206678279851">"ફક્ત ઇમર્જન્સી કૉલ"</string> <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"નેટવર્ક લૉક થયું"</string> <string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"સિમ કાર્ડ, PUK-લૉક કરેલ છે."</string> <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"વપરાશકર્તા માર્ગદર્શિકા જુઓ અથવા ગ્રાહક સંભાળનો સંપર્ક કરો."</string> @@ -1792,10 +1792,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"તમારા વ્યવસ્થાપક દ્વારા અપડેટ કરવામાં આવેલ છે"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"તમારા વ્યવસ્થાપક દ્વારા કાઢી નાખવામાં આવેલ છે"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ઓકે"</string> - <!-- no translation found for battery_saver_description_with_learn_more (4424488535318105801) --> - <skip /> - <!-- no translation found for battery_saver_description (6794188153647295212) --> - <skip /> + <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"બૅટરીની આવરદા વધારવા માટે, બૅટરી સેવર:\n\n• ઘેરી થીમ ચાલુ કરે છે\n• બૅકગ્રાઉન્ડ પ્રવૃત્તિ, અમુક વિઝ્યુઅલ ઇફેક્ટ અને “ઓકે Google” જેવી અન્ય સુવિધાઓ બંધ અથવા પ્રતિબંધિત કરે છે\n\n"<annotation id="url">"વધુ જાણો"</annotation></string> + <string name="battery_saver_description" msgid="6794188153647295212">"બૅટરીની આવરદા વધારવા માટે, બૅટરી સેવર:\n\n• ઘેરી થીમ ચાલુ કરે છે\n• બૅકગ્રાઉન્ડ પ્રવૃત્તિ, અમુક વિઝ્યુઅલ ઇફેક્ટ અને “ઓકે Google” જેવી અન્ય સુવિધાઓ બંધ અથવા પ્રતિબંધિત કરે છે"</string> <string name="data_saver_description" msgid="4995164271550590517">"ડેટા વપરાશને ઘટાડવામાં સહાય માટે, ડેટા સેવર કેટલીક ઍપને બૅકગ્રાઉન્ડમાં ડેટા મોકલવા અથવા પ્રાપ્ત કરવાથી અટકાવે છે. તમે હાલમાં ઉપયોગ કરી રહ્યાં છો તે ઍપ ડેટાને ઍક્સેસ કરી શકે છે, પરંતુ તે આ ક્યારેક જ કરી શકે છે. આનો અર્થ એ હોઈ શકે છે, ઉદાહરણ તરીકે, છબીઓ ત્યાં સુધી પ્રદર્શિત થશે નહીં જ્યાં સુધી તમે તેને ટૅપ નહીં કરો."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ડેટા સેવર ચાલુ કરીએ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ચાલુ કરો"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 06d495f9cfec..97118f8bffae 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -2030,7 +2030,7 @@ <item quantity="one"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> फ़ाइलें</item> <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> फ़ाइलें</item> </plurals> - <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"शेयर करने के लिए किसी व्यक्ति का सुझाव नहीं दिया गया है"</string> + <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"शेयर करने के लिए, किसी व्यक्ति का सुझाव नहीं दिया गया है"</string> <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"ऐप्लिकेशन की सूची"</string> <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"इस ऐप्लिकेशन को रिकॉर्ड करने की अनुमति नहीं दी गई है. हालांकि, ऐप्लिकेशन इस यूएसबी डिवाइस से ऐसा कर सकता है."</string> <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"होम"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index e5b458615197..4d6d8155a981 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1203,7 +1203,7 @@ <string name="aerr_process_repeated" msgid="1153152413537954974">"האפליקציה <xliff:g id="PROCESS">%1$s</xliff:g> נעצרת שוב ושוב"</string> <string name="aerr_restart" msgid="2789618625210505419">"פתח שוב את האפליקציה"</string> <string name="aerr_report" msgid="3095644466849299308">"משוב"</string> - <string name="aerr_close" msgid="3398336821267021852">"סגור"</string> + <string name="aerr_close" msgid="3398336821267021852">"סגירה"</string> <string name="aerr_mute" msgid="2304972923480211376">"השתק עד הפעלה מחדש של המכשיר"</string> <string name="aerr_wait" msgid="3198677780474548217">"המתן"</string> <string name="aerr_close_app" msgid="8318883106083050970">"סגור את האפליקציה"</string> @@ -1925,7 +1925,7 @@ <string name="floating_toolbar_open_overflow_description" msgid="2260297653578167367">"אפשרויות נוספות"</string> <string name="floating_toolbar_close_overflow_description" msgid="3949818077708138098">"סגור את האפשרויות הנוספות"</string> <string name="maximize_button_text" msgid="4258922519914732645">"הגדל"</string> - <string name="close_button_text" msgid="10603510034455258">"סגור"</string> + <string name="close_button_text" msgid="10603510034455258">"סגירה"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="two">בחרת <xliff:g id="COUNT_1">%1$d</xliff:g></item> @@ -2098,7 +2098,7 @@ <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> קבצים</item> <item quantity="one"><xliff:g id="FILE_NAME_0">%s</xliff:g> + קובץ אחד (<xliff:g id="COUNT_1">%d</xliff:g>)</item> </plurals> - <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"אין אנשים מומלצים שניתן לשתף איתם"</string> + <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"אין אנשים שניתן לשתף איתם"</string> <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"רשימת האפליקציות"</string> <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"לאפליקציה זו לא ניתנה הרשאת הקלטה, אבל אפשר להקליט אודיו באמצעות התקן ה-USB הזה."</string> <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"בית"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index c43503664123..375cb98b0c4f 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -1792,10 +1792,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"നിങ്ങളുടെ അഡ്മിൻ അപ്ഡേറ്റ് ചെയ്യുന്നത്"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"നിങ്ങളുടെ അഡ്മിൻ ഇല്ലാതാക്കുന്നത്"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ശരി"</string> - <!-- no translation found for battery_saver_description_with_learn_more (4424488535318105801) --> - <skip /> - <!-- no translation found for battery_saver_description (6794188153647295212) --> - <skip /> + <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"ബാറ്ററി ലെെഫ് വർദ്ധിപ്പിക്കാൻ, \'ബാറ്ററി ലാഭിക്കൽ\' ഇനിപ്പറയുന്നവ ചെയ്യുന്നു:\n\n•ഡാർക്ക് തീം ഓണാക്കുന്നു\n•പശ്ചാത്തല ആക്റ്റിവിറ്റി, ചില വിഷ്വൽ ഇഫക്റ്റുകൾ, “Ok Google” പോലുള്ള മറ്റ് ഫീച്ചറുകൾ എന്നിവ ഓഫാക്കുകയോ നിയന്ത്രിക്കുകയോ ചെയ്യന്നു\n\n"<annotation id="url">"കൂടുതലറിയുക"</annotation></string> + <string name="battery_saver_description" msgid="6794188153647295212">"ബാറ്ററി ലെെഫ് വർദ്ധിപ്പിക്കാൻ, \'ബാറ്ററി ലാഭിക്കൽ\' ഇനിപ്പറയുന്നവ ചെയ്യുന്നു:\n\n• ഡാർക്ക് തീം ഓണാക്കുന്നു\n• പശ്ചാത്തല ആക്റ്റിവിറ്റി, ചില വിഷ്വൽ ഇഫക്റ്റുകൾ, “Ok Google” പോലുള്ള മറ്റ് ഫീച്ചറുകൾ എന്നിവ ഓഫാക്കുകയോ നിയന്ത്രിക്കുകയോ ചെയ്യുന്നു"</string> <string name="data_saver_description" msgid="4995164271550590517">"ഡാറ്റാ ഉപയോഗം കുറയ്ക്കാൻ സഹായിക്കുന്നതിനായി പശ്ചാത്തലത്തിൽ ഡാറ്റ അയയ്ക്കുകയോ സ്വീകരിക്കുകയോ ചെയ്യുന്നതിൽ നിന്ന് ചില ആപ്പുകളെ ഡാറ്റാ സേവർ തടയുന്നു. നിങ്ങൾ നിലവിൽ ഉപയോഗിക്കുന്ന ഒരു ആപ്പിന് ഡാറ്റ ആക്സസ് ചെയ്യാനാകും, എന്നാൽ വല്ലപ്പോഴും മാത്രമെ സംഭവിക്കുന്നുള്ളു. ഇതിനർത്ഥം, ഉദാഹരണമായി നിങ്ങൾ ടാപ്പ് ചെയ്യുന്നത് വരെ ചിത്രങ്ങൾ പ്രദർശിപ്പിക്കുകയില്ല എന്നാണ്."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ഡാറ്റ സേവർ ഓണാക്കണോ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ഓണാക്കുക"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 20eac82eb23d..c9ac6ec47001 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -1792,10 +1792,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"तपाईंका प्रशासकले अद्यावधिक गर्नुभएको"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"तपाईंका प्रशासकले मेट्नुभएको"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ठिक छ"</string> - <!-- no translation found for battery_saver_description_with_learn_more (4424488535318105801) --> - <skip /> - <!-- no translation found for battery_saver_description (6794188153647295212) --> - <skip /> + <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"ब्याट्री सेभरले यन्त्रको ब्याट्री बढी समय टिकाउन:\n\n•अँध्यारो थिम सक्रिय गर्छ\n•पृष्ठभूमिका गतिविधि, केही दृश्यात्मक प्रभाव तथा “Hey Google” जस्ता अन्य सुविधाहरू निष्क्रिय वा सीमित पार्छ\n\n"<annotation id="url">"थप जान्नुहोस्"</annotation></string> + <string name="battery_saver_description" msgid="6794188153647295212">"ब्याट्री सेभरले यन्त्रको ब्याट्री बढी समय टिकाउन:\n\n• अँध्यारो थिम अन गर्छ\n• पृष्ठभूमिका क्रियाकलाप, केही दृश्यात्मक प्रभाव तथा “Hey Google” जस्ता अन्य सुविधाहरू अफ गर्छ वा सीमित पार्छ"</string> <string name="data_saver_description" msgid="4995164271550590517">"डेटाको प्रयोगलाई कम गर्न डेटा सर्भरले केही एपलाई पृष्ठभूमिमा डेटा पठाउन वा प्राप्त गर्न दिँदैन। तपाईंले हाल प्रयोग गरिरहनुभएको अनु्प्रयोगले डेटा चलाउन सक्छ, तर पहिला भन्दा कम अन्तरालमा मात्र। उदाहरणका लागि, तपाईले छविहरूमा ट्याप नगरेसम्म ती छविहरू देखिँदैनन्।"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"डेटा सेभर सक्रिय गर्ने हो?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"सक्रिय गर्नुहोस्"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index b0a4d47d562a..62505a31a169 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -1792,10 +1792,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"ଆପଣଙ୍କ ଆଡମିନ୍ ଅପଡେଟ୍ କରିଛନ୍ତି"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"ଆପଣଙ୍କ ଆଡମିନ୍ ଡିଲିଟ୍ କରିଛନ୍ତି"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ଠିକ୍ ଅଛି"</string> - <!-- no translation found for battery_saver_description_with_learn_more (4424488535318105801) --> - <skip /> - <!-- no translation found for battery_saver_description (6794188153647295212) --> - <skip /> + <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"ବ୍ୟାଟେରୀ ଲାଇଫ୍ ବଢ଼ାଇବାକୁ ବ୍ୟାଟେରୀ ସେଭର୍:\n\n•ଗାଢ଼ା ଥିମ୍ ଚାଲୁ କରେ\n•ପୃଷ୍ଠପଟ କାର୍ଯ୍ୟକଳାପ, କିଛି ଭିଜୁଆଲ୍ ପ୍ରଭାବ ଏବଂ “Hey Google” ପରି ଅନ୍ୟ ଫିଚରଗୁଡ଼ିକୁ ବନ୍ଦ କିମ୍ବା ପ୍ରତିବନ୍ଧିତ କରିଥାଏ\n\n"<annotation id="url">"ଅଧିକ ଜାଣନ୍ତୁ"</annotation></string> + <string name="battery_saver_description" msgid="6794188153647295212">"ବ୍ୟାଟେରୀ ଲାଇଫ୍ ବଢ଼ାଇବାକୁ ବ୍ୟାଟେରୀ ସେଭର୍:\n\n• ଗାଢ଼ା ଥିମ୍ ଚାଲୁ କରେ\n• ପୃଷ୍ଠପଟ କାର୍ଯ୍ୟକଳାପ, କିଛି ଭିଜୁଆଲ୍ ପ୍ରଭାବ ଏବଂ “Hey Google” ପରି ଅନ୍ୟ ଫିଚରଗୁଡ଼ିକୁ ବନ୍ଦ କିମ୍ବା ପ୍ରତିବନ୍ଧିତ କରିଥାଏ"</string> <string name="data_saver_description" msgid="4995164271550590517">"ଡାଟା ବ୍ୟବହାର କମ୍ କରିବାରେ ସାହାଯ୍ୟ କରିବାକୁ, ଡାଟା ସେଭର୍ ବ୍ୟାକ୍ଗ୍ରାଉଣ୍ଡରେ ଡାଟା ପଠାଇବା କିମ୍ବା ପ୍ରାପ୍ତ କରିବାକୁ କିଛି ଆପ୍କୁ ବାରଣ କରେ। ଆପଣ ବର୍ତ୍ତମାନ ବ୍ୟବହାର କରୁଥିବା ଆପ୍, ଡାଟା ଆକ୍ସେସ୍ କରିପାରେ, କିନ୍ତୁ ଏହା କମ୍ ଥର କରିପାରେ। ଏହାର ଅର୍ଥ ହୋଇପାରେ ଯେମିତି ଆପଣ ଇମେଜଗୁଡ଼ିକୁ ଟାପ୍ ନକରିବା ପର୍ଯ୍ୟନ୍ତ ସେଗୁଡ଼ିକ ଡିସପ୍ଲେ ହୁଏ ନାହିଁ।"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ଡାଟା ସେଭର୍ ଚାଲୁ କରିବେ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ଚାଲୁ କରନ୍ତୁ"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index c043a8d37ecc..6890b800ac1e 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -1179,7 +1179,7 @@ <string name="noApplications" msgid="1186909265235544019">"Ниједна апликација не може да обавља ову радњу."</string> <string name="aerr_application" msgid="4090916809370389109">"Апликација <xliff:g id="APPLICATION">%1$s</xliff:g> је заустављена"</string> <string name="aerr_process" msgid="4268018696970966407">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> је заустављен"</string> - <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> се стално зауставља(ју)"</string> + <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> се стално зауставља"</string> <string name="aerr_process_repeated" msgid="1153152413537954974">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> се стално зауставља"</string> <string name="aerr_restart" msgid="2789618625210505419">"Поново отвори апликацију"</string> <string name="aerr_report" msgid="3095644466849299308">"Пошаљите повратне информације"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 565fc5357f3d..87b087203a6a 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -2030,7 +2030,7 @@ <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> filer</item> <item quantity="one"><xliff:g id="FILE_NAME_0">%s</xliff:g> + <xliff:g id="COUNT_1">%d</xliff:g> fil</item> </plurals> - <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Det finns inga rekommendationer för delning"</string> + <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Inga rekommenderade personer att dela med"</string> <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Applista"</string> <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Appen har inte fått inspelningsbehörighet men kan spela in ljud via denna USB-enhet."</string> <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Startsida"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index e1a6d131ae16..a2ec7872113b 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -1792,10 +1792,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"మీ నిర్వాహకులు నవీకరించారు"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"మీ నిర్వాహకులు తొలగించారు"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"సరే"</string> - <!-- no translation found for battery_saver_description_with_learn_more (4424488535318105801) --> - <skip /> - <!-- no translation found for battery_saver_description (6794188153647295212) --> - <skip /> + <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"బ్యాటరీ జీవితకాలాన్ని పెంచడానికి, బ్యాటరీ సేవర్ వీటిని చేస్తుంది:\n\n• ముదురు రంగు రూపాన్ని ఆన్ చేస్తుంది\n•బ్యాక్గ్రౌండ్ యాక్టివిటీని, కొన్ని విజువల్ ఎఫెక్ట్లను, అలాగే “Ok Google” వంటి ఇతర ఫీచర్లను ఆఫ్ చేస్తుంది లేదా పరిమితం చేస్తుంది\n\n"<annotation id="url">"మరింత తెలుసుకోండి"</annotation></string> + <string name="battery_saver_description" msgid="6794188153647295212">"బ్యాటరీ జీవితకాలాన్ని పెంచడానికి, బ్యాటరీ సేవర్ వీటిని చేస్తుంది:\n\n•ముదురు రంగు రూపాన్ని ఆన్ చేస్తుంది\n•బ్యాక్గ్రౌండ్ యాక్టివిటీని, కొన్ని విజువల్ ఎఫెక్ట్లను, అలాగే “Ok Google” వంటి ఇతర ఫీచర్లను ఆఫ్ చేస్తుంది లేదా పరిమితం చేస్తుంది"</string> <string name="data_saver_description" msgid="4995164271550590517">"డేటా వినియోగాన్ని తగ్గించడంలో డేటా సేవర్ సహాయకరంగా ఉంటుంది. బ్యాక్గ్రౌండ్లో కొన్ని యాప్లు డేటాను పంపకుండా లేదా స్వీకరించకుండా నిరోధిస్తుంది. మీరు ప్రస్తుతం ఉపయోగిస్తోన్న యాప్, డేటాను యాక్సెస్ చేయగలదు. కానీ తక్కువ సార్లు మాత్రమే అలా చేయవచ్చు. ఉదాహరణకు, మీరు నొక్కే వరకు ఫోటోలు ప్రదర్శించబడవు."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"డేటా సేవర్ను ఆన్ చేయాలా?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ఆన్ చేయి"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 0d76d017b08d..15a1fe7d45f0 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -222,7 +222,7 @@ <string name="reboot_to_update_prepare" msgid="6978842143587422365">"اپ ڈیٹ کرنے کی تیاری ہو رہی ہے…"</string> <string name="reboot_to_update_package" msgid="4644104795527534811">"اپ ڈیٹ پیکج پر کاروائی کی جارہی ہے…"</string> <string name="reboot_to_update_reboot" msgid="4474726009984452312">"دوبارہ شروع ہو رہا ہے…"</string> - <string name="reboot_to_reset_title" msgid="2226229680017882787">"فیکٹری ڈیٹا کی دوبارہ ترتیب"</string> + <string name="reboot_to_reset_title" msgid="2226229680017882787">"فیکٹری ڈیٹا ری سیٹ"</string> <string name="reboot_to_reset_message" msgid="3347690497972074356">"دوبارہ شروع ہو رہا ہے…"</string> <string name="shutdown_progress" msgid="5017145516412657345">"بند ہو رہا ہے…"</string> <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"آپ کا ٹیبلیٹ بند ہو جائے گا۔"</string> @@ -686,9 +686,9 @@ <string name="policylab_forceLock" msgid="7360335502968476434">"اسکرین مقفل کریں"</string> <string name="policydesc_forceLock" msgid="1008844760853899693">"اسکرین کب اور کس طرح مقفل ہوتی ہے اس کو کنٹرول کریں۔"</string> <string name="policylab_wipeData" msgid="1359485247727537311">"سبھی ڈیٹا صاف کریں"</string> - <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"فیکٹری ڈیٹا کی دوبارہ ترتیب انجام دے کر وارننگ کے بغیر ٹیبلٹ کا ڈیٹا مٹائیں۔"</string> + <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"فیکٹری ڈیٹا ری سیٹ انجام دے کر وارننگ کے بغیر ٹیبلٹ کا ڈیٹا مٹائیں۔"</string> <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"فیکٹری ڈیٹا ری سیٹ کو انجام دے کر انتباہ کیے بغیر اپنے Android TV آلہ کا ڈیٹا مٹائیں۔"</string> - <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"فیکٹری ڈیٹا کی دوبارہ ترتیب انجام دے کر وارننگ کے بغیر فون کا ڈیٹا مٹائیں۔"</string> + <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"فیکٹری ڈیٹا ری سیٹ انجام دے کر وارننگ کے بغیر فون کا ڈیٹا مٹائیں۔"</string> <string name="policylab_wipeData_secondaryUser" msgid="413813645323433166">"صارف کا ڈیٹا ہٹائیں"</string> <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"وارننگ کے بغیر اس ٹیبلٹ پر موجود اس صارف کا ڈیٹا ہٹائیں۔"</string> <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"انتباہ کے بغیر اس Android TV آلہ پر اس صارف کا ڈیٹا ہٹائیں۔"</string> diff --git a/core/tests/coretests/src/android/view/inputmethod/EditorInfoTest.java b/core/tests/coretests/src/android/view/inputmethod/EditorInfoTest.java index 02ffc00dcba5..93de03adfa84 100644 --- a/core/tests/coretests/src/android/view/inputmethod/EditorInfoTest.java +++ b/core/tests/coretests/src/android/view/inputmethod/EditorInfoTest.java @@ -264,6 +264,25 @@ public class EditorInfoTest { InputConnection.GET_TEXT_WITH_STYLES))); } + @Test + public void surroundingTextRetrieval_writeToParcel_noException() { + StringBuilder sb = new StringBuilder("abcdefg"); + Parcel parcel = Parcel.obtain(); + EditorInfo editorInfo = new EditorInfo(); + editorInfo.initialSelStart = 2; + editorInfo.initialSelEnd = 5; + editorInfo.inputType = EditorInfo.TYPE_CLASS_TEXT; + + editorInfo.setInitialSurroundingText(sb); + sb.setLength(0); + editorInfo.writeToParcel(parcel, 0); + + try { + editorInfo.getInitialTextBeforeCursor(60, 1); + fail("Test shouldn't have exception"); + } catch (AssertionError e) { } + } + private static void assertExpectedTextLength(EditorInfo editorInfo, @Nullable Integer expectBeforeCursorLength, @Nullable Integer expectSelectionLength, @Nullable Integer expectAfterCursorLength) { diff --git a/data/etc/preinstalled-packages-platform-overlays.xml b/data/etc/preinstalled-packages-platform-overlays.xml index 84c1897a2b62..83323beb8dd4 100644 --- a/data/etc/preinstalled-packages-platform-overlays.xml +++ b/data/etc/preinstalled-packages-platform-overlays.xml @@ -19,250 +19,188 @@ <config> <install-in-user-type package="com.android.internal.display.cutout.emulation.corner"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.internal.display.cutout.emulation.double"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.internal.display.cutout.emulation.hole"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.internal.display.cutout.emulation.tall"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.internal.display.cutout.emulation.waterfall"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> - </install-in-user-type> - <install-in-user-type package="com.android.internal.systemui.navbar.twobutton"> - <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> - </install-in-user-type> - <install-in-user-type package="com.android.internal.systemui.navbar.threebutton"> - <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.internal.systemui.navbar.gestural"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.internal.systemui.navbar.gestural_extra_wide_back"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.internal.systemui.navbar.gestural_narrow_back"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.internal.systemui.navbar.gestural_wide_back"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> + </install-in-user-type> + <install-in-user-type package="com.android.internal.systemui.navbar.threebutton"> + <install-in user-type="FULL" /> + </install-in-user-type> + <install-in-user-type package="com.android.internal.systemui.navbar.twobutton"> + <install-in user-type="FULL" /> </install-in-user-type> <install-in-user-type package="com.android.internal.systemui.onehanded.gestural"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.color.amethyst"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.color.aquamarine"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.color.black"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.color.carbon"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.color.cinnamon"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.color.green"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.color.ocean"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.color.orchid"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.color.palette"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.color.purple"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.color.sand"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.color.space"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.color.tangerine"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.font.notoserifsource"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.circular.android"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.circular.launcher"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.circular.settings"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.circular.systemui"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.circular.themepicker"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.filled.android"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.filled.launcher"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.filled.settings"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.filled.systemui"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.filled.themepicker"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.kai.android"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.kai.launcher"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.kai.settings"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.kai.systemui"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.kai.themepicker"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.rounded.android"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.rounded.launcher"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.rounded.settings"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.rounded.systemui"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.rounded.themepicker"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.sam.android"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.sam.launcher"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.sam.settings"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.sam.systemui"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.sam.themepicker"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.victor.android"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.victor.launcher"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.victor.settings"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.victor.systemui"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon_pack.victor.themepicker"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon.pebble"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon.roundedrect"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon.squircle"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon.taperedrect"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon.teardrop"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> <install-in-user-type package="com.android.theme.icon.vessel"> <install-in user-type="FULL" /> - <install-in user-type="PROFILE" /> </install-in-user-type> </config> diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 06791421d60f..6798c0a3f87e 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -160,6 +160,7 @@ applications that come with the platform <permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/> <permission name="android.permission.CONTROL_INCALL_EXPERIENCE"/> <permission name="android.permission.DUMP"/> + <permission name="android.permission.HANDLE_CAR_MODE_CHANGES"/> <permission name="android.permission.INTERACT_ACROSS_USERS"/> <permission name="android.permission.LOCAL_MAC_ADDRESS"/> <permission name="android.permission.MANAGE_USERS"/> @@ -428,6 +429,10 @@ applications that come with the platform <permission name="android.permission.CAPTURE_AUDIO_OUTPUT" /> <!-- Permissions required for CTS test - AdbManagerTest --> <permission name="android.permission.MANAGE_DEBUGGING" /> + <!-- Permissions required for ATS tests - AtsCarHostTestCases, AtsCarDeviceApp --> + <permission name="android.car.permission.CAR_DRIVING_STATE" /> + <!-- Permissions required for ATS tests - AtsDeviceInfo, AtsAudioDeviceTestCases --> + <permission name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME" /> </privapp-permissions> <privapp-permissions package="com.android.statementservice"> diff --git a/data/keyboards/Vendor_046d_Product_c216.kl b/data/keyboards/Vendor_046d_Product_c216.kl index 6743323d7db8..8bc142f0cab0 100644 --- a/data/keyboards/Vendor_046d_Product_c216.kl +++ b/data/keyboards/Vendor_046d_Product_c216.kl @@ -16,15 +16,15 @@ # Logitech Dual Action Controller # -key 0x120 BUTTON_A -key 0x123 BUTTON_B -key 0x121 BUTTON_X -key 0x122 BUTTON_Y +key 0x121 BUTTON_A +key 0x122 BUTTON_B +key 0x120 BUTTON_X +key 0x123 BUTTON_Y key 0x124 BUTTON_L1 key 0x125 BUTTON_R1 key 0x126 BUTTON_L2 key 0x127 BUTTON_R2 -key 0x128 BUTTON_SELECT +key 0x128 BACK key 0x129 BUTTON_START key 0x12a BUTTON_THUMBL key 0x12b BUTTON_THUMBR diff --git a/data/keyboards/Vendor_056e_Product_2010.kl b/data/keyboards/Vendor_056e_Product_2010.kl new file mode 100644 index 000000000000..09e15eaa62b8 --- /dev/null +++ b/data/keyboards/Vendor_056e_Product_2010.kl @@ -0,0 +1,48 @@ +# Copyright (C) 2020 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Elecom JC-U4113S in DirectInput Mode (D mode). +# + +# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html + +key 306 BUTTON_A +key 307 BUTTON_B +key 304 BUTTON_X +key 305 BUTTON_Y + +key 308 BUTTON_L1 +key 309 BUTTON_R1 +key 310 BUTTON_L2 +key 311 BUTTON_R2 + +key 312 BUTTON_THUMBL +key 313 BUTTON_THUMBR + +key 314 BACK +key 315 BUTTON_START + +# Left and right stick. +axis 0x00 X +axis 0x01 Y +axis 0x05 Z +axis 0x02 RZ + +# Hat. +axis 0x10 HAT_X +axis 0x11 HAT_Y + +# "Guide" button (Xbox key). +key 316 BUTTON_MODE diff --git a/data/keyboards/Vendor_056e_Product_2013.kl b/data/keyboards/Vendor_056e_Product_2013.kl new file mode 100644 index 000000000000..c2a74a9fd442 --- /dev/null +++ b/data/keyboards/Vendor_056e_Product_2013.kl @@ -0,0 +1,44 @@ +# Copyright (C) 2020 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Elecom JC-U4113S in XInput Mode (X mode). +# + +key 304 BUTTON_A +key 305 BUTTON_B +key 307 BUTTON_X +key 308 BUTTON_Y +key 310 BUTTON_L1 +key 311 BUTTON_R1 +key 315 BUTTON_START +key 314 BACK +key 317 BUTTON_THUMBL +key 318 BUTTON_THUMBR + +# Left and right stick. +axis 0x00 X +axis 0x01 Y +axis 0x03 Z +axis 0x04 RZ + +axis 0x02 BRAKE +axis 0x05 GAS + +# Hat. +axis 0x10 HAT_X +axis 0x11 HAT_Y + +# "Guide" button (Xbox key). +key 316 BUTTON_MODE diff --git a/libs/WindowManager/Shell/res/layout/pip_menu_activity.xml b/libs/WindowManager/Shell/res/layout/pip_menu_activity.xml index 18064b547d4d..2e0a5e09e34f 100644 --- a/libs/WindowManager/Shell/res/layout/pip_menu_activity.xml +++ b/libs/WindowManager/Shell/res/layout/pip_menu_activity.xml @@ -62,25 +62,30 @@ </FrameLayout> </FrameLayout> - <ImageButton - android:id="@+id/settings" - android:layout_width="@dimen/pip_action_size" - android:layout_height="@dimen/pip_action_size" - android:layout_gravity="top|start" - android:padding="@dimen/pip_action_padding" - android:contentDescription="@string/pip_phone_settings" - android:src="@drawable/pip_ic_settings" - android:background="?android:selectableItemBackgroundBorderless" /> - - <ImageButton - android:id="@+id/dismiss" - android:layout_width="@dimen/pip_action_size" - android:layout_height="@dimen/pip_action_size" + <LinearLayout + android:id="@+id/top_end_container" android:layout_gravity="top|end" - android:padding="@dimen/pip_action_padding" - android:contentDescription="@string/pip_phone_close" - android:src="@drawable/pip_ic_close_white" - android:background="?android:selectableItemBackgroundBorderless" /> + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <ImageButton + android:id="@+id/settings" + android:layout_width="@dimen/pip_action_size" + android:layout_height="@dimen/pip_action_size" + android:padding="@dimen/pip_action_padding" + android:contentDescription="@string/pip_phone_settings" + android:src="@drawable/pip_ic_settings" + android:background="?android:selectableItemBackgroundBorderless" /> + + <ImageButton + android:id="@+id/dismiss" + android:layout_width="@dimen/pip_action_size" + android:layout_height="@dimen/pip_action_size" + android:padding="@dimen/pip_action_padding" + android:contentDescription="@string/pip_phone_close" + android:src="@drawable/pip_ic_close_white" + android:background="?android:selectableItemBackgroundBorderless" /> + </LinearLayout> <!--TODO (b/156917828): Add content description for a11y purposes?--> <ImageButton @@ -89,6 +94,7 @@ android:layout_height="@dimen/pip_resize_handle_size" android:layout_gravity="top|start" android:layout_margin="@dimen/pip_resize_handle_margin" + android:padding="@dimen/pip_resize_handle_padding" android:src="@drawable/pip_resize_handle" android:background="?android:selectableItemBackgroundBorderless" /> </FrameLayout> diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index 48c3cad596f1..1c1217681b9f 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -52,7 +52,8 @@ <!-- The touchable/draggable edge size for PIP resize. --> <dimen name="pip_resize_edge_size">48dp</dimen> - <!-- PIP Resize handle size and margin. --> + <!-- PIP Resize handle size, margin and padding. --> <dimen name="pip_resize_handle_size">12dp</dimen> <dimen name="pip_resize_handle_margin">4dp</dimen> + <dimen name="pip_resize_handle_padding">0dp</dimen> </resources> diff --git a/media/java/android/media/MediaMetrics.java b/media/java/android/media/MediaMetrics.java index 2cfaf4f3dba5..3a5216e1c4e7 100644 --- a/media/java/android/media/MediaMetrics.java +++ b/media/java/android/media/MediaMetrics.java @@ -52,6 +52,7 @@ public class MediaMetrics { public static final String AUDIO_SERVICE = AUDIO + SEPARATOR + "service"; public static final String AUDIO_VOLUME = AUDIO + SEPARATOR + "volume"; public static final String AUDIO_VOLUME_EVENT = AUDIO_VOLUME + SEPARATOR + "event"; + public static final String AUDIO_MODE = AUDIO + SEPARATOR + "mode"; } /** @@ -139,6 +140,10 @@ public class MediaMetrics { public static final Key<String> REQUEST = createKey("request", String.class); + // For audio mode + public static final Key<String> REQUESTED_MODE = + createKey("requestedMode", String.class); // audio_mode + // For Bluetooth public static final Key<String> SCO_AUDIO_MODE = createKey("scoAudioMode", String.class); diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java index 42635216e98f..f4fd1fca2ff9 100644 --- a/media/java/android/media/audiofx/AudioEffect.java +++ b/media/java/android/media/audiofx/AudioEffect.java @@ -53,6 +53,7 @@ import java.util.UUID; * <li> {@link android.media.audiofx.PresetReverb}</li> * <li> {@link android.media.audiofx.EnvironmentalReverb}</li> * <li> {@link android.media.audiofx.DynamicsProcessing}</li> + * <li> {@link android.media.audiofx.HapticGenerator}</li> * </ul> * <p>To apply the audio effect to a specific AudioTrack or MediaPlayer instance, * the application must specify the audio session ID of that instance when creating the AudioEffect. @@ -146,6 +147,14 @@ public class AudioEffect { .fromString("7261676f-6d75-7369-6364-28e2fd3ac39e"); /** + * UUID for Haptic Generator. + */ + // This is taken from system/media/audio/include/system/audio_effects/effect_hapticgenerator.h + @NonNull + public static final UUID EFFECT_TYPE_HAPTIC_GENERATOR = UUID + .fromString("1411e6d6-aecd-4021-a1cf-a6aceb0d71e5"); + + /** * Null effect UUID. See {@link AudioEffect(UUID, UUID, int, int)} for use. * @hide */ @@ -225,7 +234,8 @@ public class AudioEffect { * {@link AudioEffect#EFFECT_TYPE_BASS_BOOST}, {@link AudioEffect#EFFECT_TYPE_ENV_REVERB}, * {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, {@link AudioEffect#EFFECT_TYPE_NS}, * {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB}, {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER}, - * {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}. + * {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}, + * {@link AudioEffect#EFFECT_TYPE_HAPTIC_GENERATOR}. * </li> * <li>uuid: UUID for this particular implementation</li> * <li>connectMode: {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}</li> @@ -246,8 +256,9 @@ public class AudioEffect { * {@link AudioEffect#EFFECT_TYPE_AGC}, {@link AudioEffect#EFFECT_TYPE_BASS_BOOST}, * {@link AudioEffect#EFFECT_TYPE_ENV_REVERB}, {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, * {@link AudioEffect#EFFECT_TYPE_NS}, {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB} - * {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER} - * or {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}.<br> + * {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER}, + * {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}, + * or {@link AudioEffect#EFFECT_TYPE_HAPTIC_GENERATOR}.<br> * For reverberation, bass boost, EQ and virtualizer, the UUID * corresponds to the OpenSL ES Interface ID. */ @@ -284,7 +295,8 @@ public class AudioEffect { * {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, {@link AudioEffect#EFFECT_TYPE_NS}, * {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB}, * {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER}, - * {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}. + * {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}, + * {@link AudioEffect#EFFECT_TYPE_HAPTIC_GENERATOR}. * @param uuid UUID for this particular implementation * @param connectMode {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY} * @param name human readable effect name diff --git a/media/java/android/media/audiofx/HapticGenerator.java b/media/java/android/media/audiofx/HapticGenerator.java new file mode 100644 index 000000000000..f8529eb05c03 --- /dev/null +++ b/media/java/android/media/audiofx/HapticGenerator.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.audiofx; + +import android.annotation.NonNull; +import android.media.AudioManager; +import android.util.Log; + +import java.util.UUID; + +/** + * Haptic Generator(HG). + * <p>HG is an audio post-processor which generates haptic data based on the audio channels. The + * generated haptic data is sent along with audio data down to the audio HAL, which will require the + * device to support audio-coupled-haptic playback. In that case, the effect will only be created on + * device supporting audio-coupled-haptic playback. Call {@link HapticGenerator#isAvailable()} to + * check if the device supports this effect. + * <p>An application can create a HapticGenerator object to initiate and control this audio effect + * in the audio framework. An application can set which audio channel to be used to generate + * haptic data. + * <p>To attach the HapticGenerator to a particular AudioTrack or MediaPlayer, specify the audio + * session ID of this AudioTrack or MediaPlayer when constructing the HapticGenerator. + * <p>See {@link android.media.MediaPlayer#getAudioSessionId()} for details on audio sessions. + * <p>See {@link android.media.audiofx.AudioEffect} class for more details on controlling audio + * effects. + */ +public class HapticGenerator extends AudioEffect implements AutoCloseable { + + private static final String TAG = "HapticGenerator"; + + // For every HapticGenerator, it contains a volume control effect so that the volume control + // will always be handled in the effect chain. In that case, the HapticGenerator can generate + // haptic data based on the raw audio data. + private AudioEffect mVolumeControlEffect; + + public static boolean isAvailable() { + return AudioManager.isHapticPlaybackSupported() + && AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_HAPTIC_GENERATOR); + } + + /** + * Creates a HapticGenerator and attaches it to the given audio session. + * Use {@link android.media.AudioTrack#getAudioSessionId()} or + * {@link android.media.MediaPlayer#getAudioSessionId()} to + * apply this effect on specific AudioTrack or MediaPlayer instance. + * + * @param audioSession system wide unique audio session identifier. The HapticGenerator will be + * applied to the players with the same audio session. + * @return HapticGenerator created or null if the device does not support HapticGenerator or + * the audio session is invalid. + * @throws java.lang.IllegalArgumentException when HapticGenerator is not supported + * @throws java.lang.UnsupportedOperationException when the effect library is not loaded. + * @throws java.lang.RuntimeException for all other error + */ + public static @NonNull HapticGenerator create(int audioSession) { + return new HapticGenerator(audioSession); + } + + /** + * Class constructor. + * + * @param audioSession system wide unique audio session identifier. The HapticGenerator will be + * attached to the MediaPlayer or AudioTrack in the same audio session. + * @throws java.lang.IllegalArgumentException + * @throws java.lang.UnsupportedOperationException + * @throws java.lang.RuntimeException + */ + private HapticGenerator(int audioSession) { + super(EFFECT_TYPE_HAPTIC_GENERATOR, EFFECT_TYPE_NULL, 0, audioSession); + mVolumeControlEffect = new AudioEffect( + AudioEffect.EFFECT_TYPE_NULL, + UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"), + 0, + audioSession); + } + + /** + * Enable or disable the effect. + * + * @param enabled the requested enable state + * @return {@link #SUCCESS} in case of success, {@link #ERROR_INVALID_OPERATION} + * or {@link #ERROR_DEAD_OBJECT} in case of failure. + */ + @Override + public int setEnabled(boolean enabled) { + int ret = super.setEnabled(enabled); + if (ret == SUCCESS) { + if (mVolumeControlEffect == null + || mVolumeControlEffect.setEnabled(enabled) != SUCCESS) { + Log.w(TAG, "Failed to enable volume control effect for HapticGenerator"); + } + } + return ret; + } + + /** + * Releases the native AudioEffect resources. + */ + @Override + public void release() { + if (mVolumeControlEffect != null) { + mVolumeControlEffect.release(); + } + super.release(); + } + + /** + * Release the resources that are held by the effect. + */ + @Override + public void close() { + release(); + } +} diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index df022d562768..6e26f2c2da9e 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -3497,6 +3497,10 @@ static jlong android_media_tv_Tuner_read_dvr(JNIEnv *env, jobject dvr, jlong siz } else { ALOGE("dvrMq.beginWrite failed"); } + + if (ret > 0) { + dvrSp->mDvrMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY)); + } return (jlong) ret; } @@ -3524,7 +3528,7 @@ static jlong android_media_tv_Tuner_read_dvr_from_array( if (dvrSp->mDvrMQ->write(reinterpret_cast<unsigned char*>(src) + offset, size)) { env->ReleaseByteArrayElements(buffer, src, 0); - dvrSp->mDvrMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED)); + dvrSp->mDvrMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY)); } else { ALOGD("Failed to write FMQ"); env->ReleaseByteArrayElements(buffer, src, 0); @@ -3585,6 +3589,9 @@ static jlong android_media_tv_Tuner_write_dvr(JNIEnv *env, jobject dvr, jlong si } else { ALOGE("dvrMq.beginRead failed"); } + if (ret > 0) { + dvrSp->mDvrMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED)); + } return (jlong) ret; } diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt index c14f23f6ace0..0dc76313cf5c 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -27666,6 +27666,7 @@ package android.media.audiofx { field public static final java.util.UUID EFFECT_TYPE_DYNAMICS_PROCESSING; field public static final java.util.UUID EFFECT_TYPE_ENV_REVERB; field public static final java.util.UUID EFFECT_TYPE_EQUALIZER; + field @NonNull public static final java.util.UUID EFFECT_TYPE_HAPTIC_GENERATOR; field public static final java.util.UUID EFFECT_TYPE_LOUDNESS_ENHANCER; field public static final java.util.UUID EFFECT_TYPE_NS; field public static final java.util.UUID EFFECT_TYPE_PRESET_REVERB; @@ -28018,6 +28019,13 @@ package android.media.audiofx { field public short numBands; } + public class HapticGenerator extends android.media.audiofx.AudioEffect implements java.lang.AutoCloseable { + method public void close(); + method @NonNull public static android.media.audiofx.HapticGenerator create(int); + method public static boolean isAvailable(); + method public int setEnabled(boolean); + } + public class LoudnessEnhancer extends android.media.audiofx.AudioEffect { ctor public LoudnessEnhancer(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.RuntimeException, java.lang.UnsupportedOperationException; method public float getTargetGain() throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException; diff --git a/non-updatable-api/module-lib-current.txt b/non-updatable-api/module-lib-current.txt index c8406f199edd..a5ca196ef5b4 100644 --- a/non-updatable-api/module-lib-current.txt +++ b/non-updatable-api/module-lib-current.txt @@ -1,4 +1,12 @@ // Signature format: 2.0 +package android.app { + + public class AppOpsManager { + field public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage"; + } + +} + package android.content.rollback { public class RollbackManagerFrameworkInitializer { diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java index 37dfce4e16ce..35b2080dddf9 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java @@ -16,10 +16,12 @@ package com.android.systemui.car.navigationbar; +import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES; import static android.view.InsetsState.ITYPE_CLIMATE_BAR; import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; +import static android.view.InsetsState.ITYPE_TOP_GESTURES; import static android.view.InsetsState.containsType; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; @@ -368,13 +370,15 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, height, - WindowManager.LayoutParams.TYPE_STATUS_BAR, + WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, PixelFormat.TRANSLUCENT); lp.setTitle("TopCarNavigationBar"); + lp.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_TOP_GESTURES}; + lp.setFitInsetsTypes(0); lp.windowAnimations = 0; lp.gravity = Gravity.TOP; mWindowManager.addView(mTopNavigationBarWindow, lp); @@ -388,13 +392,14 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, height, - WindowManager.LayoutParams.TYPE_NAVIGATION_BAR, + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, PixelFormat.TRANSLUCENT); lp.setTitle("BottomCarNavigationBar"); + lp.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR, ITYPE_BOTTOM_GESTURES}; lp.windowAnimations = 0; lp.gravity = Gravity.BOTTOM; mWindowManager.addView(mBottomNavigationBarWindow, lp); diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java index 029d4c7fa2fb..0ced4021ce38 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java @@ -16,7 +16,10 @@ package com.android.systemui.car.navigationbar; +import static android.view.WindowInsets.Type.systemBars; + import android.content.Context; +import android.graphics.Insets; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -79,9 +82,28 @@ public class CarNavigationBarView extends LinearLayout { @Override public WindowInsets onApplyWindowInsets(WindowInsets windowInsets) { + applyMargins(windowInsets.getInsets(systemBars())); return windowInsets; } + private void applyMargins(Insets insets) { + final int count = getChildCount(); + for (int i = 0; i < count; i++) { + View child = getChildAt(i); + if (child.getLayoutParams() instanceof LayoutParams) { + LayoutParams lp = (LayoutParams) child.getLayoutParams(); + if (lp.rightMargin != insets.right || lp.leftMargin != insets.left + || lp.topMargin != insets.top || lp.bottomMargin != insets.bottom) { + lp.rightMargin = insets.right; + lp.leftMargin = insets.left; + lp.topMargin = insets.top; + lp.bottomMargin = insets.bottom; + child.requestLayout(); + } + } + } + } + // Used to forward touch events even if the touch was initiated from a child component @Override public boolean onInterceptTouchEvent(MotionEvent ev) { diff --git a/packages/PackageInstaller/Android.bp b/packages/PackageInstaller/Android.bp index 9420954748c4..75bd32ec0301 100644 --- a/packages/PackageInstaller/Android.bp +++ b/packages/PackageInstaller/Android.bp @@ -20,6 +20,7 @@ android_app { certificate: "platform", privileged: true, platform_apis: true, + rename_resources_package: false, static_libs: [ "xz-java", diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index 16029ee2b3b0..d042c0f89b1e 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -508,7 +508,7 @@ <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Да се пита винаги"</string> <string name="zen_mode_forever" msgid="3339224497605461291">"До изключване"</string> <string name="time_unit_just_now" msgid="3006134267292728099">"Току-що"</string> - <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Високоговорител на телефона"</string> + <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Високоговорител"</string> <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"При свързването възникна проблем. Изключете устройството и го включете отново"</string> <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Аудиоустройство с кабел"</string> <string name="help_label" msgid="3528360748637781274">"Помощ и отзиви"</string> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 3a45526290e0..fb7d00f866b1 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -555,5 +555,5 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"מושבת"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"מופעל"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"צריך להפעיל מחדש את המכשיר כדי להחיל את השינוי. יש להפעיל מחדש עכשיו או לבטל."</string> - <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"אוזניות עם חוט"</string> + <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"אוזניות חוטיות"</string> </resources> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index ac643c3a6e62..c95f8bf2fe39 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -553,5 +553,5 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"പ്രവർത്തനരഹിതമാക്കി"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"പ്രവർത്തനക്ഷമമാക്കി"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ഈ മാറ്റം ബാധകമാകുന്നതിന് നിങ്ങളുടെ ഉപകരണം റീബൂട്ട് ചെയ്യേണ്ടതുണ്ട്. ഇപ്പോൾ റീബൂട്ട് ചെയ്യുകയോ റദ്ദാക്കുകയോ ചെയ്യുക."</string> - <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"വയർ മുഖേന ബന്ധിപ്പിച്ച ഹെഡ്ഫോൺ"</string> + <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"വയേർഡ് ഹെഡ്ഫോൺ"</string> </resources> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index 41ccdeb29f3e..5c80627003cd 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -553,5 +553,5 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Imezimwa"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Imewashwa"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Ni lazima uwashe tena kifaa chako ili mabadiliko haya yatekelezwe. Washa tena sasa au ughairi."</string> - <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Vipokea sauti vyenye waya vinavyobanwa kichwani"</string> + <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Vipokea sauti vya waya"</string> </resources> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index 27576b107efd..ef3bdbc95809 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -866,9 +866,6 @@ class SettingsProtoDumpUtil { Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS, GlobalSettingsProto.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS); dumpSetting(s, p, - Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS, - GlobalSettingsProto.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS); - dumpSetting(s, p, Settings.Global.KEEP_PROFILE_IN_BACKGROUND, GlobalSettingsProto.KEEP_PROFILE_IN_BACKGROUND); diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index b90b9c1208ae..2f1191a6325a 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -311,7 +311,6 @@ public class SettingsBackupTest { Settings.Global.INTENT_FIREWALL_UPDATE_METADATA_URL, Settings.Global.JOB_SCHEDULER_CONSTANTS, Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS, - Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS, Settings.Global.KEEP_PROFILE_IN_BACKGROUND, Settings.Global.KERNEL_CPU_THREAD_READER, Settings.Global.LANG_ID_UPDATE_CONTENT_URL, diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index d50dc7cba52b..7f7afcbf11f5 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -317,6 +317,11 @@ <!-- Permissions required for CTS test - AdbManagerTest --> <uses-permission android:name="android.permission.MANAGE_DEBUGGING" /> + <!-- Permissions required for ATS tests - AtsCarHostTestCases, AtsCarDeviceApp --> + <uses-permission android:name="android.car.permission.CAR_DRIVING_STATE" /> + <!-- Permissions required for ATS tests - AtsDeviceInfo, AtsAudioDeviceTestCases --> + <uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME" /> + <application android:label="@string/app_label" android:theme="@android:style/Theme.DeviceDefault.DayNight" android:defaultToDeviceProtectedStorage="true" diff --git a/packages/Shell/res/values-bn/strings.xml b/packages/Shell/res/values-bn/strings.xml index 39f62fe6a00a..ede125bce935 100644 --- a/packages/Shell/res/values-bn/strings.xml +++ b/packages/Shell/res/values-bn/strings.xml @@ -35,7 +35,7 @@ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"জিপ ফাইলে ত্রুটি প্রতিবেদনের বিশদ বিবরণ যোগ করা যায়নি"</string> <string name="bugreport_unnamed" msgid="2800582406842092709">"নামবিহীন"</string> <string name="bugreport_info_action" msgid="2158204228510576227">"বিশদ বিবরণ"</string> - <string name="bugreport_screenshot_action" msgid="8677781721940614995">"স্ক্রিনশট"</string> + <string name="bugreport_screenshot_action" msgid="8677781721940614995">"স্ক্রিনশট নিন"</string> <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"স্ক্রিনশট সফলভাবে নেওয়া হয়েছে৷"</string> <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"স্ক্রিনশট নেওয়া যায়নি৷"</string> <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ত্রুটির প্রতিবেদন <xliff:g id="ID">#%d</xliff:g> এর বিশদ বিবরণ"</string> diff --git a/packages/SystemUI/res-keyguard/values-af/strings.xml b/packages/SystemUI/res-keyguard/values-af/strings.xml index 8a1f6de432f8..92dd9fd96111 100644 --- a/packages/SystemUI/res-keyguard/values-af/strings.xml +++ b/packages/SystemUI/res-keyguard/values-af/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Geen diens nie."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Wissel invoermetode"</string> <string name="airplane_mode" msgid="2528005343938497866">"Vliegtuigmodus"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN word vereis om vir opdatering voor te berei"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Patroon word vereis om vir opdatering voor te berei"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Wagwoord word vereis om vir opdatering voor te berei"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Patroon word vereis nadat toestel herbegin het"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN word vereis nadat toestel herbegin het"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Wagwoord word vereis nadat toestel herbegin het"</string> diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml index 0a4aee53b7be..f94c20f9ad01 100644 --- a/packages/SystemUI/res-keyguard/values-am/strings.xml +++ b/packages/SystemUI/res-keyguard/values-am/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"ከአገልግሎት መስጫ ክልል ውጪ።"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"የግቤት ስልት ቀይር"</string> <string name="airplane_mode" msgid="2528005343938497866">"የአውሮፕላን ሁነታ"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"ለዝማኔ ለማዘጋጀት ፒን ያስፈልጋል"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"ለዝማኔ ለማዘጋጀት ሥርዓተ ጥለት ያስፈልጋል"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"ለዝማኔ ለማዘጋጀት የይለፍ ቃል ያስፈልጋል"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"መሣሪያ ዳግም ከጀመረ በኋላ ሥርዓተ ጥለት ያስፈልጋል"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"መሣሪያ ዳግም ከተነሳ በኋላ ፒን ያስፈልጋል"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"መሣሪያ ዳግም ከጀመረ በኋላ የይለፍ ቃል ያስፈልጋል"</string> diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml index 491dc39aa08d..6d86a78360d8 100644 --- a/packages/SystemUI/res-keyguard/values-ar/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml @@ -113,9 +113,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"لا تتوفر خدمة."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"تبديل أسلوب الإدخال"</string> <string name="airplane_mode" msgid="2528005343938497866">"وضع الطائرة"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"يجب إدخال رقم التعريف الشخصي للتحضير للتحديث."</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"يجب رسم النقش للتحضير للتحديث."</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"يجب إدخال كلمة المرور للتحضير للتحديث."</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"يجب رسم النقش بعد إعادة تشغيل الجهاز"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"يجب إدخال رقم التعريف الشخصي بعد إعادة تشغيل الجهاز"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"يجب إدخال كلمة المرور بعد إعادة تشغيل الجهاز"</string> diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml index 4367efb8c679..3b51e480b7dd 100644 --- a/packages/SystemUI/res-keyguard/values-as/strings.xml +++ b/packages/SystemUI/res-keyguard/values-as/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"কোনো সেৱা নাই।"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ইনপুট পদ্ধতি সলনি কৰক"</string> <string name="airplane_mode" msgid="2528005343938497866">"এয়াৰপ্লেন ম\'ড"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"আপডে\'টৰ বাবে সাজু হ\'বলৈ পিনৰ আৱশ্যক"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"আপডে\'টৰ বাবে সাজু হ\'বলৈ আর্হিৰ আৱশ্যক"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"আপডে\'টৰ বাবে সাজু হ\'বলৈ পাছৱৰ্ডৰ আৱশ্যক"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ডিভাইচ ৰিষ্টাৰ্ট হোৱাৰ পিছত আৰ্হি দিয়াটো বাধ্যতামূলক"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ডিভাইচ ৰিষ্টাৰ্ট হোৱাৰ পিছত পিন দিয়াটো বাধ্যতামূলক"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ডিভাইচ ৰিষ্টাৰ্ট হোৱাৰ পিছত পাছৱৰ্ড দিয়াটো বাধ্যতামূলক"</string> diff --git a/packages/SystemUI/res-keyguard/values-az/strings.xml b/packages/SystemUI/res-keyguard/values-az/strings.xml index d89bf6a8c0ae..ea07c3db4354 100644 --- a/packages/SystemUI/res-keyguard/values-az/strings.xml +++ b/packages/SystemUI/res-keyguard/values-az/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Xidmət yoxdur."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Daxiletmə metoduna keçin"</string> <string name="airplane_mode" msgid="2528005343938497866">"Təyyarə rejimi"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Güncəlləməyə hazırlıq üçün PIN kod tələb olunur"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Güncəlləməyə hazırlıq üçün model tələb olunur"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Güncəlləməyə hazırlıq üçün parol tələb olunur"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Cihaz yenidən başladıqdan sonra model tələb olunur"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Cihaz yeniden başladıqdan sonra PIN tələb olunur"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Cihaz yeniden başladıqdan sonra parol tələb olunur"</string> diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml index 656e32301153..e206958d1e95 100644 --- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml @@ -104,9 +104,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Mreža nije dostupna."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Promeni metod unosa"</string> <string name="airplane_mode" msgid="2528005343938497866">"Režim rada u avionu"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN je obavezan radi pripreme za ažuriranje"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Šablon je obavezan radi pripreme za ažuriranje"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Lozinka je obavezna radi pripreme za ažuriranje"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Treba da unesete šablon kada se uređaj ponovo pokrene"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Treba da unesete PIN kada se uređaj ponovo pokrene"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Treba da unesete lozinku kada se uređaj ponovo pokrene"</string> diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml index 07b6f358dcfc..569e705fbcc2 100644 --- a/packages/SystemUI/res-keyguard/values-be/strings.xml +++ b/packages/SystemUI/res-keyguard/values-be/strings.xml @@ -107,9 +107,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Не абслугоўваецца."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Пераключэнне рэжыму ўводу"</string> <string name="airplane_mode" msgid="2528005343938497866">"Рэжым палёту"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Для падрыхтоўкі да абнаўлення неабходна ўвесці PIN-код"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Для падрыхтоўкі да абнаўлення неабходна ўвесці ўзор разблакіроўкі"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Для падрыхтоўкі да абнаўлення неабходна ўвесці пароль"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Пасля перазапуску прылады патрабуецца ўзор"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Пасля перазапуску прылады патрабуецца PIN-код"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Пасля перазапуску прылады патрабуецца пароль"</string> diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml index a8c64f5d9551..d015be320e20 100644 --- a/packages/SystemUI/res-keyguard/values-bg/strings.xml +++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Няма покритие."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Превключване на метода на въвеждане"</string> <string name="airplane_mode" msgid="2528005343938497866">"Самолетен режим"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"За подготовката за актуализация се изисква ПИН код"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"За подготовката за актуализация се изисква фигура"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"За подготовката за актуализация се изисква парола"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"След рестартиране на устройството се изисква фигура"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"След рестартиране на устройството се изисква ПИН код"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"След рестартиране на устройството се изисква парола"</string> diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml index 479e83ab3954..8eae6e6e2e18 100644 --- a/packages/SystemUI/res-keyguard/values-bn/strings.xml +++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"কোনো পরিষেবা নেই।"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ইনপুট পদ্ধতি পরিবর্তন করুন"</string> <string name="airplane_mode" msgid="2528005343938497866">"বিমান মোড"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"আপডেট প্রস্তুত করতে পিন দরকার"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"আপডেট প্রস্তুত করতে প্যাটার্ন দরকার"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"আপডেট প্রস্তুত করতে পাসওয়ার্ড দরকার"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ডিভাইসটি পুনরায় চালু হওয়ার পর প্যাটার্নের প্রয়োজন হবে"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ডিভাইসটি পুনরায় চালু হওয়ার পর পিন প্রয়োজন হবে"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ডিভাইসটি পুনরায় চালু হওয়ার পর পাসওয়ার্ডের প্রয়োজন হবে"</string> diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml index ada4c134fce7..286b08be1c5e 100644 --- a/packages/SystemUI/res-keyguard/values-bs/strings.xml +++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml @@ -104,9 +104,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Nema mreže."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Promjena načina unosa"</string> <string name="airplane_mode" msgid="2528005343938497866">"Način rada u avionu"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Za pripremu ažuriranja potreban je PIN"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Za pripremu ažuriranja potreban je uzorak"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Za pripremu ažuriranja potrebna je lozinka"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Potreban je uzorak nakon što se uređaj ponovo pokrene"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Potreban je PIN nakon što se uređaj ponovo pokrene"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Potrebna je lozinka nakon što se uređaj ponovo pokrene"</string> diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml index 6f5b6829c3e0..cb7fa37b281d 100644 --- a/packages/SystemUI/res-keyguard/values-ca/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Sense servei"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Canvia el mètode d\'introducció"</string> <string name="airplane_mode" msgid="2528005343938497866">"Mode d\'avió"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Cal introduir el PIN per preparar l\'actualització"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Cal introduir el patró per preparar l\'actualització"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Cal introduir la contrasenya per preparar l\'actualització"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Cal introduir el patró quan es reinicia el dispositiu"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Cal introduir el PIN quan es reinicia el dispositiu"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Cal introduir la contrasenya quan es reinicia el dispositiu"</string> diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml index a2f79adff1db..4f0c0ffa4962 100644 --- a/packages/SystemUI/res-keyguard/values-cs/strings.xml +++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml @@ -107,9 +107,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Žádný signál"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Přepnout metodu zadávání"</string> <string name="airplane_mode" msgid="2528005343938497866">"Režim Letadlo"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Příprava na aktualizaci vyžaduje PIN"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Příprava na aktualizaci vyžaduje gesto"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Příprava na aktualizaci vyžaduje heslo"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Po restartování zařízení je vyžadováno gesto"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Po restartování zařízení je vyžadován kód PIN"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Po restartování zařízení je vyžadováno heslo"</string> diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml index ef06269b5630..e486fc625699 100644 --- a/packages/SystemUI/res-keyguard/values-da/strings.xml +++ b/packages/SystemUI/res-keyguard/values-da/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ingen dækning."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Skift indtastningsmetode"</string> <string name="airplane_mode" msgid="2528005343938497866">"Flytilstand"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Du skal angive din pinkode for at forberede opdateringen"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Du skal angive dit mønster for at forberede opdateringen"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Du skal angive din adgangskode for at forberede opdateringen"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Du skal angive et mønster, når du har genstartet enheden"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Der skal angives en pinkode efter genstart af enheden"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Der skal angives en adgangskode efter genstart af enheden"</string> diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml index fdfce1ffb338..06d012f4e84d 100644 --- a/packages/SystemUI/res-keyguard/values-de/strings.xml +++ b/packages/SystemUI/res-keyguard/values-de/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Dienst nicht verfügbar"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Eingabemethode wechseln"</string> <string name="airplane_mode" msgid="2528005343938497866">"Flugmodus"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Zur Vorbereitung auf das Update ist eine PIN erforderlich"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Zur Vorbereitung auf das Update ist ein Muster erforderlich"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Zur Vorbereitung auf das Update ist ein Passwort erforderlich"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Nach dem Neustart des Geräts ist die Eingabe des Musters erforderlich"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Nach dem Neustart des Geräts ist die Eingabe der PIN erforderlich"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Nach dem Neustart des Geräts ist die Eingabe des Passworts erforderlich"</string> diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml index 8e4578f8445c..176428421476 100644 --- a/packages/SystemUI/res-keyguard/values-el/strings.xml +++ b/packages/SystemUI/res-keyguard/values-el/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Καμία υπηρεσία."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Εναλλαγή μεθόδου εισαγωγής"</string> <string name="airplane_mode" msgid="2528005343938497866">"Λειτουργία πτήσης"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Απαιτείται PIN για την προετοιμασία για ενημέρωση"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Απαιτείται μοτίβο για την προετοιμασία για ενημέρωση"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Απαιτείται κωδικός πρόσβασης για την προετοιμασία για ενημέρωση"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Απαιτείται μοτίβο μετά από την επανεκκίνηση της συσκευής"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Απαιτείται PIN μετά από την επανεκκίνηση της συσκευής"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Απαιτείται κωδικός πρόσβασης μετά από την επανεκκίνηση της συσκευής"</string> diff --git a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml index 21cfe48689ae..92a15949a8ab 100644 --- a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml +++ b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"No service"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Switch input method"</string> <string name="airplane_mode" msgid="2528005343938497866">"Aeroplane mode"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN required to prepare for update"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Pattern required to prepare for update"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Password required to prepare for update"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pattern required after device restarts"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN required after device restarts"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Password required after device restarts"</string> diff --git a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml index 921ba6b59af9..719f1a18a744 100644 --- a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml +++ b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"No service"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Switch input method"</string> <string name="airplane_mode" msgid="2528005343938497866">"Airplane mode"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN required to prepare for update"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Pattern required to prepare for update"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Password required to prepare for update"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pattern required after device restarts"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN required after device restarts"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Password required after device restarts"</string> diff --git a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml index 21cfe48689ae..92a15949a8ab 100644 --- a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml +++ b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"No service"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Switch input method"</string> <string name="airplane_mode" msgid="2528005343938497866">"Aeroplane mode"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN required to prepare for update"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Pattern required to prepare for update"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Password required to prepare for update"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pattern required after device restarts"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN required after device restarts"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Password required after device restarts"</string> diff --git a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml index 21cfe48689ae..92a15949a8ab 100644 --- a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml +++ b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"No service"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Switch input method"</string> <string name="airplane_mode" msgid="2528005343938497866">"Aeroplane mode"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN required to prepare for update"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Pattern required to prepare for update"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Password required to prepare for update"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pattern required after device restarts"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN required after device restarts"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Password required after device restarts"</string> diff --git a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml index fc59d0dfcdc5..975b1f644ef8 100644 --- a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml +++ b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"No service."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Switch input method"</string> <string name="airplane_mode" msgid="2528005343938497866">"Airplane mode"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN required to prepare for update"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Pattern required to prepare for update"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Password required to prepare for update"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pattern required after device restarts"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN required after device restarts"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Password required after device restarts"</string> diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml index ab0c8f351562..25ab6159998e 100644 --- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml +++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Sin servicio"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Cambiar método de entrada"</string> <string name="airplane_mode" msgid="2528005343938497866">"Modo de avión"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Se requiere el PIN para actualizar el sistema"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Se requiere el patrón para actualizar el sistema"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Se requiere la contraseña para actualizar el sistema"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Se requiere el patrón después de reiniciar el dispositivo"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Se requiere el PIN después de reiniciar el dispositivo"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Se requiere la contraseña después de reiniciar el dispositivo"</string> diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml index 38451c7cfba5..0754681215cc 100644 --- a/packages/SystemUI/res-keyguard/values-es/strings.xml +++ b/packages/SystemUI/res-keyguard/values-es/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Sin servicio"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Cambiar método de introducción"</string> <string name="airplane_mode" msgid="2528005343938497866">"Modo avión"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Debes introducir el PIN para prepararte para la actualización"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Debes dibujar el patrón para prepararte para la actualización"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Debes introducir la contraseña para prepararte para la actualización"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Debes introducir el patrón después de reiniciar el dispositivo"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Debes introducir el PIN después de reiniciar el dispositivo"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Debes introducir la contraseña después de reiniciar el dispositivo"</string> diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml index f8ad18bba2f7..331a95c73c5e 100644 --- a/packages/SystemUI/res-keyguard/values-et/strings.xml +++ b/packages/SystemUI/res-keyguard/values-et/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Teenus puudub."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Vaheta sisestusmeetodit"</string> <string name="airplane_mode" msgid="2528005343938497866">"Lennukirežiim"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Värskendamiseks ettevalmistuste tegemiseks tuleb sisestada PIN-kood"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Värskendamiseks ettevalmistuste tegemiseks tuleb sisestada muster"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Värskendamiseks ettevalmistuste tegemiseks tuleb sisestada parool"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pärast seadme taaskäivitamist tuleb sisestada muster"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Pärast seadme taaskäivitamist tuleb sisestada PIN-kood"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Pärast seadme taaskäivitamist tuleb sisestada parool"</string> diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml index 8510bee0711b..3ff224b9e55a 100644 --- a/packages/SystemUI/res-keyguard/values-eu/strings.xml +++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ez dago konektatuta inongo saretara."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Aldatu idazketa-metodoa"</string> <string name="airplane_mode" msgid="2528005343938497866">"Hegaldi modua"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN kodea behar da eguneratzea prestatzeko"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Eredua behar da eguneratzea prestatzeko"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Pasahitza behar da eguneratzea prestatzeko"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Eredua marraztu beharko duzu gailua berrabiarazten denean"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN kodea idatzi beharko duzu gailua berrabiarazten denean"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Pasahitza idatzi beharko duzu gailua berrabiarazten denean"</string> diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml index 43d32140b153..5e696369634e 100644 --- a/packages/SystemUI/res-keyguard/values-fa/strings.xml +++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"سرویسی وجود ندارد."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"تغییر روش ورودی"</string> <string name="airplane_mode" msgid="2528005343938497866">"حالت هواپیما"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"آمادهسازی برای بهروزرسانی به پین نیاز دارد"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"آمادهسازی برای بهروزرسانی به الگو نیاز دارد"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"آمادهسازی برای بهروزرسانی به گذرواژه نیاز دارد"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"بعد از بازنشانی دستگاه باید الگو وارد شود"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"بعد از بازنشانی دستگاه باید پین وارد شود"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"بعد از بازنشانی دستگاه باید گذرواژه وارد شود"</string> diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml index 7dc12c93e45e..54bc4d8cba58 100644 --- a/packages/SystemUI/res-keyguard/values-fi/strings.xml +++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ei yhteyttä"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Vaihda syöttötapaa."</string> <string name="airplane_mode" msgid="2528005343938497866">"Lentokonetila"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Päivitykseen valmistautuminen edellyttää PIN-koodia"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Päivitykseen valmistautuminen edellyttää kuviota"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Päivitykseen valmistautuminen edellyttää salasanaa"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Kuvio vaaditaan laitteen uudelleenkäynnistyksen jälkeen."</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN-koodi vaaditaan laitteen uudelleenkäynnistyksen jälkeen."</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Salasana vaaditaan laitteen uudelleenkäynnistyksen jälkeen."</string> diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml index f093c1745e76..3e858c2ecf12 100644 --- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Aucun service"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Changer de méthode d\'entrée"</string> <string name="airplane_mode" msgid="2528005343938497866">"Mode Avion"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Le NIP est nécessaire pour préparer la mise à jour"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Le schéma est nécessaire pour préparer la mise à jour"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Le mot de passe est nécessaire pour préparer la mise à jour"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Le schéma est exigé après le redémarrage de l\'appareil"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Le NIP est exigé après le redémarrage de l\'appareil"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Le mot de passe est exigé après le redémarrage de l\'appareil"</string> diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml index d6d5a32874c2..8551fab7281f 100644 --- a/packages/SystemUI/res-keyguard/values-fr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Aucun service."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Changer le mode de saisie"</string> <string name="airplane_mode" msgid="2528005343938497866">"Mode Avion"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Veuillez saisir le code pour lancer la préparation de la mise à jour"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Veuillez saisir le schéma pour lancer la préparation de la mise à jour"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Veuillez saisir le mot de passe pour lancer la préparation de la mise à jour"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Veuillez dessiner le schéma après le redémarrage de l\'appareil"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Veuillez saisir le code après le redémarrage de l\'appareil"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Veuillez saisir le mot de passe après le redémarrage de l\'appareil"</string> diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml index f5d5bb4d13d4..46079810aee4 100644 --- a/packages/SystemUI/res-keyguard/values-gl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Non hai servizo."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Cambia o método de introdución"</string> <string name="airplane_mode" msgid="2528005343938497866">"Modo avión"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Necesítase o PIN para preparar o dispositivo co fin de actualizalo"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Necesítase o padrón para preparar o dispositivo co fin de actualizalo"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Necesítase o contrasinal para preparar o dispositivo co fin de actualizalo"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"É necesario o padrón despois do reinicio do dispositivo"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"É necesario o PIN despois do reinicio do dispositivo"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"É necesario o contrasinal despois do reinicio do dispositivo"</string> diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml index 29e2fe040082..b02d3d97b39f 100644 --- a/packages/SystemUI/res-keyguard/values-gu/strings.xml +++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"કોઈ સેવા નથી."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ઇનપુટ પદ્ધતિ સ્વિચ કરો"</string> <string name="airplane_mode" msgid="2528005343938497866">"એરપ્લેન મોડ"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"અપડેટ માટે તૈયાર કરવા માટે પિન જરુરી છે"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"અપડેટ માટે તૈયાર કરવા માટે પૅટર્ન જરુરી છે"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"અપડેટ માટે તૈયાર કરવા માટે પાસવર્ડ જરુરી છે"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ઉપકરણનો પુનઃપ્રારંભ થાય તે પછી પૅટર્ન જરૂરી છે"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ઉપકરણનો પુનઃપ્રારંભ થાય તે પછી પિન જરૂરી છે"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ઉપકરણનો પુનઃપ્રારંભ થાય તે પછી પાસવર્ડ જરૂરી છે"</string> diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml index d26c79f9c420..f6b15de0e97e 100644 --- a/packages/SystemUI/res-keyguard/values-hi/strings.xml +++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"कोई सेवा नहीं."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"इनपुट का तरीका बदलें"</string> <string name="airplane_mode" msgid="2528005343938497866">"हवाई जहाज़ मोड"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"अपडेट के लिए पिन डालना ज़रूरी है"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"अपडेट के लिए पैटर्न डालना ज़रूरी है"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"अपडेट के लिए पासवर्ड डालना ज़रूरी है"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"डिवाइस फिर से चालू होने के बाद पैटर्न ज़रूरी है"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"डिवाइस फिर से चालू होने के बाद पिन ज़रूरी है"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"डिवाइस फिर से चालू होने के बाद पासवर्ड ज़रूरी है"</string> diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml index c8dd9b0a0932..49db3f88669a 100644 --- a/packages/SystemUI/res-keyguard/values-hr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml @@ -104,9 +104,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Nema usluge."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Promjena načina unosa"</string> <string name="airplane_mode" msgid="2528005343938497866">"Način rada u zrakoplovu"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Za pripremu ažuriranja potreban je PIN"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Za pripremu ažuriranja potreban je uzorak"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Za pripremu ažuriranja potrebna je zaporka"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Nakon ponovnog pokretanja uređaja morate unijeti uzorak"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Nakon ponovnog pokretanja uređaja morate unijeti PIN"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Nakon ponovnog pokretanja uređaja morate unijeti zaporku"</string> diff --git a/packages/SystemUI/res-keyguard/values-hu/strings.xml b/packages/SystemUI/res-keyguard/values-hu/strings.xml index f0023d20e6bd..c26998f01ff0 100644 --- a/packages/SystemUI/res-keyguard/values-hu/strings.xml +++ b/packages/SystemUI/res-keyguard/values-hu/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Nincs szolgáltatás."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Beviteli módszer váltása"</string> <string name="airplane_mode" msgid="2528005343938497866">"Repülős üzemmód"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"A frissítésre való felkészüléshez meg kell adni a PIN-kódot"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"A frissítésre való felkészüléshez meg kell adni a mintát"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"A frissítésre való felkészüléshez meg kell adni a jelszót"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Az eszköz újraindítását követően meg kell adni a mintát"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Az eszköz újraindítását követően meg kell adni a PIN-kódot"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Az eszköz újraindítását követően meg kell adni a jelszót"</string> diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml index 42247052014f..ad949d48fe0c 100644 --- a/packages/SystemUI/res-keyguard/values-hy/strings.xml +++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ծառայությունն անհասանելի է։"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Փոխել ներածման եղանակը"</string> <string name="airplane_mode" msgid="2528005343938497866">"Ավիառեժիմ"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Թարմացմանը պատրաստվելու համար անհրաժեշտ է մուտքագրել PIN-ը"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Թարմացմանը պատրաստվելու համար անհրաժեշտ է մուտքագրել նախշը"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Թարմացմանը պատրաստվելու համար անհրաժեշտ է մուտքագրել գաղտնաբառը"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Սարքը վերագործարկելուց հետո անհրաժեշտ է մուտքագրել նախշը"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Սարքը վերագործարկելուց հետո անհրաժեշտ է մուտքագրել PIN կոդը"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Սարքը վերագործարկելուց հետո անհրաժեշտ է մուտքագրել գաղտնաբառը"</string> diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml index d62795ba1b14..85b2a4726fa2 100644 --- a/packages/SystemUI/res-keyguard/values-in/strings.xml +++ b/packages/SystemUI/res-keyguard/values-in/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Tidak ada layanan."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Beralih metode masukan"</string> <string name="airplane_mode" msgid="2528005343938497866">"Mode pesawat"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN diwajibkan untuk menyiapkan update"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Pola diwajibkan untuk menyiapkan update"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Sandi diwajibkan untuk menyiapkan update"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pola diperlukan setelah perangkat dimulai ulang"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN diperlukan setelah perangkat dimulai ulang"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Sandi diperlukan setelah perangkat dimulai ulang"</string> diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml index 5e3765571c02..e40cdca33034 100644 --- a/packages/SystemUI/res-keyguard/values-is/strings.xml +++ b/packages/SystemUI/res-keyguard/values-is/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ekkert símasamband."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Skipta um innsláttaraðferð"</string> <string name="airplane_mode" msgid="2528005343938497866">"Flugstilling"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Slá þarf inn PIN-númer til að undirbúa uppfærsluna"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Teikna þarf mynstur til að undirbúa uppfærsluna"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Gefa þarf upp aðgangsorð til að undirbúa uppfærsluna"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Mynsturs er krafist þegar tækið er endurræst"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN-númers er krafist þegar tækið er endurræst"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Aðgangsorðs er krafist þegar tækið er endurræst"</string> diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml index fe460e38dc0b..e1c9ee8b7d34 100644 --- a/packages/SystemUI/res-keyguard/values-it/strings.xml +++ b/packages/SystemUI/res-keyguard/values-it/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Nessun servizio."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Cambia metodo di immissione"</string> <string name="airplane_mode" msgid="2528005343938497866">"Modalità aereo"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN obbligatorio per la preparazione all\'aggiornamento"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Sequenza obbligatoria per la preparazione all\'aggiornamento"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Password obbligatoria per la preparazione all\'aggiornamento"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Sequenza obbligatoria dopo il riavvio del dispositivo"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN obbligatorio dopo il riavvio del dispositivo"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Password obbligatoria dopo il riavvio del dispositivo"</string> diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml index 71f3048ba11c..e054f629836e 100644 --- a/packages/SystemUI/res-keyguard/values-iw/strings.xml +++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml @@ -107,9 +107,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"אין שירות."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"החלפת שיטת קלט"</string> <string name="airplane_mode" msgid="2528005343938497866">"מצב טיסה"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"נדרש קוד אימות להכנת העדכון"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"נדרש קו ביטול נעילה להכנת העדכון"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"נדרשת סיסמה להכנת העדכון"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"יש להזין את קו ביטול הנעילה לאחר הפעלה מחדש של המכשיר"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"יש להזין קוד גישה לאחר הפעלה מחדש של המכשיר"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"יש להזין סיסמה לאחר הפעלה מחדש של המכשיר"</string> diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml index 23ff82c6f2a7..957d78a8b440 100644 --- a/packages/SystemUI/res-keyguard/values-ja/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"通信サービスはありません。"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"入力方法の切り替え"</string> <string name="airplane_mode" msgid="2528005343938497866">"機内モード"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"更新の準備には PIN の入力が必要です"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"更新の準備にはパターンの入力が必要です"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"更新の準備にはパスワードが必要です"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"デバイスの再起動後はパターンの入力が必要となります"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"デバイスの再起動後は PIN の入力が必要となります"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"デバイスの再起動後はパスワードの入力が必要となります"</string> diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml index 25b9b1b22c1c..d0d15fec7172 100644 --- a/packages/SystemUI/res-keyguard/values-ka/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"სერვისი არ არის."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"შეყვანის მეთოდის გადართვა"</string> <string name="airplane_mode" msgid="2528005343938497866">"თვითმფრინავის რეჟიმი"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"განახლების მოსამზადებლად საჭიროა PIN-კოდი"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"განახლების მოსამზადებლად საჭიროა ნიმუში"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"განახლების მოსამზადებლად საჭიროა პაროლი"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"მოწყობილობის გადატვირთვის შემდეგ საჭიროა ნიმუშის დახატვა"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"მოწყობილობის გადატვირთვის შემდეგ საჭიროა PIN-კოდის შეყვანა"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"მოწყობილობის გადატვირთვის შემდეგ საჭიროა პაროლის შეყვანა"</string> diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml index 456088181d7f..62afd1e45df8 100644 --- a/packages/SystemUI/res-keyguard/values-kk/strings.xml +++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Қызмет көрсетілмейді."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Енгізу әдісін ауыстыру"</string> <string name="airplane_mode" msgid="2528005343938497866">"Ұшақ режимі"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Жаңа нұсқа орнатуға дайындау үшін PIN кодын енгізу қажет."</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Жаңа нұсқа орнатуға дайындау үшін өрнек енгізу қажет."</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Жаңа нұсқа орнатуға дайындау үшін құпия сөз енгізу қажет."</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Құрылғы қайта іске қосылғаннан кейін, өрнекті енгізу қажет"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Құрылғы қайта іске қосылғаннан кейін, PIN кодын енгізу қажет"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Құрылғы қайта іске қосылғаннан кейін, құпия сөзді енгізу қажет"</string> diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml index e5ea9ea105dd..24b5c23a6732 100644 --- a/packages/SystemUI/res-keyguard/values-km/strings.xml +++ b/packages/SystemUI/res-keyguard/values-km/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"គ្មានសេវាទេ។"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ប្ដូរវិធីបញ្ចូល"</string> <string name="airplane_mode" msgid="2528005343938497866">"មុខងារពេលជិះយន្តហោះ"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"តម្រូវឱ្យមានកូដ PIN ដើម្បីរៀបចំធ្វើបច្ចុប្បន្នភាព"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"តម្រូវឱ្យមានលំនាំ ដើម្បីរៀបចំធ្វើបច្ចុប្បន្នភាព"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"តម្រូវឱ្យមានពាក្យសម្ងាត់ ដើម្បីរៀបចំធ្វើបច្ចុប្បន្នភាព"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"តម្រូវឲ្យប្រើលំនាំ បន្ទាប់ពីឧបករណ៍ចាប់ផ្តើមឡើងវិញ"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"តម្រូវឲ្យបញ្ចូលកូដ PIN បន្ទាប់ពីឧបករណ៍ចាប់ផ្តើមឡើងវិញ"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"តម្រូវឲ្យបញ្ចូលពាក្យសម្ងាត់ បន្ទាប់ពីឧបករណ៍ចាប់ផ្តើមឡើងវិញ"</string> diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml index 8173ca047fe3..785ca4338326 100644 --- a/packages/SystemUI/res-keyguard/values-kn/strings.xml +++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"ಸೇವೆ ಇಲ್ಲ."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ಇನ್ಪುಟ್ ವಿಧಾನ ಬದಲಿಸಿ"</string> <string name="airplane_mode" msgid="2528005343938497866">"ಏರ್ಪ್ಲೇನ್ ಮೋಡ್"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"ಅಪ್ಡೇಟ್ಗಾಗಿ ಸಿದ್ಧಗೊಳಿಸಲು, ಪಿನ್ ಅಗತ್ಯವಿದೆ"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"ಅಪ್ಡೇಟ್ಗಾಗಿ ಸಿದ್ಧಗೊಳಿಸಲು, ಪ್ಯಾಟರ್ನ್ ಅಗತ್ಯವಿದೆ"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"ಅಪ್ಡೇಟ್ಗಾಗಿ ಸಿದ್ಧಗೊಳಿಸಲು, ಪಾಸ್ವರ್ಡ್ ಅಗತ್ಯವಿದೆ"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ಸಾಧನ ಮರುಪ್ರಾರಂಭಗೊಂಡ ನಂತರ ಪ್ಯಾಟರ್ನ್ ಅಗತ್ಯವಿರುತ್ತದೆ"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ಸಾಧನ ಮರುಪ್ರಾರಂಭಗೊಂಡ ನಂತರ ಪಿನ್ ಅಗತ್ಯವಿರುತ್ತದೆ"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ಸಾಧನ ಮರುಪ್ರಾರಂಭಗೊಂಡ ನಂತರ ಪಾಸ್ವರ್ಡ್ ಅಗತ್ಯವಿರುತ್ತದೆ"</string> diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml index 606bb5047245..848490ebb9b8 100644 --- a/packages/SystemUI/res-keyguard/values-ko/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"서비스 불가"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"입력 방법 전환"</string> <string name="airplane_mode" msgid="2528005343938497866">"비행기 모드"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"업데이트를 준비하려면 PIN이 필요합니다."</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"업데이트를 준비하려면 패턴이 필요합니다."</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"업데이트를 준비하려면 비밀번호가 필요합니다."</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"기기가 다시 시작되면 패턴이 필요합니다."</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"기기가 다시 시작되면 PIN이 필요합니다."</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"기기가 다시 시작되면 비밀번호가 필요합니다."</string> diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml index 72f95dbfa59f..d868788a3eca 100644 --- a/packages/SystemUI/res-keyguard/values-ky/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Интернет жок."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Киргизүү ыкмасын өзгөртүү"</string> <string name="airplane_mode" msgid="2528005343938497866">"Учак режими"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Жаңыртууга даярдоо үчүн PIN код талап кылынат"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Жаңыртууга даярдоо үчүн графикалык ачкыч талап кылынат"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Жаңыртууга даярдоо үчүн сырсөз талап кылынат"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Түзмөк кайра күйгүзүлгөндөн кийин графикалык ачкычты тартуу талап кылынат"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Түзмөк кайра күйгүзүлгөндөн кийин PIN-кодду киргизүү талап кылынат"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Түзмөк кайра күйгүзүлгөндөн кийин сырсөздү киргизүү талап кылынат"</string> diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml index 25e36c1b3115..ebaffb13d5b4 100644 --- a/packages/SystemUI/res-keyguard/values-lo/strings.xml +++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"ບໍ່ມີບໍລິການ"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ສະລັບຮູບແບບການປ້ອນຂໍ້ມູນ"</string> <string name="airplane_mode" msgid="2528005343938497866">"ໂໝດໃນຍົນ"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"ຕ້ອງໃຊ້ PIN ເພື່ອກະກຽມອັບເດດ"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"ຕ້ອງໃຊ້ຮູບແບບເພື່ອກະກຽມອັບເດດ"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"ຕ້ອງໃຊ້ລະຫັດຜ່ານເພື່ອກະກຽມອັບເດດ"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ຈຳເປັນຕ້ອງມີແບບຮູບປົດລັອກຫຼັງຈາກອຸປະກອນເລີ່ມລະບົບໃໝ່"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ຈຳເປັນຕ້ອງມີ PIN ຫຼັງຈາກອຸປະກອນເລີ່ມລະບົບໃໝ່"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ຈຳເປັນຕ້ອງມີລະຫັດຜ່ານຫຼັງຈາກອຸປະກອນເລີ່ມລະບົບໃໝ່"</string> diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml index 158efe2feabb..4d598f6bfb6d 100644 --- a/packages/SystemUI/res-keyguard/values-lt/strings.xml +++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml @@ -107,9 +107,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Nėra paslaugos."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Perjungti įvesties metodą"</string> <string name="airplane_mode" msgid="2528005343938497866">"Lėktuvo režimas"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Kad būtų pasiruošta atnaujinti, reikia įvesti PIN kodą"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Kad būtų pasiruošta atnaujinti, reikia įvesti atrakinimo piešinį"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Kad būtų pasiruošta atnaujinti, reikia įvesti slaptažodį"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Iš naujo paleidus įrenginį būtinas atrakinimo piešinys"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Iš naujo paleidus įrenginį būtinas PIN kodas"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Iš naujo paleidus įrenginį būtinas slaptažodis"</string> diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml index c4a4e7f45b38..fad67d536e58 100644 --- a/packages/SystemUI/res-keyguard/values-lv/strings.xml +++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml @@ -104,9 +104,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Nav pakalpojuma."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Pārslēgt ievades metodi"</string> <string name="airplane_mode" msgid="2528005343938497866">"Lidojuma režīms"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Lai sagatavotos atjauninājumam, nepieciešams PIN."</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Lai sagatavotos atjauninājumam, nepieciešama kombinācija."</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Lai sagatavotos atjauninājumam, nepieciešama parole."</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pēc ierīces restartēšanas ir jāievada atbloķēšanas kombinācija."</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Pēc ierīces restartēšanas ir jāievada PIN kods."</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Pēc ierīces restartēšanas ir jāievada parole."</string> diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml index de4a83b97021..1397f467e116 100644 --- a/packages/SystemUI/res-keyguard/values-mk/strings.xml +++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Нема услуга."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Префрли метод за внесување"</string> <string name="airplane_mode" msgid="2528005343938497866">"Авионски режим"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Потребен е PIN за да се подготви за ажурирање"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Потребна е шема за да се подготви за ажурирање"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Потребна е лозинка за да се подготви за ажурирање"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Потребна е шема по рестартирање на уредот"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Потребен е PIN-код по рестартирање на уредот"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Потребна е лозинка по рестартирање на уредот"</string> diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml index da26ba788932..f82f822ca26c 100644 --- a/packages/SystemUI/res-keyguard/values-ml/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"സേവനമില്ല"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ഇൻപുട്ട് രീതി മാറുക"</string> <string name="airplane_mode" msgid="2528005343938497866">"ഫ്ലൈറ്റ് മോഡ്"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"അപ്ഡേറ്റിനായി തയ്യാറെടുക്കാൻ പിൻ ആവശ്യമാണ്"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"അപ്ഡേറ്റിനായി തയ്യാറെടുക്കാൻ പാറ്റേൺ ആവശ്യമാണ്"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"അപ്ഡേറ്റിനായി തയ്യാറെടുക്കാൻ പാസ്വേഡ് ആവശ്യമാണ്"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ഉപകരണം റീസ്റ്റാർട്ടായശേഷം പാറ്റേൺ വരയ്ക്കേണ്ടതുണ്ട്"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ഉപകരണം റീസ്റ്റാർട്ടായശേഷം പിൻ നൽകേണ്ടതുണ്ട്"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ഉപകരണം റീസ്റ്റാർട്ടായശേഷം പാസ്വേഡ് നൽകേണ്ടതുണ്ട്"</string> diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml index fb032f15df7f..462017af1922 100644 --- a/packages/SystemUI/res-keyguard/values-mn/strings.xml +++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Үйлчилгээ алга."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Оруулах аргыг сэлгэх"</string> <string name="airplane_mode" msgid="2528005343938497866">"Нислэгийн горим"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Шинэчлэхэд бэлтгэхийн тулд ПИН шаардлагатай"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Шинэчлэхэд бэлтгэхийн тулд хээ шаардлагатай"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Шинэчлэхэд бэлтгэхийн тулд нууц үг шаардлагатай"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Төхөөрөмжийг дахин эхлүүлсний дараа загвар оруулах шаардлагатай"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Төхөөрөмжийг дахин эхлүүлсний дараа ПИН оруулах шаардлагатай"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Төхөөрөмжийг дахин эхлүүлсний дараа нууц үг оруулах шаардлагатай"</string> diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml index e79e5c5d9234..0166791dc3ba 100644 --- a/packages/SystemUI/res-keyguard/values-mr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"सेवा नाही."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"इनपुट पद्धत स्विच करा"</string> <string name="airplane_mode" msgid="2528005343938497866">"विमान मोड"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"अपडेटसाठी तयार करण्याकरिता पिन आवश्यक आहे"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"अपडेटसाठी तयार करण्याकरिता पॅटर्न आवश्यक आहे"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"अपडेटसाठी तयार करण्याकरिता पासवर्ड आवश्यक आहे"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"डिव्हाइस रीस्टार्ट झाल्यावर पॅटर्न आवश्यक आहे"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"डिव्हाइस रीस्टार्ट झाल्यावर पिन आवश्यक आहे"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"डिव्हाइस रीस्टार्ट झाल्यावर पासवर्ड आवश्यक आहे"</string> diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml index 5bc5df4d7c26..67500866f3d4 100644 --- a/packages/SystemUI/res-keyguard/values-ms/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Tiada perkhidmatan."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Tukar kaedah masukan"</string> <string name="airplane_mode" msgid="2528005343938497866">"Mod Pesawat"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN diperlukan untuk menyediakan kemas kini"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Corak diperlukan untuk menyediakan kemas kini"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Kata laluan diperlukan untuk menyediakan kemas kini"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Corak diperlukan setelah peranti dimulakan semula"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN diperlukan setelah peranti dimulakan semula"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Kata laluan diperlukan setelah peranti dimulakan semula"</string> diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml index 43732d8ff260..3b32f06e19cd 100644 --- a/packages/SystemUI/res-keyguard/values-my/strings.xml +++ b/packages/SystemUI/res-keyguard/values-my/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"ဝန်ဆောင်မှု မရှိပါ။"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"စာရိုက်စနစ်ပြောင်းရန်"</string> <string name="airplane_mode" msgid="2528005343938497866">"လေယာဉ်ပျံမုဒ်"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"အပ်ဒိတ်အတွက် ပြင်ဆင်ရန် ပင်နံပါတ် လိုပါသည်"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"အပ်ဒိတ်အတွက် ပြင်ဆင်ရန် ပုံစံလိုပါသည်"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"အပ်ဒိတ်အတွက် ပြင်ဆင်ရန် စကားဝှက် လိုပါသည်"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"စက်ပစ္စည်းကို ပိတ်ပြီးပြန်ဖွင့်လိုက်သည့်အခါတွင် ပုံစံ လိုအပ်ပါသည်"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"စက်ပစ္စည်းကို ပိတ်ပြီးပြန်ဖွင့်လိုက်သည့်အခါတွင် ပင်နံပါတ် လိုအပ်ပါသည်"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"စက်ပစ္စည်းကို ပိတ်ပြီးပြန်ဖွင့်လိုက်သည့်အခါတွင် စကားဝှက် လိုအပ်ပါသည်"</string> diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml index 6dd3b2ad6e72..ebd8f2922ba2 100644 --- a/packages/SystemUI/res-keyguard/values-nb/strings.xml +++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ingen tilkobling."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Bytt inndatametode"</string> <string name="airplane_mode" msgid="2528005343938497866">"Flymodus"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN-koden kreves for å klargjøre for oppdateringen"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Mønsteret kreves for å klargjøre for oppdateringen"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Passordet kreves for å klargjøre for oppdateringen"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Du må tegne mønsteret etter at enheten har startet på nytt"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Du må skrive inn PIN-koden etter at enheten har startet på nytt"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Du må skrive inn passordet etter at enheten har startet på nytt"</string> diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml index a1e6d62234e9..ce05e38dca10 100644 --- a/packages/SystemUI/res-keyguard/values-ne/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"सेवा उपलब्ध छैन।"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"इनपुट विधिलाई स्विच गर्नुहोस्"</string> <string name="airplane_mode" msgid="2528005343938497866">"हवाइजहाज मोड"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"अद्यावधिक गर्ने कार्यका लागि तयार पार्न PIN चाहिन्छ"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"अद्यावधिक गर्ने कार्यका लागि तयार पार्न प्याटर्न चाहिन्छ"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"अद्यावधिक गर्ने कार्यका लागि तयार पार्न पासवर्ड चाहिन्छ"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"यन्त्र पुनः सुरु भएपछि ढाँचा आवश्यक पर्दछ"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"यन्त्र पुनः सुरु भएपछि PIN आवश्यक पर्दछ"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"यन्त्र पुनः सुरु भएपछि पासवर्ड आवश्यक पर्दछ"</string> diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml index f3c35a405bd6..aa783e84b892 100644 --- a/packages/SystemUI/res-keyguard/values-nl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Geen service."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Invoermethode wijzigen"</string> <string name="airplane_mode" msgid="2528005343938497866">"Vliegtuigmodus"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Pincode vereist voor voorbereiding op update"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Patroon vereist voor voorbereiding op update"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Wachtwoord vereist voor voorbereiding op update"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Patroon vereist nadat het apparaat opnieuw is opgestart"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Pincode vereist nadat het apparaat opnieuw is opgestart"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Wachtwoord vereist nadat het apparaat opnieuw is opgestart"</string> diff --git a/packages/SystemUI/res-keyguard/values-or/strings.xml b/packages/SystemUI/res-keyguard/values-or/strings.xml index e92dc42680e1..8bbdcf1e9eb6 100644 --- a/packages/SystemUI/res-keyguard/values-or/strings.xml +++ b/packages/SystemUI/res-keyguard/values-or/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"କୌଣସି ସେବା ନାହିଁ।"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ଇନପୁଟ୍ ପଦ୍ଧତି ବଦଳାନ୍ତୁ"</string> <string name="airplane_mode" msgid="2528005343938497866">"ଏରୋପ୍ଲେନ୍ ମୋଡ୍"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"ଅପଡେଟ୍ ପାଇଁ ପ୍ରସ୍ତୁତ ହେବାକୁ PIN ଆବଶ୍ୟକ"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"ଅପଡେଟ୍ ପାଇଁ ପ୍ରସ୍ତୁତ ହେବାକୁ ପାଟର୍ନ ଆବଶ୍ୟକ"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"ଅପଡେଟ୍ ପାଇଁ ପ୍ରସ୍ତୁତ ହେବାକୁ ପାସୱାର୍ଡ ଆବଶ୍ୟକ"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ଡିଭାଇସ୍ ରିଷ୍ଟାର୍ଟ ହେବା ପରେ ପାଟର୍ନ ଆବଶ୍ୟକ ଅଟେ"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ଡିଭାଇସ୍ ରିଷ୍ଟାର୍ଟ ହେବାପରେ ପାସ୍ୱର୍ଡ ଆବଶ୍ୟକ"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ଡିଭାଇସ୍ ରିଷ୍ଟାର୍ଟ ହେବା ପରେ ପାସୱର୍ଡ ଆବଶ୍ୟକ ଅଟେ"</string> diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml index 5c83ab8a354c..78e066526840 100644 --- a/packages/SystemUI/res-keyguard/values-pa/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"ਕੋਈ ਸੇਵਾ ਨਹੀਂ।"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ਇਨਪੁੱਟ ਵਿਧੀ ਸਵਿੱਚ ਕਰੋ"</string> <string name="airplane_mode" msgid="2528005343938497866">"ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"ਅੱਪਡੇਟ ਨੂੰ ਤਿਆਰ ਕਰਨ ਲਈ ਪਿੰਨ ਲੋੜੀਂਦਾ ਹੈ"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"ਅੱਪਡੇਟ ਨੂੰ ਤਿਆਰ ਕਰਨ ਲਈ ਪੈਟਰਨ ਲੋੜੀਂਦਾ ਹੈ"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"ਅੱਪਡੇਟ ਨੂੰ ਤਿਆਰ ਕਰਨ ਲਈ ਪਾਸਵਰਡ ਲੋੜੀਂਦਾ ਹੈ"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ਡੀਵਾਈਸ ਦੇ ਮੁੜ-ਚਾਲੂ ਹੋਣ \'ਤੇ ਪੈਟਰਨ ਦੀ ਲੋੜ ਹੈ"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ਡੀਵਾਈਸ ਦੇ ਮੁੜ-ਚਾਲੂ ਹੋਣ \'ਤੇ ਪਿੰਨ ਦੀ ਲੋੜ ਹੈ"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ਡੀਵਾਈਸ ਦੇ ਮੁੜ-ਚਾਲੂ ਹੋਣ \'ਤੇ ਪਾਸਵਰਡ ਦੀ ਲੋੜ ਹੈ"</string> diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml index 5f1df3e109b1..5094cf9983a1 100644 --- a/packages/SystemUI/res-keyguard/values-pl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml @@ -107,9 +107,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Brak usługi."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Przełączanie metody wprowadzania"</string> <string name="airplane_mode" msgid="2528005343938497866">"Tryb samolotowy"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Aby przygotować się do aktualizacji, wymagany jest kod PIN"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Aby przygotować się do aktualizacji, wymagany jest wzór"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Aby przygotować się do aktualizacji, wymagane jest hasło"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Po ponownym uruchomieniu urządzenia wymagany jest wzór"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Po ponownym uruchomieniu urządzenia wymagany jest kod PIN"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Po ponownym uruchomieniu urządzenia wymagane jest hasło"</string> diff --git a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml index 1e47efa2cc4f..5bfc3dbc900d 100644 --- a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Sem serviço."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Alterar o método de entrada"</string> <string name="airplane_mode" msgid="2528005343938497866">"Modo avião"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Insira o PIN para se preparar para a atualização"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Insira o padrão para se preparar para a atualização"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Insira a senha para se preparar para a atualização"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"O padrão é exigido após a reinicialização do dispositivo"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"O PIN é exigido após a reinicialização do dispositivo"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"A senha é exigida após a reinicialização do dispositivo"</string> diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml index 09cfcf1da02f..5af8bc09a05b 100644 --- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Sem serviço."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Alternar o método de introdução"</string> <string name="airplane_mode" msgid="2528005343938497866">"Modo de avião"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"É necessário introduzir o PIN para a preparação para a atualização."</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"É necessário introduzir o padrão para a preparação para a atualização."</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"É necessário introduzir a palavra-passe para a preparação para a atualização."</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"É necessário um padrão após reiniciar o dispositivo"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"É necessário um PIN após reiniciar o dispositivo"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"É necessária uma palavra-passe após reiniciar o dispositivo"</string> diff --git a/packages/SystemUI/res-keyguard/values-pt/strings.xml b/packages/SystemUI/res-keyguard/values-pt/strings.xml index 1e47efa2cc4f..5bfc3dbc900d 100644 --- a/packages/SystemUI/res-keyguard/values-pt/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pt/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Sem serviço."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Alterar o método de entrada"</string> <string name="airplane_mode" msgid="2528005343938497866">"Modo avião"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Insira o PIN para se preparar para a atualização"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Insira o padrão para se preparar para a atualização"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Insira a senha para se preparar para a atualização"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"O padrão é exigido após a reinicialização do dispositivo"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"O PIN é exigido após a reinicialização do dispositivo"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"A senha é exigida após a reinicialização do dispositivo"</string> diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml index 7df2db6f03f1..8122241e6613 100644 --- a/packages/SystemUI/res-keyguard/values-ro/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml @@ -104,9 +104,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Fără serviciu."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Comutați metoda de introducere"</string> <string name="airplane_mode" msgid="2528005343938497866">"Mod Avion"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Pentru a vă pregăti pentru actualizare este necesar codul PIN"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Pentru a vă pregăti pentru actualizare este necesar modelul"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Pentru a vă pregăti pentru actualizare este necesară parola"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Modelul este necesar după repornirea dispozitivului"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Codul PIN este necesar după repornirea dispozitivului"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Parola este necesară după repornirea dispozitivului"</string> diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml index ccd3c968cd51..b80b479ca29a 100644 --- a/packages/SystemUI/res-keyguard/values-ru/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml @@ -107,9 +107,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Нет сигнала."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Сменить способ ввода"</string> <string name="airplane_mode" msgid="2528005343938497866">"Режим полета"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Для подготовки к обновлению необходимо ввести PIN-код."</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Для подготовки к обновлению необходимо ввести графический ключ."</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Для подготовки к обновлению необходимо ввести пароль."</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"После перезагрузки устройства необходимо ввести графический ключ"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"После перезагрузки устройства необходимо ввести PIN-код"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"После перезагрузки устройства необходимо ввести пароль"</string> diff --git a/packages/SystemUI/res-keyguard/values-si/strings.xml b/packages/SystemUI/res-keyguard/values-si/strings.xml index 3dfc282ccae5..1cd876f15d47 100644 --- a/packages/SystemUI/res-keyguard/values-si/strings.xml +++ b/packages/SystemUI/res-keyguard/values-si/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"සේවාව නැත."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ආදාන ක්රමය මාරු කිරීම"</string> <string name="airplane_mode" msgid="2528005343938497866">"ගුවන් යානා ප්රකාරය"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"යාවත්කාලීනය සඳහා සුදානම් කිරීමට PIN අවශ්යය"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"යාවත්කාලීනය සඳහා සුදානම් කිරීමට රටාව අවශ්යය"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"යාවත්කාලීනය සඳහා සුදානම් කිරීමට මුරපදය අවශ්යය"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"උපාංගය නැවත ආරම්භ වූ පසු රටාව අවශ්යයි"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"උපාංගය නැවත ආරම්භ වූ පසු PIN අංකය අවශ්යයි"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"උපාංගය නැවත ආරම්භ වූ පසු මුරපදය අවශ්යයි"</string> diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml index 8568e14fecc3..801a7dbccf6d 100644 --- a/packages/SystemUI/res-keyguard/values-sk/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml @@ -107,9 +107,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Žiadny signál."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Prepnúť metódu vstupu"</string> <string name="airplane_mode" msgid="2528005343938497866">"Režim v lietadle"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Príprava na aktualizáciu vyžaduje zadanie kódu PIN"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Príprava na aktualizáciu vyžaduje zadanie vzoru"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Príprava na aktualizáciu vyžaduje zadanie hesla"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Po reštartovaní zariadenia musíte zadať bezpečnostný vzor"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Po reštartovaní zariadenia musíte zadať kód PIN"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Po reštartovaní zariadenia musíte zadať heslo"</string> diff --git a/packages/SystemUI/res-keyguard/values-sl/strings.xml b/packages/SystemUI/res-keyguard/values-sl/strings.xml index 168158d9d602..967255cb50e7 100644 --- a/packages/SystemUI/res-keyguard/values-sl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sl/strings.xml @@ -107,9 +107,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ni storitve."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Preklop načina vnosa"</string> <string name="airplane_mode" msgid="2528005343938497866">"Način za letalo"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Za pripravo na posodobitev morate vnesti kodo PIN"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Za pripravo na posodobitev morate vnesti vzorec"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Za pripravo na posodobitev morate vnesti geslo"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Po vnovičnem zagonu naprave je treba vnesti vzorec"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Po vnovičnem zagonu naprave je treba vnesti kodo PIN"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Po vnovičnem zagonu naprave je treba vnesti geslo"</string> diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml index 14973f82dc4d..382a4dcafed7 100644 --- a/packages/SystemUI/res-keyguard/values-sq/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Nuk ka shërbim."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Ndërro metodën e hyrjes"</string> <string name="airplane_mode" msgid="2528005343938497866">"Modaliteti i aeroplanit"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Kërkohet kodi PIN për t\'u përgatitur për përditësimin"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Kërkohet motivi për t\'u përgatitur për përditësimin"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Kërkohet fjalëkalimi për t\'u përgatitur për përditësimin"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Kërkohet motivi pas rinisjes së pajisjes"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Kërkohet kodi PIN pas rinisjes së pajisjes"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Kërkohet fjalëkalimi pas rinisjes së pajisjes"</string> diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml index 24a1125f9a7d..f83df3f8925e 100644 --- a/packages/SystemUI/res-keyguard/values-sr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml @@ -104,9 +104,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Мрежа није доступна."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Промени метод уноса"</string> <string name="airplane_mode" msgid="2528005343938497866">"Режим рада у авиону"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN је обавезан ради припреме за ажурирање"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Шаблон је обавезан ради припреме за ажурирање"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Лозинка је обавезна ради припреме за ажурирање"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Треба да унесете шаблон када се уређај поново покрене"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Треба да унесете PIN када се уређај поново покрене"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Треба да унесете лозинку када се уређај поново покрене"</string> diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml index a37c4809ccdb..a037bffa4da2 100644 --- a/packages/SystemUI/res-keyguard/values-sv/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ingen tjänst."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Byt inmatningsmetod"</string> <string name="airplane_mode" msgid="2528005343938497866">"Flygplansläge"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Pinkod krävs för att förbereda för uppdatering"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Grafiskt lösenord krävs för att förbereda för uppdatering"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Lösenord krävs för att förbereda för uppdatering"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Du måste ange grafiskt lösenord när du har startat om enheten"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Du måste ange pinkod när du har startat om enheten"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Du måste ange lösenord när du har startat om enheten"</string> diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml index c4a9a1445ceb..efa5ecfd44fd 100644 --- a/packages/SystemUI/res-keyguard/values-sw/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Hakuna mtandao."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Kubadili mbinu ya kuingiza data"</string> <string name="airplane_mode" msgid="2528005343938497866">"Hali ya ndegeni"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Inahitaji PIN ili kujiandaa kwa ajili ya sasisho"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Inahitaji mchoro ili kujiandaa kwa ajili ya sasisho"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Inahitaji nenosiri ili kujiandaa kwa ajili ya sasisho"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Unafaa kuchora mchoro baada ya kuwasha kifaa upya"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Unafaa kuweka PIN baada ya kuwasha kifaa upya"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Unafaa kuweka nenosiri baada ya kuwasha kifaa upya"</string> diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml index a4dc0be3496f..96dbbb0314d6 100644 --- a/packages/SystemUI/res-keyguard/values-ta/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"சேவை இல்லை."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"உள்ளீட்டு முறையை மாற்றும்"</string> <string name="airplane_mode" msgid="2528005343938497866">"விமானப் பயன்முறை"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"புதுப்பிப்பிற்குத் தயார்செய்ய பின் தேவை"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"புதுப்பிப்பிற்குத் தயார்செய்ய பேட்டர்ன் தேவை"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"புதுப்பிப்பிற்குத் தயார்செய்ய கடவுச்சொல் தேவை"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"சாதனத்தை மீண்டும் தொடங்கியதும், பேட்டர்னை வரைய வேண்டும்"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"சாதனத்தை மீண்டும் தொடங்கியதும், பின்னை உள்ளிட வேண்டும்"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"சாதனத்தை மீண்டும் தொடங்கியதும், கடவுச்சொல்லை உள்ளிட வேண்டும்"</string> diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml index 3e27ce8ba702..74386bc7a487 100644 --- a/packages/SystemUI/res-keyguard/values-te/strings.xml +++ b/packages/SystemUI/res-keyguard/values-te/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"సేవ లేదు."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ఇన్పుట్ పద్ధతిని మార్చు"</string> <string name="airplane_mode" msgid="2528005343938497866">"విమానం మోడ్"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"అప్డేట్కు సిద్ధం చేయడానికి పిన్ అవసరం"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"అప్డేట్కు సిద్ధం చేయడానికి ఆకృతి అవసరం"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"అప్డేట్కు సిద్ధం చేయడానికి పాస్వర్డ్ అవసరం"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"పరికరాన్ని పునఃప్రారంభించిన తర్వాత నమూనాను గీయాలి"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"డివైజ్ను పునఃప్రారంభించిన తర్వాత పిన్ నమోదు చేయాలి"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"పరికరాన్ని పునఃప్రారంభించిన తర్వాత పాస్వర్డ్ను నమోదు చేయాలి"</string> diff --git a/packages/SystemUI/res-keyguard/values-th/strings.xml b/packages/SystemUI/res-keyguard/values-th/strings.xml index 48ae2ceb9fbd..e157be4ac18e 100644 --- a/packages/SystemUI/res-keyguard/values-th/strings.xml +++ b/packages/SystemUI/res-keyguard/values-th/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"ไม่มีบริการ"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"สลับวิธีการป้อนข้อมูล"</string> <string name="airplane_mode" msgid="2528005343938497866">"โหมดบนเครื่องบิน"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"ต้องใช้ PIN เพื่อเตรียมรับการอัปเดต"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"ต้องใช้รูปแบบเพื่อเตรียมรับการอัปเดต"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"ต้องใช้รหัสผ่านเพื่อเตรียมรับการอัปเดต"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ต้องวาดรูปแบบหลังจากอุปกรณ์รีสตาร์ท"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ต้องระบุ PIN หลังจากอุปกรณ์รีสตาร์ท"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ต้องป้อนรหัสผ่านหลังจากอุปกรณ์รีสตาร์ท"</string> diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml index bd87b20a2ccb..7b7e17dc8dcb 100644 --- a/packages/SystemUI/res-keyguard/values-tl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Walang serbisyo."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Magpalit ng pamamaraan ng pag-input"</string> <string name="airplane_mode" msgid="2528005343938497866">"Airplane mode"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Kinakailangan ang PIN para makapaghanda sa pag-update"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Kinakailangan ang pattern para makapaghanda sa pag-update"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Kinakailangan ang password para makapaghanda sa pag-update"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Kailangan ng pattern pagkatapos mag-restart ng device"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Kailangan ng PIN pagkatapos mag-restart ng device"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Kailangan ng password pagkatapos mag-restart ng device"</string> diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml index cf37451a9ed8..8c0caead0bdb 100644 --- a/packages/SystemUI/res-keyguard/values-tr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Hizmet yok."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Giriş yöntemini değiştir"</string> <string name="airplane_mode" msgid="2528005343938497866">"Uçak modu"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Güncellemenin hazırlanması için PIN gerekli"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Güncellemenin hazırlanması için desen gerekli"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Güncellemenin hazırlanması için şifre gerekli"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Cihaz yeniden başladıktan sonra desen gerekir"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Cihaz yeniden başladıktan sonra PIN gerekir"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Cihaz yeniden başladıktan sonra şifre gerekir"</string> diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml index 0ccd012c5221..6e5ce0f142dc 100644 --- a/packages/SystemUI/res-keyguard/values-uk/strings.xml +++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml @@ -107,9 +107,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Зв’язку немає."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Змінити метод введення"</string> <string name="airplane_mode" msgid="2528005343938497866">"Режим польоту"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Щоб підготуватися до оновлення, введіть PIN-код"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Щоб підготуватися до оновлення, введіть ключ"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Щоб підготуватися до оновлення, введіть пароль"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Після перезавантаження пристрою потрібно ввести ключ"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Після перезавантаження пристрою потрібно ввести PIN-код"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Після перезавантаження пристрою потрібно ввести пароль"</string> diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml index 22a477e3d63f..0fd5e17c953e 100644 --- a/packages/SystemUI/res-keyguard/values-ur/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"کوئی سروس نہیں ہے۔"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"اندراج کا طریقہ سوئچ کریں"</string> <string name="airplane_mode" msgid="2528005343938497866">"ہوائی جہاز وضع"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"اپ ڈیٹ تیار کرنے کے لیے PIN درکار ہے"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"اپ ڈیٹ تیار کرنے کے لیے پیٹرن درکار ہے"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"اپ ڈیٹ تیار کرنے کے لیے پاس ورڈ درکار ہے"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"آلہ دوبارہ چالو ہونے کے بعد پیٹرن درکار ہوتا ہے"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"آلہ دوبارہ چالو ہونے کے بعد PIN درکار ہوتا ہے"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"آلہ دوبارہ چالو ہونے کے بعد پاسورڈ درکار ہوتا ہے"</string> diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml index 72d4fae575b8..323fea5a608e 100644 --- a/packages/SystemUI/res-keyguard/values-uz/strings.xml +++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Aloqa yo‘q."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Matn kiritish usulini almashtirish"</string> <string name="airplane_mode" msgid="2528005343938497866">"Parvoz rejimi"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Yangilashga tayyorlash uchun PIN kod talab etiladi"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Yangilashga tayyorlash uchun grafik kalit talab etiladi"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Yangilashga tayyorlash uchun parol talab etiladi"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Qurilma o‘chirib yoqilgandan keyin grafik kalit talab qilinadi"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Qurilma o‘chirib yoqilgandan keyin PIN kod talab qilinadi"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Qurilma o‘chirib yoqilgandan keyin parol talab qilinadi"</string> diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml index de642f3cc27c..2ba5089c7ed9 100644 --- a/packages/SystemUI/res-keyguard/values-vi/strings.xml +++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Không có dịch vụ."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Chuyển phương thức nhập"</string> <string name="airplane_mode" msgid="2528005343938497866">"Chế độ trên máy bay"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Cần nhập mã PIN để chuẩn bị cập nhật"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Cần nhập hình mở khóa để chuẩn bị cập nhật"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Cần nhập mật khẩu để chuẩn bị cập nhật"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Yêu cầu hình mở khóa sau khi thiết bị khởi động lại"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Yêu cầu mã PIN sau khi thiết bị khởi động lại"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Yêu cầu mật khẩu sau khi thiết bị khởi động lại"</string> diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml index be162b0b5790..b4bff5fab6d6 100644 --- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"无服务。"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"切换输入法"</string> <string name="airplane_mode" msgid="2528005343938497866">"飞行模式"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"需要输入 PIN 码才能让设备做好更新准备"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"需要绘制解锁图案才能让设备做好更新准备"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"需要输入密码才能让设备做好更新准备"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"重启设备后需要绘制解锁图案"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"重启设备后需要输入 PIN 码"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"重启设备后需要输入密码"</string> diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml index 33e5b44ac31e..b3d387706fa5 100644 --- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"沒有服務。"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"轉換輸入方法"</string> <string name="airplane_mode" msgid="2528005343938497866">"飛行模式"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"必須提供 PIN 碼,才能準備進行更新"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"必須畫出上鎖圖案,才能準備進行更新"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"必須輸入密碼,才能準備進行更新"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"裝置重新啟動後,必須畫出上鎖圖案才能使用"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"裝置重新啟動後,必須輸入 PIN 碼才能使用"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"裝置重新啟動後,必須輸入密碼才能使用"</string> diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml index 763233cc2e15..03dec4852771 100644 --- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"沒有服務。"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"切換輸入法"</string> <string name="airplane_mode" msgid="2528005343938497866">"飛航模式"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"請輸入 PIN 碼,以便為更新作業進行準備"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"請畫出解鎖圖案,以便為更新作業進行準備"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"請輸入密碼,以便為更新作業進行準備"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"裝置重新啟動後需要畫出解鎖圖案"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"裝置重新啟動後需要輸入 PIN 碼"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"裝置重新啟動後需要輸入密碼"</string> diff --git a/packages/SystemUI/res-keyguard/values-zu/strings.xml b/packages/SystemUI/res-keyguard/values-zu/strings.xml index 397c868e6547..5ab567f706c3 100644 --- a/packages/SystemUI/res-keyguard/values-zu/strings.xml +++ b/packages/SystemUI/res-keyguard/values-zu/strings.xml @@ -101,9 +101,6 @@ <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ayikho isevisi"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Shintsha indlela yokufaka"</string> <string name="airplane_mode" msgid="2528005343938497866">"Imodi yendiza"</string> - <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Iphinikhodi iyadingeka ukuze kulungiselelwe isibuyekezo"</string> - <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Iphethini iyadingeka ukuze kulungiselelwe isibuyekezo"</string> - <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Iphasiwedi iyadingeka ukuze kulungiselelwe isibuyekezo"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Iphethini iyadingeka ngemuva kokuqala kabusha kwedivayisi"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Iphinikhodi iyadingeka ngemuva kokuqala kabusha kwedivayisi"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Iphasiwedi iyadingeka ngemuva kokuqala kabusha kwedivayisi"</string> diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml index 4d184d5758d3..f7e9fedd5f66 100644 --- a/packages/SystemUI/res-keyguard/values/strings.xml +++ b/packages/SystemUI/res-keyguard/values/strings.xml @@ -240,15 +240,6 @@ <!-- Description of airplane mode --> <string name="airplane_mode">Airplane mode</string> - <!-- An explanation text that the PIN needs to be entered to prepare for an operating system update. [CHAR LIMIT=80] --> - <string name="kg_prompt_reason_prepare_for_update_pin">PIN required to prepare for update</string> - - <!-- An explanation text that the pattern needs to be entered to prepare for an operating system update. [CHAR LIMIT=80] --> - <string name="kg_prompt_reason_prepare_for_update_pattern">Pattern required to prepare for update</string> - - <!-- An explanation text that the password needs to be entered to prepare for an operating system update. [CHAR LIMIT=80] --> - <string name="kg_prompt_reason_prepare_for_update_password">Password required to prepare for update</string> - <!-- An explanation text that the pattern needs to be solved since the device has just been restarted. [CHAR LIMIT=80] --> <string name="kg_prompt_reason_restart_pattern">Pattern required after device restarts</string> diff --git a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button_ccw_start_0.xml index 3304c19b1ed8..ff5cb9ef6b67 100644 --- a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml +++ b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button_ccw_start_0.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2017 The Android Open Source Project + Copyright (C) 2020 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ android:viewportHeight="28.0"> <!-- Use scaleX to flip icon so arrows always point in the direction of motion --> <group android:name="icon" android:pivotX="14" android:pivotY="14" - android:scaleX="?attr/rotateButtonScaleX"> + android:scaleX="1"> <!-- Tint color to be set directly --> <path android:fillColor="#FFFFFFFF" android:pathData="M12.02,10.83L9.25,8.06l2.77,-2.77l1.12,1.12l-0.85,0.86h5.16c0.72,0 1.31,0.56 1.31,1.26v9.16l-1.58,-1.58V8.85h-4.89l0.86,0.86L12.02,10.83zM15.98,17.17l-1.12,1.12l0.85,0.86h-4.88v-7.26L9.25,10.3v9.17c0,0.7 0.59,1.26 1.31,1.26h5.16v0.01l-0.85,0.85l1.12,1.12l2.77,-2.77L15.98,17.17z"/> @@ -107,8 +107,8 @@ <objectAnimator android:propertyName="rotation" android:startOffset="100" android:duration="600" - android:valueFrom="?attr/rotateButtonStartAngle" - android:valueTo="?attr/rotateButtonEndAngle"> + android:valueFrom="0" + android:valueTo="-90"> <aapt:attr name="android:interpolator"> <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> </aapt:attr> @@ -118,14 +118,14 @@ <objectAnimator android:propertyName="rotation" android:startOffset="1300" android:duration="100" - android:valueFrom="?attr/rotateButtonStartAngle" - android:valueTo="?attr/rotateButtonStartAngle"/> + android:valueFrom="0" + android:valueTo="0"/> <!-- Icon rotation with start timing offset after fade in --> <objectAnimator android:propertyName="rotation" android:duration="600" - android:valueFrom="?attr/rotateButtonStartAngle" - android:valueTo="?attr/rotateButtonEndAngle"> + android:valueFrom="0" + android:valueTo="-90"> <aapt:attr name="android:interpolator"> <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> </aapt:attr> @@ -135,14 +135,14 @@ <objectAnimator android:propertyName="rotation" android:startOffset="1300" android:duration="100" - android:valueFrom="?attr/rotateButtonStartAngle" - android:valueTo="?attr/rotateButtonStartAngle"/> + android:valueFrom="0" + android:valueTo="0"/> <!-- Icon rotation with start timing offset after fade in --> <objectAnimator android:propertyName="rotation" android:duration="600" - android:valueFrom="?attr/rotateButtonStartAngle" - android:valueTo="?attr/rotateButtonEndAngle"> + android:valueFrom="0" + android:valueTo="-90"> <aapt:attr name="android:interpolator"> <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> </aapt:attr> @@ -152,14 +152,14 @@ <objectAnimator android:propertyName="rotation" android:startOffset="1300" android:duration="100" - android:valueFrom="?attr/rotateButtonStartAngle" - android:valueTo="?attr/rotateButtonStartAngle"/> + android:valueFrom="0" + android:valueTo="0"/> <!-- Icon rotation with start timing offset after fade in --> <objectAnimator android:propertyName="rotation" android:duration="600" - android:valueFrom="?attr/rotateButtonStartAngle" - android:valueTo="?attr/rotateButtonEndAngle"> + android:valueFrom="0" + android:valueTo="-90"> <aapt:attr name="android:interpolator"> <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> </aapt:attr> @@ -169,14 +169,14 @@ <objectAnimator android:propertyName="rotation" android:startOffset="1300" android:duration="100" - android:valueFrom="?attr/rotateButtonStartAngle" - android:valueTo="?attr/rotateButtonStartAngle"/> + android:valueFrom="0" + android:valueTo="0"/> <!-- Icon rotation with start timing offset after fade in --> <objectAnimator android:propertyName="rotation" android:duration="600" - android:valueFrom="?attr/rotateButtonStartAngle" - android:valueTo="?attr/rotateButtonEndAngle"> + android:valueFrom="0" + android:valueTo="-90"> <aapt:attr name="android:interpolator"> <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> </aapt:attr> diff --git a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button_ccw_start_90.xml b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button_ccw_start_90.xml new file mode 100644 index 000000000000..90fedb17ecf1 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button_ccw_start_90.xml @@ -0,0 +1,187 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> + <aapt:attr name="android:drawable"> + <vector android:name="root" + android:width="28dp" + android:height="28dp" + android:viewportWidth="28.0" + android:viewportHeight="28.0"> + <!-- Use scaleX to flip icon so arrows always point in the direction of motion --> + <group android:name="icon" android:pivotX="14" android:pivotY="14" + android:scaleX="1"> + <!-- Tint color to be set directly --> + <path android:fillColor="#FFFFFFFF" + android:pathData="M12.02,10.83L9.25,8.06l2.77,-2.77l1.12,1.12l-0.85,0.86h5.16c0.72,0 1.31,0.56 1.31,1.26v9.16l-1.58,-1.58V8.85h-4.89l0.86,0.86L12.02,10.83zM15.98,17.17l-1.12,1.12l0.85,0.86h-4.88v-7.26L9.25,10.3v9.17c0,0.7 0.59,1.26 1.31,1.26h5.16v0.01l-0.85,0.85l1.12,1.12l2.77,-2.77L15.98,17.17z"/> + </group> + </vector> + </aapt:attr> + + <!-- Repeat all animations 5 times but don't fade out at the end --> + <target android:name="root"> + <aapt:attr name="android:animation"> + <set android:ordering="sequentially"> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + <!-- Linear fade out --> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="1700" + android:valueFrom="1" + android:valueTo="0" + android:interpolator="@android:anim/linear_interpolator"/> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + <!-- Linear fade out --> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="1700" + android:valueFrom="1" + android:valueTo="0" + android:interpolator="@android:anim/linear_interpolator"/> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + <!-- Linear fade out --> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="1700" + android:valueFrom="1" + android:valueTo="0" + android:interpolator="@android:anim/linear_interpolator"/> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + <!-- Linear fade out --> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="1700" + android:valueFrom="1" + android:valueTo="0" + android:interpolator="@android:anim/linear_interpolator"/> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + </set> + </aapt:attr> + </target> + <target android:name="icon"> + <aapt:attr name="android:animation"> + <set android:ordering="sequentially"> + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="100" + android:duration="600" + android:valueFrom="90" + android:valueTo="0"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + + <!-- Reset rotation position for fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="1300" + android:duration="100" + android:valueFrom="90" + android:valueTo="90"/> + + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:duration="600" + android:valueFrom="90" + android:valueTo="0"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + + <!-- Reset rotation position for fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="1300" + android:duration="100" + android:valueFrom="90" + android:valueTo="90"/> + + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:duration="600" + android:valueFrom="90" + android:valueTo="0"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + + <!-- Reset rotation position for fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="1300" + android:duration="100" + android:valueFrom="90" + android:valueTo="90"/> + + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:duration="600" + android:valueFrom="90" + android:valueTo="0"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + + <!-- Reset rotation position for fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="1300" + android:duration="100" + android:valueFrom="90" + android:valueTo="90"/> + + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:duration="600" + android:valueFrom="90" + android:valueTo="0"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> +</animated-vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button_cw_start_0.xml b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button_cw_start_0.xml new file mode 100644 index 000000000000..a89e7a34ad26 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button_cw_start_0.xml @@ -0,0 +1,187 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> + <aapt:attr name="android:drawable"> + <vector android:name="root" + android:width="28dp" + android:height="28dp" + android:viewportWidth="28.0" + android:viewportHeight="28.0"> + <!-- Use scaleX to flip icon so arrows always point in the direction of motion --> + <group android:name="icon" android:pivotX="14" android:pivotY="14" + android:scaleX="-1"> + <!-- Tint color to be set directly --> + <path android:fillColor="#FFFFFFFF" + android:pathData="M12.02,10.83L9.25,8.06l2.77,-2.77l1.12,1.12l-0.85,0.86h5.16c0.72,0 1.31,0.56 1.31,1.26v9.16l-1.58,-1.58V8.85h-4.89l0.86,0.86L12.02,10.83zM15.98,17.17l-1.12,1.12l0.85,0.86h-4.88v-7.26L9.25,10.3v9.17c0,0.7 0.59,1.26 1.31,1.26h5.16v0.01l-0.85,0.85l1.12,1.12l2.77,-2.77L15.98,17.17z"/> + </group> + </vector> + </aapt:attr> + + <!-- Repeat all animations 5 times but don't fade out at the end --> + <target android:name="root"> + <aapt:attr name="android:animation"> + <set android:ordering="sequentially"> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + <!-- Linear fade out --> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="1700" + android:valueFrom="1" + android:valueTo="0" + android:interpolator="@android:anim/linear_interpolator"/> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + <!-- Linear fade out --> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="1700" + android:valueFrom="1" + android:valueTo="0" + android:interpolator="@android:anim/linear_interpolator"/> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + <!-- Linear fade out --> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="1700" + android:valueFrom="1" + android:valueTo="0" + android:interpolator="@android:anim/linear_interpolator"/> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + <!-- Linear fade out --> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="1700" + android:valueFrom="1" + android:valueTo="0" + android:interpolator="@android:anim/linear_interpolator"/> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + </set> + </aapt:attr> + </target> + <target android:name="icon"> + <aapt:attr name="android:animation"> + <set android:ordering="sequentially"> + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="100" + android:duration="600" + android:valueFrom="0" + android:valueTo="90"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + + <!-- Reset rotation position for fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="1300" + android:duration="100" + android:valueFrom="0" + android:valueTo="0"/> + + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:duration="600" + android:valueFrom="0" + android:valueTo="90"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + + <!-- Reset rotation position for fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="1300" + android:duration="100" + android:valueFrom="0" + android:valueTo="0"/> + + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:duration="600" + android:valueFrom="0" + android:valueTo="90"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + + <!-- Reset rotation position for fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="1300" + android:duration="100" + android:valueFrom="0" + android:valueTo="0"/> + + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:duration="600" + android:valueFrom="0" + android:valueTo="90"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + + <!-- Reset rotation position for fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="1300" + android:duration="100" + android:valueFrom="0" + android:valueTo="0"/> + + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:duration="600" + android:valueFrom="0" + android:valueTo="90"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> +</animated-vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button_cw_start_90.xml b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button_cw_start_90.xml new file mode 100644 index 000000000000..0dc67b0d22af --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button_cw_start_90.xml @@ -0,0 +1,187 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> + <aapt:attr name="android:drawable"> + <vector android:name="root" + android:width="28dp" + android:height="28dp" + android:viewportWidth="28.0" + android:viewportHeight="28.0"> + <!-- Use scaleX to flip icon so arrows always point in the direction of motion --> + <group android:name="icon" android:pivotX="14" android:pivotY="14" + android:scaleX="-1"> + <!-- Tint color to be set directly --> + <path android:fillColor="#FFFFFFFF" + android:pathData="M12.02,10.83L9.25,8.06l2.77,-2.77l1.12,1.12l-0.85,0.86h5.16c0.72,0 1.31,0.56 1.31,1.26v9.16l-1.58,-1.58V8.85h-4.89l0.86,0.86L12.02,10.83zM15.98,17.17l-1.12,1.12l0.85,0.86h-4.88v-7.26L9.25,10.3v9.17c0,0.7 0.59,1.26 1.31,1.26h5.16v0.01l-0.85,0.85l1.12,1.12l2.77,-2.77L15.98,17.17z"/> + </group> + </vector> + </aapt:attr> + + <!-- Repeat all animations 5 times but don't fade out at the end --> + <target android:name="root"> + <aapt:attr name="android:animation"> + <set android:ordering="sequentially"> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + <!-- Linear fade out --> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="1700" + android:valueFrom="1" + android:valueTo="0" + android:interpolator="@android:anim/linear_interpolator"/> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + <!-- Linear fade out --> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="1700" + android:valueFrom="1" + android:valueTo="0" + android:interpolator="@android:anim/linear_interpolator"/> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + <!-- Linear fade out --> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="1700" + android:valueFrom="1" + android:valueTo="0" + android:interpolator="@android:anim/linear_interpolator"/> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + <!-- Linear fade out --> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="1700" + android:valueFrom="1" + android:valueTo="0" + android:interpolator="@android:anim/linear_interpolator"/> + <!-- Linear fade in--> + <objectAnimator android:propertyName="alpha" + android:duration="100" + android:startOffset="100" + android:valueFrom="0" + android:valueTo="1" + android:interpolator="@android:anim/linear_interpolator" /> + </set> + </aapt:attr> + </target> + <target android:name="icon"> + <aapt:attr name="android:animation"> + <set android:ordering="sequentially"> + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="100" + android:duration="600" + android:valueFrom="90" + android:valueTo="180"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + + <!-- Reset rotation position for fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="1300" + android:duration="100" + android:valueFrom="90" + android:valueTo="90"/> + + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:duration="600" + android:valueFrom="90" + android:valueTo="180"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + + <!-- Reset rotation position for fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="1300" + android:duration="100" + android:valueFrom="90" + android:valueTo="90"/> + + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:duration="600" + android:valueFrom="90" + android:valueTo="180"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + + <!-- Reset rotation position for fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="1300" + android:duration="100" + android:valueFrom="90" + android:valueTo="90"/> + + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:duration="600" + android:valueFrom="90" + android:valueTo="180"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + + <!-- Reset rotation position for fade in --> + <objectAnimator android:propertyName="rotation" + android:startOffset="1300" + android:duration="100" + android:valueFrom="90" + android:valueTo="90"/> + + <!-- Icon rotation with start timing offset after fade in --> + <objectAnimator android:propertyName="rotation" + android:duration="600" + android:valueFrom="90" + android:valueTo="180"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> +</animated-vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-af/strings_tv.xml b/packages/SystemUI/res/values-af/strings_tv.xml index 2ea6c60ab1b8..f277529397f6 100644 --- a/packages/SystemUI/res/values-af/strings_tv.xml +++ b/packages/SystemUI/res/values-af/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Beeld-in-beeld"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Titellose program)"</string> - <string name="pip_close" msgid="5775212044472849930">"Maak PIP toe"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Volskerm"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofoon aktief"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s het toegang tot jou mikrofoon"</string> </resources> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index f09a7e719332..300ca0e5b141 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -917,17 +917,13 @@ <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ገጽ <xliff:g id="ID_1">%1$d</xliff:g> ከ <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"ማያ ገጽ ቁልፍ"</string> <string name="thermal_shutdown_title" msgid="2702966892682930264">"ስልክ በሙቀት ምክንያት ጠፍቷል"</string> - <!-- no translation found for thermal_shutdown_message (6142269839066172984) --> - <skip /> + <string name="thermal_shutdown_message" msgid="6142269839066172984">"የእርስዎ ስልክ በመደበኛ ሁኔታ እየሠራ ነው።\nለተጨማሪ መረጃ መታ ያድርጉ"</string> <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"የእርስዎ ስልክ በጣም ግሎ ነበር፣ ስለዚህ እንዲቀዘቅዝ ጠፍቷል። የእርስዎ ስልክ አሁን በመደበኝነት እያሄደ ነው።\n\nየሚከተሉትን ካደረጉ የእርስዎ በጣም ሊግል ይችላል፦\n • ኃይል በጣም የሚጠቀሙ መተግበሪያዎችን (እንደ ጨዋታ፣ ቪዲዮ ወይም የአሰሳ መተግበሪያዎች ያሉ) ከተጠቀሙ\n • ትላልቅ ፋይሎችን ካወረዱ ወይም ከሰቀሉ\n • ስልክዎን በከፍተኛ ሙቀት ውስጥ ከተጠቀሙ"</string> - <!-- no translation found for thermal_shutdown_dialog_help_text (6413474593462902901) --> - <skip /> + <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"የእንክብካቤ ደረጃዎችን ይመልከቱ"</string> <string name="high_temp_title" msgid="2218333576838496100">"ስልኩ እየሞቀ ነው"</string> - <!-- no translation found for high_temp_notif_message (1277346543068257549) --> - <skip /> + <string name="high_temp_notif_message" msgid="1277346543068257549">"አንዳንድ ባሕሪያት ስልኩ እየቀዘቀዘ እያለ ውስን ይሆናሉ።\nለተጨማሪ መረጃ መታ ያድርጉ"</string> <string name="high_temp_dialog_message" msgid="3793606072661253968">"የእርስዎ ስልክ በራስ-ሰር ለመቀዝቀዝ ይሞክራል። አሁንም ስልክዎን መጠቀም ይችላሉ፣ ነገር ግን ሊንቀራፈፍ ይችላል።\n\nአንዴ ስልክዎ ከቀዘቀዘ በኋላ በመደበኝነት ያሄዳል።"</string> - <!-- no translation found for high_temp_dialog_help_text (7380171287943345858) --> - <skip /> + <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"የእንክብካቤ ደረጃዎችን ይመልከቱ"</string> <string name="high_temp_alarm_title" msgid="2359958549570161495">"ኃይል መሙያን ይንቀሉ"</string> <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"የዚህን መሣሪያ ባትሪ መሙላት ላይ ችግር አለ። የኃይል አስማሚውን ይንቀሉትና ሊግል ስለሚችል ገመዱን ይጠብቁት።"</string> <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"የእንክብካቤ ደረጃዎችን ይመልከቱ"</string> diff --git a/packages/SystemUI/res/values-am/strings_tv.xml b/packages/SystemUI/res/values-am/strings_tv.xml index 83e3fd9f539f..d9ec459d06f7 100644 --- a/packages/SystemUI/res/values-am/strings_tv.xml +++ b/packages/SystemUI/res/values-am/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"ስዕል-ላይ-ስዕል"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(ርዕስ የሌለው ፕሮግራም)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIPን ዝጋ"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"ሙሉ ማያ ገጽ"</string> <string name="mic_active" msgid="5766614241012047024">"ማይክራፎን ንቁ ነው"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s የእርስዎን ማይክራፎን ደርሶበታል"</string> </resources> diff --git a/packages/SystemUI/res/values-ar/strings_tv.xml b/packages/SystemUI/res/values-ar/strings_tv.xml index 76403ab1a4ee..c29d804f841f 100644 --- a/packages/SystemUI/res/values-ar/strings_tv.xml +++ b/packages/SystemUI/res/values-ar/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"نافذة ضمن النافذة"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(ليس هناك عنوان للبرنامج)"</string> - <string name="pip_close" msgid="5775212044472849930">"إغلاق PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"ملء الشاشة"</string> <string name="mic_active" msgid="5766614241012047024">"الميكروفون نشط"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"تمكن %1$s من الوصول إلى الميكروفون الخاص بك."</string> </resources> diff --git a/packages/SystemUI/res/values-as/strings_tv.xml b/packages/SystemUI/res/values-as/strings_tv.xml index 2076c99bf901..1db8f2297cc3 100644 --- a/packages/SystemUI/res/values-as/strings_tv.xml +++ b/packages/SystemUI/res/values-as/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"চিত্ৰৰ ভিতৰত চিত্ৰ"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(শিৰোনামবিহীন কাৰ্যক্ৰম)"</string> - <string name="pip_close" msgid="5775212044472849930">"পিপ বন্ধ কৰক"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"সম্পূৰ্ণ স্ক্ৰীণ"</string> <string name="mic_active" msgid="5766614241012047024">"মাইক্ৰ’ফ’ন সক্ৰিয় কৰা আছে"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$sএ আপোনাৰ মাইক্ৰ’ফ’ন এক্সেছ কৰিছে"</string> </resources> diff --git a/packages/SystemUI/res/values-az/strings_tv.xml b/packages/SystemUI/res/values-az/strings_tv.xml index e4e8880df847..d690c642488f 100644 --- a/packages/SystemUI/res/values-az/strings_tv.xml +++ b/packages/SystemUI/res/values-az/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Şəkil-içində-Şəkil"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Başlıqsız proqram)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP bağlayın"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Tam ekran"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofon Aktivdir"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s mikrofona daxil olub"</string> </resources> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml index 4e2d610da4c5..d045ceaa4fca 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Slika u slici"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Program bez naslova)"</string> - <string name="pip_close" msgid="5775212044472849930">"Zatvori PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Ceo ekran"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofon je aktivan"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikacija %1$s je pristupila mikrofonu"</string> </resources> diff --git a/packages/SystemUI/res/values-be/strings_tv.xml b/packages/SystemUI/res/values-be/strings_tv.xml index c75a49236e04..37f925e1fae1 100644 --- a/packages/SystemUI/res/values-be/strings_tv.xml +++ b/packages/SystemUI/res/values-be/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Відарыс у відарысе"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Праграма без назвы)"</string> - <string name="pip_close" msgid="5775212044472849930">"Закрыць PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Ва ўвесь экран"</string> <string name="mic_active" msgid="5766614241012047024">"Мікрафон актыўны"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"Праграма \"%1$s\" атрымала доступ да мікрафона"</string> </resources> diff --git a/packages/SystemUI/res/values-bg/strings_tv.xml b/packages/SystemUI/res/values-bg/strings_tv.xml index 6d2b842117f1..f322079f77a1 100644 --- a/packages/SystemUI/res/values-bg/strings_tv.xml +++ b/packages/SystemUI/res/values-bg/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Картина в картината"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Програма без заглавие)"</string> - <string name="pip_close" msgid="5775212044472849930">"Затваряне на PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Цял екран"</string> <string name="mic_active" msgid="5766614241012047024">"Микрофонът е активен"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s осъществи достъп до микрофона ви"</string> </resources> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 1be233d02876..a584955b534d 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -76,7 +76,7 @@ <string name="learn_more" msgid="4690632085667273811">"আরও জানুন"</string> <string name="compat_mode_on" msgid="4963711187149440884">"স্ক্রীণ পূরণ করতে জুম করুন"</string> <string name="compat_mode_off" msgid="7682459748279487945">"ফুল স্ক্রিন করুন"</string> - <string name="global_action_screenshot" msgid="2760267567509131654">"স্ক্রিনশট"</string> + <string name="global_action_screenshot" msgid="2760267567509131654">"স্ক্রিনশট নিন"</string> <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"একটি ছবি পাঠানো হয়েছে"</string> <string name="screenshot_saving_ticker" msgid="6519186952674544916">"স্ক্রিনশট সেভ করা হচ্ছে..."</string> <string name="screenshot_saving_title" msgid="2298349784913287333">"স্ক্রিনশট সেভ করা হচ্ছে..."</string> @@ -917,17 +917,13 @@ <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>টির মধ্যে <xliff:g id="ID_1">%1$d</xliff:g> নং পৃষ্ঠা"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"লক স্ক্রিন"</string> <string name="thermal_shutdown_title" msgid="2702966892682930264">"আপনার ফোন গরম হওয়ার জন্য বন্ধ হয়ে গেছে"</string> - <!-- no translation found for thermal_shutdown_message (6142269839066172984) --> - <skip /> + <string name="thermal_shutdown_message" msgid="6142269839066172984">"আপনার ফোন এখন ভালভাবে কাজ করছে।\nআরও তথ্যের জন্য ট্যাপ করুন"</string> <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"আপনার ফোন খুব বেশি গরম হয়েছিল বলে ঠাণ্ডা হওয়ার জন্য বন্ধ হয়ে গেছে। আপনার ফোন ঠিক-ঠাক ভাবে চলছে না।\n\nআপনার ফোন খুব বেশি গরম হয়ে যাবে যদি আপনি:\n •এমন অ্যাপ ব্যবহার করলে যেটি আপনার ডিভাইসের রিসোর্স বেশি ব্যবহার করে (যেমন গেমিং, ভিডিও বা নেভিগেশন অ্যাপ)\n • বড় ফাইল ডাউনলোড বা আপলোড করলে\n • বেশি তাপমাত্রায় আপনার ফোন ব্যবহার করলে"</string> - <!-- no translation found for thermal_shutdown_dialog_help_text (6413474593462902901) --> - <skip /> + <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ডিভাইস রক্ষণাবেক্ষণের ধাপগুলি দেখুন"</string> <string name="high_temp_title" msgid="2218333576838496100">"ফোনটি গরম হচ্ছে"</string> - <!-- no translation found for high_temp_notif_message (1277346543068257549) --> - <skip /> + <string name="high_temp_notif_message" msgid="1277346543068257549">"ফোন ঠাণ্ডা না হওয়া পর্যন্ত কিছু ফিচার কাজ করে না।\nআরও তথ্যের জন্য ট্যাপ করুন"</string> <string name="high_temp_dialog_message" msgid="3793606072661253968">"আপনার ফোনটি নিজে থেকেই ঠাণ্ডা হওয়ার চেষ্টা করবে৷ আপনি তবুও আপনার ফোন ব্যবহার করতে পারেন, কিন্তু এটি একটু ধীরে চলতে পারে৷\n\nআপনার ফোনটি পুরোপুরি ঠাণ্ডা হয়ে গেলে এটি স্বাভাবিকভাবে চলবে৷"</string> - <!-- no translation found for high_temp_dialog_help_text (7380171287943345858) --> - <skip /> + <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ডিভাইস রক্ষণাবেক্ষণের ধাপগুলি দেখুন"</string> <string name="high_temp_alarm_title" msgid="2359958549570161495">"চার্জার আনপ্লাগ করুন"</string> <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"এই ডিভাইস চার্জ করার সময় সমস্যা হয়েছে। চার্জিং কেবলটি হয়ত গরম হয়ে গেছে, পাওয়ার অ্যাডাপ্টারটি আনপ্লাগ করুন।"</string> <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"কী করতে হবে ধাপে ধাপে দেখুন"</string> diff --git a/packages/SystemUI/res/values-bn/strings_tv.xml b/packages/SystemUI/res/values-bn/strings_tv.xml index 795314c4b15c..56ca0233ae45 100644 --- a/packages/SystemUI/res/values-bn/strings_tv.xml +++ b/packages/SystemUI/res/values-bn/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"ছবির-মধ্যে-ছবি"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(শিরোনামহীন প্রোগ্রাম)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP বন্ধ করুন"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"পূর্ণ স্ক্রিন"</string> <string name="mic_active" msgid="5766614241012047024">"মাইক্রোফোন চালু আছে"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s আপনার ডিভাইসের মাইক্রোফোন অ্যাক্সেস করেছে"</string> </resources> diff --git a/packages/SystemUI/res/values-bs/strings_tv.xml b/packages/SystemUI/res/values-bs/strings_tv.xml index 1dd803516841..acd93d657bac 100644 --- a/packages/SystemUI/res/values-bs/strings_tv.xml +++ b/packages/SystemUI/res/values-bs/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Slika u slici"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Program bez naslova)"</string> - <string name="pip_close" msgid="5775212044472849930">"Zatvori PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Cijeli ekran"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofon je aktivan"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikacija %1$s je pristupila vašem mikrofonu"</string> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 61b8e814eacb..7267c31b1f36 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -21,7 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4811759950673118541">"IU del sistema"</string> <string name="status_bar_clear_all_button" msgid="2491321682873657397">"Esborra"</string> - <string name="status_bar_no_notifications_title" msgid="7812479124981107507">"Cap notificació"</string> + <string name="status_bar_no_notifications_title" msgid="7812479124981107507">"No hi ha cap notificació"</string> <string name="status_bar_ongoing_events_title" msgid="3986169317496615446">"Continu"</string> <string name="status_bar_latest_events_title" msgid="202755896454005436">"Notificacions"</string> <string name="battery_low_title" msgid="6891106956328275225">"És possible que la bateria s\'esgoti aviat"</string> @@ -517,7 +517,7 @@ <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Esborra totes les notificacions silencioses"</string> <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificacions pausades pel mode No molestis"</string> <string name="media_projection_action_text" msgid="3634906766918186440">"Comença ara"</string> - <string name="empty_shade_text" msgid="8935967157319717412">"Cap notificació"</string> + <string name="empty_shade_text" msgid="8935967157319717412">"No hi ha cap notificació"</string> <string name="profile_owned_footer" msgid="2756770645766113964">"El perfil es pot supervisar"</string> <string name="vpn_footer" msgid="3457155078010607471">"És possible que la xarxa estigui supervisada."</string> <string name="branded_vpn_footer" msgid="816930186313188514">"És possible que la xarxa estigui supervisada"</string> diff --git a/packages/SystemUI/res/values-ca/strings_tv.xml b/packages/SystemUI/res/values-ca/strings_tv.xml index 44cc9410ed0b..c41d5714e60e 100644 --- a/packages/SystemUI/res/values-ca/strings_tv.xml +++ b/packages/SystemUI/res/values-ca/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Pantalla en pantalla"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Programa sense títol)"</string> - <string name="pip_close" msgid="5775212044472849930">"Tanca PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Pantalla completa"</string> <string name="mic_active" msgid="5766614241012047024">"Micròfon actiu"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ha accedit al teu micròfon"</string> </resources> diff --git a/packages/SystemUI/res/values-cs/strings_tv.xml b/packages/SystemUI/res/values-cs/strings_tv.xml index 0494bc12b469..2d95d46a078f 100644 --- a/packages/SystemUI/res/values-cs/strings_tv.xml +++ b/packages/SystemUI/res/values-cs/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Obraz v obraze"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Bez názvu)"</string> - <string name="pip_close" msgid="5775212044472849930">"Ukončit obraz v obraze (PIP)"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Celá obrazovka"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofon je aktivní"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikace %1$s použila mikrofon"</string> </resources> diff --git a/packages/SystemUI/res/values-da/strings_tv.xml b/packages/SystemUI/res/values-da/strings_tv.xml index 5b8bf6c9c2c4..f70427d90cd0 100644 --- a/packages/SystemUI/res/values-da/strings_tv.xml +++ b/packages/SystemUI/res/values-da/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Integreret billede"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Program uden titel)"</string> - <string name="pip_close" msgid="5775212044472849930">"Luk integreret billede"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Fuld skærm"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofonen er slået til"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s fik adgang til din mikrofon"</string> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index ccb7d14395b6..52275fcd637e 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -917,17 +917,13 @@ <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Seite <xliff:g id="ID_1">%1$d</xliff:g> von <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Sperrbildschirm"</string> <string name="thermal_shutdown_title" msgid="2702966892682930264">"Ausgeschaltet, da zu heiß"</string> - <!-- no translation found for thermal_shutdown_message (6142269839066172984) --> - <skip /> + <string name="thermal_shutdown_message" msgid="6142269839066172984">"Dein Smartphone funktioniert jetzt wieder normal.\nFür mehr Informationen tippen."</string> <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Dein Smartphone war zu heiß und wurde zum Abkühlen ausgeschaltet. Nun funktioniert es wieder normal.\n\nMögliche Ursachen:\n • Verwendung ressourcenintensiver Apps (z. B. Spiele-, Video- oder Navigations-Apps)\n • Download oder Upload großer Dateien \n • Verwendung des Smartphones bei hohen Temperaturen"</string> - <!-- no translation found for thermal_shutdown_dialog_help_text (6413474593462902901) --> - <skip /> + <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Schritte zur Abkühlung des Geräts ansehen"</string> <string name="high_temp_title" msgid="2218333576838496100">"Smartphone wird warm"</string> - <!-- no translation found for high_temp_notif_message (1277346543068257549) --> - <skip /> + <string name="high_temp_notif_message" msgid="1277346543068257549">"Einige Funktionen sind während der Abkühlphase des Smartphones eingeschränkt.\nFür mehr Informationen tippen."</string> <string name="high_temp_dialog_message" msgid="3793606072661253968">"Dein Smartphone kühlt sich automatisch ab. Du kannst dein Smartphone weiterhin nutzen, aber es reagiert möglicherweise langsamer.\n\nSobald dein Smartphone abgekühlt ist, funktioniert es wieder normal."</string> - <!-- no translation found for high_temp_dialog_help_text (7380171287943345858) --> - <skip /> + <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Schritte zur Abkühlung des Geräts ansehen"</string> <string name="high_temp_alarm_title" msgid="2359958549570161495">"Ladegerät vom Stromnetz trennen"</string> <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"Beim Laden dieses Geräts ist ein Problem aufgetreten. Trenne das Netzteil vom Stromnetz. Sei dabei vorsichtig, denn das Netzteil oder das Kabel könnte heiß sein."</string> <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"Schritte zur Fehlerbehebung ansehen"</string> diff --git a/packages/SystemUI/res/values-de/strings_tv.xml b/packages/SystemUI/res/values-de/strings_tv.xml index ba2052840c10..b947b2ce1336 100644 --- a/packages/SystemUI/res/values-de/strings_tv.xml +++ b/packages/SystemUI/res/values-de/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Bild im Bild"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Kein Sendungsname gefunden)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP schließen"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Vollbild"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofon aktiv"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s hat auf dein Mikrofon zugegriffen"</string> </resources> diff --git a/packages/SystemUI/res/values-el/strings_tv.xml b/packages/SystemUI/res/values-el/strings_tv.xml index 5f93f3246f82..d03961366a2c 100644 --- a/packages/SystemUI/res/values-el/strings_tv.xml +++ b/packages/SystemUI/res/values-el/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Λειτουργία Picture-in-picture"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Δεν υπάρχει τίτλος προγράμματος)"</string> - <string name="pip_close" msgid="5775212044472849930">"Κλείσιμο PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Πλήρης οθόνη"</string> <string name="mic_active" msgid="5766614241012047024">"Ενεργό μικρόφωνο"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"Πραγματοποιήθηκε πρόσβαση στο μικρόφωνό σας από το %1$s"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rAU/strings_tv.xml b/packages/SystemUI/res/values-en-rAU/strings_tv.xml index efbaa1c42e60..f81611fba4a5 100644 --- a/packages/SystemUI/res/values-en-rAU/strings_tv.xml +++ b/packages/SystemUI/res/values-en-rAU/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Picture-in-picture"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(No title program)"</string> - <string name="pip_close" msgid="5775212044472849930">"Close PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Full screen"</string> <string name="mic_active" msgid="5766614241012047024">"Microphone active"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s accessed your microphone"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rCA/strings_tv.xml b/packages/SystemUI/res/values-en-rCA/strings_tv.xml index efbaa1c42e60..f81611fba4a5 100644 --- a/packages/SystemUI/res/values-en-rCA/strings_tv.xml +++ b/packages/SystemUI/res/values-en-rCA/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Picture-in-picture"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(No title program)"</string> - <string name="pip_close" msgid="5775212044472849930">"Close PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Full screen"</string> <string name="mic_active" msgid="5766614241012047024">"Microphone active"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s accessed your microphone"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rGB/strings_tv.xml b/packages/SystemUI/res/values-en-rGB/strings_tv.xml index efbaa1c42e60..f81611fba4a5 100644 --- a/packages/SystemUI/res/values-en-rGB/strings_tv.xml +++ b/packages/SystemUI/res/values-en-rGB/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Picture-in-picture"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(No title program)"</string> - <string name="pip_close" msgid="5775212044472849930">"Close PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Full screen"</string> <string name="mic_active" msgid="5766614241012047024">"Microphone active"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s accessed your microphone"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rIN/strings_tv.xml b/packages/SystemUI/res/values-en-rIN/strings_tv.xml index efbaa1c42e60..f81611fba4a5 100644 --- a/packages/SystemUI/res/values-en-rIN/strings_tv.xml +++ b/packages/SystemUI/res/values-en-rIN/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Picture-in-picture"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(No title program)"</string> - <string name="pip_close" msgid="5775212044472849930">"Close PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Full screen"</string> <string name="mic_active" msgid="5766614241012047024">"Microphone active"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s accessed your microphone"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rXC/strings_tv.xml b/packages/SystemUI/res/values-en-rXC/strings_tv.xml index 1ca2385af9c4..88c5843b7c96 100644 --- a/packages/SystemUI/res/values-en-rXC/strings_tv.xml +++ b/packages/SystemUI/res/values-en-rXC/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Picture-in-Picture"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(No title program)"</string> - <string name="pip_close" msgid="5775212044472849930">"Close PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Full screen"</string> <string name="mic_active" msgid="5766614241012047024">"Microphone Active"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s accessed your microphone"</string> </resources> diff --git a/packages/SystemUI/res/values-es-rUS/strings_tv.xml b/packages/SystemUI/res/values-es-rUS/strings_tv.xml index 3921fd822e57..8e9e048b06f6 100644 --- a/packages/SystemUI/res/values-es-rUS/strings_tv.xml +++ b/packages/SystemUI/res/values-es-rUS/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Pantalla en pantalla"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Sin título de programa)"</string> - <string name="pip_close" msgid="5775212044472849930">"Cerrar PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Pantalla completa"</string> <string name="mic_active" msgid="5766614241012047024">"Micrófono activado"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s accedió al micrófono"</string> </resources> diff --git a/packages/SystemUI/res/values-es/strings_tv.xml b/packages/SystemUI/res/values-es/strings_tv.xml index e18d9b6075bc..6a72a3d3a77e 100644 --- a/packages/SystemUI/res/values-es/strings_tv.xml +++ b/packages/SystemUI/res/values-es/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Imagen en imagen"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Programa sin título)"</string> - <string name="pip_close" msgid="5775212044472849930">"Cerrar PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Pantalla completa"</string> <string name="mic_active" msgid="5766614241012047024">"Micrófono activado"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ha accedido a tu micrófono"</string> </resources> diff --git a/packages/SystemUI/res/values-et/strings_tv.xml b/packages/SystemUI/res/values-et/strings_tv.xml index f36d8ec89eed..61c14356809b 100644 --- a/packages/SystemUI/res/values-et/strings_tv.xml +++ b/packages/SystemUI/res/values-et/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Pilt pildis"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Programmi pealkiri puudub)"</string> - <string name="pip_close" msgid="5775212044472849930">"Sule PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Täisekraan"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofon on aktiivne"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s pääses teie mikrofonile juurde"</string> </resources> diff --git a/packages/SystemUI/res/values-eu/strings_tv.xml b/packages/SystemUI/res/values-eu/strings_tv.xml index bdd1ffadf652..e77de5015fa1 100644 --- a/packages/SystemUI/res/values-eu/strings_tv.xml +++ b/packages/SystemUI/res/values-eu/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Pantaila txiki gainjarria"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Programa izengabea)"</string> - <string name="pip_close" msgid="5775212044472849930">"Itxi PIPa"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Pantaila osoa"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofonoa aktibatuta dago"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s aplikazioak mikrofonoa atzitu du"</string> </resources> diff --git a/packages/SystemUI/res/values-fa/strings_tv.xml b/packages/SystemUI/res/values-fa/strings_tv.xml index fb6d42c2e3ba..bf3987d6e10d 100644 --- a/packages/SystemUI/res/values-fa/strings_tv.xml +++ b/packages/SystemUI/res/values-fa/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"تصویر در تصویر"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(برنامه بدون عنوان)"</string> - <string name="pip_close" msgid="5775212044472849930">"بستن PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"تمام صفحه"</string> <string name="mic_active" msgid="5766614241012047024">"میکروفون فعال است"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s به میکروفون شما دسترسی پیدا کرد"</string> </resources> diff --git a/packages/SystemUI/res/values-fi/strings_tv.xml b/packages/SystemUI/res/values-fi/strings_tv.xml index e22a1660db0c..0b1f02f4cad4 100644 --- a/packages/SystemUI/res/values-fi/strings_tv.xml +++ b/packages/SystemUI/res/values-fi/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Kuva kuvassa"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Nimetön)"</string> - <string name="pip_close" msgid="5775212044472849930">"Sulje PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Koko näyttö"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofoni aktiivinen"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s sai pääsyn mikrofoniisi"</string> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml index abf4c1916d29..23dd656c431f 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Incrustation d\'image"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Aucun programme de titre)"</string> - <string name="pip_close" msgid="5775212044472849930">"Fermer mode IDI"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Plein écran"</string> <string name="mic_active" msgid="5766614241012047024">"Microphone actif"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s a accédé à votre microphone"</string> </resources> diff --git a/packages/SystemUI/res/values-fr/strings_tv.xml b/packages/SystemUI/res/values-fr/strings_tv.xml index 1fc43a1cff4a..4ab6a24b1aca 100644 --- a/packages/SystemUI/res/values-fr/strings_tv.xml +++ b/packages/SystemUI/res/values-fr/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Picture-in-Picture (PIP)"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Programme sans titre)"</string> - <string name="pip_close" msgid="5775212044472849930">"Fermer mode PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Plein écran"</string> <string name="mic_active" msgid="5766614241012047024">"Micro actif"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s a accédé à votre micro"</string> </resources> diff --git a/packages/SystemUI/res/values-gl/strings_tv.xml b/packages/SystemUI/res/values-gl/strings_tv.xml index 9455f956e890..123a86ef8322 100644 --- a/packages/SystemUI/res/values-gl/strings_tv.xml +++ b/packages/SystemUI/res/values-gl/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Pantalla superposta"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Programa sen título)"</string> - <string name="pip_close" msgid="5775212044472849930">"Pechar PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Pantalla completa"</string> <string name="mic_active" msgid="5766614241012047024">"Micrófono activo"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s accedeu ao teu micrófono"</string> </resources> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 6860c28eb276..5d3d3af8f917 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -917,17 +917,13 @@ <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> માંથી <xliff:g id="ID_1">%1$d</xliff:g> પૃષ્ઠ"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"લૉક સ્ક્રીન"</string> <string name="thermal_shutdown_title" msgid="2702966892682930264">"ફોન વધુ પડતી ગરમીને લીધે બંધ થઇ ગયો છે"</string> - <!-- no translation found for thermal_shutdown_message (6142269839066172984) --> - <skip /> + <string name="thermal_shutdown_message" msgid="6142269839066172984">"તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે.\nવધુ માહિતી માટે ટૅપ કરો"</string> <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"તમારો ફોન અત્યંત ગરમ હતો, તેથી તે ઠંડો થવા આપમેળે બંધ થઇ ગયો છે. તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે.\n\nતમારો ફોન અત્યંત ગરમ થઇ શકે છે, જો તમે:\n • એવી ઍપ્લિકેશન વાપરતા હો જે સંસાધન સઘન રીતે વાપરતી હોય (જેમ કે ગેમિંગ, વીડિઓ, અથવા નેવિગેટ કરતી ઍપ્લિકેશનો)\n • મોટી ફાઇલો અપલોડ અથવા ડાઉનલોડ કરતા હો\n • તમારા ફોનનો ઉપયોગ ઉચ્ચ તાપમાનમાં કરતા હો"</string> - <!-- no translation found for thermal_shutdown_dialog_help_text (6413474593462902901) --> - <skip /> + <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"સારસંભાળના પગલાં જુઓ"</string> <string name="high_temp_title" msgid="2218333576838496100">"ફોન ગરમ થઈ રહ્યો છે"</string> - <!-- no translation found for high_temp_notif_message (1277346543068257549) --> - <skip /> + <string name="high_temp_notif_message" msgid="1277346543068257549">"ફોન ઠંડો થાય ત્યાં સુધી અમુક સુવિધાઓ મર્યાદિત હોય છે.\nવધુ માહિતી માટે ટૅપ કરો"</string> <string name="high_temp_dialog_message" msgid="3793606072661253968">"તમારો ફોન આપમેળે ઠંડો થવાનો પ્રયાસ કરશે. તમે હજી પણ તમારા ફોનનો ઉપયોગ કરી શકો છો, પરંતુ તે કદાચ થોડો ધીમો ચાલે.\n\nતમારો ફોન ઠંડો થઈ જવા પર, તે સામાન્ય રીતે ચાલશે."</string> - <!-- no translation found for high_temp_dialog_help_text (7380171287943345858) --> - <skip /> + <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"સારસંભાળના પગલાં જુઓ"</string> <string name="high_temp_alarm_title" msgid="2359958549570161495">"ચાર્જરને અનપ્લગ કરો"</string> <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"આ ડિવાઇસને ચાર્જ કરવામાં કોઈ સમસ્યા છે. પાવર અડૅપ્ટર અનપ્લગ કરો અને કાળજી લેજો કદાચ કેબલ થોડો ગરમ થયો હોઈ શકે છે."</string> <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"સારસંભાળના પગલાં જુઓ"</string> diff --git a/packages/SystemUI/res/values-gu/strings_tv.xml b/packages/SystemUI/res/values-gu/strings_tv.xml index 3ea64873a856..72a6803aa202 100644 --- a/packages/SystemUI/res/values-gu/strings_tv.xml +++ b/packages/SystemUI/res/values-gu/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"ચિત્રમાં-ચિત્ર"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(કોઈ ટાઇટલ પ્રોગ્રામ નથી)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP બંધ કરો"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"પૂર્ણ સ્ક્રીન"</string> <string name="mic_active" msgid="5766614241012047024">"માઇક્રોફોન સક્રિય છે"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$sએ તમારો માઇક્રોફોન ઍક્સેસ કર્યો હતો"</string> </resources> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 2b8c9832d7f8..f6bc4cdab087 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -370,7 +370,7 @@ <string name="quick_settings_location_off_label" msgid="7923929131443915919">"जगह की जानकारी बंद है"</string> <string name="quick_settings_media_device_label" msgid="8034019242363789941">"मीडिया डिवाइस"</string> <string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string> - <string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"केवल आपातकालीन कॉल"</string> + <string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"सिर्फ़ आपातकालीन कॉल"</string> <string name="quick_settings_settings_label" msgid="2214639529565474534">"सेटिंग"</string> <string name="quick_settings_time_label" msgid="3352680970557509303">"समय"</string> <string name="quick_settings_user_label" msgid="1253515509432672496">"मुझे"</string> @@ -519,7 +519,7 @@ <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"बिना आवाज़ की सभी सूचनाएं हटाएं"</string> <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'परेशान न करें\' सुविधा के ज़रिए कुछ समय के लिए सूचनाएं दिखाना रोक दिया गया है"</string> <string name="media_projection_action_text" msgid="3634906766918186440">"अभी शुरू करें"</string> - <string name="empty_shade_text" msgid="8935967157319717412">"कोई सूचना नहीं मिली"</string> + <string name="empty_shade_text" msgid="8935967157319717412">"कोई सूचना नहीं है"</string> <string name="profile_owned_footer" msgid="2756770645766113964">"प्रोफ़ाइल को मॉनीटर किया जा सकता है"</string> <string name="vpn_footer" msgid="3457155078010607471">"नेटवर्क को मॉनीटर किया जा सकता है"</string> <string name="branded_vpn_footer" msgid="816930186313188514">"नेटवर्क को मॉनिटर किया जा सकता है"</string> diff --git a/packages/SystemUI/res/values-hi/strings_tv.xml b/packages/SystemUI/res/values-hi/strings_tv.xml index e5c6eb2e6e20..9282c3c4b861 100644 --- a/packages/SystemUI/res/values-hi/strings_tv.xml +++ b/packages/SystemUI/res/values-hi/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"पिक्चर में पिक्चर"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(कोई शीर्षक कार्यक्रम नहीं)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP बंद करें"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"फ़ुल स्क्रीन"</string> <string name="mic_active" msgid="5766614241012047024">"माइक्रोफ़ोन चालू है"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ने आपका माइक्रोफ़ोन ऐक्सेस किया था"</string> </resources> diff --git a/packages/SystemUI/res/values-hr/strings_tv.xml b/packages/SystemUI/res/values-hr/strings_tv.xml index e226460298b7..59dcd0ceadbb 100644 --- a/packages/SystemUI/res/values-hr/strings_tv.xml +++ b/packages/SystemUI/res/values-hr/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Slika u slici"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Program bez naslova)"</string> - <string name="pip_close" msgid="5775212044472849930">"Zatvori PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Cijeli zaslon"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofon aktivan"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikacija %1$s pristupila je mikrofonu"</string> </resources> diff --git a/packages/SystemUI/res/values-hu/strings_tv.xml b/packages/SystemUI/res/values-hu/strings_tv.xml index f039c0d82238..548207244ad0 100644 --- a/packages/SystemUI/res/values-hu/strings_tv.xml +++ b/packages/SystemUI/res/values-hu/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Kép a képben"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Cím nélküli program)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP bezárása"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Teljes képernyő"</string> <string name="mic_active" msgid="5766614241012047024">"A mikrofon aktív"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"A(z) %1$s hozzáfért a mikrofonhoz"</string> </resources> diff --git a/packages/SystemUI/res/values-hy/strings_tv.xml b/packages/SystemUI/res/values-hy/strings_tv.xml index d5dad69ca1ac..4009335ec7d5 100644 --- a/packages/SystemUI/res/values-hy/strings_tv.xml +++ b/packages/SystemUI/res/values-hy/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Նկար նկարի մեջ"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Առանց վերնագրի ծրագիր)"</string> - <string name="pip_close" msgid="5775212044472849930">"Փակել PIP-ն"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Լիէկրան"</string> <string name="mic_active" msgid="5766614241012047024">"Խոսափողն ակտիվացված է"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s հավելվածն օգտագործել է ձեր խոսափողը"</string> </resources> diff --git a/packages/SystemUI/res/values-in/strings_tv.xml b/packages/SystemUI/res/values-in/strings_tv.xml index 5c4212358c65..670f8125582a 100644 --- a/packages/SystemUI/res/values-in/strings_tv.xml +++ b/packages/SystemUI/res/values-in/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Picture-in-picture"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Program tanpa judul)"</string> - <string name="pip_close" msgid="5775212044472849930">"Tutup PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Layar penuh"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofon Aktif"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s mengakses mikrofon"</string> </resources> diff --git a/packages/SystemUI/res/values-is/strings_tv.xml b/packages/SystemUI/res/values-is/strings_tv.xml index d3a2bec324ee..27334af093f5 100644 --- a/packages/SystemUI/res/values-is/strings_tv.xml +++ b/packages/SystemUI/res/values-is/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Mynd í mynd"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Efni án titils)"</string> - <string name="pip_close" msgid="5775212044472849930">"Loka mynd í mynd"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Allur skjárinn"</string> <string name="mic_active" msgid="5766614241012047024">"Hljóðnemi virkur"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s fékk aðgang að hljóðnemanum þínum"</string> </resources> diff --git a/packages/SystemUI/res/values-it/strings_tv.xml b/packages/SystemUI/res/values-it/strings_tv.xml index 782b959a134a..e0fce871895a 100644 --- a/packages/SystemUI/res/values-it/strings_tv.xml +++ b/packages/SystemUI/res/values-it/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Picture in picture"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Programma senza titolo)"</string> - <string name="pip_close" msgid="5775212044472849930">"Chiudi PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Schermo intero"</string> <string name="mic_active" msgid="5766614241012047024">"Microfono attivo"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ha avuto accesso al tuo microfono"</string> </resources> diff --git a/packages/SystemUI/res/values-iw/strings_tv.xml b/packages/SystemUI/res/values-iw/strings_tv.xml index 1e5fc91ecff1..2bd86efa02a4 100644 --- a/packages/SystemUI/res/values-iw/strings_tv.xml +++ b/packages/SystemUI/res/values-iw/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"תמונה בתוך תמונה"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(תוכנית ללא כותרת)"</string> - <string name="pip_close" msgid="5775212044472849930">"סגור PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"מסך מלא"</string> <string name="mic_active" msgid="5766614241012047024">"המיקרופון פעיל"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s קיבלה גישה למיקרופון שלך"</string> </resources> diff --git a/packages/SystemUI/res/values-ja/strings_tv.xml b/packages/SystemUI/res/values-ja/strings_tv.xml index 32f30d388320..1e7d05bb3713 100644 --- a/packages/SystemUI/res/values-ja/strings_tv.xml +++ b/packages/SystemUI/res/values-ja/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"ピクチャー イン ピクチャー"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(無題の番組)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP を閉じる"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"全画面表示"</string> <string name="mic_active" msgid="5766614241012047024">"マイク: 有効"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s がマイクにアクセスしました"</string> </resources> diff --git a/packages/SystemUI/res/values-ka/strings_tv.xml b/packages/SystemUI/res/values-ka/strings_tv.xml index b0ed30a4f218..476658d816f2 100644 --- a/packages/SystemUI/res/values-ka/strings_tv.xml +++ b/packages/SystemUI/res/values-ka/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"ეკრანი ეკრანში"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(პროგრამის სათაურის გარეშე)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP-ის დახურვა"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"სრულ ეკრანზე"</string> <string name="mic_active" msgid="5766614241012047024">"მიკროფონი აქტიურია"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s-მა გამოიყენა თქვენი მიკროფონი"</string> </resources> diff --git a/packages/SystemUI/res/values-kk/strings_tv.xml b/packages/SystemUI/res/values-kk/strings_tv.xml index 323c5e6c0bc7..d4b3c73f8308 100644 --- a/packages/SystemUI/res/values-kk/strings_tv.xml +++ b/packages/SystemUI/res/values-kk/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Суреттегі сурет"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Атаусыз бағдарлама)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP жабу"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Толық экран"</string> <string name="mic_active" msgid="5766614241012047024">"Микрофон қосулы"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s микрофоныңызды пайдаланды."</string> </resources> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 7410ddded885..36d5aa8ab45b 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -917,17 +917,13 @@ <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ទំព័រ <xliff:g id="ID_1">%1$d</xliff:g> នៃ <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"អេក្រង់ចាក់សោ"</string> <string name="thermal_shutdown_title" msgid="2702966892682930264">"ទូរសព្ទបានបិទដោយសារវាឡើងកម្តៅ"</string> - <!-- no translation found for thermal_shutdown_message (6142269839066172984) --> - <skip /> + <string name="thermal_shutdown_message" msgid="6142269839066172984">"ឥឡូវនេះ ទូរសព្ទរបស់អ្នកកំពុងដំណើរការជាធម្មតា។\nសូមចុចដើម្បីទទួលបានព័ត៌មានបន្ថែម"</string> <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ទូរសព្ទរបស់អ្នកក្តៅពេក ដូច្នេះវាបានបិទដើម្បីបន្ថយកម្តៅ។ ឥឡូវនេះ ទូរសព្ទរបស់អ្នកកំពុងដំណើរការធម្មតា។\n\nទូរសព្ទរបស់អ្នកអាចនឹងឡើងកម្តៅខ្លាំងជ្រុល ប្រសិនបើអ្នក៖\n • ប្រើប្រាស់កម្មវិធីដែលប្រើប្រាស់ទិន្នន័យច្រើនក្នុងរយៈពេលខ្លី (ដូចជាហ្គេម វីដេអូ ឬកម្មវិធីរុករក)\n • ទាញយក ឬបង្ហោះឯកសារដែលមានទំហំធំ\n • ប្រើប្រាស់ទូរសព្ទរបស់អ្នកនៅកន្លែងមានសីតុណ្ហភាពខ្ពស់"</string> - <!-- no translation found for thermal_shutdown_dialog_help_text (6413474593462902901) --> - <skip /> + <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"មើលជំហានថែទាំ"</string> <string name="high_temp_title" msgid="2218333576838496100">"ទូរសព្ទនេះកំពុងកើនកម្តៅ"</string> - <!-- no translation found for high_temp_notif_message (1277346543068257549) --> - <skip /> + <string name="high_temp_notif_message" msgid="1277346543068257549">"មុខងារមួយចំនួននឹងមិនអាចប្រើបានពេញលេញនោះទេ ខណៈពេលដែលទូរសព្ទកំពុងបញ្ចុះកម្ដៅ។\nសូមចុចដើម្បីទទួលបានព័ត៌មានបន្ថែម"</string> <string name="high_temp_dialog_message" msgid="3793606072661253968">"ទូរសព្ទរបស់អ្នកនឹងព្យាយាមបញ្ចុះកម្តៅដោយស្វ័យប្រវត្តិ។ អ្នកនៅតែអាចប្រើទូរសព្ទរបស់អ្នកបានដដែល ប៉ុន្តែវានឹងដំណើរការយឺតជាងមុន។\n\nបន្ទាប់ពីទូរសព្ទរបស់អ្នកត្រជាក់ជាងមុនហើយ វានឹងដំណើរការដូចធម្មតា។"</string> - <!-- no translation found for high_temp_dialog_help_text (7380171287943345858) --> - <skip /> + <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"មើលជំហានថែទាំ"</string> <string name="high_temp_alarm_title" msgid="2359958549570161495">"ផ្ដាច់ឆ្នាំងសាក"</string> <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"មានបញ្ហាក្នុងការសាកថ្មឧបករណ៍នេះ។ សូមផ្ដាច់ឆ្នាំងសាក ហើយប្រុងប្រយ័ត្ន ដោយសារខ្សែអាចមានកម្ដៅក្ដៅ។"</string> <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"មើលជំហានថែទាំ"</string> diff --git a/packages/SystemUI/res/values-km/strings_tv.xml b/packages/SystemUI/res/values-km/strings_tv.xml index f905f49f695b..685a5e482e89 100644 --- a/packages/SystemUI/res/values-km/strings_tv.xml +++ b/packages/SystemUI/res/values-km/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"រូបក្នុងរូប"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(កម្មវិធីគ្មានចំណងជើង)"</string> - <string name="pip_close" msgid="5775212044472849930">"បិទ PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"ពេញអេក្រង់"</string> <string name="mic_active" msgid="5766614241012047024">"មីក្រូហ្វូនកំពុងដំណើរការ"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s បានចូលប្រើមីក្រូហ្វូនរបស់អ្នក"</string> </resources> diff --git a/packages/SystemUI/res/values-kn/strings_tv.xml b/packages/SystemUI/res/values-kn/strings_tv.xml index d01e14780046..7db0c7080919 100644 --- a/packages/SystemUI/res/values-kn/strings_tv.xml +++ b/packages/SystemUI/res/values-kn/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರ"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(ಶೀರ್ಷಿಕೆ ರಹಿತ ಕಾರ್ಯಕ್ರಮ)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP ಮುಚ್ಚಿ"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"ಪೂರ್ಣ ಪರದೆ"</string> <string name="mic_active" msgid="5766614241012047024">"ಮೈಕ್ರೋಫೋನ್ ಸಕ್ರಿಯವಾಗಿದೆ"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ನಿಮ್ಮ ಮೈಕ್ರೋಫೋನ್ ಅನ್ನು ಪ್ರವೇಶಿಸಿದೆ"</string> </resources> diff --git a/packages/SystemUI/res/values-ko/strings_tv.xml b/packages/SystemUI/res/values-ko/strings_tv.xml index 0615fe85d72e..10889705ddc3 100644 --- a/packages/SystemUI/res/values-ko/strings_tv.xml +++ b/packages/SystemUI/res/values-ko/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"PIP 모드"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(제목 없는 프로그램)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP 닫기"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"전체화면"</string> <string name="mic_active" msgid="5766614241012047024">"마이크 사용 중"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s에서 내 마이크에 액세스했습니다."</string> </resources> diff --git a/packages/SystemUI/res/values-ky/strings_tv.xml b/packages/SystemUI/res/values-ky/strings_tv.xml index 5b40ca93bac2..b69b1c6e26b5 100644 --- a/packages/SystemUI/res/values-ky/strings_tv.xml +++ b/packages/SystemUI/res/values-ky/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Сүрөт ичиндеги сүрөт"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Аталышы жок программа)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP\'ти жабуу"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Толук экран"</string> <string name="mic_active" msgid="5766614241012047024">"Микрофон күйүк"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s микрофонуңузду колдонууда"</string> </resources> diff --git a/packages/SystemUI/res/values-lo/strings_tv.xml b/packages/SystemUI/res/values-lo/strings_tv.xml index 7e7a4dded891..056612eb49e9 100644 --- a/packages/SystemUI/res/values-lo/strings_tv.xml +++ b/packages/SystemUI/res/values-lo/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"ສະແດງຜົນຫຼາຍຢ່າງພ້ອມກັນ"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(ໂປຣແກຣມບໍ່ມີຊື່)"</string> - <string name="pip_close" msgid="5775212044472849930">"ປິດ PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"ເຕັມໜ້າຈໍ"</string> <string name="mic_active" msgid="5766614241012047024">"ໄມໂຄຣໂຟນເປີດໃຊ້ຢູ່"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ເຂົ້າເຖິງໄມໂຄຣໂຟນຂອງທ່ານແລ້ວ"</string> </resources> diff --git a/packages/SystemUI/res/values-lt/strings_tv.xml b/packages/SystemUI/res/values-lt/strings_tv.xml index cb0cb6c2845b..7739680c82b3 100644 --- a/packages/SystemUI/res/values-lt/strings_tv.xml +++ b/packages/SystemUI/res/values-lt/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Vaizdas vaizde"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Programa be pavadinimo)"</string> - <string name="pip_close" msgid="5775212044472849930">"Uždaryti PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Visas ekranas"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofonas aktyvus"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"„%1$s“ pasiekė jūsų mikrofoną"</string> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 01bbdca17a3d..cbe076896d9f 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -294,7 +294,7 @@ <string name="accessibility_quick_settings_more_time" msgid="7646479831704665284">"Vairāk laika."</string> <string name="accessibility_quick_settings_less_time" msgid="9110364286464977870">"Mazāk laika."</string> <string name="accessibility_quick_settings_flashlight_off" msgid="7606563260714825190">"Apgaismojums ir izslēgts."</string> - <string name="accessibility_quick_settings_flashlight_unavailable" msgid="7458591827288347635">"Zibspuldze nav pieejama."</string> + <string name="accessibility_quick_settings_flashlight_unavailable" msgid="7458591827288347635">"Lukturītis nav pieejams."</string> <string name="accessibility_quick_settings_flashlight_on" msgid="3785616827729850766">"Apgaismojums ir ieslēgts."</string> <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3782375441381402599">"Apgaismojums ir izslēgts."</string> <string name="accessibility_quick_settings_flashlight_changed_on" msgid="4747870681508334200">"Apgaismojums ir ieslēgts."</string> @@ -407,7 +407,7 @@ <item quantity="other">%d ierīces</item> </plurals> <string name="quick_settings_notifications_label" msgid="3379631363952582758">"Paziņojumi"</string> - <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Zibspuldze"</string> + <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lukturītis"</string> <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera tiek lietota"</string> <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobilie dati"</string> <string name="quick_settings_cellular_detail_data_usage" msgid="6105969068871138427">"Datu lietojums"</string> diff --git a/packages/SystemUI/res/values-lv/strings_tv.xml b/packages/SystemUI/res/values-lv/strings_tv.xml index e08b0ea4379f..6b841d2c244b 100644 --- a/packages/SystemUI/res/values-lv/strings_tv.xml +++ b/packages/SystemUI/res/values-lv/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Attēls attēlā"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Programma bez nosaukuma)"</string> - <string name="pip_close" msgid="5775212044472849930">"Aizvērt PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Pilnekrāna režīms"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofons ir aktīvs"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"Lietotne %1$s piekļuva jūsu mikrofonam"</string> </resources> diff --git a/packages/SystemUI/res/values-mk/strings_tv.xml b/packages/SystemUI/res/values-mk/strings_tv.xml index b4de2156155c..a935cc47b6cf 100644 --- a/packages/SystemUI/res/values-mk/strings_tv.xml +++ b/packages/SystemUI/res/values-mk/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Слика во слика"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Програма без наслов)"</string> - <string name="pip_close" msgid="5775212044472849930">"Затвори PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Цел екран"</string> <string name="mic_active" msgid="5766614241012047024">"Микрофонот е активен"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s пристапи до вашиот микрофон"</string> </resources> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index e3a3f82f9d6e..22392279a919 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -917,17 +917,13 @@ <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"പേജ് <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"ലോക്ക് സ്ക്രീൻ"</string> <string name="thermal_shutdown_title" msgid="2702966892682930264">"ചൂട് കൂടിയതിനാൽ ഫോൺ ഓഫാക്കി"</string> - <!-- no translation found for thermal_shutdown_message (6142269839066172984) --> - <skip /> + <string name="thermal_shutdown_message" msgid="6142269839066172984">"നിങ്ങളുടെ ഫോൺ ഇപ്പോൾ സാധാരണ ഗതിയിൽ പ്രവർത്തിക്കുന്നു.\nകൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string> <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ഫോൺ ചൂടായിരിക്കുന്നതിനാൽ തണുക്കാൻ ഓഫാക്കിയിരിക്കുന്നു. ഫോൺ ഇപ്പോൾ സാധാരണഗതിയിൽ പ്രവർത്തിക്കുന്നു.\n\nഫോണിന് ചൂട് കൂടാൻ കാരണം:\n • ഗെയിമിംഗ്, വീഡിയോ അല്ലെങ്കിൽ നാവിഗേഷൻ തുടങ്ങിയ റിസോഴ്സ്-ഇന്റൻസീവായ ആപ്പുകൾ ഉപയോഗിക്കുന്നത്\n • വലിയ ഫയലുകൾ അപ്ലോഡോ ഡൗൺലോഡോ ചെയ്യുന്നത്\n • ഉയർന്ന താപനിലയിൽ ഫോൺ ഉപയോഗിക്കുന്നത്"</string> - <!-- no translation found for thermal_shutdown_dialog_help_text (6413474593462902901) --> - <skip /> + <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"പരിപാലന നിർദ്ദേശങ്ങൾ കാണുക"</string> <string name="high_temp_title" msgid="2218333576838496100">"ഫോൺ ചൂടായിക്കൊണ്ടിരിക്കുന്നു"</string> - <!-- no translation found for high_temp_notif_message (1277346543068257549) --> - <skip /> + <string name="high_temp_notif_message" msgid="1277346543068257549">"ഫോൺ തണുത്തുകൊണ്ടിരിക്കുമ്പോൾ ചില ഫീച്ചറുകൾ പരിമിതപ്പെടുത്തപ്പെടും.\nകൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string> <string name="high_temp_dialog_message" msgid="3793606072661253968">"നിങ്ങളുടെ ഫോൺ സ്വയമേവ തണുക്കാൻ ശ്രമിക്കും. നിങ്ങൾക്ക് അപ്പോഴും ഫോൺ ഉപയോഗിക്കാമെങ്കിലും പ്രവർത്തനം മന്ദഗതിയിലായിരിക്കും.\n\nതണുത്തുകഴിഞ്ഞാൽ, ഫോൺ സാധാരണ ഗതിയിൽ പ്രവർത്തിക്കും."</string> - <!-- no translation found for high_temp_dialog_help_text (7380171287943345858) --> - <skip /> + <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"പരിപാലന നിർദ്ദേശങ്ങൾ കാണുക"</string> <string name="high_temp_alarm_title" msgid="2359958549570161495">"ചാർജർ അൺപ്ലഗ് ചെയ്യുക"</string> <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"ഈ ഉപകരണം ചാർജ് ചെയ്യുന്നതിൽ തടസ്സമുണ്ട്. പവർ അഡാപ്റ്റർ അൺപ്ലഗ് ചെയ്യുക, കേബിളിന് ചൂടുണ്ടായിരിക്കുമെന്നതിനാൽ ശ്രദ്ധിക്കണം."</string> <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"മുൻകരുതൽ നടപടികൾ കാണുക"</string> diff --git a/packages/SystemUI/res/values-ml/strings_tv.xml b/packages/SystemUI/res/values-ml/strings_tv.xml index bf925c454f6d..97843376a364 100644 --- a/packages/SystemUI/res/values-ml/strings_tv.xml +++ b/packages/SystemUI/res/values-ml/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"ചിത്രത്തിനുള്ളിൽ ചിത്രം"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(പേരില്ലാത്ത പ്രോഗ്രാം)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP അടയ്ക്കുക"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"പൂര്ണ്ണ സ്ക്രീന്"</string> <string name="mic_active" msgid="5766614241012047024">"മൈക്രോഫോൺ സജീവമാണ്"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s, നിങ്ങളുടെ മൈക്രോഫോൺ ആക്സസ് ചെയ്തു"</string> </resources> diff --git a/packages/SystemUI/res/values-mn/strings_tv.xml b/packages/SystemUI/res/values-mn/strings_tv.xml index 6eb4449a9796..3a5ff747a01e 100644 --- a/packages/SystemUI/res/values-mn/strings_tv.xml +++ b/packages/SystemUI/res/values-mn/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Дэлгэцэн-доторх-Дэлгэц"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Гарчиггүй хөтөлбөр)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP-г хаах"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Бүтэн дэлгэц"</string> <string name="mic_active" msgid="5766614241012047024">"Микрофон идэвхтэй байна"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s нь таны микрофонд хандcан байна"</string> </resources> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 4f1476e9a30c..79b7ae8b12a5 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -917,17 +917,13 @@ <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"पृष्ठ <xliff:g id="ID_2">%2$d</xliff:g> पैकी <xliff:g id="ID_1">%1$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"लॉक स्क्रीन"</string> <string name="thermal_shutdown_title" msgid="2702966892682930264">"तापल्यामुळे फोन बंद झाला"</string> - <!-- no translation found for thermal_shutdown_message (6142269839066172984) --> - <skip /> + <string name="thermal_shutdown_message" msgid="6142269839066172984">"तुमचा फोन आता नेहमीप्रमाणे काम करत आहे.\nअधिक माहितीसाठी टॅप करा"</string> <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"तुमचा फोन खूप तापलाय, म्हणून तो थंड होण्यासाठी बंद झाला आहे. तुमचा फोन आता व्यवस्थित सुरू आहे.\n\nतुम्ही असे केल्यास तुमचा फोन खूप तापेल:\n •संसाधन केंद्रित अॅप वापरणे (गेमिंग, व्हिडिओ किंवा नेव्हिगेशन अॅप यासारखे)\n •मोठ्या फाइल डाउनलोड किंवा अपलोड करणे\n •उच्च तापमानामध्ये तुमचा फोन वापरणे"</string> - <!-- no translation found for thermal_shutdown_dialog_help_text (6413474593462902901) --> - <skip /> + <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"काय काळजी घ्यावी ते पाहा"</string> <string name="high_temp_title" msgid="2218333576838496100">"फोन ऊष्ण होत आहे"</string> - <!-- no translation found for high_temp_notif_message (1277346543068257549) --> - <skip /> + <string name="high_temp_notif_message" msgid="1277346543068257549">"फोन थंड होईपर्यंत काही वैशिष्ट्ये मर्यादित केली.\nअधिक माहितीसाठी टॅप करा"</string> <string name="high_temp_dialog_message" msgid="3793606072661253968">"तुमचा फोन स्वयंचलितपणे थंड होईल. तुम्ही अद्यापही तुमचा फोन वापरू शकता परंतु तो कदाचित धीमेपणे कार्य करेल.\n\nतुमचा फोन एकदा थंड झाला की, तो सामान्यपणे कार्य करेल."</string> - <!-- no translation found for high_temp_dialog_help_text (7380171287943345858) --> - <skip /> + <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"काय काळजी घ्यावी ते पाहा"</string> <string name="high_temp_alarm_title" msgid="2359958549570161495">"चार्जर अनप्लग करा"</string> <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"हे डिव्हाइस चार्ज करताना समस्या आहे. पॉवर अडॅप्टर अनप्लग करा आणि शक्य तेवढी काळजी घ्या कदाचित केबल गरम असू शकते."</string> <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"काय काळजी घ्यावी ते पाहा"</string> diff --git a/packages/SystemUI/res/values-mr/strings_tv.xml b/packages/SystemUI/res/values-mr/strings_tv.xml index 587832a6bda6..7f58fe779e03 100644 --- a/packages/SystemUI/res/values-mr/strings_tv.xml +++ b/packages/SystemUI/res/values-mr/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"चित्रा-मध्ये-चित्र"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(शीर्षक नसलेला कार्यक्रम)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP बंद करा"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"फुल स्क्रीन"</string> <string name="mic_active" msgid="5766614241012047024">"मायक्रोफोन ॲक्टिव्ह आहे"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s यांनी तुमचा मायक्रोफोन अॅक्सेस केला आहे"</string> </resources> diff --git a/packages/SystemUI/res/values-ms/strings_tv.xml b/packages/SystemUI/res/values-ms/strings_tv.xml index ba6a85e3e546..3c62891c5530 100644 --- a/packages/SystemUI/res/values-ms/strings_tv.xml +++ b/packages/SystemUI/res/values-ms/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Gambar dalam Gambar"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Program tiada tajuk)"</string> - <string name="pip_close" msgid="5775212044472849930">"Tutup PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Skrin penuh"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofon Aktif"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s telah mengakses mikrofon anda"</string> </resources> diff --git a/packages/SystemUI/res/values-my/strings_tv.xml b/packages/SystemUI/res/values-my/strings_tv.xml index e33a1c32557a..88d7d53d8390 100644 --- a/packages/SystemUI/res/values-my/strings_tv.xml +++ b/packages/SystemUI/res/values-my/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"တစ်ခုပေါ်တစ်ခု ထပ်၍ ဖွင့်ခြင်း"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(ခေါင်းစဉ်မဲ့ အစီအစဉ်)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP ကိုပိတ်ပါ"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"မျက်နှာပြင် အပြည့်"</string> <string name="mic_active" msgid="5766614241012047024">"မိုက်ခရိုဖုန်း ဖွင့်ထားသည်"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s က သင့်မိုက်ခရိုဖုန်းကို သုံးထားသည်"</string> </resources> diff --git a/packages/SystemUI/res/values-nb/strings_tv.xml b/packages/SystemUI/res/values-nb/strings_tv.xml index 9b466788d9e0..cd558735315f 100644 --- a/packages/SystemUI/res/values-nb/strings_tv.xml +++ b/packages/SystemUI/res/values-nb/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Bilde-i-bilde"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Program uten tittel)"</string> - <string name="pip_close" msgid="5775212044472849930">"Lukk PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Fullskjerm"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofonen er aktiv"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s fikk tilgang til mikrofonen din"</string> </resources> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 3cf586c0f4f6..d962af76ec41 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -917,17 +917,13 @@ <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> मध्ये पृष्ठ <xliff:g id="ID_1">%1$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"लक स्क्रिन"</string> <string name="thermal_shutdown_title" msgid="2702966892682930264">"फोन अति नै तातिएकाले चिसिन बन्द भयो"</string> - <!-- no translation found for thermal_shutdown_message (6142269839066172984) --> - <skip /> + <string name="thermal_shutdown_message" msgid="6142269839066172984">"तपाईंको फोन अहिले सामान्य रूपमा चलिरहेको छ।\nथप जानकारीका लागि ट्याप गर्नुहोस्"</string> <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"तपाईंको फोन अति नै तातिएकाले चिसिन बन्द भयो। तपाईंको फोन अब सामान्य ढंगले चल्दै छ।\n\nतपाईंले निम्न कुराहरू गर्नुभयो भने तपाईंको फोन अत्यन्त तातो हुनसक्छ:\n • धेरै संसाधन खपत गर्ने एपहरूको प्रयोग (जस्तै गेमिङ, भिडियो वा नेभिगेसन एपहरू)\n • ठूला फाइलहरूको डाउनलोड वा अपलोड\n • उच्च तापक्रममा फोनको प्रयोग"</string> - <!-- no translation found for thermal_shutdown_dialog_help_text (6413474593462902901) --> - <skip /> + <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"यन्त्रको हेरचाह गर्ने तरिका हेर्नुहोस्"</string> <string name="high_temp_title" msgid="2218333576838496100">"फोन तातो भइरहेको छ"</string> - <!-- no translation found for high_temp_notif_message (1277346543068257549) --> - <skip /> + <string name="high_temp_notif_message" msgid="1277346543068257549">"फोन नचिस्सिँदासम्म केही सुविधाहरू उपलब्ध हुने छैनन्।\nथप जानकारीका लागि ट्याप गर्नुहोस्"</string> <string name="high_temp_dialog_message" msgid="3793606072661253968">"तपाईंको फोन स्वतः चिसो हुने प्रयास गर्ने छ। तपाईं अझै पनि आफ्नो फोनको प्रयोग गर्न सक्नुहुन्छ तर त्यो अझ ढिलो चल्न सक्छ।\n\nचिसो भएपछि तपाईंको फोन सामान्य गतिमा चल्नेछ।"</string> - <!-- no translation found for high_temp_dialog_help_text (7380171287943345858) --> - <skip /> + <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"यन्त्रको हेरचाह गर्ने तरिका हेर्नुहोस्"</string> <string name="high_temp_alarm_title" msgid="2359958549570161495">"चार्जर अनप्लग गर्नुहोस्"</string> <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"यो यन्त्र चार्ज गर्दा कुनै समस्या भयो। पावर एडाप्टर अनप्लग गर्नुहोस् र केबल तातो हुन सक्ने भएकाले ध्यान दिनुहोस्।"</string> <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"हेरचाहसम्बन्धी चरणहरू हेर्नुहोस्"</string> diff --git a/packages/SystemUI/res/values-ne/strings_tv.xml b/packages/SystemUI/res/values-ne/strings_tv.xml index 20411351b549..22f7f71793fa 100644 --- a/packages/SystemUI/res/values-ne/strings_tv.xml +++ b/packages/SystemUI/res/values-ne/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Picture-in-Picture"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(शीर्षकविहीन कार्यक्रम)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP लाई बन्द गर्नुहोस्"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"फुल स्क्रिन"</string> <string name="mic_active" msgid="5766614241012047024">"माइक्रोफोन सक्रिय छ"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ले तपाईंको माइक्रोफोनमाथि पहुँच राख्यो"</string> </resources> diff --git a/packages/SystemUI/res/values-nl/strings_tv.xml b/packages/SystemUI/res/values-nl/strings_tv.xml index c8dd088f8725..3b8e3201e440 100644 --- a/packages/SystemUI/res/values-nl/strings_tv.xml +++ b/packages/SystemUI/res/values-nl/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Scherm-in-scherm"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Naamloos programma)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP sluiten"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Volledig scherm"</string> <string name="mic_active" msgid="5766614241012047024">"Microfoon actief"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s heeft toegang tot je microfoon gehad"</string> </resources> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index c74a69a1e579..e112f446acb1 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -917,17 +917,13 @@ <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ପୃଷ୍ଠା <xliff:g id="ID_1">%1$d</xliff:g> ମୋଟ <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"ଲକ୍ ସ୍କ୍ରୀନ୍"</string> <string name="thermal_shutdown_title" msgid="2702966892682930264">"ଗରମ ହେତୁ ଫୋନ୍ ଅଫ୍ କରିଦିଆଗଲା"</string> - <!-- no translation found for thermal_shutdown_message (6142269839066172984) --> - <skip /> + <string name="thermal_shutdown_message" msgid="6142269839066172984">"ଆପଣଙ୍କ ଫୋନ୍ ବର୍ତ୍ତମାନ ସାମାନ୍ୟ ରୂପେ ଚାଲୁଛି।\nଅଧିକ ସୂଚନା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string> <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ଆପଣଙ୍କ ଫୋନ୍ ବହୁତ ଗରମ ଥିଲା, ତେଣୁ ଏହାକୁ ଥଣ୍ଡା କରାଯିବାକୁ ଅଫ୍ କରିଦିଆଗଲା। ଆପଣଙ୍କ ଫୋନ୍ ବର୍ତ୍ତମାନ ସାମାନ୍ୟ ଅବସ୍ଥାରେ ଚାଲୁଛି।\n\nଆପଣଙ୍କ ଫୋନ୍ ଅଧିକ ଗରମ ହୋଇଯାଇପାରେ ଯଦି ଆପଣ:\n • ରିସୋର୍ସ-ଇଣ୍ଟେନସିଭ୍ ଆପ୍ (ଯେପରିକି ଗେମିଙ୍ଗ, ଭିଡିଓ, କିମ୍ବା ନେଭିଗେସନ୍ ଆପ୍) ବ୍ୟବହାର କରନ୍ତି\n • ବଡ ଫାଇଲ୍ ଡାଉନଲୋଡ୍ କିମ୍ବା ଅପଲୋଡ୍ କରନ୍ତି\n • ଅଧିକ ତାପମାତ୍ରାରେ ଆପଣଙ୍କ ଫୋନ୍ ବ୍ୟବହାର କରନ୍ତି"</string> - <!-- no translation found for thermal_shutdown_dialog_help_text (6413474593462902901) --> - <skip /> + <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ଯତ୍ନ ନେବା ପାଇଁ ଷ୍ଟେପଗୁଡ଼ିକ ଦେଖନ୍ତୁ"</string> <string name="high_temp_title" msgid="2218333576838496100">"ଫୋନ୍ ଗରମ ହୋଇଯାଉଛି"</string> - <!-- no translation found for high_temp_notif_message (1277346543068257549) --> - <skip /> + <string name="high_temp_notif_message" msgid="1277346543068257549">"ଫୋନ୍ ଥଣ୍ଡା ହେବା ସମୟରେ କିଛି ଫିଚର୍ ଠିକ ଭାବେ କାମ କରିନଥାଏ।\nଅଧିକ ସୂଚନା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string> <string name="high_temp_dialog_message" msgid="3793606072661253968">"ଆପଣଙ୍କ ଫୋନ୍ ସ୍ୱଚାଳିତ ଭାବେ ଥଣ୍ଡା ହେବାକୁ ଚେଷ୍ଟା କରିବ। ଆପଣ ତଥାପି ନିଜ ଫୋନ୍ ବ୍ୟବହାର କରିପାରିବେ, କିନ୍ତୁ ଏହା ଧୀରେ ଚାଲିପାରେ।\n\nଆପଣଙ୍କ ଫୋନ୍ ଥଣ୍ଡା ହୋଇଯିବାପରେ, ଏହା ସାମାନ୍ୟ ଭାବେ ଚାଲିବ।"</string> - <!-- no translation found for high_temp_dialog_help_text (7380171287943345858) --> - <skip /> + <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ଯତ୍ନ ନେବା ପାଇଁ ଷ୍ଟେପଗୁଡ଼ିକ ଦେଖନ୍ତୁ"</string> <string name="high_temp_alarm_title" msgid="2359958549570161495">"ଚାର୍ଜର୍ ଅନ୍ପ୍ଲଗ୍ କରନ୍ତୁ"</string> <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"ଏହି ଡିଭାଇସ୍ ଚାର୍ଜ କରିବାରେ ଗୋଟିଏ ସମସ୍ୟା ଅଛି। ଯେହେତୁ କେବଳ ଗରମ ହୋଇଯାଇପାରେ, ତେଣୁ ପାୱାର୍ ଆଡପ୍ଟର୍ ଅନ୍ପ୍ଲଗ୍ କରନ୍ତୁ ଏବଂ ଯତ୍ନ ନିଅନ୍ତୁ।"</string> <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"ସେବା ସମ୍ବନ୍ଧିତ ଷ୍ଟେପ୍ଗୁଡ଼ିକ ଦେଖନ୍ତୁ"</string> diff --git a/packages/SystemUI/res/values-or/strings_tv.xml b/packages/SystemUI/res/values-or/strings_tv.xml index 4593d6ad8c6c..b44dc3bffe12 100644 --- a/packages/SystemUI/res/values-or/strings_tv.xml +++ b/packages/SystemUI/res/values-or/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"ପିକଚର୍-ଇନ୍-ପିକଚର୍"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(କୌଣସି ଟାଇଟଲ୍ ପ୍ରୋଗ୍ରାମ୍ ନାହିଁ)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP ବନ୍ଦ କରନ୍ତୁ"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍"</string> <string name="mic_active" msgid="5766614241012047024">"ମାଇକ୍ରୋଫୋନ୍ ସକ୍ରିୟ"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ଆପଣଙ୍କର ମାଇକ୍ରୋଫୋନ୍କୁ ଆକ୍ସେସ୍ କରିଛି"</string> </resources> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 7c462db7bb6a..6ac824b59e6b 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -917,17 +917,13 @@ <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ਦਾ <xliff:g id="ID_1">%1$d</xliff:g> ਪੰਨਾ"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">" ਲਾਕ ਸਕ੍ਰੀਨ"</string> <string name="thermal_shutdown_title" msgid="2702966892682930264">"ਗਰਮ ਹੋਣ ਕਾਰਨ ਫ਼ੋਨ ਬੰਦ ਹੋ ਗਿਆ"</string> - <!-- no translation found for thermal_shutdown_message (6142269839066172984) --> - <skip /> + <string name="thermal_shutdown_message" msgid="6142269839066172984">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\nਵਧੇਰੇ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string> <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">\n"ਤੁਹਾਡਾ ਫ਼ੋਨ ਬਹੁਤ ਗਰਮ ਸੀ, ਇਸ ਲਈ ਇਹ ਠੰਡਾ ਹੋਣ ਵਾਸਤੇ ਬੰਦ ਹੋ ਗਿਆ ਸੀ। ਤੁਹਾਡਾ ਫ਼ੋਨ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\n\nਤੁਹਾਡਾ ਫ਼ੋਨ ਬਹੁਤ ਗਰਮ ਹੋ ਸਕਦਾ ਹੈ ਜੇ:\n • ਤੁਸੀਂ ਸਰੋਤਾਂ ਦੀ ਵੱਧ ਵਰਤੋਂ ਵਾਲੀਆਂ ਐਪਾਂ (ਜਿਵੇਂ ਗੇਮਿੰਗ, ਵੀਡੀਓ, ਜਾਂ ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਐਪਾਂ) ਵਰਤਦੇ ਹੋ • ਵੱਡੀਆਂ ਫ਼ਾਈਲਾਂ ਡਾਊਨਲੋਡ ਜਾਂ ਅੱਪਲੋਡ ਕਰਦੇ ਹੋ\n • ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਉੱਚ ਤਾਪਮਾਨਾਂ ਵਿੱਚ ਵਰਤਦੇ ਹੋ"</string> - <!-- no translation found for thermal_shutdown_dialog_help_text (6413474593462902901) --> - <skip /> + <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ਦੇਖਭਾਲ ਦੇ ਪੜਾਅ ਦੇਖੋ"</string> <string name="high_temp_title" msgid="2218333576838496100">"ਫ਼ੋਨ ਗਰਮ ਹੋ ਰਿਹਾ ਹੈ"</string> - <!-- no translation found for high_temp_notif_message (1277346543068257549) --> - <skip /> + <string name="high_temp_notif_message" msgid="1277346543068257549">"ਫ਼ੋਨ ਦੇ ਠੰਡਾ ਹੋਣ ਦੇ ਦੌਰਾਨ ਕੁਝ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਸੀਮਤ ਹੁੰਦੀਆਂ ਹਨ।\nਵਧੇਰੇ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string> <string name="high_temp_dialog_message" msgid="3793606072661253968">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਸਵੈਚਲਿਤ ਰੂਪ ਵਿੱਚ ਠੰਡਾ ਹੋਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੇਗਾ। ਤੁਸੀਂ ਹਾਲੇ ਵੀ ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਵਰਤ ਸਕਦੇ ਹੋ, ਪਰੰਤੂ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਇਹ ਵਧੇਰੇ ਹੌਲੀ ਚੱਲੇ।\n\nਇੱਕ ਵਾਰ ਠੰਡਾ ਹੋਣ ਤੋਂ ਬਾਅਦ ਤੁਹਾਡਾ ਫ਼ੋਨ ਸਧਾਰਨ ਤੌਰ \'ਤੇ ਚੱਲੇਗਾ।"</string> - <!-- no translation found for high_temp_dialog_help_text (7380171287943345858) --> - <skip /> + <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ਦੇਖਭਾਲ ਦੇ ਪੜਾਅ ਦੇਖੋ"</string> <string name="high_temp_alarm_title" msgid="2359958549570161495">"ਚਾਰਜਰ ਨੂੰ ਕੱਢੋ"</string> <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"ਇਸ ਡੀਵਾਈਸ ਨੂੰ ਚਾਰਜ ਕਰਨ ਵਿੱਚ ਕੋਈ ਸਮੱਸਿਆ ਆ ਗਈ ਹੈ। ਪਾਵਰ ਅਡਾਪਟਰ ਨੂੰ ਕੱਢੋ ਅਤੇ ਧਿਆਨ ਰੱਖੋ ਸ਼ਾਇਦ ਕੇਬਲ ਗਰਮ ਹੋਵੇ।"</string> <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"ਦੇਖਭਾਲ ਦੇ ਪੜਾਅ ਦੇਖੋ"</string> diff --git a/packages/SystemUI/res/values-pa/strings_tv.xml b/packages/SystemUI/res/values-pa/strings_tv.xml index fd567698088b..f5300b318d10 100644 --- a/packages/SystemUI/res/values-pa/strings_tv.xml +++ b/packages/SystemUI/res/values-pa/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"ਤਸਵੀਰ-ਵਿੱਚ-ਤਸਵੀਰ"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(ਸਿਰਲੇਖ-ਰਹਿਤ ਪ੍ਰੋਗਰਾਮ)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP ਬੰਦ ਕਰੋ"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"ਪੂਰੀ ਸਕ੍ਰੀਨ"</string> <string name="mic_active" msgid="5766614241012047024">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਕਿਰਿਆਸ਼ੀਲ"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ਨੇ ਤੁਹਾਡੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ"</string> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index a1f8ea652235..f5ef1a045bdd 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -989,7 +989,7 @@ <string name="slice_permission_deny" msgid="6870256451658176895">"Odmów"</string> <string name="auto_saver_title" msgid="6873691178754086596">"Kliknij, by zaplanować działanie oszczędzania baterii"</string> <string name="auto_saver_text" msgid="3214960308353838764">"Oszczędzanie baterii włącza się, jeśli bateria jest prawie wyczerpana"</string> - <string name="no_auto_saver_action" msgid="7467924389609773835">"Nie"</string> + <string name="no_auto_saver_action" msgid="7467924389609773835">"Nie, dziękuję"</string> <string name="auto_saver_enabled_title" msgid="4294726198280286333">"Harmonogram oszczędzania baterii jest aktywny"</string> <string name="auto_saver_enabled_text" msgid="7889491183116752719">"Oszczędzanie baterii włączy się automatycznie, gdy poziom naładowania baterii spadnie poniżej <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string> <string name="open_saver_setting_action" msgid="2111461909782935190">"Ustawienia"</string> diff --git a/packages/SystemUI/res/values-pl/strings_tv.xml b/packages/SystemUI/res/values-pl/strings_tv.xml index 852ea5056460..b060141b0275 100644 --- a/packages/SystemUI/res/values-pl/strings_tv.xml +++ b/packages/SystemUI/res/values-pl/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Obraz w obrazie"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Program bez tytułu)"</string> - <string name="pip_close" msgid="5775212044472849930">"Zamknij PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Pełny ekran"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofon aktywny"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikacja %1$s uzyskała dostęp do mikrofonu"</string> </resources> diff --git a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml index a0cbeafb9c9a..19cb4eacf402 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Picture-in-picture"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(programa sem título)"</string> - <string name="pip_close" msgid="5775212044472849930">"Fechar PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Tela cheia"</string> <string name="mic_active" msgid="5766614241012047024">"Microfone ativado"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s acessou seu microfone"</string> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml index 65a6f03ede5a..2e60421c9008 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Ecrã no ecrã"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Sem título do programa)"</string> - <string name="pip_close" msgid="5775212044472849930">"Fechar PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Ecrã inteiro"</string> <string name="mic_active" msgid="5766614241012047024">"Microfone ativado"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s acedeu ao microfone"</string> </resources> diff --git a/packages/SystemUI/res/values-pt/strings_tv.xml b/packages/SystemUI/res/values-pt/strings_tv.xml index a0cbeafb9c9a..19cb4eacf402 100644 --- a/packages/SystemUI/res/values-pt/strings_tv.xml +++ b/packages/SystemUI/res/values-pt/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Picture-in-picture"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(programa sem título)"</string> - <string name="pip_close" msgid="5775212044472849930">"Fechar PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Tela cheia"</string> <string name="mic_active" msgid="5766614241012047024">"Microfone ativado"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s acessou seu microfone"</string> </resources> diff --git a/packages/SystemUI/res/values-ro/strings_tv.xml b/packages/SystemUI/res/values-ro/strings_tv.xml index 1bfbd71fef9b..f4349ff91b05 100644 --- a/packages/SystemUI/res/values-ro/strings_tv.xml +++ b/packages/SystemUI/res/values-ro/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Picture-in-Picture"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Program fără titlu)"</string> - <string name="pip_close" msgid="5775212044472849930">"Închideți PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Ecran complet"</string> <string name="mic_active" msgid="5766614241012047024">"Microfon activ"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s a accesat microfonul"</string> </resources> diff --git a/packages/SystemUI/res/values-ru/strings_tv.xml b/packages/SystemUI/res/values-ru/strings_tv.xml index b668cf96908b..b8638b711176 100644 --- a/packages/SystemUI/res/values-ru/strings_tv.xml +++ b/packages/SystemUI/res/values-ru/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Картинка в картинке"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Без названия)"</string> - <string name="pip_close" msgid="5775212044472849930">"\"Кадр в кадре\" – выйти"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Во весь экран"</string> <string name="mic_active" msgid="5766614241012047024">"Микрофон включен"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"Приложение \"%1$s\" использовало доступ к микрофону."</string> </resources> diff --git a/packages/SystemUI/res/values-si/strings_tv.xml b/packages/SystemUI/res/values-si/strings_tv.xml index 167d10578f16..411c0a075914 100644 --- a/packages/SystemUI/res/values-si/strings_tv.xml +++ b/packages/SystemUI/res/values-si/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"පින්තූරය-තුළ-පින්තූරය"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(මාතෘකාවක් නැති වැඩසටහන)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP වසන්න"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"සම්පූර්ණ තිරය"</string> <string name="mic_active" msgid="5766614241012047024">"මයික්රොෆෝනය සක්රියයි"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ඔබේ මයික්රොෆෝනයට ප්රවේශ වී ඇත"</string> </resources> diff --git a/packages/SystemUI/res/values-sk/strings_tv.xml b/packages/SystemUI/res/values-sk/strings_tv.xml index 562742ae5f1b..b52dada595c7 100644 --- a/packages/SystemUI/res/values-sk/strings_tv.xml +++ b/packages/SystemUI/res/values-sk/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Obraz v obraze"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Program bez názvu)"</string> - <string name="pip_close" msgid="5775212044472849930">"Zavrieť režim PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Celá obrazovka"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofón je aktívny"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikácia %1$s použila váš mikrofón"</string> </resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 1ae0209a45cd..e1e5852098b9 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -926,19 +926,6 @@ <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Uredi vrstni red nastavitev."</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. stran od <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaklenjen zaslon"</string> - <string name="pip_phone_expand" msgid="1424988917240616212">"Razširi"</string> - <string name="pip_phone_minimize" msgid="9057117033655996059">"Minimiraj"</string> - <string name="pip_phone_close" msgid="8801864042095341824">"Zapri"</string> - <string name="pip_phone_settings" msgid="5687538631925004341">"Nastavitve"</string> - <string name="pip_phone_dismiss_hint" msgid="5825740708095316710">"Povlecite navzdol, da opustite"</string> - <string name="pip_menu_title" msgid="6365909306215631910">"Meni"</string> - <string name="pip_notification_title" msgid="8661573026059630525">"<xliff:g id="NAME">%s</xliff:g> je v načinu slika v sliki"</string> - <string name="pip_notification_message" msgid="4991831338795022227">"Če ne želite, da aplikacija <xliff:g id="NAME">%s</xliff:g> uporablja to funkcijo, se dotaknite, da odprete nastavitve, in funkcijo izklopite."</string> - <string name="pip_play" msgid="333995977693142810">"Predvajaj"</string> - <string name="pip_pause" msgid="1139598607050555845">"Začasno ustavi"</string> - <string name="pip_skip_to_next" msgid="3864212650579956062">"Preskoči na naslednjega"</string> - <string name="pip_skip_to_prev" msgid="3742589641443049237">"Preskoči na prejšnjega"</string> - <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Spremeni velikost"</string> <string name="thermal_shutdown_title" msgid="2702966892682930264">"Tel. izklopljen zaradi vročine"</string> <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefon zdaj deluje normalno.\nDotaknite se za več informacij"</string> <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon je bil prevroč, zato se je izklopil, da se ohladi. Zdaj normalno deluje.\n\nTelefon lahko postane prevroč ob:\n • uporabi aplikacij, ki intenzivno porabljajo sredstva (npr. za igranje iger, videoposnetke ali navigacijo)\n • prenosu ali nalaganju velikih datotek\n • uporabi telefona pri visokih temp."</string> diff --git a/packages/SystemUI/res/values-sl/strings_tv.xml b/packages/SystemUI/res/values-sl/strings_tv.xml index d3e4f259f881..109d797ebcf9 100644 --- a/packages/SystemUI/res/values-sl/strings_tv.xml +++ b/packages/SystemUI/res/values-sl/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Slika v sliki"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Program brez naslova)"</string> - <string name="pip_close" msgid="5775212044472849930">"Zapri način PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Celozaslonsko"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofon je aktiven"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikacija %1$s je dostopala do mikrofona"</string> </resources> diff --git a/packages/SystemUI/res/values-sq/strings_tv.xml b/packages/SystemUI/res/values-sq/strings_tv.xml index 624be930cc92..6cecdb6e38f4 100644 --- a/packages/SystemUI/res/values-sq/strings_tv.xml +++ b/packages/SystemUI/res/values-sq/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Figurë brenda figurës"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Program pa titull)"</string> - <string name="pip_close" msgid="5775212044472849930">"Mbyll PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Ekrani i plotë"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofoni aktiv"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s pati qasje te mikrofoni yt"</string> </resources> diff --git a/packages/SystemUI/res/values-sr/strings_tv.xml b/packages/SystemUI/res/values-sr/strings_tv.xml index 96846e702002..322938f4f787 100644 --- a/packages/SystemUI/res/values-sr/strings_tv.xml +++ b/packages/SystemUI/res/values-sr/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Слика у слици"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Програм без наслова)"</string> - <string name="pip_close" msgid="5775212044472849930">"Затвори PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Цео екран"</string> <string name="mic_active" msgid="5766614241012047024">"Микрофон је активан"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"Апликација %1$s је приступила микрофону"</string> </resources> diff --git a/packages/SystemUI/res/values-sv/strings_tv.xml b/packages/SystemUI/res/values-sv/strings_tv.xml index cf40057a005a..fb28af449fb7 100644 --- a/packages/SystemUI/res/values-sv/strings_tv.xml +++ b/packages/SystemUI/res/values-sv/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Bild-i-bild"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Namnlöst program)"</string> - <string name="pip_close" msgid="5775212044472849930">"Stäng PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Helskärm"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofonen är aktiv"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s har fått åtkomst till mikrofonen"</string> </resources> diff --git a/packages/SystemUI/res/values-sw/strings_tv.xml b/packages/SystemUI/res/values-sw/strings_tv.xml index 7e2a64cf5a6c..b51f93410bb4 100644 --- a/packages/SystemUI/res/values-sw/strings_tv.xml +++ b/packages/SystemUI/res/values-sw/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Picha ndani ya picha"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Programu isiyo na jina)"</string> - <string name="pip_close" msgid="5775212044472849930">"Funga PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Skrini nzima"</string> <string name="mic_active" msgid="5766614241012047024">"Maikrofoni Inatumika"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s imefikia maikrofoni yako"</string> </resources> diff --git a/packages/SystemUI/res/values-ta/strings_tv.xml b/packages/SystemUI/res/values-ta/strings_tv.xml index 43418053f841..1ae3d1d3bdcd 100644 --- a/packages/SystemUI/res/values-ta/strings_tv.xml +++ b/packages/SystemUI/res/values-ta/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"பிக்ச்சர்-இன்-பிக்ச்சர்"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(தலைப்பு இல்லை)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIPஐ மூடு"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"முழுத்திரை"</string> <string name="mic_active" msgid="5766614241012047024">"மைக்ரோஃபோன் செயலிலுள்ளது"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s உங்கள் மைக்ரோஃபோனைப் பயன்படுத்தியது"</string> </resources> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 49c9af1bad48..13319d9719b8 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -917,17 +917,13 @@ <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>లో <xliff:g id="ID_1">%1$d</xliff:g>వ పేజీ"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"లాక్ స్క్రీన్"</string> <string name="thermal_shutdown_title" msgid="2702966892682930264">"వేడెక్కినందుకు ఫోన్ ఆఫ్ చేయబడింది"</string> - <!-- no translation found for thermal_shutdown_message (6142269839066172984) --> - <skip /> + <string name="thermal_shutdown_message" msgid="6142269839066172984">"మీ ఫోన్ ఇప్పుడు సాధారణంగా పని చేస్తోంది.\nమరింత సమాచారం కోసం ట్యాప్ చేయండి"</string> <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"మీ ఫోన్ చాలా వేడిగా ఉంది, కనుక చల్లబర్చడానికి ఆఫ్ చేయబడింది. మీ ఫోన్ ఇప్పుడు సాధారణంగా పని చేస్తుంది.\n\nమీరు ఇలా చేస్తే మీ ఫోన్ చాలా వేడెక్కవచ్చు:\n • వనరు-ఆధారిత అనువర్తనాలు (గేమింగ్, వీడియో లేదా నావిగేషన్ వంటి అనువర్తనాలు) ఉపయోగించడం\n • పెద్ద ఫైల్లను డౌన్లోడ్ లేదా అప్లోడ్ చేయడం\n • అధిక ఉష్ణోగ్రతలలో మీ ఫోన్ని ఉపయోగించడం"</string> - <!-- no translation found for thermal_shutdown_dialog_help_text (6413474593462902901) --> - <skip /> + <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"తీసుకోవాల్సిన జాగ్రత్తలు ఏమిటో చూడండి"</string> <string name="high_temp_title" msgid="2218333576838496100">"ఫోన్ వేడెక్కుతోంది"</string> - <!-- no translation found for high_temp_notif_message (1277346543068257549) --> - <skip /> + <string name="high_temp_notif_message" msgid="1277346543068257549">"ఫోన్ను చల్లబరిచే క్రమంలో కొన్ని ఫీచర్లు పరిమితం చేయబడ్డాయి.\nమరింత సమాచారం కోసం ట్యాప్ చేయండి"</string> <string name="high_temp_dialog_message" msgid="3793606072661253968">"మీ ఫోన్ స్వయంచాలకంగా చల్లబడటానికి ప్రయత్నిస్తుంది. మీరు ఇప్పటికీ మీ ఫోన్ను ఉపయోగించవచ్చు, కానీ దాని పనితీరు నెమ్మదిగా ఉండవచ్చు.\n\nమీ ఫోన్ చల్లబడిన తర్వాత, అది సాధారణ రీతిలో పని చేస్తుంది."</string> - <!-- no translation found for high_temp_dialog_help_text (7380171287943345858) --> - <skip /> + <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"తీసుకోవాల్సిన జాగ్రత్తలు ఏమిటో చూడండి"</string> <string name="high_temp_alarm_title" msgid="2359958549570161495">"ప్లగ్ నుండి ఛార్జర్ తీసివేయండి"</string> <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"ఈ పరికరాన్ని ఛార్జ్ చేయడంలో సమస్య ఉంది. పవర్ అడాప్టర్ను ప్లగ్ నుండి తీసివేసి, కేబుల్ ఏమైనా వేడిగా అయితే తగిన జాగ్రత్తలు తీసుకోండి."</string> <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"తీసుకోవాల్సిన జాగ్రత్తలు ఏమిటో చూడండి"</string> diff --git a/packages/SystemUI/res/values-te/strings_tv.xml b/packages/SystemUI/res/values-te/strings_tv.xml index df8b06d6705a..27911795d771 100644 --- a/packages/SystemUI/res/values-te/strings_tv.xml +++ b/packages/SystemUI/res/values-te/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"పిక్చర్-ఇన్-పిక్చర్"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(శీర్షిక లేని ప్రోగ్రామ్)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIPని మూసివేయి"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"పూర్తి స్క్రీన్"</string> <string name="mic_active" msgid="5766614241012047024">"మైక్రోఫోన్ యాక్టివ్గా ఉంది"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"మీ మైక్రోఫోన్ను %1$s యాక్సెస్ చేసింది"</string> </resources> diff --git a/packages/SystemUI/res/values-th/strings_tv.xml b/packages/SystemUI/res/values-th/strings_tv.xml index 14d458a5a4f2..783b1f47ca7a 100644 --- a/packages/SystemUI/res/values-th/strings_tv.xml +++ b/packages/SystemUI/res/values-th/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"การแสดงภาพซ้อนภาพ"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(ไม่มีชื่อรายการ)"</string> - <string name="pip_close" msgid="5775212044472849930">"ปิด PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"เต็มหน้าจอ"</string> <string name="mic_active" msgid="5766614241012047024">"ไมโครโฟนเปิดใช้งานอยู่"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s เข้าถึงไมโครโฟนแล้ว"</string> </resources> diff --git a/packages/SystemUI/res/values-tl/strings_tv.xml b/packages/SystemUI/res/values-tl/strings_tv.xml index 6e873f30edf2..bf46b8fe599a 100644 --- a/packages/SystemUI/res/values-tl/strings_tv.xml +++ b/packages/SystemUI/res/values-tl/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Picture-in-Picture"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Walang pamagat na programa)"</string> - <string name="pip_close" msgid="5775212044472849930">"Isara ang PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Full screen"</string> <string name="mic_active" msgid="5766614241012047024">"Aktibo ang Mikropono"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"Na-access ng %1$s ang iyong mikropono"</string> </resources> diff --git a/packages/SystemUI/res/values-tr/strings_tv.xml b/packages/SystemUI/res/values-tr/strings_tv.xml index be87e4cbcbda..30d1fc9cdb9f 100644 --- a/packages/SystemUI/res/values-tr/strings_tv.xml +++ b/packages/SystemUI/res/values-tr/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Pencere İçinde Pencere"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Başlıksız program)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP\'yi kapat"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Tam ekran"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofon Etkin"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s mikrofonunuza erişti"</string> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 66df805a2a2f..11eb18cc48d2 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -929,11 +929,11 @@ <string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон перегрівся й вимкнувся"</string> <string name="thermal_shutdown_message" msgid="6142269839066172984">"Зараз телефон працює як зазвичай.\nНатисніть, щоб дізнатися більше"</string> <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Телефон перегрівся, тому вимкнувся, щоб охолонути. Зараз він працює, як зазвичай.\n\nТелефон перегрівається, якщо ви:\n • використовуєте ресурсомісткі додатки (ігри, відео, навігація)\n • завантажуєте великі файли на телефон або з нього\n • використовуєте телефон за високої температури"</string> - <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Переглянути застереження"</string> + <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Переглянути запобіжні заходи"</string> <string name="high_temp_title" msgid="2218333576838496100">"Телефон нагрівається"</string> <string name="high_temp_notif_message" msgid="1277346543068257549">"Під час охолодження деякі функції обмежуються.\nНатисніть, щоб дізнатися більше"</string> <string name="high_temp_dialog_message" msgid="3793606072661253968">"Ваш телефон охолоджуватиметься автоматично. Ви можете далі користуватися телефоном, але він може працювати повільніше.\n\nКоли телефон охолоне, він працюватиме належним чином."</string> - <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Переглянути застереження"</string> + <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Переглянути запобіжні заходи"</string> <string name="high_temp_alarm_title" msgid="2359958549570161495">"Відключіть зарядний пристрій"</string> <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"Виникла проблема із заряджанням пристрою. Відключіть адаптер живлення, однак будьте обережні, оскільки кабель може бути гарячим."</string> <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"Переглянути застереження"</string> diff --git a/packages/SystemUI/res/values-uk/strings_tv.xml b/packages/SystemUI/res/values-uk/strings_tv.xml index a11e553fea62..e3872cc35963 100644 --- a/packages/SystemUI/res/values-uk/strings_tv.xml +++ b/packages/SystemUI/res/values-uk/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Картинка в картинці"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Програма без назви)"</string> - <string name="pip_close" msgid="5775212044472849930">"Закрити PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"На весь екран"</string> <string name="mic_active" msgid="5766614241012047024">"Мікрофон активовано"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"Додаток %1$s отримав доступ до вашого мікрофона"</string> </resources> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index b740d22921dc..d7645e9bcb5b 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -917,17 +917,13 @@ <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"صفحہ <xliff:g id="ID_1">%1$d</xliff:g> از <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"مقفل اسکرین"</string> <string name="thermal_shutdown_title" msgid="2702966892682930264">"حرارت کی وجہ سے فون آف ہو گیا"</string> - <!-- no translation found for thermal_shutdown_message (6142269839066172984) --> - <skip /> + <string name="thermal_shutdown_message" msgid="6142269839066172984">"آپ کا فون اب حسب معمول چل رہا ہے۔\nمزید معلومات کیلئے تھپتھپائیں"</string> <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"آپ کا فون کافی گرم ہو گيا تھا، اس لئے سرد ہونے کیلئے یہ آف ہو گیا۔ اب آپ کا فون حسب معمول کام کر رہا ہے۔\n\nمندرجہ ذیل چیزیں کرنے پر آپ کا فون کافی گرم ہو سکتا ہے:\n • ماخذ کا زیادہ استعمال کرنے والی ایپس (جیسے کہ گیمنگ، ویڈیو، یا نیویگیشن ایپس) کا استعمال کرنا\n • بڑی فائلز ڈاؤن لوڈ یا اپ لوڈ کرنا\n • اعلی درجہ حرارت میں فون کا استعمال کرنا"</string> - <!-- no translation found for thermal_shutdown_dialog_help_text (6413474593462902901) --> - <skip /> + <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"نگہداشت کے اقدامات ملاحظہ کریں"</string> <string name="high_temp_title" msgid="2218333576838496100">"فون گرم ہو رہا ہے"</string> - <!-- no translation found for high_temp_notif_message (1277346543068257549) --> - <skip /> + <string name="high_temp_notif_message" msgid="1277346543068257549">"فون کے ٹھنڈے ہو جانے تک کچھ خصوصیات محدود ہیں۔\nمزید معلومات کیلئے تھپتھپائیں"</string> <string name="high_temp_dialog_message" msgid="3793606072661253968">"آپ کا فون خودکار طور پر ٹھنڈا ہونے کی کوشش کرے گا۔ آپ ابھی بھی اپنا فون استعمال کر سکتے ہیں، مگر ہو سکتا ہے یہ سست چلے۔\n\nایک بار آپ کا فون ٹھنڈا ہوجائے تو یہ معمول کے مطابق چلے گا۔"</string> - <!-- no translation found for high_temp_dialog_help_text (7380171287943345858) --> - <skip /> + <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"نگہداشت کے اقدامات ملاحظہ کریں"</string> <string name="high_temp_alarm_title" msgid="2359958549570161495">"چارجر ان پلگ کریں"</string> <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"اس آلہ کو چارج کرنے میں ایک مسئلہ ہے۔ پاور ایڈاپٹر کو ان پلگ کریں اور دھیان دیں کیونکہ تار گرم ہو سکتا ہے۔"</string> <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"نگہداشت کے اقدامات ملاحظہ کریں"</string> diff --git a/packages/SystemUI/res/values-ur/strings_tv.xml b/packages/SystemUI/res/values-ur/strings_tv.xml index 8f5ad0d63cf1..cb50fafaf931 100644 --- a/packages/SystemUI/res/values-ur/strings_tv.xml +++ b/packages/SystemUI/res/values-ur/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"تصویر میں تصویر"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(بلا عنوان پروگرام)"</string> - <string name="pip_close" msgid="5775212044472849930">"PIP بند کریں"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"فُل اسکرین"</string> <string name="mic_active" msgid="5766614241012047024">"مائیکروفون فعال ہے"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s نے آپ کے مائیکروفون تک رسائی حاصل کی ہے"</string> </resources> diff --git a/packages/SystemUI/res/values-uz/strings_tv.xml b/packages/SystemUI/res/values-uz/strings_tv.xml index 6fb5d732bfbd..09bc51ee293c 100644 --- a/packages/SystemUI/res/values-uz/strings_tv.xml +++ b/packages/SystemUI/res/values-uz/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Tasvir ustida tasvir"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Nomsiz)"</string> - <string name="pip_close" msgid="5775212044472849930">"Kadr ichida kadr – chiqish"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Butun ekran"</string> <string name="mic_active" msgid="5766614241012047024">"Mikrofon faol"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s mikrofondan foydalandi"</string> </resources> diff --git a/packages/SystemUI/res/values-vi/strings_tv.xml b/packages/SystemUI/res/values-vi/strings_tv.xml index 03b53561d06e..f298407bcaf3 100644 --- a/packages/SystemUI/res/values-vi/strings_tv.xml +++ b/packages/SystemUI/res/values-vi/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Ảnh trong ảnh"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Không có chương trình tiêu đề)"</string> - <string name="pip_close" msgid="5775212044472849930">"Đóng PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Toàn màn hình"</string> <string name="mic_active" msgid="5766614241012047024">"Micrô đang hoạt động"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s đang dùng micrô của bạn"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml index acb6ee0123e6..aa3e251c9c35 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"画中画"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(节目没有标题)"</string> - <string name="pip_close" msgid="5775212044472849930">"关闭画中画"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"全屏"</string> <string name="mic_active" msgid="5766614241012047024">"麦克风处于启用状态"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s访问过您的麦克风"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml index 1cd63144b904..45d3229cdcb6 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"畫中畫"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(沒有標題的節目)"</string> - <string name="pip_close" msgid="5775212044472849930">"關閉 PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"全螢幕"</string> <string name="mic_active" msgid="5766614241012047024">"麥克風已啟用"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"「%1$s」已存取您的麥克風"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml index b48fc6f99755..fdd088449567 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"子母畫面"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(無標題的節目)"</string> - <string name="pip_close" msgid="5775212044472849930">"關閉子母畫面"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"全螢幕"</string> <string name="mic_active" msgid="5766614241012047024">"麥克風已開啟"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"「%1$s」已存取你的麥克風"</string> </resources> diff --git a/packages/SystemUI/res/values-zu/strings_tv.xml b/packages/SystemUI/res/values-zu/strings_tv.xml index c6f8d3ffcc74..4fed753a88ad 100644 --- a/packages/SystemUI/res/values-zu/strings_tv.xml +++ b/packages/SystemUI/res/values-zu/strings_tv.xml @@ -19,10 +19,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"Isithombe-esithombeni"</string> - <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Alukho uhlelo lwesihloko)"</string> - <string name="pip_close" msgid="5775212044472849930">"Vala i-PIP"</string> - <string name="pip_fullscreen" msgid="3877997489869475181">"Iskrini esigcwele"</string> <string name="mic_active" msgid="5766614241012047024">"Imakrofoni iyasebenza"</string> <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ifinyelele imakrofoni yakho"</string> </resources> diff --git a/packages/SystemUI/res/values/arrays_tv.xml b/packages/SystemUI/res/values/arrays_tv.xml index 3343a84e7a9c..9c7707791180 100644 --- a/packages/SystemUI/res/values/arrays_tv.xml +++ b/packages/SystemUI/res/values/arrays_tv.xml @@ -17,23 +17,6 @@ */ --> <resources> - <!-- List of package names or class names which are considered as Settings, - so PIP location should be adjusted to the left of the side panel. - If it should be applied for all activities in a package, add the package name. - If it should be applied for an activity in a package, add its class name with package name. - The class name must follow format 'package_name/.class_name' ('/.' in between). - This can be overriden in an overlay. - --> - <string-array name="tv_pip_settings_class_name" translatable="false"> - <item>com.android.tv.settings</item> - <item>com.google.android.leanbacklauncher/.settings.HomeScreenSettingsActivity</item> - <item>com.google.android.apps.mediashell/.settings.CastSettingsActivity</item> - <item>com.google.android.katniss.setting/.SpeechSettingsActivity</item> - <item>com.google.android.katniss.setting/.SearchSettingsActivity</item> - <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"> </string-array> </resources> diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml index 10c72102bba3..84dbd60b799d 100644 --- a/packages/SystemUI/res/values/attrs.xml +++ b/packages/SystemUI/res/values/attrs.xml @@ -133,11 +133,6 @@ <attr name="buttonStrokeWidth" format="dimension" /> </declare-styleable> - <!-- Used to style rotate suggestion button AVD animations --> - <attr name="rotateButtonStartAngle" format="float" /> - <attr name="rotateButtonEndAngle" format="float" /> - <attr name="rotateButtonScaleX" format="float" /> - <!-- Used to style charging animation AVD animation --> <attr name="chargingAnimColor" format="color" /> diff --git a/packages/SystemUI/res/values/config_tv.xml b/packages/SystemUI/res/values/config_tv.xml index d8c9428f2676..5cb840f24c84 100644 --- a/packages/SystemUI/res/values/config_tv.xml +++ b/packages/SystemUI/res/values/config_tv.xml @@ -16,10 +16,6 @@ <resources> <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows, - when the PIP menu is shown with settings. --> - <string translatable="false" name="pip_settings_bounds">"662 756 1142 1026"</string> - - <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows, when the PIP menu is shown in center. --> <string translatable="false" name="pip_menu_bounds">"596 280 1324 690"</string> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 68c2a38f53c3..9e5b94ee855c 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -604,31 +604,6 @@ <item name="android:colorBackground">?android:attr/colorSecondary</item> </style> - <!-- Used to style rotate suggestion button AVD animations --> - <style name="RotateButtonCCWStart0"> - <item name="rotateButtonStartAngle">0</item> - <item name="rotateButtonEndAngle">-90</item> - <item name="rotateButtonScaleX">1</item> - </style> - - <style name="RotateButtonCCWStart90"> - <item name="rotateButtonStartAngle">90</item> - <item name="rotateButtonEndAngle">0</item> - <item name="rotateButtonScaleX">1</item> - </style> - - <style name="RotateButtonCWStart0"> - <item name="rotateButtonStartAngle">0</item> - <item name="rotateButtonEndAngle">90</item> - <item name="rotateButtonScaleX">-1</item> - </style> - - <style name="RotateButtonCWStart90"> - <item name="rotateButtonStartAngle">90</item> - <item name="rotateButtonEndAngle">180</item> - <item name="rotateButtonScaleX">-1</item> - </style> - <style name="MediaPlayer.Button" parent="@android:style/Widget.Material.Button.Borderless.Small"> <item name="android:background">@drawable/qs_media_light_source</item> <item name="android:tint">@android:color/white</item> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java index 65bf7e6e5025..97317cf5580f 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java @@ -138,7 +138,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView case PROMPT_REASON_USER_REQUEST: return R.string.kg_prompt_reason_user_request; case PROMPT_REASON_PREPARE_FOR_UPDATE: - return R.string.kg_prompt_reason_prepare_for_update_password; + return R.string.kg_prompt_reason_timeout_password; case PROMPT_REASON_NONE: return 0; default: diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java index ad92f8f623e4..c4a9fcb45284 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java @@ -440,8 +440,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_user_request); break; case PROMPT_REASON_PREPARE_FOR_UPDATE: - mSecurityMessageDisplay.setMessage( - R.string.kg_prompt_reason_prepare_for_update_pattern); + mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_timeout_pattern); break; case PROMPT_REASON_NONE: break; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java index 6d865ab525f3..c7f27cf8a71a 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java @@ -117,7 +117,7 @@ public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView case PROMPT_REASON_USER_REQUEST: return R.string.kg_prompt_reason_user_request; case PROMPT_REASON_PREPARE_FOR_UPDATE: - return R.string.kg_prompt_reason_prepare_for_update_pin; + return R.string.kg_prompt_reason_timeout_pin; case PROMPT_REASON_NONE: return 0; default: diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 498b6b2455d7..8a36e7b127db 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -1338,7 +1338,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private CancellationSignal mFaceCancelSignal; private FingerprintManager mFpm; private FaceManager mFaceManager; - private FaceSensorProperties mFaceSensorProperties; + private List<FaceSensorProperties> mFaceSensorProperties; private boolean mFingerprintLockedOut; private TelephonyManager mTelephonyManager; @@ -2100,7 +2100,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } mFaceCancelSignal = new CancellationSignal(); - if (isEncryptedOrLockdown(userId) && mFaceSensorProperties.supportsFaceDetection) { + // This would need to be updated for multi-sensor devices + final boolean supportsFaceDetection = !mFaceSensorProperties.isEmpty() + && mFaceSensorProperties.get(0).supportsFaceDetection; + if (isEncryptedOrLockdown(userId) && supportsFaceDetection) { mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback, userId); } else { mFaceManager.authenticate(null /* crypto */, mFaceCancelSignal, diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index 42911374dc87..980e4c0fd333 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -38,6 +38,7 @@ import android.hardware.biometrics.IBiometricSysuiReceiver; import android.hardware.biometrics.PromptInfo; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; +import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.IFingerprintService; import android.os.Bundle; import android.os.Handler; @@ -265,6 +266,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, context.registerReceiver(mBroadcastReceiver, filter); } + @SuppressWarnings("deprecation") @Override public void start() { mCommandQueue.addCallback(this); @@ -273,10 +275,13 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, final FingerprintManager fpm = mContext.getSystemService(FingerprintManager.class); if (fpm != null && fpm.isHardwareDetected()) { - // TODO(b/160024833): Enumerate through all of the sensors and check whether - // at least one of them is UDFPS. - if (fpm.isUdfps()) { - mUdfpsController = new UdfpsController(mContext, mWindowManager); + final List<FingerprintSensorProperties> fingerprintSensorProperties = + fpm.getSensorProperties(); + for (FingerprintSensorProperties props : fingerprintSensorProperties) { + if (props.sensorType == FingerprintSensorProperties.TYPE_UDFPS) { + mUdfpsController = new UdfpsController(mContext, mWindowManager); + break; + } } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java index c6d128631930..87489262a420 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java @@ -712,22 +712,6 @@ class Bubble implements BubbleViewProvider { return Objects.hash(mKey); } - @Override - public void logUIEvent(int bubbleCount, int action, float normalX, float normalY, int index) { - SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED, - mPackageName, - mChannelId, - mNotificationId, - index, - bubbleCount, - action, - normalX, - normalY, - showInShade(), - false /* isOngoing (unused) */, - false /* isAppForeground (unused) */); - } - @Nullable private static String getTitle(@NonNull final NotificationEntry e) { final CharSequence titleCharSeq = e.getSbn().getNotification().extras.getCharSequence( diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java index d2dc506c8e5c..10f4385ed443 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java @@ -34,6 +34,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.R; import com.android.systemui.bubbles.BubbleController.DismissReason; +import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -59,7 +60,7 @@ import javax.inject.Singleton; @Singleton public class BubbleData { - private BubbleLogger mLogger = new BubbleLoggerImpl(); + private BubbleLoggerImpl mLogger = new BubbleLoggerImpl(); private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleData" : TAG_BUBBLES; @@ -611,6 +612,30 @@ public class BubbleData { } /** + * Logs the bubble UI event. + * + * @param provider The bubble view provider that is being interacted on. Null value indicates + * that the user interaction is not specific to one bubble. + * @param action The user interaction enum + * @param packageName SystemUI package + * @param bubbleCount Number of bubbles in the stack + * @param bubbleIndex Index of bubble in the stack + * @param normalX Normalized x position of the stack + * @param normalY Normalized y position of the stack + */ + void logBubbleEvent(@Nullable BubbleViewProvider provider, int action, String packageName, + int bubbleCount, int bubbleIndex, float normalX, float normalY) { + if (provider == null) { + mLogger.logStackUiChanged(packageName, action, bubbleCount, normalX, normalY); + } else if (provider.getKey().equals(BubbleOverflow.KEY)) { + mLogger.logShowOverflow(packageName, action, bubbleCount, normalX, normalY); + } else { + mLogger.logBubbleUiChanged((Bubble) provider, packageName, action, bubbleCount, normalX, + normalY, bubbleIndex); + } + } + + /** * Requests a change to the expanded state. * * @param shouldExpand the new requested state diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLoggerImpl.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLoggerImpl.java index c1dd8c36ff6f..d702cc4e0062 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLoggerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLoggerImpl.java @@ -17,6 +17,7 @@ package com.android.systemui.bubbles; import com.android.internal.logging.UiEventLoggerImpl; +import com.android.systemui.shared.system.SysUiStatsLog; /** * Implementation of UiEventLogger for logging bubble UI events. @@ -64,4 +65,52 @@ public class BubbleLoggerImpl extends UiEventLoggerImpl implements BubbleLogger log(b, Event.BUBBLE_OVERFLOW_ADD_USER_GESTURE); } } + + void logStackUiChanged(String packageName, int action, int bubbleCount, float normalX, + float normalY) { + SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED, + packageName, + null /* notification channel */, + 0 /* notification ID */, + 0 /* bubble position */, + bubbleCount, + action, + normalX, + normalY, + false /* unread bubble */, + false /* on-going bubble */, + false /* isAppForeground (unused) */); + } + + void logShowOverflow(String packageName, int action, int bubbleCount, float normalX, + float normalY) { + SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED, + packageName, + BubbleOverflow.KEY /* notification channel */, + 0 /* notification ID */, + 0 /* bubble position */, + bubbleCount, + action, + normalX, + normalY, + false /* unread bubble */, + false /* on-going bubble */, + false /* isAppForeground (unused) */); + } + + void logBubbleUiChanged(Bubble bubble, String packageName, int action, int bubbleCount, + float normalX, float normalY, int index) { + SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED, + packageName, + bubble.getChannelId() /* notification channel */, + bubble.getNotificationId() /* notification ID */, + index, + bubbleCount, + action, + normalX, + normalY, + bubble.showInShade() /* isUnread */, + false /* isOngoing (unused) */, + false /* isAppForeground (unused) */); + } }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java index dadcb3a3a7c4..bb9d1095a37a 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java @@ -163,12 +163,6 @@ public class BubbleOverflow implements BubbleViewProvider { } @Override - public void logUIEvent(int bubbleCount, int action, float normalX, float normalY, - int index) { - // TODO(b/149133814) Log overflow UI events. - } - - @Override public View getIconView() { return mOverflowBtn; } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index b328f62e067e..f02945ef843a 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -2891,23 +2891,13 @@ public class BubbleStackView extends FrameLayout * @param action the user interaction enum. */ private void logBubbleEvent(@Nullable BubbleViewProvider provider, int action) { - if (provider == null || provider.getKey().equals(BubbleOverflow.KEY)) { - SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED, - mContext.getApplicationInfo().packageName, - provider == null ? null : BubbleOverflow.KEY /* notification channel */, - 0 /* notification ID */, - 0 /* bubble position */, - getBubbleCount(), - action, - getNormalizedXPosition(), - getNormalizedYPosition(), - false /* unread bubble */, - false /* on-going bubble */, - false /* isAppForeground (unused) */); - return; - } - provider.logUIEvent(getBubbleCount(), action, getNormalizedXPosition(), - getNormalizedYPosition(), getBubbleIndex(provider)); + mBubbleData.logBubbleEvent(provider, + action, + mContext.getApplicationInfo().packageName, + getBubbleCount(), + getBubbleIndex(provider), + getNormalizedXPosition(), + getNormalizedYPosition()); } /** diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java index ca3e2e27fa9a..f1a01be48397 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java @@ -32,8 +32,6 @@ interface BubbleViewProvider { @Nullable View getIconView(); - void logUIEvent(int bubbleCount, int action, float normalX, float normalY, int index); - String getKey(); Bitmap getBadgedImage(); diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java index ab7af43f91d2..f35322bd2a77 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java @@ -22,7 +22,6 @@ import android.content.Context; import android.hardware.SensorManager; import android.net.Uri; import android.provider.DeviceConfig; -import android.util.DisplayMetrics; import android.view.MotionEvent; import androidx.annotation.NonNull; @@ -62,7 +61,7 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { private static final String PROXIMITY_SENSOR_TAG = "FalsingManager"; private final ProximitySensor mProximitySensor; - private final DisplayMetrics mDisplayMetrics; + private final FalsingDataProvider mFalsingDataProvider; private FalsingManager mInternalFalsingManager; private DeviceConfig.OnPropertiesChangedListener mDeviceConfigListener; private final DeviceConfigProxy mDeviceConfig; @@ -74,18 +73,19 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { @Inject FalsingManagerProxy(Context context, PluginManager pluginManager, @Main Executor executor, - DisplayMetrics displayMetrics, ProximitySensor proximitySensor, + ProximitySensor proximitySensor, DeviceConfigProxy deviceConfig, DockManager dockManager, KeyguardUpdateMonitor keyguardUpdateMonitor, DumpManager dumpManager, @UiBackground Executor uiBgExecutor, - StatusBarStateController statusBarStateController) { - mDisplayMetrics = displayMetrics; + StatusBarStateController statusBarStateController, + FalsingDataProvider falsingDataProvider) { mProximitySensor = proximitySensor; mDockManager = dockManager; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mUiBgExecutor = uiBgExecutor; mStatusBarStateController = statusBarStateController; + mFalsingDataProvider = falsingDataProvider; mProximitySensor.setTag(PROXIMITY_SENSOR_TAG); mProximitySensor.setDelay(SensorManager.SENSOR_DELAY_GAME); mDeviceConfig = deviceConfig; @@ -143,7 +143,7 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { mInternalFalsingManager = new FalsingManagerImpl(context, mUiBgExecutor); } else { mInternalFalsingManager = new BrightLineFalsingManager( - new FalsingDataProvider(mDisplayMetrics), + mFalsingDataProvider, mKeyguardUpdateMonitor, mProximitySensor, mDeviceConfig, diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java index 95d5ad9a7a94..a50f9ce9713b 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java @@ -132,7 +132,9 @@ public class BrightLineFalsingManager implements FalsingManager { } private void registerSensors() { - mProximitySensor.register(mSensorEventListener); + if (!mDataProvider.isWirelessCharging()) { + mProximitySensor.register(mSensorEventListener); + } } private void unregisterSensors() { diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingDataProvider.java index 5494c644c22c..ea46441c8fbe 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingDataProvider.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingDataProvider.java @@ -22,10 +22,13 @@ import android.view.MotionEvent.PointerCoords; import android.view.MotionEvent.PointerProperties; import com.android.systemui.classifier.Classifier; +import com.android.systemui.statusbar.policy.BatteryController; import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; + /** * Acts as a cache and utility class for FalsingClassifiers. */ @@ -36,6 +39,7 @@ public class FalsingDataProvider { private final int mWidthPixels; private final int mHeightPixels; + private final BatteryController mBatteryController; private final float mXdpi; private final float mYdpi; @@ -50,11 +54,13 @@ public class FalsingDataProvider { private MotionEvent mFirstRecentMotionEvent; private MotionEvent mLastMotionEvent; - public FalsingDataProvider(DisplayMetrics displayMetrics) { + @Inject + public FalsingDataProvider(DisplayMetrics displayMetrics, BatteryController batteryController) { mXdpi = displayMetrics.xdpi; mYdpi = displayMetrics.ydpi; mWidthPixels = displayMetrics.widthPixels; mHeightPixels = displayMetrics.heightPixels; + mBatteryController = batteryController; FalsingClassifier.logInfo("xdpi, ydpi: " + getXdpi() + ", " + getYdpi()); FalsingClassifier.logInfo("width, height: " + getWidthPixels() + ", " + getHeightPixels()); @@ -177,6 +183,11 @@ public class FalsingDataProvider { return mLastMotionEvent.getY() < mFirstRecentMotionEvent.getY(); } + /** Returns true if phone is being charged without a cable. */ + boolean isWirelessCharging() { + return mBatteryController.isWirelessCharging(); + } + private void recalculateData() { if (!mDirty) { return; diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java index 6b8fcd562e6f..e5cc1384efa4 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java @@ -29,6 +29,7 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.fragments.FragmentService; import com.android.systemui.keyguard.KeyguardSliceProvider; import com.android.systemui.onehanded.dagger.OneHandedModule; +import com.android.systemui.pip.phone.PipMenuActivity; import com.android.systemui.pip.phone.dagger.PipModule; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.util.InjectionInflationController; @@ -121,4 +122,9 @@ public interface SystemUIRootComponent { * Member injection into the supplied argument. */ void inject(KeyguardSliceProvider keyguardSliceProvider); + + /** + * Member injection into the supplied argument. + */ + void inject(PipMenuActivity pipMenuActivity); } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index 0800a201bd92..abbbd1713250 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -408,10 +408,13 @@ public class DozeTriggers implements DozeMachine.Part { break; case DOZE_PULSING: case DOZE_PULSING_BRIGHT: - case DOZE_AOD_DOCKED: mWantProx = true; mWantTouchScreenSensors = false; break; + case DOZE_AOD_DOCKED: + mWantProx = false; + mWantTouchScreenSensors = false; + break; case DOZE_PULSE_DONE: mDozeSensors.requestTemporaryDisable(); // A pulse will temporarily disable sensors that require a touch screen. diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index e12b7dd259a5..075318b3f1f7 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -306,7 +306,7 @@ class MediaCarouselController @Inject constructor( private fun updatePageIndicator() { val numPages = mediaContent.getChildCount() - pageIndicator.setNumPages(numPages, Color.WHITE) + pageIndicator.setNumPages(numPages) if (numPages == 1) { pageIndicator.setLocation(0f) } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index 0d6b522046f7..35e56ee87967 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -178,6 +178,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements Rect startBounds = (Rect) args.arg2; Rect toBounds = (Rect) args.arg3; userResizePip(startBounds, toBounds); + if (updateBoundsCallback != null) { + updateBoundsCallback.accept(toBounds); + } break; } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java index 05b9b0ec3957..361aafacdf76 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java @@ -36,9 +36,9 @@ import android.media.session.PlaybackState; import android.os.UserHandle; import com.android.systemui.Dependency; +import com.android.systemui.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.statusbar.policy.UserInfoController; -import com.android.wm.shell.R; import java.util.ArrayList; import java.util.Collections; diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java index ad5a13e78cb4..d6f3e163ad70 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java @@ -76,12 +76,15 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import com.android.systemui.Interpolators; +import com.android.systemui.SystemUIFactory; import com.android.wm.shell.R; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import javax.inject.Inject; + /** * Translucent activity that gets started on top of a task in PIP to allow the user to control it. */ @@ -100,6 +103,7 @@ public class PipMenuActivity extends Activity { public static final int MESSAGE_POINTER_EVENT = 7; public static final int MESSAGE_MENU_EXPANDED = 8; public static final int MESSAGE_FADE_OUT_MENU = 9; + public static final int MESSAGE_UPDATE_MENU_LAYOUT = 10; private static final int INITIAL_DISMISS_DELAY = 3500; private static final int POST_INTERACTION_DISMISS_DELAY = 2000; @@ -129,8 +133,12 @@ public class PipMenuActivity extends Activity { private View mSettingsButton; private View mDismissButton; private View mResizeHandle; + private View mTopEndContainer; private int mBetweenActionPaddingLand; + @Inject + PipMenuIconsAlgorithm mPipMenuIconsAlgorithm; + private AnimatorSet mMenuContainerAnimator; private ValueAnimator.AnimatorUpdateListener mMenuBgUpdateListener = @@ -193,6 +201,11 @@ public class PipMenuActivity extends Activity { fadeOutMenu(); break; } + case MESSAGE_UPDATE_MENU_LAYOUT: { + final Rect bounds = (Rect) msg.obj; + mPipMenuIconsAlgorithm.onBoundsChanged(bounds); + break; + } } } }; @@ -208,6 +221,9 @@ public class PipMenuActivity extends Activity { getWindow().addFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH); super.onCreate(savedInstanceState); + + SystemUIFactory.getInstance().getRootComponent().inject(this); + setContentView(R.layout.pip_menu_activity); mAccessibilityManager = getSystemService(AccessibilityManager.class); @@ -217,6 +233,7 @@ public class PipMenuActivity extends Activity { mViewRoot.setBackground(mBackgroundDrawable); mMenuContainer = findViewById(R.id.menu_container); mMenuContainer.setAlpha(0); + mTopEndContainer = findViewById(R.id.top_end_container); mSettingsButton = findViewById(R.id.settings); mSettingsButton.setAlpha(0); mSettingsButton.setOnClickListener((v) -> { @@ -238,6 +255,8 @@ public class PipMenuActivity extends Activity { mBetweenActionPaddingLand = getResources().getDimensionPixelSize( R.dimen.pip_between_action_padding_land); + mPipMenuIconsAlgorithm.bindViews((ViewGroup) mViewRoot, (ViewGroup) mTopEndContainer, + mResizeHandle, mSettingsButton, mDismissButton); updateFromIntent(getIntent()); setTitle(R.string.pip_menu_title); setDisablePreviewScreenshots(true); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java index 87e66fdc375c..267c5eacd139 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java @@ -574,6 +574,22 @@ public class PipMenuActivityController { } } + /** + * Tell the PIP Menu to recalculate its layout given its current position on the display. + */ + public void updateMenuLayout(Rect bounds) { + if (mToActivityMessenger != null) { + Message m = Message.obtain(); + m.what = PipMenuActivity.MESSAGE_UPDATE_MENU_LAYOUT; + m.obj = bounds; + try { + mToActivityMessenger.send(m); + } catch (RemoteException e) { + Log.e(TAG, "Could not dispatch touch event", e); + } + } + } + public void dump(PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; pw.println(prefix + TAG); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuIconsAlgorithm.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuIconsAlgorithm.java new file mode 100644 index 000000000000..69a04d8d3e22 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuIconsAlgorithm.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.pip.phone; + +import android.content.Context; +import android.graphics.Rect; +import android.util.Log; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +import javax.inject.Inject; + +/** + * Helper class to calculate and place the menu icons on the PIP Menu. + */ +public class PipMenuIconsAlgorithm { + + private static final String TAG = "PipMenuIconsAlgorithm"; + + private boolean mFinishedLayout = false; + protected ViewGroup mViewRoot; + protected ViewGroup mTopEndContainer; + protected View mDragHandle; + protected View mSettingsButton; + protected View mDismissButton; + + @Inject + public PipMenuIconsAlgorithm(Context context) { + } + + /** + * Bind the necessary views. + */ + public void bindViews(ViewGroup viewRoot, ViewGroup topEndContainer, View dragHandle, + View settingsButton, View dismissButton) { + mViewRoot = viewRoot; + mTopEndContainer = topEndContainer; + mDragHandle = dragHandle; + mSettingsButton = settingsButton; + mDismissButton = dismissButton; + } + + + /** + * Updates the position of the drag handle based on where the PIP window is on the screen. + */ + public void onBoundsChanged(Rect bounds) { + if (mViewRoot == null || mTopEndContainer == null || mDragHandle == null + || mSettingsButton == null || mDismissButton == null) { + Log.e(TAG, "One if the required views is null."); + } + + //We only need to calculate the layout once since it does not change. + if (!mFinishedLayout) { + mTopEndContainer.removeView(mSettingsButton); + mViewRoot.addView(mSettingsButton); + + setLayoutGravity(mDragHandle, Gravity.START | Gravity.TOP); + setLayoutGravity(mSettingsButton, Gravity.START | Gravity.TOP); + mFinishedLayout = true; + } + } + + /** + * Set the gravity on the given view. + */ + protected static void setLayoutGravity(View v, int gravity) { + if (v.getLayoutParams() instanceof FrameLayout.LayoutParams) { + FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) v.getLayoutParams(); + params.gravity = gravity; + v.setLayoutParams(params); + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java index 9f0b1de21b52..ca3ef2465498 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java @@ -127,7 +127,10 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, new PhysicsAnimator.SpringConfig( SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_LOW_BOUNCY); - private final Consumer<Rect> mUpdateBoundsCallback = mBounds::set; + private final Consumer<Rect> mUpdateBoundsCallback = (Rect newBounds) -> { + mMenuController.updateMenuLayout(newBounds); + mBounds.set(newBounds); + }; /** * Whether we're springing to the touch event location (vs. moving it to that position @@ -248,7 +251,10 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, mBounds.set(toBounds); } else { mTemporaryBounds.set(toBounds); - mPipTaskOrganizer.scheduleUserResizePip(mBounds, mTemporaryBounds, null); + mPipTaskOrganizer.scheduleUserResizePip(mBounds, mTemporaryBounds, + (Rect newBounds) -> { + mMenuController.updateMenuLayout(newBounds); + }); } } else { // If PIP is 'catching up' after being stuck in the dismiss target, update the animation diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index f4553fd3d716..5434b62e19b8 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -56,6 +56,7 @@ import androidx.dynamicanimation.animation.SpringForce; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.logging.MetricsLoggerWrapper; +import com.android.systemui.R; import com.android.systemui.model.SysUiState; import com.android.systemui.pip.PipAnimationController; import com.android.systemui.pip.PipBoundsHandler; @@ -67,7 +68,6 @@ import com.android.systemui.util.DismissCircleView; import com.android.systemui.util.FloatingContentCoordinator; import com.android.systemui.util.animation.PhysicsAnimator; import com.android.systemui.util.magnetictarget.MagnetizedObject; -import com.android.wm.shell.R; import java.io.PrintWriter; @@ -348,7 +348,7 @@ public class PipTouchHandler { } private boolean shouldShowResizeHandle() { - return !mPipBoundsHandler.hasSaveReentryBounds(); + return false; } public void setTouchGesture(PipTouchGesture gesture) { diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java index b8947ab05968..2138f092b790 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java @@ -43,10 +43,10 @@ import android.os.RemoteException; import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; -import android.util.Pair; import android.view.DisplayInfo; import com.android.systemui.Dependency; +import com.android.systemui.R; import com.android.systemui.UiOffloadThread; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.pip.BasePipManager; @@ -58,7 +58,6 @@ import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedSta import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.systemui.stackdivider.Divider; -import com.android.wm.shell.R; import java.util.ArrayList; import java.util.List; @@ -74,10 +73,6 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio private static final String TAG = "PipManager"; static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - private static final String SETTINGS_PACKAGE_AND_CLASS_DELIMITER = "/"; - - private static List<Pair<String, String>> sSettingsPackageAndClassNamePairList; - /** * State when there's no PIP. */ @@ -123,10 +118,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio private final Handler mHandler = new Handler(); private List<Listener> mListeners = new ArrayList<>(); private List<MediaListener> mMediaListeners = new ArrayList<>(); - private Rect mCurrentPipBounds; private Rect mPipBounds; private Rect mDefaultPipBounds = new Rect(); - private Rect mSettingsPipBounds; private Rect mMenuModePipBounds; private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED; private boolean mInitialized; @@ -261,37 +254,6 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio broadcastDispatcher.registerReceiver(mBroadcastReceiver, intentFilter, null /* handler */, UserHandle.ALL); - if (sSettingsPackageAndClassNamePairList == null) { - String[] settings = mContext.getResources().getStringArray( - R.array.tv_pip_settings_class_name); - sSettingsPackageAndClassNamePairList = new ArrayList<>(); - if (settings != null) { - for (int i = 0; i < settings.length; i++) { - Pair<String, String> entry = null; - String[] packageAndClassName = - settings[i].split(SETTINGS_PACKAGE_AND_CLASS_DELIMITER); - switch (packageAndClassName.length) { - case 1: - entry = Pair.<String, String>create(packageAndClassName[0], null); - break; - case 2: - if (packageAndClassName[1] != null) { - entry = Pair.<String, String>create(packageAndClassName[0], - packageAndClassName[1].startsWith(".") - ? packageAndClassName[0] + packageAndClassName[1] - : packageAndClassName[1]); - } - break; - } - if (entry != null) { - sSettingsPackageAndClassNamePairList.add(entry); - } else { - Log.w(TAG, "Ignoring malformed settings name " + settings[i]); - } - } - } - } - // Initialize the last orientation and apply the current configuration Configuration initialConfig = mContext.getResources().getConfiguration(); mLastOrientation = initialConfig.orientation; @@ -319,15 +281,13 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio } Resources res = mContext.getResources(); - mSettingsPipBounds = Rect.unflattenFromString(res.getString( - R.string.pip_settings_bounds)); mMenuModePipBounds = Rect.unflattenFromString(res.getString( R.string.pip_menu_bounds)); // Reset the PIP bounds and apply. PIP bounds can be changed by two reasons. // 1. Configuration changed due to the language change (RTL <-> RTL) // 2. SystemUI restarts after the crash - mPipBounds = isSettingsShown() ? mSettingsPipBounds : mDefaultPipBounds; + mPipBounds = mDefaultPipBounds; resizePinnedStack(getPinnedStackInfo() == null ? STATE_NO_PIP : STATE_PIP); } @@ -448,9 +408,10 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio return; } mState = state; + final Rect newBounds; switch (mState) { case STATE_NO_PIP: - mCurrentPipBounds = null; + newBounds = null; // If the state was already STATE_NO_PIP, then do not resize the stack below as it // will not exist if (wasStateNoPip) { @@ -458,16 +419,15 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio } break; case STATE_PIP_MENU: - mCurrentPipBounds = mMenuModePipBounds; + newBounds = mMenuModePipBounds; break; case STATE_PIP: // fallthrough default: - mCurrentPipBounds = mPipBounds; + newBounds = mPipBounds; break; } - if (mCurrentPipBounds != null) { - mPipTaskOrganizer.scheduleAnimateResizePip(mCurrentPipBounds, mResizeAnimationDuration, - null); + if (newBounds != null) { + mPipTaskOrganizer.scheduleAnimateResizePip(newBounds, mResizeAnimationDuration, null); } else { mPipTaskOrganizer.exitPip(mResizeAnimationDuration); } @@ -628,30 +588,6 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio return PLAYBACK_STATE_UNAVAILABLE; } - private boolean isSettingsShown() { - List<RunningTaskInfo> runningTasks; - try { - runningTasks = mActivityTaskManager.getTasks(1); - if (runningTasks.isEmpty()) { - return false; - } - } catch (RemoteException e) { - Log.d(TAG, "Failed to detect top activity", e); - return false; - } - ComponentName topActivity = runningTasks.get(0).topActivity; - for (Pair<String, String> componentName : sSettingsPackageAndClassNamePairList) { - String packageName = componentName.first; - if (topActivity.getPackageName().equals(packageName)) { - String className = componentName.second; - if (className == null || topActivity.getClassName().equals(className)) { - return true; - } - } - } - return false; - } - private TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() { @Override public void onTaskStackChanged() { @@ -680,9 +616,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio } } if (getState() == STATE_PIP) { - Rect bounds = isSettingsShown() ? mSettingsPipBounds : mDefaultPipBounds; - if (mPipBounds != bounds) { - mPipBounds = bounds; + if (mPipBounds != mDefaultPipBounds) { + mPipBounds = mDefaultPipBounds; resizePinnedStack(STATE_PIP); } } @@ -704,7 +639,6 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio stackInfo.taskNames[stackInfo.taskNames.length - 1]); // Set state to STATE_PIP so we show it when the pinned stack animation ends. mState = STATE_PIP; - mCurrentPipBounds = mPipBounds; mMediaSessionManager.addOnActiveSessionsChangedListener( mActiveMediaSessionListener, null); updateMediaController(mMediaSessionManager.getActiveSessions(null)); diff --git a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java index 2c76d70fb3cc..f8655cc44d2a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java @@ -10,10 +10,18 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; +import androidx.annotation.NonNull; + +import com.android.settingslib.Utils; import com.android.systemui.R; import java.util.ArrayList; +/** + * Page indicator for using with pageable layouts + * + * Supports {@code android.R.attr.tint}. If missing, it will use the current accent color. + */ public class PageIndicator extends ViewGroup { private static final String TAG = "PageIndicator"; @@ -31,12 +39,22 @@ public class PageIndicator extends ViewGroup { private final int mPageIndicatorWidth; private final int mPageIndicatorHeight; private final int mPageDotWidth; + private @NonNull ColorStateList mTint; private int mPosition = -1; private boolean mAnimating; public PageIndicator(Context context, AttributeSet attrs) { super(context, attrs); + + TypedArray array = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.tint}); + if (array.hasValue(0)) { + mTint = array.getColorStateList(0); + } else { + mTint = Utils.getColorAccent(context); + } + array.recycle(); + mPageIndicatorWidth = (int) mContext.getResources().getDimension(R.dimen.qs_page_indicator_width); mPageIndicatorHeight = @@ -45,15 +63,6 @@ public class PageIndicator extends ViewGroup { } public void setNumPages(int numPages) { - TypedArray array = getContext().obtainStyledAttributes( - new int[]{android.R.attr.colorControlActivated}); - int color = array.getColor(0, 0); - array.recycle(); - setNumPages(numPages, color); - } - - /** Overload of setNumPages that allows the indicator color to be specified.*/ - public void setNumPages(int numPages, int color) { setVisibility(numPages > 1 ? View.VISIBLE : View.GONE); if (numPages == getChildCount()) { return; @@ -67,13 +76,41 @@ public class PageIndicator extends ViewGroup { while (numPages > getChildCount()) { ImageView v = new ImageView(mContext); v.setImageResource(R.drawable.minor_a_b); - v.setImageTintList(ColorStateList.valueOf(color)); + v.setImageTintList(mTint); addView(v, new LayoutParams(mPageIndicatorWidth, mPageIndicatorHeight)); } // Refresh state. setIndex(mPosition >> 1); } + /** + * @return the current tint list for this view. + */ + @NonNull + public ColorStateList getTintList() { + return mTint; + } + + /** + * Set the color for this view. + * <br> + * Calling this will change the color of the current view and any new dots that are added to it. + * @param color the new color + */ + public void setTintList(@NonNull ColorStateList color) { + if (color.equals(mTint)) { + return; + } + mTint = color; + final int N = getChildCount(); + for (int i = 0; i < N; i++) { + View v = getChildAt(i); + if (v instanceof ImageView) { + ((ImageView) v).setImageTintList(mTint); + } + } + } + public void setLocation(float location) { int index = (int) location; setContentDescription(getContext().getString(R.string.accessibility_quick_settings_page, diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java index 3eed8ad89075..560998b5d1d8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java @@ -508,7 +508,6 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { mPageListener.onPageChanged(isLayoutRtl() ? position == mPages.size() - 1 : position == 0); } - } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java index 9c0030d528e7..adf2f654b951 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java @@ -17,6 +17,7 @@ package com.android.systemui.qs.tiles; import android.content.Intent; +import android.os.Bundle; import android.provider.Settings; import android.provider.Settings.Secure; import android.service.quicksettings.Tile; @@ -35,6 +36,10 @@ import javax.inject.Inject; /** Quick settings tile: Invert colors **/ public class ColorInversionTile extends QSTileImpl<BooleanState> { + private static final String EXTRA_FRAGMENT_ARGS_KEY = ":settings:fragment_args_key"; + private static final String EXTRA_SHOW_FRAGMENT_ARGS_KEY = ":settings:show_fragment_args"; + private static final String COLOR_INVERSION_PREFERENCE_KEY = "toggle_inversion_preference"; + private final Icon mIcon = ResourceIcon.get(drawable.ic_invert_colors); private final SecureSetting mSetting; @@ -78,7 +83,11 @@ public class ColorInversionTile extends QSTileImpl<BooleanState> { @Override public Intent getLongClickIntent() { - return new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); + Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); + Bundle bundle = new Bundle(); + bundle.putString(EXTRA_FRAGMENT_ARGS_KEY, COLOR_INVERSION_PREFERENCE_KEY); + intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGS_KEY, bundle); + return intent; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java index 9d81d3563ebb..a86ab41141a6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java @@ -842,7 +842,7 @@ public class ShadeListBuilder implements Dumpable { } private static final NotifSection sDefaultSection = - new NotifSection("DefaultSection") { + new NotifSection("UnknownSection") { @Override public boolean isInSection(ListEntry entry) { return true; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java index 4b244bb18975..68ec6b620a53 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.notification.collection.coordinator; +import static android.app.NotificationManager.IMPORTANCE_MIN; + import android.app.Notification; import android.os.UserHandle; import android.service.notification.StatusBarNotification; @@ -24,9 +26,11 @@ import android.util.ArraySet; import com.android.systemui.ForegroundServiceController; import com.android.systemui.appops.AppOpsController; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.statusbar.notification.collection.ListEntry; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter; +import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender; import com.android.systemui.util.Assert; @@ -43,6 +47,8 @@ import javax.inject.Singleton; * Tags notifications with appOps * Lifetime extends notifications associated with an ongoing ForegroundService. * Filters out notifications that represent foreground services that are no longer running + * Puts foreground service notifications into the FGS section. See {@link NotifCoordinators} for + * section ordering priority. * * Previously this logic lived in * frameworks/base/packages/SystemUI/src/com/android/systemui/ForegroundServiceController @@ -86,6 +92,10 @@ public class AppOpsCoordinator implements Coordinator { mAppOpsController.addCallback(ForegroundServiceController.APP_OPS, this::onAppOpsChanged); } + public NotifSection getSection() { + return mNotifSection; + } + /** * Filters out notifications that represent foreground services that are no longer running or * that already have an app notification with the appOps tagged to @@ -204,6 +214,23 @@ public class AppOpsCoordinator implements Coordinator { } }; + /** + * Puts foreground service notifications into its own section. + */ + private final NotifSection mNotifSection = new NotifSection("ForegroundService") { + @Override + public boolean isInSection(ListEntry entry) { + NotificationEntry notificationEntry = entry.getRepresentativeEntry(); + if (notificationEntry != null) { + Notification notification = notificationEntry.getSbn().getNotification(); + return notification.isForegroundService() + && notification.isColorized() + && entry.getRepresentativeEntry().getImportance() > IMPORTANCE_MIN; + } + return false; + } + }; + private void onAppOpsChanged(int code, int uid, String packageName, boolean active) { mMainExecutor.execute(() -> handleAppOpsChanged(code, uid, packageName, active)); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt index 1bac938a9fca..1a9de8829faf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt @@ -16,17 +16,25 @@ package com.android.systemui.statusbar.notification.collection.coordinator +import com.android.systemui.statusbar.notification.collection.ListEntry import com.android.systemui.statusbar.notification.collection.NotifPipeline import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter +import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON import javax.inject.Inject import javax.inject.Singleton /** - * A coordinator that elevates important conversation notifications + * A Conversation/People Coordinator that: + * - Elevates important conversation notifications + * - Puts conversations into its own people section. @see [NotifCoordinators] for section ordering. */ @Singleton -class ConversationCoordinator @Inject constructor() : Coordinator { +class ConversationCoordinator @Inject constructor( + private val peopleNotificationIdentifier: PeopleNotificationIdentifier +) : Coordinator { private val notificationPromoter = object : NotifPromoter(TAG) { override fun shouldPromoteToTopLevel(entry: NotificationEntry): Boolean { @@ -34,10 +42,24 @@ class ConversationCoordinator @Inject constructor() : Coordinator { } } + private val mNotifSection: NotifSection = object : NotifSection("People") { + override fun isInSection(entry: ListEntry): Boolean { + return isConversation(entry.representativeEntry!!) + } + } + override fun attach(pipeline: NotifPipeline) { pipeline.addPromoter(notificationPromoter) } + fun getSection(): NotifSection { + return mNotifSection + } + + private fun isConversation(entry: NotificationEntry): Boolean = + peopleNotificationIdentifier.getPeopleNotificationType(entry.sbn, entry.ranking) != + TYPE_NON_PERSON + companion object { private const val TAG = "ConversationCoordinator" } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/Coordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/Coordinator.java index d8b2e4089f30..c1a11b2f64c8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/Coordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/Coordinator.java @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.notification.collection.coordinator; import com.android.systemui.statusbar.notification.collection.NotifPipeline; -import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable; /** @@ -29,8 +28,4 @@ public interface Coordinator { * Coordinators should register their listeners and {@link Pluggable}s to the pipeline. */ void attach(NotifPipeline pipeline); - - default NotifSection getSection() { - return null; - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java index 3fde2ed249d9..72597afc3b90 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java @@ -88,7 +88,6 @@ public class HeadsUpCoordinator implements Coordinator { pipeline.addNotificationLifetimeExtender(mLifetimeExtender); } - @Override public NotifSection getSection() { return mNotifSection; } @@ -192,7 +191,7 @@ public class HeadsUpCoordinator implements Coordinator { } }; - private final NotifSection mNotifSection = new NotifSection(TAG) { + private final NotifSection mNotifSection = new NotifSection("HeadsUp") { @Override public boolean isInSection(ListEntry entry) { return isCurrentlyShowingHun(entry); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java index 99e822c66a8f..a09c6509e65e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java @@ -60,6 +60,7 @@ public class NotifCoordinators implements Dumpable { PreparationCoordinator preparationCoordinator, MediaCoordinator mediaCoordinator) { dumpManager.registerDumpable(TAG, this); + mCoordinators.add(new HideLocallyDismissedNotifsCoordinator()); mCoordinators.add(hideNotifsForOtherUsersCoordinator); mCoordinators.add(keyguardCoordinator); @@ -67,20 +68,22 @@ public class NotifCoordinators implements Dumpable { mCoordinators.add(appOpsCoordinator); mCoordinators.add(deviceProvisionedCoordinator); mCoordinators.add(bubbleCoordinator); + mCoordinators.add(mediaCoordinator); + mCoordinators.add(conversationCoordinator); if (featureFlags.isNewNotifPipelineRenderingEnabled()) { - mCoordinators.add(conversationCoordinator); mCoordinators.add(headsUpCoordinator); mCoordinators.add(preparationCoordinator); } - // TODO: add new Coordinators here! (b/112656837) - mCoordinators.add(mediaCoordinator); - // TODO: add the sections in a particular ORDER (HeadsUp < People < Alerting) - for (Coordinator c : mCoordinators) { - if (c.getSection() != null) { - mOrderedSections.add(c.getSection()); - } + // Manually add Ordered Sections + // HeadsUp > FGS > People > Alerting > Silent > Unknown/Default + if (featureFlags.isNewNotifPipelineRenderingEnabled()) { + mOrderedSections.add(headsUpCoordinator.getSection()); // HeadsUp } + mOrderedSections.add(appOpsCoordinator.getSection()); // ForegroundService + mOrderedSections.add(conversationCoordinator.getSection()); // People + mOrderedSections.add(rankingCoordinator.getAlertingSection()); // Alerting + mOrderedSections.add(rankingCoordinator.getSilentSection()); // Silent } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java index e9cbf32ee052..0d2f9da77db7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java @@ -17,15 +17,19 @@ package com.android.systemui.statusbar.notification.collection.coordinator; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.notification.collection.ListEntry; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter; +import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection; +import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider; import javax.inject.Inject; import javax.inject.Singleton; /** * Filters out NotificationEntries based on its Ranking and dozing state. + * Assigns alerting / silent section based on the importance of the notification entry. * We check the NotificationEntry's Ranking for: * - whether the notification's app is suspended or hiding its notifications * - whether DND settings are hiding notifications from ambient display or the notification list @@ -35,10 +39,14 @@ public class RankingCoordinator implements Coordinator { private static final String TAG = "RankingNotificationCoordinator"; private final StatusBarStateController mStatusBarStateController; + private final HighPriorityProvider mHighPriorityProvider; @Inject - public RankingCoordinator(StatusBarStateController statusBarStateController) { + public RankingCoordinator( + StatusBarStateController statusBarStateController, + HighPriorityProvider highPriorityProvider) { mStatusBarStateController = statusBarStateController; + mHighPriorityProvider = highPriorityProvider; } @Override @@ -49,6 +57,28 @@ public class RankingCoordinator implements Coordinator { pipeline.addPreGroupFilter(mDozingFilter); } + public NotifSection getAlertingSection() { + return mAlertingNotifSection; + } + + public NotifSection getSilentSection() { + return mSilentNotifSection; + } + + private final NotifSection mAlertingNotifSection = new NotifSection("Alerting") { + @Override + public boolean isInSection(ListEntry entry) { + return mHighPriorityProvider.isHighPriority(entry); + } + }; + + private final NotifSection mSilentNotifSection = new NotifSection("Silent") { + @Override + public boolean isInSection(ListEntry entry) { + return !mHighPriorityProvider.isHighPriority(entry); + } + }; + /** * Checks whether to filter out the given notification based the notification's Ranking object. * NotifListBuilder invalidates the notification list each time the ranking is updated, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java index d7d09e05c238..d3b8a8cd2093 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java @@ -34,6 +34,8 @@ import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; +import java.lang.ref.WeakReference; + class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeActionHelper { @VisibleForTesting @@ -47,7 +49,11 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc private static final long SWIPE_MENU_TIMING = 200; - private NotificationMenuRowPlugin mCurrMenuRow; + // Hold a weak ref to the menu row so that it isn't accidentally retained in memory. The + // lifetime of the row should be the same as the ActivatableView, which is owned by the + // NotificationStackScrollLayout. If the notification isn't in the notification shade, then it + // isn't possible to swipe it and, so, this class doesn't need to "help." + private WeakReference<NotificationMenuRowPlugin> mCurrMenuRowRef; private boolean mIsExpanded; private boolean mPulsing; @@ -82,11 +88,17 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc return mMenuExposedView; } - public void setCurrentMenuRow(NotificationMenuRowPlugin menuRow) { - mCurrMenuRow = menuRow; + @VisibleForTesting + void setCurrentMenuRow(NotificationMenuRowPlugin menuRow) { + mCurrMenuRowRef = menuRow != null ? new WeakReference(menuRow) : null; } - public NotificationMenuRowPlugin getCurrentMenuRow() { return mCurrMenuRow; } + public NotificationMenuRowPlugin getCurrentMenuRow() { + if (mCurrMenuRowRef == null) { + return null; + } + return mCurrMenuRowRef.get(); + } @VisibleForTesting protected Handler getHandler() { return mHandler; } @@ -102,8 +114,9 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc @Override protected void onChildSnappedBack(View animView, float targetLeft) { - if (mCurrMenuRow != null && targetLeft == 0) { - mCurrMenuRow.resetMenu(); + final NotificationMenuRowPlugin menuRow = getCurrentMenuRow(); + if (menuRow != null && targetLeft == 0) { + menuRow.resetMenu(); clearCurrentMenuRow(); } } @@ -129,10 +142,11 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc @VisibleForTesting protected void initializeRow(SwipeableView row) { if (row.hasFinishedInitialization()) { - mCurrMenuRow = row.createMenu(); - if (mCurrMenuRow != null) { - mCurrMenuRow.setMenuClickListener(mMenuListener); - mCurrMenuRow.onTouchStart(); + final NotificationMenuRowPlugin menuRow = row.createMenu(); + setCurrentMenuRow(menuRow); + if (menuRow != null) { + menuRow.setMenuClickListener(mMenuListener); + menuRow.onTouchStart(); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java index 5bc17f5bc2c6..53b369c3543e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java @@ -50,12 +50,12 @@ public class ContextualButton extends ButtonDispatcher { /** * Reload the drawable from resource id, should reapply the previous dark intensity. */ - public void updateIcon() { + public void updateIcon(int lightIconColor, int darkIconColor) { if (getCurrentView() == null || !getCurrentView().isAttachedToWindow() || mIconResId == 0) { return; } final KeyButtonDrawable currentDrawable = getImageDrawable(); - KeyButtonDrawable drawable = getNewDrawable(); + KeyButtonDrawable drawable = getNewDrawable(lightIconColor, darkIconColor); if (currentDrawable != null) { drawable.setDarkIntensity(currentDrawable.getDarkIntensity()); } @@ -116,9 +116,9 @@ public class ContextualButton extends ButtonDispatcher { mGroup = group; } - protected KeyButtonDrawable getNewDrawable() { - return KeyButtonDrawable.create(getContext().getApplicationContext(), mIconResId, - false /* shadow */); + protected KeyButtonDrawable getNewDrawable(int lightIconColor, int darkIconColor) { + return KeyButtonDrawable.create(getContext().getApplicationContext(), lightIconColor, + darkIconColor, mIconResId, false /* shadow */, null /* ovalBackground */); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java index 9e843f93d00e..c1017f4def0f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java @@ -111,9 +111,9 @@ public class ContextualButtonGroup extends ButtonDispatcher { * Update all the icons that are attached to this group. This will get all the buttons to update * their icons for their buttons. */ - public void updateIcons() { + public void updateIcons(int lightIconColor, int darkIconColor) { for (ButtonData data : mButtonData) { - data.button.updateIcon(); + data.button.updateIcon(lightIconColor, darkIconColor); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java index 539158c40d45..a35aca553c4f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java @@ -231,7 +231,6 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa } } - Dependency.get(ProtoTracer.class).add(this); mLongPressTimeout = Math.min(MAX_LONG_PRESS_TIMEOUT, ViewConfiguration.getLongPressTimeout()); @@ -286,6 +285,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa */ public void onNavBarAttached() { mIsAttached = true; + Dependency.get(ProtoTracer.class).add(this); mOverviewProxyService.addCallback(mQuickSwitchListener); updateIsEnabled(); startTracking(); @@ -296,6 +296,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa */ public void onNavBarDetached() { mIsAttached = false; + Dependency.get(ProtoTracer.class).remove(this); mOverviewProxyService.removeCallback(mQuickSwitchListener); updateIsEnabled(); stopTracking(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java index 16b5a2389ec6..687f5f15a78c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java @@ -16,19 +16,16 @@ package com.android.systemui.statusbar.phone; -import android.annotation.ColorInt; import android.content.Context; import android.content.res.Resources; import android.graphics.Color; import android.graphics.PixelFormat; -import android.view.ContextThemeWrapper; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Surface; import android.view.View; import android.view.WindowManager; -import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.statusbar.policy.KeyButtonDrawable; import com.android.systemui.statusbar.policy.KeyButtonView; @@ -65,6 +62,8 @@ public class FloatingRotationButton implements RotationButton { @Override public void setRotationButtonController(RotationButtonController rotationButtonController) { mRotationButtonController = rotationButtonController; + updateIcon(mRotationButtonController.getLightIconColor(), + mRotationButtonController.getDarkIconColor()); } @Override @@ -101,7 +100,6 @@ public class FloatingRotationButton implements RotationButton { default: break; } - updateIcon(); mWindowManager.addView(mKeyButtonView, lp); if (mKeyButtonDrawable != null && mKeyButtonDrawable.canAnimate()) { mKeyButtonDrawable.resetAnimation(); @@ -126,17 +124,13 @@ public class FloatingRotationButton implements RotationButton { } @Override - public void updateIcon() { - if (!mIsShowing) { - return; - } - mKeyButtonDrawable = getImageDrawable(); + public void updateIcon(int lightIconColor, int darkIconColor) { + Color ovalBackgroundColor = Color.valueOf(Color.red(darkIconColor), + Color.green(darkIconColor), Color.blue(darkIconColor), BACKGROUND_ALPHA); + mKeyButtonDrawable = KeyButtonDrawable.create(mRotationButtonController.getContext(), + lightIconColor, darkIconColor, mRotationButtonController.getIconResId(), + false /* shadow */, ovalBackgroundColor); mKeyButtonView.setImageDrawable(mKeyButtonDrawable); - mKeyButtonDrawable.setCallback(mKeyButtonView); - if (mKeyButtonDrawable != null && mKeyButtonDrawable.canAnimate()) { - mKeyButtonDrawable.resetAnimation(); - mKeyButtonDrawable.startAnimation(); - } } @Override @@ -151,20 +145,7 @@ public class FloatingRotationButton implements RotationButton { @Override public KeyButtonDrawable getImageDrawable() { - Context context = new ContextThemeWrapper(mContext.getApplicationContext(), - mRotationButtonController.getStyleRes()); - final int dualToneDarkTheme = Utils.getThemeAttr(context, R.attr.darkIconTheme); - final int dualToneLightTheme = Utils.getThemeAttr(context, R.attr.lightIconTheme); - Context lightContext = new ContextThemeWrapper(context, dualToneLightTheme); - Context darkContext = new ContextThemeWrapper(context, dualToneDarkTheme); - @ColorInt int darkColor = Utils.getColorAttrDefaultColor(darkContext, - R.attr.singleToneColor); - Color ovalBackgroundColor = Color.valueOf(Color.red(darkColor), Color.green(darkColor), - Color.blue(darkColor), BACKGROUND_ALPHA); - - return KeyButtonDrawable.create(lightContext, - Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor), darkColor, - R.drawable.ic_sysbar_rotate_button, false /* shadow */, ovalBackgroundColor); + return mKeyButtonDrawable; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 1eab427b4155..7936e533f76d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -48,6 +48,7 @@ import android.os.Bundle; import android.util.AttributeSet; import android.util.Log; import android.util.SparseArray; +import android.view.ContextThemeWrapper; import android.view.Display; import android.view.MotionEvent; import android.view.Surface; @@ -63,6 +64,7 @@ import android.view.inputmethod.InputMethodManager; import android.widget.FrameLayout; import com.android.internal.annotations.VisibleForTesting; +import com.android.settingslib.Utils; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; @@ -124,6 +126,9 @@ public class NavigationBarView extends FrameLayout implements private KeyButtonDrawable mHomeDefaultIcon; private KeyButtonDrawable mRecentIcon; private KeyButtonDrawable mDockedIcon; + private Context mLightContext; + private int mLightIconColor; + private int mDarkIconColor; private EdgeBackGestureHandler mEdgeBackGestureHandler; private final DeadZone mDeadZone; @@ -278,6 +283,12 @@ public class NavigationBarView extends FrameLayout implements public NavigationBarView(Context context, AttributeSet attrs) { super(context, attrs); + final Context darkContext = new ContextThemeWrapper(context, + Utils.getThemeAttr(context, R.attr.darkIconTheme)); + mLightContext = new ContextThemeWrapper(context, + Utils.getThemeAttr(context, R.attr.lightIconTheme)); + mLightIconColor = Utils.getColorAttrDefaultColor(mLightContext, R.attr.singleToneColor); + mDarkIconColor = Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor); mIsVertical = false; mLongClickableAccessibilityButton = false; mNavBarMode = Dependency.get(NavigationModeController.class).addListener(this); @@ -290,7 +301,7 @@ public class NavigationBarView extends FrameLayout implements final ContextualButton imeSwitcherButton = new ContextualButton(R.id.ime_switcher, R.drawable.ic_ime_switcher_default); final RotationContextButton rotateSuggestionButton = new RotationContextButton( - R.id.rotate_suggestion, R.drawable.ic_sysbar_rotate_button); + R.id.rotate_suggestion, R.drawable.ic_sysbar_rotate_button_ccw_start_0); final ContextualButton accessibilityButton = new ContextualButton(R.id.accessibility_button, R.drawable.ic_sysbar_accessibility_button); @@ -303,8 +314,8 @@ public class NavigationBarView extends FrameLayout implements mOverviewProxyService = Dependency.get(OverviewProxyService.class); mRecentsOnboarding = new RecentsOnboarding(context, mOverviewProxyService); mFloatingRotationButton = new FloatingRotationButton(context); - mRotationButtonController = new RotationButtonController(context, - R.style.RotateButtonCCWStart90, + mRotationButtonController = new RotationButtonController(mLightContext, + mLightIconColor, mDarkIconColor, isGesturalMode ? mFloatingRotationButton : rotateSuggestionButton); mConfiguration = new Configuration(); @@ -501,7 +512,7 @@ public class NavigationBarView extends FrameLayout implements } if (densityChange || dirChange) { mRecentIcon = getDrawable(R.drawable.ic_sysbar_recent); - mContextualButtonGroup.updateIcons(); + mContextualButtonGroup.updateIcons(mLightIconColor, mDarkIconColor); } if (orientationChange || densityChange || dirChange) { mBackIcon = getBackDrawable(); @@ -559,11 +570,6 @@ public class NavigationBarView extends FrameLayout implements drawable.setRotation(mIsVertical ? 90 : 0); } - private KeyButtonDrawable chooseNavigationIconDrawable(@DrawableRes int icon, - @DrawableRes int quickStepIcon) { - return getDrawable(chooseNavigationIconDrawableRes(icon, quickStepIcon)); - } - private @DrawableRes int chooseNavigationIconDrawableRes(@DrawableRes int icon, @DrawableRes int quickStepIcon) { final boolean quickStepEnabled = mOverviewProxyService.shouldShowSwipeUpUI(); @@ -571,11 +577,8 @@ public class NavigationBarView extends FrameLayout implements } private KeyButtonDrawable getDrawable(@DrawableRes int icon) { - return KeyButtonDrawable.create(mContext, icon, true /* hasShadow */); - } - - private KeyButtonDrawable getDrawable(@DrawableRes int icon, boolean hasShadow) { - return KeyButtonDrawable.create(mContext, icon, hasShadow); + return KeyButtonDrawable.create(mLightContext, mLightIconColor, mDarkIconColor, icon, + true /* hasShadow */, null /* ovalBackgroundColor */); } /** To be called when screen lock/unlock state changes */ @@ -861,7 +864,6 @@ public class NavigationBarView extends FrameLayout implements mBarTransitions.onNavigationModeChanged(mNavBarMode); mEdgeBackGestureHandler.onNavigationModeChanged(mNavBarMode); mRecentsOnboarding.onNavigationModeChanged(mNavBarMode); - getRotateSuggestionButton().onNavigationModeChanged(mNavBarMode); if (isGesturalMode(mNavBarMode)) { mRegionSamplingHelper.start(mSamplingBounds); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButton.java index 2580c0e77013..687efd34ee30 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButton.java @@ -27,7 +27,7 @@ interface RotationButton { boolean show(); boolean hide(); boolean isVisible(); - void updateIcon(); + void updateIcon(int lightIconColor, int darkIconColor); void setOnClickListener(View.OnClickListener onClickListener); void setOnHoverListener(View.OnHoverListener onHoverListener); KeyButtonDrawable getImageDrawable(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java index 59b10e416b03..f83cdd488c04 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java @@ -21,6 +21,8 @@ import static com.android.internal.view.RotationPolicy.NATURAL_ROTATION; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; +import android.annotation.ColorInt; +import android.annotation.DrawableRes; import android.annotation.StyleRes; import android.app.StatusBarManager; import android.content.ContentResolver; @@ -30,6 +32,7 @@ import android.os.Looper; import android.os.RemoteException; import android.provider.Settings; import android.util.Log; +import android.view.ContextThemeWrapper; import android.view.IRotationWatcher.Stub; import android.view.MotionEvent; import android.view.Surface; @@ -40,6 +43,7 @@ import android.view.accessibility.AccessibilityManager; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLoggerImpl; +import com.android.settingslib.Utils; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; @@ -61,10 +65,12 @@ public class RotationButtonController { private static final int NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION = 3; + private final Context mContext; + private final RotationButton mRotationButton; + private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper()); private final UiEventLogger mUiEventLogger = new UiEventLoggerImpl(); private final ViewRippler mViewRippler = new ViewRippler(); - private @StyleRes int mStyleRes; private int mLastRotationSuggestion; private boolean mPendingRotationSuggestion; private boolean mHoveringRotationSuggestion; @@ -75,6 +81,9 @@ public class RotationButtonController { private boolean mListenersRegistered = false; private boolean mIsNavigationBarShowing; private boolean mSkipOverrideUserLockPrefsOnce; + private int mLightIconColor; + private int mDarkIconColor; + private int mIconResId = R.drawable.ic_sysbar_rotate_button_ccw_start_90; private final Runnable mRemoveRotationProposal = () -> setRotateSuggestionButtonState(false /* visible */); @@ -82,9 +91,6 @@ public class RotationButtonController { () -> mPendingRotationSuggestion = false; private Animator mRotateHideAnimator; - private final Context mContext; - private final RotationButton mRotationButton; - private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper()); private final Stub mRotationWatcher = new Stub() { @Override @@ -117,12 +123,14 @@ public class RotationButtonController { return (disable2Flags & StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS) != 0; } - RotationButtonController(Context context, @StyleRes int style, RotationButton rotationButton) { + RotationButtonController(Context context, @ColorInt int lightIconColor, + @ColorInt int darkIconColor, RotationButton rotationButton) { mContext = context; + mLightIconColor = lightIconColor; + mDarkIconColor = darkIconColor; mRotationButton = rotationButton; mRotationButton.setRotationButtonController(this); - mStyleRes = style; mIsNavigationBarShowing = true; mRotationLockController = Dependency.get(RotationLockController.class); mAccessibilityManagerWrapper = Dependency.get(AccessibilityManagerWrapper.class); @@ -275,17 +283,20 @@ public class RotationButtonController { return; } + // TODO: Remove styles? // Prepare to show the navbar icon by updating the icon style to change anim params mLastRotationSuggestion = rotation; // Remember rotation for click final boolean rotationCCW = isRotationAnimationCCW(windowRotation, rotation); - int style; if (windowRotation == Surface.ROTATION_0 || windowRotation == Surface.ROTATION_180) { - style = rotationCCW ? R.style.RotateButtonCCWStart90 : R.style.RotateButtonCWStart90; + mIconResId = rotationCCW + ? R.drawable.ic_sysbar_rotate_button_ccw_start_90 + : R.drawable.ic_sysbar_rotate_button_cw_start_90; } else { // 90 or 270 - style = rotationCCW ? R.style.RotateButtonCCWStart0 : R.style.RotateButtonCWStart0; + mIconResId = rotationCCW + ? R.drawable.ic_sysbar_rotate_button_ccw_start_0 + : R.drawable.ic_sysbar_rotate_button_ccw_start_0; } - mStyleRes = style; - mRotationButton.updateIcon(); + mRotationButton.updateIcon(mLightIconColor, mDarkIconColor); if (mIsNavigationBarShowing) { // The navbar is visible so show the icon right away @@ -316,14 +327,26 @@ public class RotationButtonController { } } - @StyleRes int getStyleRes() { - return mStyleRes; + Context getContext() { + return mContext; } RotationButton getRotationButton() { return mRotationButton; } + @DrawableRes int getIconResId() { + return mIconResId; + } + + @ColorInt int getLightIconColor() { + return mLightIconColor; + } + + @ColorInt int getDarkIconColor() { + return mDarkIconColor; + } + private void onRotateSuggestionClick(View v) { mUiEventLogger.log(RotationButtonEvent.ROTATION_SUGGESTION_ACCEPTED); incrementNumAcceptedRotationSuggestionsIfNeeded(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java index bd9675280b0b..d7e95e43ea8f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java @@ -16,22 +16,16 @@ package com.android.systemui.statusbar.phone; -import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; - import android.annotation.DrawableRes; import android.annotation.IdRes; -import android.content.Context; -import android.view.ContextThemeWrapper; import android.view.View; import com.android.systemui.statusbar.policy.KeyButtonDrawable; /** Containing logic for the rotation button in nav bar. */ -public class RotationContextButton extends ContextualButton implements - NavigationModeController.ModeChangedListener, RotationButton { +public class RotationContextButton extends ContextualButton implements RotationButton { public static final boolean DEBUG_ROTATION = false; - private int mNavBarMode = NAV_BAR_MODE_3BUTTON; private RotationButtonController mRotationButtonController; public RotationContextButton(@IdRes int buttonResId, @DrawableRes int iconResId) { @@ -56,16 +50,10 @@ public class RotationContextButton extends ContextualButton implements } @Override - protected KeyButtonDrawable getNewDrawable() { - Context context = new ContextThemeWrapper(getContext().getApplicationContext(), - mRotationButtonController.getStyleRes()); - return KeyButtonDrawable.create(context, mIconResId, false /* shadow */, - null /* ovalBackgroundColor */); - } - - @Override - public void onNavigationModeChanged(int mode) { - mNavBarMode = mode; + protected KeyButtonDrawable getNewDrawable(int lightIconColor, int darkIconColor) { + return KeyButtonDrawable.create(mRotationButtonController.getContext(), + lightIconColor, darkIconColor, mRotationButtonController.getIconResId(), + false /* shadow */, null /* ovalBackgroundColor */); } @Override 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 8ee0bdf2938a..c5acd9bd0f06 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -2477,7 +2477,6 @@ public class StatusBar extends SystemUI implements DemoMode, private final Runnable mCheckBarModes = this::checkBarModes; public void setInteracting(int barWindow, boolean interacting) { - final boolean changing = ((mInteractingWindows & barWindow) != 0) != interacting; mInteractingWindows = interacting ? (mInteractingWindows | barWindow) : (mInteractingWindows & ~barWindow); @@ -2486,11 +2485,6 @@ public class StatusBar extends SystemUI implements DemoMode, } else { mAutoHideController.resumeSuspendedAutoHide(); } - // manually dismiss the volume panel when interacting with the nav bar - if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) { - mNavigationBarController.touchAutoDim(mDisplayId); - dismissVolumeDialog(); - } checkBarModes(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java index 23d03a4b225a..755938863b5e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java @@ -37,7 +37,6 @@ import android.graphics.Rect; import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.Drawable; import android.util.FloatProperty; -import android.view.ContextThemeWrapper; import android.view.View; import com.android.settingslib.Utils; @@ -439,34 +438,6 @@ public class KeyButtonDrawable extends Drawable { } /** - * Creates a KeyButtonDrawable with a shadow given its icon. The tint applied to the drawable - * is determined by the dark and light theme given by the context. - * @param ctx Context to get the drawable and determine the dark and light theme - * @param icon the icon resource id - * @param hasShadow if a shadow will appear with the drawable - * @param ovalBackgroundColor the color of the oval bg that will be drawn - * @return KeyButtonDrawable - */ - public static KeyButtonDrawable create(@NonNull Context ctx, @DrawableRes int icon, - boolean hasShadow, Color ovalBackgroundColor) { - final int dualToneDarkTheme = Utils.getThemeAttr(ctx, R.attr.darkIconTheme); - final int dualToneLightTheme = Utils.getThemeAttr(ctx, R.attr.lightIconTheme); - Context lightContext = new ContextThemeWrapper(ctx, dualToneLightTheme); - Context darkContext = new ContextThemeWrapper(ctx, dualToneDarkTheme); - return KeyButtonDrawable.create(lightContext, darkContext, icon, hasShadow, - ovalBackgroundColor); - } - - /** - * Creates a KeyButtonDrawable with a shadow given its icon. For more information, see - * {@link #create(Context, int, boolean, boolean)}. - */ - public static KeyButtonDrawable create(@NonNull Context ctx, @DrawableRes int icon, - boolean hasShadow) { - return create(ctx, icon, hasShadow, null /* ovalBackgroundColor */); - } - - /** * Creates a KeyButtonDrawable with a shadow given its icon. For more information, see * {@link #create(Context, int, boolean, boolean)}. */ diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 5f153f86d322..4a8ada09b3d2 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -132,6 +132,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Mock private FaceManager mFaceManager; @Mock + private List<FaceSensorProperties> mFaceSensorProperties; + @Mock private BiometricManager mBiometricManager; @Mock private PackageManager mPackageManager; @@ -175,7 +177,13 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { when(mFaceManager.isHardwareDetected()).thenReturn(true); when(mFaceManager.hasEnrolledTemplates()).thenReturn(true); when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true); - when(mFaceManager.getSensorProperties()).thenReturn(new FaceSensorProperties()); + when(mFaceManager.getSensorProperties()).thenReturn(mFaceSensorProperties); + + // IBiometricsFace@1.0 does not support detection, only authentication. + when(mFaceSensorProperties.isEmpty()).thenReturn(false); + when(mFaceSensorProperties.get(anyInt())).thenReturn(new FaceSensorProperties(0 /* id */, + false /* supportsFaceDetection */)); + when(mFingerprintManager.isHardwareDetected()).thenReturn(true); when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true); when(mUserManager.isUserUnlocked(anyInt())).thenReturn(true); diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java index dd3a7858fd1f..b6cc2ee03f38 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java +++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java @@ -140,6 +140,10 @@ public abstract class SysuiTestCase { return null; } + protected FakeBroadcastDispatcher getFakeBroadcastDispatcher() { + return mFakeBroadcastDispatcher; + } + public SysuiTestableContext getContext() { return mContext; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java index ae7387996322..c3c9ecc23d59 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java @@ -29,8 +29,8 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.testing.UiEventLoggerFake; import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.brightline.BrightLineFalsingManager; +import com.android.systemui.classifier.brightline.FalsingDataProvider; import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManagerFake; import com.android.systemui.dump.DumpManager; @@ -42,6 +42,8 @@ import com.android.systemui.util.DeviceConfigProxyFake; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.time.FakeSystemClock; +import com.android.systemui.utils.leaks.FakeBatteryController; +import com.android.systemui.utils.leaks.LeakCheckedTest; import org.junit.After; import org.junit.Before; @@ -52,7 +54,7 @@ import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) -public class FalsingManagerProxyTest extends SysuiTestCase { +public class FalsingManagerProxyTest extends LeakCheckedTest { @Mock(stubOnly = true) PluginManager mPluginManager; @Mock(stubOnly = true) @@ -62,7 +64,7 @@ public class FalsingManagerProxyTest extends SysuiTestCase { @Mock DumpManager mDumpManager; private FalsingManagerProxy mProxy; private DeviceConfigProxy mDeviceConfig; - private DisplayMetrics mDisplayMetrics = new DisplayMetrics(); + private FalsingDataProvider mFalsingDataProvider; private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); private DockManager mDockManager = new DockManagerFake(); @@ -75,6 +77,8 @@ public class FalsingManagerProxyTest extends SysuiTestCase { mDeviceConfig = new DeviceConfigProxyFake(); mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, BRIGHTLINE_FALSING_MANAGER_ENABLED, "false", false); + mFalsingDataProvider = new FalsingDataProvider( + new DisplayMetrics(), new FakeBatteryController(getLeakCheck())); } @After @@ -86,9 +90,9 @@ public class FalsingManagerProxyTest extends SysuiTestCase { @Test public void test_brightLineFalsingManagerDisabled() { - mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, mDisplayMetrics, + mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, mProximitySensor, mDeviceConfig, mDockManager, mKeyguardUpdateMonitor, - mDumpManager, mUiBgExecutor, mStatusBarStateController); + mDumpManager, mUiBgExecutor, mStatusBarStateController, mFalsingDataProvider); assertThat(mProxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class)); } @@ -97,17 +101,17 @@ public class FalsingManagerProxyTest extends SysuiTestCase { mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, BRIGHTLINE_FALSING_MANAGER_ENABLED, "true", false); mExecutor.runAllReady(); - mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, mDisplayMetrics, + mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, mProximitySensor, mDeviceConfig, mDockManager, mKeyguardUpdateMonitor, - mDumpManager, mUiBgExecutor, mStatusBarStateController); + mDumpManager, mUiBgExecutor, mStatusBarStateController, mFalsingDataProvider); assertThat(mProxy.getInternalFalsingManager(), instanceOf(BrightLineFalsingManager.class)); } @Test public void test_brightLineFalsingManagerToggled() throws InterruptedException { - mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, mDisplayMetrics, + mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, mProximitySensor, mDeviceConfig, mDockManager, mKeyguardUpdateMonitor, - mDumpManager, mUiBgExecutor, mStatusBarStateController); + mDumpManager, mUiBgExecutor, mStatusBarStateController, mFalsingDataProvider); assertThat(mProxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class)); mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java index 2f05f0b4c69b..061664b4f6d4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java @@ -17,6 +17,7 @@ package com.android.systemui.classifier.brightline; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; @@ -27,7 +28,6 @@ import android.util.DisplayMetrics; import com.android.internal.logging.testing.UiEventLoggerFake; import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.SysuiTestCase; import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManagerFake; import com.android.systemui.statusbar.StatusBarState; @@ -37,6 +37,8 @@ import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.DeviceConfigProxyFake; import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.sensors.ThresholdSensor; +import com.android.systemui.utils.leaks.FakeBatteryController; +import com.android.systemui.utils.leaks.LeakCheckedTest; import org.junit.Before; import org.junit.Test; @@ -47,7 +49,7 @@ import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper -public class BrightLineFalsingManagerTest extends SysuiTestCase { +public class BrightLineFalsingManagerTest extends LeakCheckedTest { @Mock @@ -55,23 +57,26 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase { @Mock private ProximitySensor mProximitySensor; private SysuiStatusBarStateController mStatusBarStateController; + private FalsingDataProvider mFalsingDataProvider; + private FakeBatteryController mFakeBatteryController; private BrightLineFalsingManager mFalsingManager; @Before public void setup() { MockitoAnnotations.initMocks(this); + mFakeBatteryController = new FakeBatteryController(getLeakCheck()); DisplayMetrics dm = new DisplayMetrics(); dm.xdpi = 100; dm.ydpi = 100; dm.widthPixels = 100; dm.heightPixels = 100; - FalsingDataProvider falsingDataProvider = new FalsingDataProvider(dm); + mFalsingDataProvider = new FalsingDataProvider(dm, mFakeBatteryController); DeviceConfigProxy deviceConfigProxy = new DeviceConfigProxyFake(); DockManager dockManager = new DockManagerFake(); mStatusBarStateController = new StatusBarStateControllerImpl(new UiEventLoggerFake()); mStatusBarStateController.setState(StatusBarState.KEYGUARD); - mFalsingManager = new BrightLineFalsingManager(falsingDataProvider, + mFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider, mKeyguardUpdateMonitor, mProximitySensor, deviceConfigProxy, dockManager, mStatusBarStateController); } @@ -83,6 +88,13 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase { } @Test + public void testNoProximityWhenWirelessCharging() { + mFakeBatteryController.setWirelessCharging(true); + mFalsingManager.onScreenTurningOn(); + verify(mProximitySensor, never()).register(any(ThresholdSensor.Listener.class)); + } + + @Test public void testUnregisterSensor() { mFalsingManager.onScreenTurningOn(); reset(mProximitySensor); diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ClassifierTest.java index 3ba5d1ac79ea..a4d198a14541 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ClassifierTest.java @@ -21,29 +21,30 @@ import static com.android.systemui.classifier.Classifier.UNLOCK; import android.util.DisplayMetrics; import android.view.MotionEvent; -import com.android.systemui.SysuiTestCase; +import com.android.systemui.utils.leaks.FakeBatteryController; +import com.android.systemui.utils.leaks.LeakCheckedTest; import org.junit.After; -import org.junit.Before; import java.util.ArrayList; import java.util.List; -public class ClassifierTest extends SysuiTestCase { +public class ClassifierTest extends LeakCheckedTest { private FalsingDataProvider mDataProvider; private List<MotionEvent> mMotionEvents = new ArrayList<>(); private float mOffsetX = 0; private float mOffsetY = 0; + private FakeBatteryController mFakeBatteryController; - @Before public void setup() { DisplayMetrics displayMetrics = new DisplayMetrics(); displayMetrics.xdpi = 100; displayMetrics.ydpi = 100; displayMetrics.widthPixels = 1000; displayMetrics.heightPixels = 1000; - mDataProvider = new FalsingDataProvider(displayMetrics); + mFakeBatteryController = new FakeBatteryController(getLeakCheck()); + mDataProvider = new FalsingDataProvider(displayMetrics, mFakeBatteryController); mDataProvider.setInteractionType(UNLOCK); } @@ -56,6 +57,10 @@ public class ClassifierTest extends SysuiTestCase { return mDataProvider; } + FakeBatteryController getFakeBatteryController() { + return mFakeBatteryController; + } + void setOffsetX(float offsetX) { mOffsetX = offsetX; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/FalsingDataProviderTest.java index 448c2f7b33ad..f13bc7379436 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/FalsingDataProviderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/FalsingDataProviderTest.java @@ -26,6 +26,8 @@ import android.view.MotionEvent; import androidx.test.filters.SmallTest; +import com.android.systemui.utils.leaks.FakeBatteryController; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -37,17 +39,19 @@ import java.util.List; @RunWith(AndroidTestingRunner.class) public class FalsingDataProviderTest extends ClassifierTest { + private FakeBatteryController mFakeBatteryController; private FalsingDataProvider mDataProvider; @Before public void setup() { super.setup(); + mFakeBatteryController = new FakeBatteryController(getLeakCheck()); DisplayMetrics displayMetrics = new DisplayMetrics(); displayMetrics.xdpi = 100; displayMetrics.ydpi = 100; displayMetrics.widthPixels = 1000; displayMetrics.heightPixels = 1000; - mDataProvider = new FalsingDataProvider(displayMetrics); + mDataProvider = new FalsingDataProvider(displayMetrics, mFakeBatteryController); } @After @@ -246,4 +250,12 @@ public class FalsingDataProviderTest extends ClassifierTest { assertThat(mDataProvider.isUp(), is(false)); mDataProvider.onSessionEnd(); } + + @Test + public void test_isWirelessCharging() { + assertThat(mDataProvider.isWirelessCharging(), is(false)); + + mFakeBatteryController.setWirelessCharging(true); + assertThat(mDataProvider.isWirelessCharging(), is(true)); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java index 314b19140e7a..960ea79f36b4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java @@ -16,6 +16,11 @@ package com.android.systemui.statusbar.notification.collection.coordinator; +import static android.app.Notification.FLAG_FOREGROUND_SERVICE; +import static android.app.NotificationManager.IMPORTANCE_DEFAULT; +import static android.app.NotificationManager.IMPORTANCE_HIGH; +import static android.app.NotificationManager.IMPORTANCE_MIN; + import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; @@ -43,6 +48,7 @@ import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter; +import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender; import com.android.systemui.util.concurrency.FakeExecutor; @@ -68,13 +74,13 @@ public class AppOpsCoordinatorTest extends SysuiTestCase { @Mock private AppOpsController mAppOpsController; @Mock private NotifPipeline mNotifPipeline; - private NotificationEntry mEntry; - private Notification mNotification; + private NotificationEntryBuilder mEntryBuilder; private AppOpsCoordinator mAppOpsCoordinator; private NotifFilter mForegroundFilter; private NotifCollectionListener mNotifCollectionListener; private AppOpsController.Callback mAppOpsCallback; private NotifLifetimeExtender mForegroundNotifLifetimeExtender; + private NotifSection mFgsSection; private FakeSystemClock mClock = new FakeSystemClock(); private FakeExecutor mExecutor = new FakeExecutor(mClock); @@ -90,11 +96,8 @@ public class AppOpsCoordinatorTest extends SysuiTestCase { mAppOpsController, mExecutor); - mNotification = new Notification(); - mEntry = new NotificationEntryBuilder() - .setUser(new UserHandle(NOTIF_USER_ID)) - .setNotification(mNotification) - .build(); + mEntryBuilder = new NotificationEntryBuilder() + .setUser(new UserHandle(NOTIF_USER_ID)); mAppOpsCoordinator.attach(mNotifPipeline); @@ -122,11 +125,14 @@ public class AppOpsCoordinatorTest extends SysuiTestCase { ArgumentCaptor.forClass(AppOpsController.Callback.class); verify(mAppOpsController).addCallback(any(int[].class), appOpsCaptor.capture()); mAppOpsCallback = appOpsCaptor.getValue(); + + mFgsSection = mAppOpsCoordinator.getSection(); } @Test public void filterTest_disclosureUnnecessary() { - StatusBarNotification sbn = mEntry.getSbn(); + NotificationEntry entry = mEntryBuilder.build(); + StatusBarNotification sbn = entry.getSbn(); // GIVEN the notification is a disclosure notification when(mForegroundServiceController.isDisclosureNotification(sbn)).thenReturn(true); @@ -136,84 +142,91 @@ public class AppOpsCoordinatorTest extends SysuiTestCase { .thenReturn(false); // THEN filter out the notification - assertTrue(mForegroundFilter.shouldFilterOut(mEntry, 0)); + assertTrue(mForegroundFilter.shouldFilterOut(entry, 0)); } @Test public void filterTest_systemAlertNotificationUnnecessary() { - StatusBarNotification sbn = mEntry.getSbn(); - - // GIVEN the notification is a system alert notification + not a disclosure notification - when(mForegroundServiceController.isSystemAlertNotification(sbn)).thenReturn(true); - when(mForegroundServiceController.isDisclosureNotification(sbn)).thenReturn(false); - // GIVEN the alert notification isn't needed for this user final Bundle extras = new Bundle(); extras.putStringArray(Notification.EXTRA_FOREGROUND_APPS, new String[]{TEST_PKG}); - mNotification.extras = extras; + mEntryBuilder.modifyNotification(mContext) + .setExtras(extras); + NotificationEntry entry = mEntryBuilder.build(); + StatusBarNotification sbn = entry.getSbn(); when(mForegroundServiceController.isSystemAlertWarningNeeded(sbn.getUserId(), TEST_PKG)) .thenReturn(false); + // GIVEN the notification is a system alert notification + not a disclosure notification + when(mForegroundServiceController.isSystemAlertNotification(sbn)).thenReturn(true); + when(mForegroundServiceController.isDisclosureNotification(sbn)).thenReturn(false); + + // THEN filter out the notification - assertTrue(mForegroundFilter.shouldFilterOut(mEntry, 0)); + assertTrue(mForegroundFilter.shouldFilterOut(entry, 0)); } @Test public void filterTest_doNotFilter() { - StatusBarNotification sbn = mEntry.getSbn(); + NotificationEntry entry = mEntryBuilder.build(); + StatusBarNotification sbn = entry.getSbn(); // GIVEN the notification isn't a system alert notification nor a disclosure notification when(mForegroundServiceController.isSystemAlertNotification(sbn)).thenReturn(false); when(mForegroundServiceController.isDisclosureNotification(sbn)).thenReturn(false); // THEN don't filter out the notification - assertFalse(mForegroundFilter.shouldFilterOut(mEntry, 0)); + assertFalse(mForegroundFilter.shouldFilterOut(entry, 0)); } @Test public void extendLifetimeText_notForeground() { // GIVEN the notification doesn't represent a foreground service - mNotification.flags = 0; + mEntryBuilder.modifyNotification(mContext) + .setFlag(FLAG_FOREGROUND_SERVICE, false); // THEN don't extend the lifetime assertFalse(mForegroundNotifLifetimeExtender - .shouldExtendLifetime(mEntry, NotificationListenerService.REASON_CLICK)); + .shouldExtendLifetime(mEntryBuilder.build(), + NotificationListenerService.REASON_CLICK)); } @Test public void extendLifetimeText_foregroundNotifRecentlyPosted() { // GIVEN the notification represents a foreground service that was just posted - mNotification.flags |= Notification.FLAG_FOREGROUND_SERVICE; - mEntry = new NotificationEntryBuilder() - .setUser(new UserHandle(NOTIF_USER_ID)) + Notification notification = new Notification.Builder(mContext, "test_channel") + .setFlag(FLAG_FOREGROUND_SERVICE, true) + .build(); + NotificationEntry entry = mEntryBuilder .setSbn(new StatusBarNotification(TEST_PKG, TEST_PKG, NOTIF_USER_ID, "", - NOTIF_USER_ID, NOTIF_USER_ID, mNotification, + NOTIF_USER_ID, NOTIF_USER_ID, notification, new UserHandle(NOTIF_USER_ID), "", System.currentTimeMillis())) - .setNotification(mNotification) + .setNotification(notification) .build(); // THEN extend the lifetime assertTrue(mForegroundNotifLifetimeExtender - .shouldExtendLifetime(mEntry, NotificationListenerService.REASON_CLICK)); + .shouldExtendLifetime(entry, NotificationListenerService.REASON_CLICK)); } @Test public void extendLifetimeText_foregroundNotifOld() { // GIVEN the notification represents a foreground service that was posted 10 seconds ago - mNotification.flags |= Notification.FLAG_FOREGROUND_SERVICE; - mEntry = new NotificationEntryBuilder() - .setUser(new UserHandle(NOTIF_USER_ID)) + Notification notification = new Notification.Builder(mContext, "test_channel") + .setFlag(FLAG_FOREGROUND_SERVICE, true) + .build(); + NotificationEntry entry = mEntryBuilder .setSbn(new StatusBarNotification(TEST_PKG, TEST_PKG, NOTIF_USER_ID, "", - NOTIF_USER_ID, NOTIF_USER_ID, mNotification, + NOTIF_USER_ID, NOTIF_USER_ID, notification, new UserHandle(NOTIF_USER_ID), "", System.currentTimeMillis() - 10000)) - .setNotification(mNotification) + .setNotification(notification) .build(); // THEN don't extend the lifetime because the extended time exceeds MIN_FGS_TIME_MS assertFalse(mForegroundNotifLifetimeExtender - .shouldExtendLifetime(mEntry, NotificationListenerService.REASON_CLICK)); + .shouldExtendLifetime(entry, NotificationListenerService.REASON_CLICK)); } @Test @@ -345,4 +358,41 @@ public class AppOpsCoordinatorTest extends SysuiTestCase { // THEN the entry's active app ops is updated to empty assertTrue(entry.mActiveAppOps.isEmpty()); } + + @Test + public void testIncludeFGSInSection_importanceDefault() { + // GIVEN the notification represents a colorized foreground service with > min importance + mEntryBuilder + .setFlag(mContext, FLAG_FOREGROUND_SERVICE, true) + .setImportance(IMPORTANCE_DEFAULT) + .modifyNotification(mContext).setColorized(true); + + // THEN the entry is in the fgs section + assertTrue(mFgsSection.isInSection(mEntryBuilder.build())); + } + + @Test + public void testDiscludeFGSInSection_importanceMin() { + // GIVEN the notification represents a colorized foreground service with min importance + mEntryBuilder + .setFlag(mContext, FLAG_FOREGROUND_SERVICE, true) + .setImportance(IMPORTANCE_MIN) + .modifyNotification(mContext).setColorized(true); + + // THEN the entry is NOT in the fgs section + assertFalse(mFgsSection.isInSection(mEntryBuilder.build())); + } + + @Test + public void testDiscludeNonFGSInSection() { + // GIVEN the notification represents a colorized notification with high importance that + // is NOT a foreground service + mEntryBuilder + .setImportance(IMPORTANCE_HIGH) + .setFlag(mContext, FLAG_FOREGROUND_SERVICE, false) + .modifyNotification(mContext).setColorized(false); + + // THEN the entry is NOT in the fgs section + assertFalse(mFgsSection.isInSection(mEntryBuilder.build())); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt index dfc627e14d8c..be5c8a846afb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt @@ -25,6 +25,9 @@ import com.android.systemui.statusbar.notification.collection.NotifPipeline import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter +import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Before @@ -40,38 +43,52 @@ import org.mockito.Mockito.`when` as whenever @RunWith(AndroidTestingRunner::class) @TestableLooper.RunWithLooper class ConversationCoordinatorTest : SysuiTestCase() { - - private var coordinator: ConversationCoordinator = ConversationCoordinator() - // captured listeners and pluggables: - private var promoter: NotifPromoter? = null + private lateinit var promoter: NotifPromoter + private lateinit var peopleSection: NotifSection @Mock - private val pipeline: NotifPipeline? = null + private lateinit var pipeline: NotifPipeline + @Mock + private lateinit var peopleNotificationIdentifier: PeopleNotificationIdentifier @Mock - private val channel: NotificationChannel? = null - private var entry: NotificationEntry? = null + private lateinit var channel: NotificationChannel + private lateinit var entry: NotificationEntry + + private lateinit var coordinator: ConversationCoordinator @Before fun setUp() { MockitoAnnotations.initMocks(this) - whenever(channel!!.isImportantConversation).thenReturn(true) + coordinator = ConversationCoordinator(peopleNotificationIdentifier) + whenever(channel.isImportantConversation).thenReturn(true) - coordinator.attach(pipeline!!) + coordinator.attach(pipeline) // capture arguments: val notifPromoterCaptor = ArgumentCaptor.forClass(NotifPromoter::class.java) verify(pipeline).addPromoter(notifPromoterCaptor.capture()) promoter = notifPromoterCaptor.value + peopleSection = coordinator.getSection() + entry = NotificationEntryBuilder().setChannel(channel).build() } @Test - fun testPromotesCurrentHUN() { - + fun testPromotesImportantConversations() { // only promote important conversations - assertTrue(promoter!!.shouldPromoteToTopLevel(entry)) - assertFalse(promoter!!.shouldPromoteToTopLevel(NotificationEntryBuilder().build())) + assertTrue(promoter.shouldPromoteToTopLevel(entry)) + assertFalse(promoter.shouldPromoteToTopLevel(NotificationEntryBuilder().build())) + } + + @Test + fun testInPeopleSection() { + whenever(peopleNotificationIdentifier.getPeopleNotificationType( + entry.sbn, entry.ranking)).thenReturn(TYPE_PERSON) + + // only put people notifications in this section + assertTrue(peopleSection.isInSection(entry)) + assertFalse(peopleSection.isInSection(NotificationEntryBuilder().build())) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java index 85acbe6d440b..5f10f38b2ee8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java @@ -36,6 +36,8 @@ import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter; +import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection; +import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider; import org.junit.Before; import org.junit.Test; @@ -50,6 +52,7 @@ import org.mockito.MockitoAnnotations; public class RankingCoordinatorTest extends SysuiTestCase { @Mock private StatusBarStateController mStatusBarStateController; + @Mock private HighPriorityProvider mHighPriorityProvider; @Mock private NotifPipeline mNotifPipeline; @Captor private ArgumentCaptor<NotifFilter> mNotifFilterCaptor; @@ -58,16 +61,23 @@ public class RankingCoordinatorTest extends SysuiTestCase { private NotifFilter mCapturedSuspendedFilter; private NotifFilter mCapturedDozingFilter; + private NotifSection mAlertingSection; + private NotifSection mSilentSection; + @Before public void setup() { MockitoAnnotations.initMocks(this); - RankingCoordinator rankingCoordinator = new RankingCoordinator(mStatusBarStateController); + RankingCoordinator rankingCoordinator = + new RankingCoordinator(mStatusBarStateController, mHighPriorityProvider); mEntry = new NotificationEntryBuilder().build(); rankingCoordinator.attach(mNotifPipeline); verify(mNotifPipeline, times(2)).addPreGroupFilter(mNotifFilterCaptor.capture()); mCapturedSuspendedFilter = mNotifFilterCaptor.getAllValues().get(0); mCapturedDozingFilter = mNotifFilterCaptor.getAllValues().get(1); + + mAlertingSection = rankingCoordinator.getAlertingSection(); + mSilentSection = rankingCoordinator.getSilentSection(); } @Test @@ -130,6 +140,26 @@ public class RankingCoordinatorTest extends SysuiTestCase { assertTrue(mCapturedDozingFilter.shouldFilterOut(mEntry, 0)); } + @Test + public void testIncludeInSectionAlerting() { + // GIVEN the entry is high priority + when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(true); + + // THEN entry is in the alerting section + assertTrue(mAlertingSection.isInSection(mEntry)); + assertFalse(mSilentSection.isInSection(mEntry)); + } + + @Test + public void testIncludeInSectionSilent() { + // GIVEN the entry isn't high priority + when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(false); + + // THEN entry is in the silent section + assertFalse(mAlertingSection.isInSection(mEntry)); + assertTrue(mSilentSection.isInSection(mEntry)); + } + private RankingBuilder getRankingForUnfilteredNotif() { return new RankingBuilder() .setKey(mEntry.getKey()) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java index 6433376cd2a9..b5060ee416f7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -190,13 +191,13 @@ public class NavigationBarContextTest extends SysuiTestCase { kbd2.setDarkIntensity(0f); // Update icon returns the drawable intensity to half - doReturn(kbd1).when(button).getNewDrawable(); - button.updateIcon(); + doReturn(kbd1).when(button).getNewDrawable(anyInt(), anyInt()); + button.updateIcon(0, 0); assertEquals(TEST_DARK_INTENSITY, kbd1.getDarkIntensity(), DARK_INTENSITY_ERR); // Return old dark intensity on new drawable after update icon - doReturn(kbd2).when(button).getNewDrawable(); - button.updateIcon(); + doReturn(kbd2).when(button).getNewDrawable(anyInt(), anyInt()); + button.updateIcon(0, 0); assertEquals(TEST_DARK_INTENSITY, kbd2.getDarkIntensity(), DARK_INTENSITY_ERR); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java index d6b38ff4936f..f21235c12cde 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java @@ -59,8 +59,8 @@ public class NavigationBarRotationContextTest extends SysuiTestCase { final View view = new View(mContext); mRotationButton = mock(RotationButton.class); - mRotationButtonController = spy( - new RotationButtonController(mContext, RES_UNDEF, mRotationButton)); + mRotationButtonController = spy(new RotationButtonController(mContext, 0, 0, + mRotationButton)); final KeyButtonDrawable kbd = mock(KeyButtonDrawable.class); doReturn(view).when(mRotationButton).getCurrentView(); doReturn(true).when(mRotationButton).acceptRotationProposal(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java index 8ec4cb8b927b..50c1e73f6aac 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java @@ -25,6 +25,8 @@ import java.io.PrintWriter; public class FakeBatteryController extends BaseLeakChecker<BatteryStateChangeCallback> implements BatteryController { + private boolean mWirelessCharging; + public FakeBatteryController(LeakCheck test) { super(test, "battery"); } @@ -58,4 +60,13 @@ public class FakeBatteryController extends BaseLeakChecker<BatteryStateChangeCal public boolean isAodPowerSave() { return false; } + + @Override + public boolean isWirelessCharging() { + return mWirelessCharging; + } + + public void setWirelessCharging(boolean wirelessCharging) { + mWirelessCharging = wirelessCharging; + } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index fa18ccb53408..57250d52b2ab 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -4900,7 +4900,13 @@ public class ActivityManagerService extends IActivityManager.Stub mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId); } - boolean didSomething = mProcessList.killPackageProcessesLocked(packageName, appId, userId, + // Notify first that the package is stopped, so its process won't be restarted unexpectedly + // if there is an activity of the package without attached process becomes visible when + // killing its other processes with visible activities. + boolean didSomething = + mAtmInternal.onForceStopPackage(packageName, doit, evenPersistent, userId); + + didSomething |= mProcessList.killPackageProcessesLocked(packageName, appId, userId, ProcessList.INVALID_ADJ, callerWillRestart, false /* allowRestart */, doit, evenPersistent, true /* setRemoved */, packageName == null ? ApplicationExitInfo.REASON_USER_STOPPED @@ -4909,9 +4915,6 @@ public class ActivityManagerService extends IActivityManager.Stub (packageName == null ? ("stop user " + userId) : ("stop " + packageName)) + " due to " + reason); - didSomething |= - mAtmInternal.onForceStopPackage(packageName, doit, evenPersistent, userId); - if (mServices.bringDownDisabledPackageServicesLocked( packageName, null /* filterByClasses */, userId, evenPersistent, doit)) { if (!doit) { diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index b3231909e4b7..433317b038b3 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -6020,7 +6020,7 @@ public class AppOpsService extends IAppOpsService.Stub { private void resampleAppOpForPackageLocked(@NonNull String packageName, boolean pickOp) { mMessagesCollectedCount = 0.0f; mSampledAppOpCode = pickOp ? ThreadLocalRandom.current().nextInt(_NUM_OP) : OP_NONE; - mAcceptableLeftDistance = _NUM_OP; + mAcceptableLeftDistance = _NUM_OP - 1; mSampledPackage = packageName; } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index c45cefe5bf0c..2d77d6f8add8 100755 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -283,6 +283,7 @@ public class AudioService extends IAudioService.Stub private static final int MSG_HDMI_VOLUME_CHECK = 28; private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29; private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30; + private static final int MSG_CHECK_MODE_FOR_UID = 31; // start of messages handled under wakelock // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) @@ -3683,12 +3684,14 @@ public class AudioService extends IAudioService.Stub private final IBinder mCb; // To be notified of client's death private final int mPid; private final int mUid; + private String mPackage; private int mMode = AudioSystem.MODE_NORMAL; // Current mode set by this client - SetModeDeathHandler(IBinder cb, int pid, int uid) { + SetModeDeathHandler(IBinder cb, int pid, int uid, String caller) { mCb = cb; mPid = pid; mUid = uid; + mPackage = caller; } public void binderDied() { @@ -3726,6 +3729,10 @@ public class AudioService extends IAudioService.Stub public int getUid() { return mUid; } + + public String getPackage() { + return mPackage; + } } /** @see AudioManager#setMode(int) */ @@ -3807,6 +3814,9 @@ public class AudioService extends IAudioService.Stub hdlr = h; // Remove from client list so that it is re-inserted at top of list iter.remove(); + if (hdlr.getMode() == AudioSystem.MODE_IN_COMMUNICATION) { + mAudioHandler.removeEqualMessages(MSG_CHECK_MODE_FOR_UID, hdlr); + } try { hdlr.getBinder().unlinkToDeath(hdlr, 0); if (cb != hdlr.getBinder()){ @@ -3837,7 +3847,7 @@ public class AudioService extends IAudioService.Stub } } else { if (hdlr == null) { - hdlr = new SetModeDeathHandler(cb, pid, uid); + hdlr = new SetModeDeathHandler(cb, pid, uid, caller); } // Register for client death notification try { @@ -3884,6 +3894,7 @@ public class AudioService extends IAudioService.Stub // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL mModeLogger.log( new PhoneStateEvent(caller, pid, mode, newModeOwnerPid, actualMode)); + int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE); int device = getDeviceForStream(streamType); int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device); @@ -3894,6 +3905,16 @@ public class AudioService extends IAudioService.Stub // change of mode may require volume to be re-applied on some devices updateAbsVolumeMultiModeDevices(oldMode, actualMode); + + if (actualMode == AudioSystem.MODE_IN_COMMUNICATION) { + sendMsg(mAudioHandler, + MSG_CHECK_MODE_FOR_UID, + SENDMSG_QUEUE, + 0, + 0, + hdlr, + CHECK_MODE_FOR_UID_PERIOD_MS); + } } return newModeOwnerPid; } @@ -6402,6 +6423,35 @@ public class AudioService extends IAudioService.Stub case MSG_BROADCAST_MICROPHONE_MUTE: mSystemServer.sendMicrophoneMuteChangedIntent(); break; + + case MSG_CHECK_MODE_FOR_UID: + synchronized (mDeviceBroker.mSetModeLock) { + if (msg.obj == null) { + break; + } + // If the app corresponding to this mode death handler object is not + // capturing or playing audio anymore after 3 seconds, remove it + // from the stack. Otherwise, check again in 3 seconds. + SetModeDeathHandler h = (SetModeDeathHandler) msg.obj; + if (mSetModeDeathHandlers.indexOf(h) < 0) { + break; + } + if (mRecordMonitor.isRecordingActiveForUid(h.getUid()) + || mPlaybackMonitor.isPlaybackActiveForUid(h.getUid())) { + sendMsg(mAudioHandler, + MSG_CHECK_MODE_FOR_UID, + SENDMSG_QUEUE, + 0, + 0, + h, + CHECK_MODE_FOR_UID_PERIOD_MS); + break; + } + // For now just log the fact that an app is hogging the audio mode. + // TODO(b/160260850): remove abusive app from audio mode stack. + mModeLogger.log(new PhoneStateEvent(h.getPackage(), h.getPid())); + } + break; } } } @@ -7045,6 +7095,8 @@ public class AudioService extends IAudioService.Stub private static final int UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX = (20 * 3600 * 1000); // 20 hours private static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000; // 1 minute polling interval private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000; // 30s after boot completed + // check playback or record activity every 3 seconds for UIDs owning mode IN_COMMUNICATION + private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 3000; private int safeMediaVolumeIndex(int device) { if (!mSafeMediaVolumeDevices.contains(device)) { diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java index f3ff02f3aedc..0eb5a5d1fb48 100644 --- a/services/core/java/com/android/server/audio/AudioServiceEvents.java +++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java @@ -27,28 +27,82 @@ import com.android.server.audio.AudioDeviceInventory.WiredDeviceConnectionState; public class AudioServiceEvents { final static class PhoneStateEvent extends AudioEventLogger.Event { + static final int MODE_SET = 0; + static final int MODE_IN_COMMUNICATION_TIMEOUT = 1; + + final int mOp; final String mPackage; final int mOwnerPid; final int mRequesterPid; final int mRequestedMode; final int mActualMode; + /** used for MODE_SET */ PhoneStateEvent(String callingPackage, int requesterPid, int requestedMode, int ownerPid, int actualMode) { + mOp = MODE_SET; mPackage = callingPackage; mRequesterPid = requesterPid; mRequestedMode = requestedMode; mOwnerPid = ownerPid; mActualMode = actualMode; + logMetricEvent(); + } + + /** used for MODE_IN_COMMUNICATION_TIMEOUT */ + PhoneStateEvent(String callingPackage, int ownerPid) { + mOp = MODE_IN_COMMUNICATION_TIMEOUT; + mPackage = callingPackage; + mOwnerPid = ownerPid; + mRequesterPid = 0; + mRequestedMode = 0; + mActualMode = 0; + logMetricEvent(); } @Override public String eventToString() { - return new StringBuilder("setMode(").append(AudioSystem.modeToString(mRequestedMode)) - .append(") from package=").append(mPackage) - .append(" pid=").append(mRequesterPid) - .append(" selected mode=").append(AudioSystem.modeToString(mActualMode)) - .append(" by pid=").append(mOwnerPid).toString(); + switch (mOp) { + case MODE_SET: + return new StringBuilder("setMode(") + .append(AudioSystem.modeToString(mRequestedMode)) + .append(") from package=").append(mPackage) + .append(" pid=").append(mRequesterPid) + .append(" selected mode=") + .append(AudioSystem.modeToString(mActualMode)) + .append(" by pid=").append(mOwnerPid).toString(); + case MODE_IN_COMMUNICATION_TIMEOUT: + return new StringBuilder("mode IN COMMUNICATION timeout") + .append(" for package=").append(mPackage) + .append(" pid=").append(mOwnerPid).toString(); + default: return new StringBuilder("FIXME invalid op:").append(mOp).toString(); + } + } + + /** + * Audio Analytics unique Id. + */ + private static final String mMetricsId = MediaMetrics.Name.AUDIO_MODE; + + private void logMetricEvent() { + switch (mOp) { + case MODE_SET: + new MediaMetrics.Item(mMetricsId) + .set(MediaMetrics.Property.EVENT, "set") + .set(MediaMetrics.Property.REQUESTED_MODE, + AudioSystem.modeToString(mRequestedMode)) + .set(MediaMetrics.Property.MODE, AudioSystem.modeToString(mActualMode)) + .set(MediaMetrics.Property.CALLING_PACKAGE, mPackage) + .record(); + return; + case MODE_IN_COMMUNICATION_TIMEOUT: + new MediaMetrics.Item(mMetricsId) + .set(MediaMetrics.Property.EVENT, "inCommunicationTimeout") + .set(MediaMetrics.Property.CALLING_PACKAGE, mPackage) + .record(); + return; + default: return; + } } } diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java index 98f409ea98e7..a5778836aa6e 100644 --- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java +++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java @@ -366,6 +366,23 @@ public final class PlaybackActivityMonitor releasePlayer(piid, 0); } + /** + * Returns true if a player belonging to the app with given uid is active. + * + * @param uid the app uid + * @return true if a player is active, false otherwise + */ + public boolean isPlaybackActiveForUid(int uid) { + synchronized (mPlayerLock) { + for (AudioPlaybackConfiguration apc : mPlayers.values()) { + if (apc.isActive() && apc.getClientUid() == uid) { + return true; + } + } + } + return false; + } + protected void dump(PrintWriter pw) { // players pw.println("\nPlaybackActivityMonitor dump time: " diff --git a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java index 32c6cc32a78d..ea0107ecfd23 100644 --- a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java +++ b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java @@ -215,6 +215,25 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin dispatchCallbacks(updateSnapshot(AudioManager.RECORD_CONFIG_EVENT_RELEASE, riid, null)); } + /** + * Returns true if a recorder belonging to the app with given uid is active. + * + * @param uid the app uid + * @return true if a recorder is active, false otherwise + */ + public boolean isRecordingActiveForUid(int uid) { + synchronized (mRecordStates) { + for (RecordingState state : mRecordStates) { + // Note: isActiveConfiguration() == true => state.getConfig() != null + if (state.isActiveConfiguration() + && state.getConfig().getClientUid() == uid) { + return true; + } + } + } + return false; + } + private void dispatchCallbacks(List<AudioRecordingConfiguration> configs) { if (configs == null) { // null means "no changes" return; diff --git a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java index 7f2b18b9edf5..6c57208c1e84 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java @@ -29,8 +29,8 @@ import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.face.V1_0.IBiometricsFace; import android.hardware.biometrics.face.V1_0.IBiometricsFaceClientCallback; import android.hardware.face.Face; -import android.hardware.face.IFaceServiceReceiver; import android.hardware.face.FaceSensorProperties; +import android.hardware.face.IFaceServiceReceiver; import android.os.Build; import android.os.Handler; import android.os.IBinder; @@ -269,7 +269,7 @@ class Face10 implements IHwBinder.DeathRecipient { Face10(@NonNull Context context, int sensorId, @NonNull LockoutResetDispatcher lockoutResetDispatcher) { - mFaceSensorProperties = new FaceSensorProperties(false /* supportsFaceDetect */); + mFaceSensorProperties = new FaceSensorProperties(sensorId, false /* supportsFaceDetect */); mContext = context; mSensorId = sensorId; mScheduler = new BiometricScheduler(TAG, null /* gestureAvailabilityTracker */); @@ -559,7 +559,7 @@ class Face10 implements IHwBinder.DeathRecipient { return daemon != null; } - FaceSensorProperties getFaceSensorProperties() { + @NonNull FaceSensorProperties getFaceSensorProperties() { return mFaceSensorProperties; } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java index 610faa04ca3b..b832a09f8f88 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java @@ -44,6 +44,7 @@ import com.android.server.biometrics.sensors.LockoutTracker; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -65,6 +66,20 @@ public class FaceService extends SystemService { */ private final class FaceServiceWrapper extends IFaceService.Stub { @Override // Binder call + public List<FaceSensorProperties> getSensorProperties(String opPackageName) { + Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); + final List<FaceSensorProperties> properties = new ArrayList<>(); + + if (mFace10 != null) { + properties.add(mFace10.getFaceSensorProperties()); + } + + Slog.d(TAG, "Retrieved sensor properties for: " + opPackageName + + ", sensors: " + properties.size()); + return properties; + } + + @Override // Binder call public void generateChallenge(IBinder token, IFaceServiceReceiver receiver, String opPackageName) { Utils.checkPermission(getContext(), MANAGE_BIOMETRIC); @@ -239,12 +254,6 @@ public class FaceService extends SystemService { return !mFace10.getEnrolledFaces(userId).isEmpty(); } - @Override // Binder call - public FaceSensorProperties getSensorProperties(String opPackageName) { - Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); - return mFace10.getFaceSensorProperties(); - } - @Override public @LockoutTracker.LockoutMode int getLockoutModeForUser(int userId) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java index 20ee3f375ab1..dad038626762 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java @@ -31,6 +31,7 @@ import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; import android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprintClientCallback; import android.hardware.fingerprint.Fingerprint; +import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.hardware.fingerprint.IUdfpsOverlayController; import android.os.Handler; @@ -85,7 +86,7 @@ class Fingerprint21 implements IHwBinder.DeathRecipient { private final Context mContext; private final IActivityTaskManager mActivityTaskManager; - private final SensorProperties mSensorProperties; + private final FingerprintSensorProperties mSensorProperties; private final BiometricScheduler mScheduler; private final Handler mHandler; private final LockoutResetDispatcher mLockoutResetDispatcher; @@ -98,25 +99,6 @@ class Fingerprint21 implements IHwBinder.DeathRecipient { @Nullable private IUdfpsOverlayController mUdfpsOverlayController; private int mCurrentUserId = UserHandle.USER_NULL; - /** - * Static properties that never change for a given sensor. - */ - private static final class SensorProperties { - // Unique sensorId - final int sensorId; - // Is the sensor under-display - final boolean isUdfps; - // Supports finger detection without exposing accept/reject and without incrementing the - // lockout counter - final boolean supportsFingerDetectOnly; - - SensorProperties(int sensorId, boolean isUdfps, boolean supportsFingerDetectOnly) { - this.sensorId = sensorId; - this.isUdfps = isUdfps; - this.supportsFingerDetectOnly = supportsFingerDetectOnly; - } - } - private final class BiometricTaskStackListener extends TaskStackListener { @Override public void onTaskStackChanged() { @@ -314,9 +296,11 @@ class Fingerprint21 implements IHwBinder.DeathRecipient { isUdfps = false; } } - // Fingerprint2.1 supports finger-detect only since lockout is controlled in the framework. - mSensorProperties = new SensorProperties(sensorId, isUdfps, - true /* supportsFingerDetectOnly */); + + final @FingerprintSensorProperties.SensorType int sensorType = + isUdfps ? FingerprintSensorProperties.TYPE_UDFPS + : FingerprintSensorProperties.TYPE_REAR; + mSensorProperties = new FingerprintSensorProperties(sensorId, sensorType); } @Override @@ -558,6 +542,10 @@ class Fingerprint21 implements IHwBinder.DeathRecipient { return daemon != null; } + @NonNull FingerprintSensorProperties getFingerprintSensorProperties() { + return mSensorProperties; + } + void rename(int fingerId, int userId, String name) { mHandler.post(() -> { FingerprintUtils.getInstance().renameBiometricForUser(mContext, userId, fingerId, name); @@ -592,10 +580,6 @@ class Fingerprint21 implements IHwBinder.DeathRecipient { udfps.onFingerUp(); } - boolean isUdfps() { - return mSensorProperties.isUdfps; - } - void setUdfpsOverlayController(IUdfpsOverlayController controller) { mUdfpsOverlayController = controller; } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java index 4d33fd6301e2..e4387c9e2b81 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java @@ -23,10 +23,8 @@ import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT; import static android.Manifest.permission.USE_BIOMETRIC; import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL; import static android.Manifest.permission.USE_FINGERPRINT; -import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; import android.annotation.NonNull; -import android.app.ActivityManager; import android.app.AppOpsManager; import android.content.Context; import android.content.pm.PackageManager; @@ -34,6 +32,7 @@ import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; import android.hardware.fingerprint.Fingerprint; +import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.IFingerprintClientActiveCallback; import android.hardware.fingerprint.IFingerprintService; import android.hardware.fingerprint.IFingerprintServiceReceiver; @@ -42,7 +41,6 @@ import android.os.Binder; import android.os.IBinder; import android.os.NativeHandle; import android.os.Process; -import android.os.RemoteException; import android.os.UserHandle; import android.util.EventLog; import android.util.Slog; @@ -58,6 +56,7 @@ import com.android.server.biometrics.sensors.LockoutTracker; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -81,6 +80,20 @@ public class FingerprintService extends SystemService { */ private final class FingerprintServiceWrapper extends IFingerprintService.Stub { @Override // Binder call + public List<FingerprintSensorProperties> getSensorProperties(String opPackageName) { + Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); + final List<FingerprintSensorProperties> properties = new ArrayList<>(); + + if (mFingerprint21 != null) { + properties.add(mFingerprint21.getFingerprintSensorProperties()); + } + + Slog.d(TAG, "Retrieved sensor properties for: " + opPackageName + + ", sensors: " + properties.size()); + return properties; + } + + @Override // Binder call public void generateChallenge(IBinder token, IFingerprintServiceReceiver receiver, String opPackageName) { Utils.checkPermission(getContext(), MANAGE_FINGERPRINT); @@ -122,19 +135,27 @@ public class FingerprintService extends SystemService { return; } - if (Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId) - && Utils.isKeyguard(getContext(), opPackageName)) { - // If this happens, something in KeyguardUpdateMonitor is wrong. - // SafetyNet for b/79776455 - EventLog.writeEvent(0x534e4554, "79776455"); - Slog.e(TAG, "Authenticate invoked when user is encrypted or lockdown"); - return; + // Keyguard check must be done on the caller's binder identity, since it also checks + // permission. + final boolean isKeyguard = Utils.isKeyguard(getContext(), opPackageName); + + // Clear calling identity when checking LockPatternUtils for StrongAuth flags. + final long identity = Binder.clearCallingIdentity(); + try { + if (isKeyguard && Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId)) { + // If this happens, something in KeyguardUpdateMonitor is wrong. + // SafetyNet for b/79776455 + EventLog.writeEvent(0x534e4554, "79776455"); + Slog.e(TAG, "Authenticate invoked when user is encrypted or lockdown"); + return; + } + } finally { + Binder.restoreCallingIdentity(identity); } final boolean restricted = getContext().checkCallingPermission(MANAGE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED; - final int statsClient = Utils.isKeyguard(getContext(), opPackageName) - ? BiometricsProtoEnums.CLIENT_KEYGUARD + final int statsClient = isKeyguard ? BiometricsProtoEnums.CLIENT_KEYGUARD : BiometricsProtoEnums.CLIENT_FINGERPRINT_MANAGER; mFingerprint21.scheduleAuthenticate(token, operationId, userId, 0 /* cookie */, new ClientMonitorCallbackConverter(receiver), opPackageName, surface, @@ -365,12 +386,6 @@ public class FingerprintService extends SystemService { } @Override - public boolean isUdfps() { - Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); - return mFingerprint21.isUdfps(); - } - - @Override public void setUdfpsOverlayController(IUdfpsOverlayController controller) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); mFingerprint21.setUdfpsOverlayController(controller); diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index ea047888caff..d6557f6410ec 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -5288,6 +5288,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @Override public void onTempPowerSaveWhitelistChange(int appId, boolean added) { synchronized (mUidRulesFirstLock) { + if (!mSystemReady) { + return; + } mLogger.tempPowerSaveWlChanged(appId, added); if (added) { mPowerSaveTempWhitelistAppIds.put(appId, true); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index e75dab73478e..03868e922bdd 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -209,7 +209,6 @@ import com.android.server.policy.keyguard.KeyguardStateMonitor.StateCallback; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.vr.VrManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal; -import com.android.server.wm.ActivityTaskManagerInternal.SleepToken; import com.android.server.wm.AppTransition; import com.android.server.wm.DisplayPolicy; import com.android.server.wm.DisplayRotation; @@ -491,7 +490,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private boolean mPendingKeyguardOccluded; private boolean mKeyguardOccludedChanged; - SleepToken mScreenOffSleepToken; + private ActivityTaskManagerInternal.SleepTokenAcquirer mScreenOffSleepTokenAcquirer; volatile boolean mKeyguardOccluded; Intent mHomeIntent; Intent mCarDockIntent; @@ -1741,6 +1740,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { new AccessibilityShortcutController(mContext, new Handler(), mCurrentUserId); mLogger = new MetricsLogger(); + mScreenOffSleepTokenAcquirer = mActivityTaskManagerInternal + .createSleepTokenAcquirer("ScreenOff"); + Resources res = mContext.getResources(); mWakeOnDpadKeyPress = res.getBoolean(com.android.internal.R.bool.config_wakeOnDpadKeyPress); @@ -4984,15 +4986,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { // TODO (multidisplay): Support multiple displays in WindowManagerPolicy. private void updateScreenOffSleepToken(boolean acquire) { if (acquire) { - if (mScreenOffSleepToken == null) { - mScreenOffSleepToken = mActivityTaskManagerInternal.acquireSleepToken( - "ScreenOff", DEFAULT_DISPLAY); - } + mScreenOffSleepTokenAcquirer.acquire(DEFAULT_DISPLAY); } else { - if (mScreenOffSleepToken != null) { - mScreenOffSleepToken.release(); - mScreenOffSleepToken = null; - } + mScreenOffSleepTokenAcquirer.release(DEFAULT_DISPLAY); } } diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java index 710185db7fbd..651eafd77fe7 100644 --- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java +++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java @@ -140,6 +140,10 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { @IntDef({NAV_BAR_LEFT, NAV_BAR_RIGHT, NAV_BAR_BOTTOM}) @interface NavigationBarPosition {} + @Retention(SOURCE) + @IntDef({ALT_BAR_UNKNOWN, ALT_BAR_LEFT, ALT_BAR_RIGHT, ALT_BAR_BOTTOM, ALT_BAR_TOP}) + @interface AltBarPosition {} + /** * Pass this event to the user / app. To be returned from * {@link #interceptKeyBeforeQueueing}. @@ -395,14 +399,6 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { return false; } - /** - * Returns true if the window has a letterbox and any part of that letterbox overlaps with - * the given {@code rect}. - */ - default boolean isLetterboxedOverlappingWith(Rect rect) { - return false; - } - /** @return the current windowing mode of this window. */ int getWindowingMode(); diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java index 2a4a69ddde4f..4a2dfdcaac7a 100644 --- a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java +++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java @@ -49,6 +49,7 @@ import com.android.server.power.batterysaver.BatterySaverPolicy.Policy; import com.android.server.power.batterysaver.BatterySavingStats.BatterySaverState; import com.android.server.power.batterysaver.BatterySavingStats.DozeState; import com.android.server.power.batterysaver.BatterySavingStats.InteractiveState; +import com.android.server.power.batterysaver.BatterySavingStats.PlugState; import java.util.ArrayList; import java.util.Objects; @@ -551,17 +552,14 @@ public class BatterySaverController implements BatterySaverPolicyListener { : DozeState.NOT_DOZING; synchronized (mLock) { - if (mIsPluggedIn) { - mBatterySavingStats.startCharging(); - return; - } mBatterySavingStats.transitionState( getFullEnabledLocked() ? BatterySaverState.ON : (getAdaptiveEnabledLocked() ? BatterySaverState.ADAPTIVE : BatterySaverState.OFF), isInteractive ? InteractiveState.INTERACTIVE : InteractiveState.NON_INTERACTIVE, - dozeMode); + dozeMode, + mIsPluggedIn ? PlugState.PLUGGED : PlugState.UNPLUGGED); } } diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySavingStats.java b/services/core/java/com/android/server/power/batterysaver/BatterySavingStats.java index 3dbc0072f8b4..05695d919910 100644 --- a/services/core/java/com/android/server/power/batterysaver/BatterySavingStats.java +++ b/services/core/java/com/android/server/power/batterysaver/BatterySavingStats.java @@ -17,8 +17,8 @@ package com.android.server.power.batterysaver; import android.os.BatteryManagerInternal; import android.os.SystemClock; -import android.util.ArrayMap; import android.util.Slog; +import android.util.SparseArray; import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; @@ -93,6 +93,20 @@ public class BatterySavingStats { } } + /** Whether the device is plugged in or not. */ + interface PlugState { + int UNPLUGGED = 0; + int PLUGGED = 1; + + int SHIFT = DozeState.SHIFT + DozeState.BITS; + int BITS = 1; + int MASK = (1 << BITS) - 1; + + static int fromIndex(int index) { + return (index >> SHIFT) & MASK; + } + } + /** * Various stats in each state. */ @@ -140,7 +154,6 @@ public class BatterySavingStats { private BatteryManagerInternal mBatteryManagerInternal; private static final int STATE_NOT_INITIALIZED = -1; - private static final int STATE_CHARGING = -2; /** * Current state, one of STATE_* or values returned by {@link #statesToIndex}. @@ -153,20 +166,26 @@ public class BatterySavingStats { */ @VisibleForTesting @GuardedBy("mLock") - final ArrayMap<Integer, Stat> mStats = new ArrayMap<>(); + final SparseArray<Stat> mStats = new SparseArray<>(); @GuardedBy("mLock") private int mBatterySaverEnabledCount = 0; @GuardedBy("mLock") - private boolean mIsBatterySaverEnabled; - - @GuardedBy("mLock") private long mLastBatterySaverEnabledTime = 0; @GuardedBy("mLock") private long mLastBatterySaverDisabledTime = 0; + @GuardedBy("mLock") + private int mAdaptiveBatterySaverEnabledCount = 0; + + @GuardedBy("mLock") + private long mLastAdaptiveBatterySaverEnabledTime = 0; + + @GuardedBy("mLock") + private long mLastAdaptiveBatterySaverDisabledTime = 0; + /** Visible for unit tests */ @VisibleForTesting public BatterySavingStats(Object lock) { @@ -189,10 +208,11 @@ public class BatterySavingStats { */ @VisibleForTesting static int statesToIndex( - int batterySaverState, int interactiveState, int dozeState) { + int batterySaverState, int interactiveState, int dozeState, int plugState) { int ret = batterySaverState & BatterySaverState.MASK; ret |= (interactiveState & InteractiveState.MASK) << InteractiveState.SHIFT; ret |= (dozeState & DozeState.MASK) << DozeState.SHIFT; + ret |= (plugState & PlugState.MASK) << PlugState.SHIFT; return ret; } @@ -204,12 +224,11 @@ public class BatterySavingStats { switch (state) { case STATE_NOT_INITIALIZED: return "NotInitialized"; - case STATE_CHARGING: - return "Charging"; } return "BS=" + BatterySaverState.fromIndex(state) + ",I=" + InteractiveState.fromIndex(state) - + ",D=" + DozeState.fromIndex(state); + + ",D=" + DozeState.fromIndex(state) + + ",P=" + PlugState.fromIndex(state); } /** @@ -230,8 +249,9 @@ public class BatterySavingStats { /** * @return {@link Stat} fo a given state triplet. */ - private Stat getStat(int batterySaverState, int interactiveState, int dozeState) { - return getStat(statesToIndex(batterySaverState, interactiveState, dozeState)); + private Stat getStat(int batterySaverState, int interactiveState, int dozeState, + int plugState) { + return getStat(statesToIndex(batterySaverState, interactiveState, dozeState, plugState)); } @VisibleForTesting @@ -258,26 +278,17 @@ public class BatterySavingStats { } /** - * Called from the outside whenever any of the states changes, when the device is not plugged - * in. + * Called from the outside whenever any of the states change. */ - public void transitionState(int batterySaverState, int interactiveState, int dozeState) { + void transitionState(int batterySaverState, int interactiveState, int dozeState, + int plugState) { synchronized (mLock) { final int newState = statesToIndex( - batterySaverState, interactiveState, dozeState); + batterySaverState, interactiveState, dozeState, plugState); transitionStateLocked(newState); } } - /** - * Called from the outside when the device is plugged in. - */ - public void startCharging() { - synchronized (mLock) { - transitionStateLocked(STATE_CHARGING); - } - } - @GuardedBy("mLock") private void transitionStateLocked(int newState) { if (mCurrentState == newState) { @@ -287,17 +298,33 @@ public class BatterySavingStats { final int batteryLevel = injectBatteryLevel(); final int batteryPercent = injectBatteryPercent(); - final boolean oldBatterySaverEnabled = - BatterySaverState.fromIndex(mCurrentState) != BatterySaverState.OFF; - final boolean newBatterySaverEnabled = - BatterySaverState.fromIndex(newState) != BatterySaverState.OFF; - if (oldBatterySaverEnabled != newBatterySaverEnabled) { - mIsBatterySaverEnabled = newBatterySaverEnabled; - if (newBatterySaverEnabled) { - mBatterySaverEnabledCount++; - mLastBatterySaverEnabledTime = injectCurrentTime(); - } else { - mLastBatterySaverDisabledTime = injectCurrentTime(); + final int oldBatterySaverState = mCurrentState < 0 + ? BatterySaverState.OFF : BatterySaverState.fromIndex(mCurrentState); + final int newBatterySaverState = newState < 0 + ? BatterySaverState.OFF : BatterySaverState.fromIndex(newState); + if (oldBatterySaverState != newBatterySaverState) { + switch (newBatterySaverState) { + case BatterySaverState.ON: + mBatterySaverEnabledCount++; + mLastBatterySaverEnabledTime = now; + if (oldBatterySaverState == BatterySaverState.ADAPTIVE) { + mLastAdaptiveBatterySaverDisabledTime = now; + } + break; + case BatterySaverState.OFF: + if (oldBatterySaverState == BatterySaverState.ON) { + mLastBatterySaverDisabledTime = now; + } else { + mLastAdaptiveBatterySaverDisabledTime = now; + } + break; + case BatterySaverState.ADAPTIVE: + mAdaptiveBatterySaverEnabledCount++; + mLastAdaptiveBatterySaverEnabledTime = now; + if (oldBatterySaverState == BatterySaverState.ON) { + mLastBatterySaverDisabledTime = now; + } + break; } } @@ -377,7 +404,18 @@ public class BatterySavingStats { pw.print(indent); pw.print("Battery Saver is currently: "); - pw.println(mIsBatterySaverEnabled ? "ON" : "OFF"); + switch (BatterySaverState.fromIndex(mCurrentState)) { + case BatterySaverState.OFF: + pw.println("OFF"); + break; + case BatterySaverState.ON: + pw.println("ON"); + break; + case BatterySaverState.ADAPTIVE: + pw.println("ADAPTIVE"); + break; + } + if (mLastBatterySaverEnabledTime > 0) { pw.print(indent); pw.print(" "); @@ -400,9 +438,34 @@ public class BatterySavingStats { pw.print(indent); pw.print(" "); - pw.print("Times enabled: "); + pw.print("Times full enabled: "); pw.println(mBatterySaverEnabledCount); + if (mLastAdaptiveBatterySaverEnabledTime > 0) { + pw.print(indent); + pw.print(" "); + pw.print("Last ADAPTIVE ON time: "); + pw.print(sdf.format( + new Date(now - nowElapsed + mLastAdaptiveBatterySaverEnabledTime))); + pw.print(" "); + TimeUtils.formatDuration(mLastAdaptiveBatterySaverEnabledTime, nowElapsed, pw); + pw.println(); + } + if (mLastAdaptiveBatterySaverDisabledTime > 0) { + pw.print(indent); + pw.print(" "); + pw.print("Last ADAPTIVE OFF time: "); + pw.print(sdf.format( + new Date(now - nowElapsed + mLastAdaptiveBatterySaverDisabledTime))); + pw.print(" "); + TimeUtils.formatDuration(mLastAdaptiveBatterySaverDisabledTime, nowElapsed, pw); + pw.println(); + } + pw.print(indent); + pw.print(" "); + pw.print("Times adaptive enabled: "); + pw.println(mAdaptiveBatterySaverEnabledCount); + pw.println(); pw.print(indent); @@ -436,8 +499,10 @@ public class BatterySavingStats { pw.print(interactiveLabel); pw.print(": "); - final Stat offStat = getStat(BatterySaverState.OFF, interactiveState, dozeState); - final Stat onStat = getStat(BatterySaverState.ON, interactiveState, dozeState); + final Stat offStat = getStat(BatterySaverState.OFF, interactiveState, dozeState, + PlugState.UNPLUGGED); + final Stat onStat = getStat(BatterySaverState.ON, interactiveState, dozeState, + PlugState.UNPLUGGED); pw.println(String.format("%6dm %6dmAh(%3d%%) %8.1fmAh/h %6dm %6dmAh(%3d%%) %8.1fmAh/h", offStat.totalMinutes(), diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java index 4f18d07a843f..6ba675db0aed 100644 --- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java @@ -640,7 +640,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba } for (String apexPackageName : apexPackageNames) { - // We will not recieve notifications when an apex is updated, + // We will not receive notifications when an apex is updated, // so check now in case any rollbacks ought to be expired. The // onPackagedReplace function is safe to call if the package // hasn't actually been updated. @@ -827,7 +827,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba } /** - * Do code and userdata backups to enable rollback of the given session. + * Do code and user-data backups to enable rollback of the given session. * In case of multiPackage sessions, <code>session</code> should be one of * the child sessions, not the parent session. * @@ -915,7 +915,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba } } - /** + /* * The order is important here! Always enable the embedded apk-in-apex (if any) before * enabling the embedding apex. Otherwise the rollback object might be in an inconsistent * state where an embedding apex is successfully enabled while one of its embedded @@ -1323,7 +1323,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba assertInWorkerThread(); int rollbackId = allocateRollbackId(); final int userId; - if (parentSession.getUser() == UserHandle.ALL) { + if (parentSession.getUser().equals(UserHandle.ALL)) { userId = UserHandle.SYSTEM.getIdentifier(); } else { userId = parentSession.getUser().getIdentifier(); diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java index 189b21fb81a6..7565d8f9647c 100644 --- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java @@ -396,8 +396,7 @@ class ActivityMetricsLogger { mLastLogTimeSecs = now; mWindowState = WINDOW_STATE_INVALID; - ActivityStack stack = - mSupervisor.mRootWindowContainer.getTopDisplayFocusedStack(); + Task stack = mSupervisor.mRootWindowContainer.getTopDisplayFocusedStack(); if (stack == null) { return; } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index bec0ce944e3f..63ece0465993 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -136,18 +136,6 @@ import static com.android.server.wm.ActivityRecordProto.VISIBLE; import static com.android.server.wm.ActivityRecordProto.VISIBLE_REQUESTED; import static com.android.server.wm.ActivityRecordProto.VISIBLE_SET_FROM_TRANSFERRED_STARTING_WINDOW; import static com.android.server.wm.ActivityRecordProto.WINDOW_TOKEN; -import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED; -import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING; -import static com.android.server.wm.ActivityStack.ActivityState.FINISHING; -import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSED; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSING; -import static com.android.server.wm.ActivityStack.ActivityState.RESTARTING_PROCESS; -import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; -import static com.android.server.wm.ActivityStack.ActivityState.STARTED; -import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; -import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; -import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_APP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; @@ -192,6 +180,18 @@ 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.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION; +import static com.android.server.wm.Task.ActivityState.DESTROYED; +import static com.android.server.wm.Task.ActivityState.DESTROYING; +import static com.android.server.wm.Task.ActivityState.FINISHING; +import static com.android.server.wm.Task.ActivityState.INITIALIZING; +import static com.android.server.wm.Task.ActivityState.PAUSED; +import static com.android.server.wm.Task.ActivityState.PAUSING; +import static com.android.server.wm.Task.ActivityState.RESTARTING_PROCESS; +import static com.android.server.wm.Task.ActivityState.RESUMED; +import static com.android.server.wm.Task.ActivityState.STARTED; +import static com.android.server.wm.Task.ActivityState.STOPPED; +import static com.android.server.wm.Task.ActivityState.STOPPING; +import static com.android.server.wm.Task.STACK_VISIBILITY_VISIBLE; import static com.android.server.wm.TaskPersister.DEBUG; import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; @@ -309,8 +309,8 @@ import com.android.server.protolog.common.ProtoLog; import com.android.server.uri.NeededUriGrants; import com.android.server.uri.UriPermissionOwner; import com.android.server.wm.ActivityMetricsLogger.TransitionInfoSnapshot; -import com.android.server.wm.ActivityStack.ActivityState; import com.android.server.wm.SurfaceAnimator.AnimationType; +import com.android.server.wm.Task.ActivityState; import com.android.server.wm.WindowManagerService.H; import com.android.server.wm.utils.InsetUtils; @@ -658,6 +658,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // TODO: Have a WindowContainer state for tracking exiting/deferred removal. boolean mIsExiting; + // Force an app transition to be ran in the case the visibility of the app did not change. + // We use this for the case of moving a Root Task to the back with multiple activities, and the + // top activity enters PIP; the bottom activity's visibility stays the same, but we need to + // run the transition. + boolean mRequestForceTransition; boolean mEnteringAnimation; @@ -1150,7 +1155,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } void updateMultiWindowMode() { - if (task == null || task.getStack() == null || !attachedToProcess()) { + if (task == null || task.getRootTask() == null || !attachedToProcess()) { return; } @@ -1175,7 +1180,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } void updatePictureInPictureMode(Rect targetStackBounds, boolean forceUpdate) { - if (task == null || task.getStack() == null || !attachedToProcess()) { + if (task == null || task.getRootTask() == null || !attachedToProcess()) { return; } @@ -1216,8 +1221,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A this.task = task; } - ActivityStack getStack() { - return task != null ? task.getStack() : null; + Task getStack() { + return task != null ? task.getRootTask() : null; } @Override @@ -1264,10 +1269,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (getDisplayContent() != null) { getDisplayContent().mClosingApps.remove(this); } - } else if (mLastParent != null && mLastParent.getStack() != null) { - task.getStack().mExitingActivities.remove(this); + } else if (mLastParent != null && mLastParent.getRootTask() != null) { + task.getRootTask().mExitingActivities.remove(this); } - final ActivityStack stack = getStack(); + final Task stack = getStack(); // If we reparent, make sure to remove ourselves from the old animation registry. if (mAnimatingActivityRegistry != null) { @@ -1394,6 +1399,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } /** + * @see Letterbox#notIntersectsOrFullyContains(Rect) + */ + boolean letterboxNotIntersectsOrFullyContains(Rect rect) { + return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect); + } + + /** * @return {@code true} if there is a letterbox and any part of that letterbox overlaps with * the given {@code rect}. */ @@ -2113,8 +2125,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } /** @return Root task of this activity, null if there is no task. */ - ActivityStack getRootTask() { - return task != null ? (ActivityStack) task.getRootTask() : null; + Task getRootTask() { + return task != null ? task.getRootTask() : null; } int getRootTaskId() { @@ -2122,7 +2134,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } DisplayContent getDisplay() { - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); return stack != null ? stack.getDisplay() : null; } @@ -2192,7 +2204,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } boolean isInStackLocked() { - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); return stack != null && stack.isInTask(this) != null; } @@ -2402,7 +2414,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); if (stack == null) { Slog.w(TAG, "moveActivityStackToFront: invalid task or stack: activity=" + this + " task=" + task); @@ -2534,7 +2546,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return FINISH_RESULT_CANCELLED; } - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); final boolean mayAdjustTop = (isState(RESUMED) || stack.mResumedActivity == null) && stack.isFocusedStackOnDisplay(); final boolean shouldAdjustGlobalFocus = mayAdjustTop @@ -2564,7 +2576,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // We are finishing the top focused activity and its task has nothing to be focused so // the next focusable task should be focused. - if (mayAdjustTop && ((ActivityStack) task).topRunningActivity(true /* focusableOnly */) + if (mayAdjustTop && task.topRunningActivity(true /* focusableOnly */) == null) { task.adjustFocusToNextFocusableTask("finish-top", false /* allowFocusSelf */, shouldAdjustGlobalFocus); @@ -2693,7 +2705,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean isCurrentVisible = mVisibleRequested || isState(PAUSED); if (isCurrentVisible) { - final ActivityStack stack = getStack(); + final Task stack = getStack(); final ActivityRecord activity = stack.mResumedActivity; boolean ensureVisibility = false; if (activity != null && !activity.occludesParent()) { @@ -2763,7 +2775,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Make sure the record is cleaned out of other places. mStackSupervisor.mStoppingActivities.remove(this); - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); final TaskDisplayArea taskDisplayArea = getDisplayArea(); // TODO(b/137329632): Exclude current activity when looking for the next one with // DisplayContent#topRunningActivity(). @@ -2923,7 +2935,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A boolean safelyDestroy(String reason) { if (isDestroyable()) { if (DEBUG_SWITCH) { - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); Slog.v(TAG_SWITCH, "Safely destroying " + this + " in state " + getState() + " resumed=" + stack.mResumedActivity + " pausing=" + stack.mPausingActivity @@ -2940,8 +2952,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A null /* resultData */, null /* resultGrants */); makeFinishingLocked(); if (ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE) { - Slog.i(TAG_ADD_REMOVE, "Removing activity " + this + " from stack callers=" - + Debug.getCallers(5)); + Slog.i(TAG_ADD_REMOVE, "Removing activity " + this + " from stack, reason=" + + reason + ", callers=" + Debug.getCallers(5)); } takeFromHistory(); @@ -3217,7 +3229,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A getDisplayContent().mNoAnimationNotifyOnTransitionFinished.add(token); } - final ActivityStack stack = getStack(); + final Task stack = getStack(); if (delayed && !isEmpty()) { // set the token aside because it has an active animation to be finished ProtoLog.v(WM_DEBUG_ADD_REMOVE, @@ -3731,7 +3743,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } final boolean isSleeping() { - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); return stack != null ? stack.shouldSleepActivities() : mAtmService.isSleepingLocked(); } @@ -4199,6 +4211,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (mUseTransferredAnimation) { return false; } + // If it was set to true, reset the last request to force the transition. + mRequestForceTransition = false; return super.applyAnimation(lp, transit, enter, isVoiceInteraction, sources); } @@ -4342,7 +4356,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // transition animation // * or this is an opening app and windows are being replaced (e.g. freeform window to // normal window). - return isVisible() != visible || (!isVisible() && mIsExiting) + return isVisible() != visible || mRequestForceTransition || (!isVisible() && mIsExiting) || (visible && forAllWindows(WindowState::waitingForReplacement, true)); } @@ -4564,7 +4578,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return visibleIgnoringKeyguard; } - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); if (stack == null) { return false; } @@ -4601,7 +4615,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } boolean shouldBeVisible() { - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); if (stack == null) { return false; } @@ -4622,7 +4636,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // If this activity is paused, tell it to now show its window. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making visible and scheduling visibility: " + this); - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); try { if (stack.mTranslucentActivityWaiting != null) { updateOptionsLocked(returningOptions); @@ -4899,7 +4913,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mStackSupervisor.reportResumedActivityLocked(this); resumeKeyDispatchingLocked(); - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); mStackSupervisor.mNoAnimActivities.clear(); // Mark the point when the activity is resuming @@ -4927,7 +4941,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity paused: token=" + appToken + ", timeout=" + timeout); - final ActivityStack stack = getStack(); + final Task stack = getStack(); if (stack != null) { removePauseTimeout(); @@ -4992,7 +5006,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A void stopIfPossible() { if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Stopping: " + this); - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); if (isNoHistory()) { if (!finishing) { if (!stack.shouldSleepActivities()) { @@ -5049,7 +5063,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A void activityStopped(Bundle newIcicle, PersistableBundle newPersistentState, CharSequence description) { - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); final boolean isStopping = mState == STOPPING; if (!isStopping && mState != RESTARTING_PROCESS) { Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this); @@ -5099,7 +5113,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mStackSupervisor.mStoppingActivities.add(this); } - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); // If we already have a few activities waiting to stop, then give up on things going idle // and start clearing them out. Or if r is the last of activity of the last task the stack // will be empty and must be cleared immediately. @@ -5135,7 +5149,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); if (stack == null) { return false; } @@ -5151,7 +5165,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A void finishLaunchTickingLocked() { launchTickTime = 0; - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); if (stack == null) { return; } @@ -5582,7 +5596,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // First find the real culprit... if this activity has stopped, then the key dispatching // timeout should not be caused by this. if (stopped) { - final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack(); + final Task stack = mRootWindowContainer.getTopDisplayFocusedStack(); if (stack == null) { return this; } @@ -5646,7 +5660,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return (r != null) ? r.getRootTask().isInTask(r) : null; } - static ActivityStack getStackLocked(IBinder token) { + static Task getStackLocked(IBinder token) { final ActivityRecord r = ActivityRecord.isInStackLocked(token); if (r != null) { return r.getRootTask(); @@ -5659,7 +5673,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A * {@link android.view.Display#INVALID_DISPLAY} if not attached. */ int getDisplayId() { - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); if (stack == null) { return INVALID_DISPLAY; } @@ -5671,7 +5685,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // This would be redundant. return false; } - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); if (isState(RESUMED) || stack == null || this == stack.mPausingActivity || !mHaveState || !stopped) { // We're not ready for this kind of thing. @@ -5993,7 +6007,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A getTransit(), task)) { task.getBounds(mTmpRect); } else { - final ActivityStack stack = getStack(); + final Task stack = getStack(); if (stack == null) { return; } @@ -6816,7 +6830,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A private void applyAspectRatio(Rect outBounds, Rect containingAppBounds, Rect containingBounds) { final float maxAspectRatio = info.maxAspectRatio; - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); final float minAspectRatio = info.minAspectRatio; if (task == null || stack == null || (inMultiWindowMode() && !shouldUseSizeCompatMode()) @@ -6922,7 +6936,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A */ boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow, boolean ignoreVisibility) { - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); if (stack.mConfigWillChange) { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Skipping config check (will change): " + this); @@ -7473,7 +7487,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (!getTurnScreenOnFlag()) { return false; } - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); return stack != null && !stack.inMultiWindowMode() && stack.checkKeyguardVisibility(this, true /* shouldBeVisible */, diff --git a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java index 5dfc261480f2..8540fa7cf347 100644 --- a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java +++ b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java @@ -16,10 +16,10 @@ package com.android.server.wm; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSING; -import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; +import static com.android.server.wm.Task.ActivityState.PAUSING; +import static com.android.server.wm.Task.ActivityState.RESUMED; import android.util.ArraySet; import android.util.Slog; diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java deleted file mode 100644 index 686e016f1d35..000000000000 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ /dev/null @@ -1,3266 +0,0 @@ -/* - * Copyright (C) 2010 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.ActivityTaskManager.INVALID_TASK_ID; -import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; -import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; -import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; -import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; -import static android.app.WindowConfiguration.activityTypeToString; -import static android.app.WindowConfiguration.windowingModeToString; -import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT; -import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING; -import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS; -import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; -import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD; -import static android.view.Display.INVALID_DISPLAY; -import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE; -import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN; -import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE; -import static android.view.WindowManager.TRANSIT_NONE; -import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY; -import static android.view.WindowManager.TRANSIT_TASK_CLOSE; -import static android.view.WindowManager.TRANSIT_TASK_OPEN; -import static android.view.WindowManager.TRANSIT_TASK_OPEN_BEHIND; -import static android.view.WindowManager.TRANSIT_TASK_TO_BACK; -import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; - -import static com.android.server.wm.ActivityStack.ActivityState.PAUSED; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSING; -import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; -import static com.android.server.wm.ActivityStack.ActivityState.STARTED; -import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; -import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; -import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME; -import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; -import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList; -import static com.android.server.wm.ActivityStackSupervisor.printThisActivity; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_APP; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_APP; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CLEANUP; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TRANSITION; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY; -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.ActivityTaskManagerService.H.FIRST_ACTIVITY_STACK_MSG; -import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE; -import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE; -import static com.android.server.wm.TaskProto.ACTIVITY_TYPE; -import static com.android.server.wm.TaskProto.ANIMATING_BOUNDS; -import static com.android.server.wm.TaskProto.BOUNDS; -import static com.android.server.wm.TaskProto.CREATED_BY_ORGANIZER; -import static com.android.server.wm.TaskProto.DISPLAY_ID; -import static com.android.server.wm.TaskProto.FILLS_PARENT; -import static com.android.server.wm.TaskProto.LAST_NON_FULLSCREEN_BOUNDS; -import static com.android.server.wm.TaskProto.MIN_HEIGHT; -import static com.android.server.wm.TaskProto.MIN_WIDTH; -import static com.android.server.wm.TaskProto.ORIG_ACTIVITY; -import static com.android.server.wm.TaskProto.REAL_ACTIVITY; -import static com.android.server.wm.TaskProto.RESIZE_MODE; -import static com.android.server.wm.TaskProto.RESUMED_ACTIVITY; -import static com.android.server.wm.TaskProto.ROOT_TASK_ID; -import static com.android.server.wm.TaskProto.SURFACE_HEIGHT; -import static com.android.server.wm.TaskProto.SURFACE_WIDTH; -import static com.android.server.wm.TaskProto.WINDOW_CONTAINER; -import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; -import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; -import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; - -import static java.lang.Integer.MAX_VALUE; - -import android.annotation.IntDef; -import android.annotation.Nullable; -import android.app.Activity; -import android.app.ActivityManager; -import android.app.ActivityManagerInternal; -import android.app.ActivityOptions; -import android.app.AppGlobals; -import android.app.IActivityController; -import android.app.RemoteAction; -import android.app.ResultInfo; -import android.app.servertransaction.ActivityResultItem; -import android.app.servertransaction.ClientTransaction; -import android.app.servertransaction.NewIntentItem; -import android.app.servertransaction.PauseActivityItem; -import android.app.servertransaction.ResumeActivityItem; -import android.content.ComponentName; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.res.Configuration; -import android.graphics.Point; -import android.graphics.Rect; -import android.os.Binder; -import android.os.Debug; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.Message; -import android.os.RemoteException; -import android.os.SystemClock; -import android.os.Trace; -import android.os.UserHandle; -import android.service.voice.IVoiceInteractionSession; -import android.util.Log; -import android.util.Slog; -import android.util.proto.ProtoOutputStream; -import android.view.Display; -import android.view.DisplayInfo; - -import com.android.internal.annotations.GuardedBy; -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.app.IVoiceInteractor; -import com.android.internal.os.logging.MetricsLoggerWrapper; -import com.android.internal.util.function.pooled.PooledConsumer; -import com.android.internal.util.function.pooled.PooledFunction; -import com.android.internal.util.function.pooled.PooledLambda; -import com.android.server.Watchdog; -import com.android.server.am.ActivityManagerService; -import com.android.server.am.ActivityManagerService.ItemMatcher; -import com.android.server.am.AppTimeTracker; -import com.android.server.uri.NeededUriGrants; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; - -/** - * State and management of a single stack of activities. - */ -class ActivityStack extends Task { - private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_ATM; - static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE; - private static final String TAG_APP = TAG + POSTFIX_APP; - static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP; - private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE; - private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE; - private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS; - private static final String TAG_STACK = TAG + POSTFIX_STACK; - private static final String TAG_STATES = TAG + POSTFIX_STATES; - private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH; - static final String TAG_TASKS = TAG + POSTFIX_TASKS; - private static final String TAG_TRANSITION = TAG + POSTFIX_TRANSITION; - private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING; - static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY; - - // Set to false to disable the preview that is shown while a new activity - // is being started. - private static final boolean SHOW_APP_STARTING_PREVIEW = true; - - // How long to wait for all background Activities to redraw following a call to - // convertToTranslucent(). - private static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000; - - @IntDef(prefix = {"STACK_VISIBILITY"}, value = { - STACK_VISIBILITY_VISIBLE, - STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT, - STACK_VISIBILITY_INVISIBLE, - }) - @interface StackVisibility {} - - /** Stack is visible. No other stacks on top that fully or partially occlude it. */ - static final int STACK_VISIBILITY_VISIBLE = 0; - - /** Stack is partially occluded by other translucent stack(s) on top of it. */ - static final int STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT = 1; - - /** Stack is completely invisible. */ - static final int STACK_VISIBILITY_INVISIBLE = 2; - - enum ActivityState { - INITIALIZING, - STARTED, - RESUMED, - PAUSING, - PAUSED, - STOPPING, - STOPPED, - FINISHING, - DESTROYING, - DESTROYED, - RESTARTING_PROCESS - } - - // The topmost Activity passed to convertToTranslucent(). When non-null it means we are - // waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they - // are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the - // Activity in mTranslucentActivityWaiting is notified via - // Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last - // background activity being drawn then the same call will be made with a true value. - ActivityRecord mTranslucentActivityWaiting = null; - ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent = new ArrayList<>(); - - /** - * Set when we know we are going to be calling updateConfiguration() - * soon, so want to skip intermediate config checks. - */ - boolean mConfigWillChange; - - /** - * Used to keep resumeTopActivityUncheckedLocked() from being entered recursively - */ - boolean mInResumeTopActivity = false; - - int mCurrentUser; - - /** For comparison with DisplayContent bounds. */ - private Rect mTmpRect = new Rect(); - private Rect mTmpRect2 = new Rect(); - - // If this is true, we are in the bounds animating mode. The task will be down or upscaled to - // perfectly fit the region it would have been cropped to. We may also avoid certain logic we - // would otherwise apply while resizing, while resizing in the bounds animating mode. - private boolean mBoundsAnimating = false; - // Set when an animation has been requested but has not yet started from the UI thread. This is - // cleared when the animation actually starts. - private boolean mBoundsAnimatingRequested = false; - private Rect mBoundsAnimationTarget = new Rect(); - private Rect mBoundsAnimationSourceHintBounds = new Rect(); - - Rect mPreAnimationBounds = new Rect(); - - private final AnimatingActivityRegistry mAnimatingActivityRegistry = - new AnimatingActivityRegistry(); - - private boolean mTopActivityOccludesKeyguard; - private ActivityRecord mTopDismissingKeyguardActivity; - - private static final int TRANSLUCENT_TIMEOUT_MSG = FIRST_ACTIVITY_STACK_MSG + 1; - - private final Handler mHandler; - - private class ActivityStackHandler extends Handler { - - ActivityStackHandler(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case TRANSLUCENT_TIMEOUT_MSG: { - synchronized (mAtmService.mGlobalLock) { - notifyActivityDrawnLocked(null); - } - } break; - } - } - } - - private static final ResetTargetTaskHelper sResetTargetTaskHelper = new ResetTargetTaskHelper(); - private final EnsureActivitiesVisibleHelper mEnsureActivitiesVisibleHelper = - new EnsureActivitiesVisibleHelper(this); - private final EnsureVisibleActivitiesConfigHelper mEnsureVisibleActivitiesConfigHelper = - new EnsureVisibleActivitiesConfigHelper(); - private class EnsureVisibleActivitiesConfigHelper { - private boolean mUpdateConfig; - private boolean mPreserveWindow; - private boolean mBehindFullscreen; - - void reset(boolean preserveWindow) { - mPreserveWindow = preserveWindow; - mUpdateConfig = false; - mBehindFullscreen = false; - } - - void process(ActivityRecord start, boolean preserveWindow) { - if (start == null || !start.mVisibleRequested) { - return; - } - reset(preserveWindow); - - final PooledFunction f = PooledLambda.obtainFunction( - EnsureVisibleActivitiesConfigHelper::processActivity, this, - PooledLambda.__(ActivityRecord.class)); - forAllActivities(f, start, true /*includeBoundary*/, true /*traverseTopToBottom*/); - f.recycle(); - - if (mUpdateConfig) { - // Ensure the resumed state of the focus activity if we updated the configuration of - // any activity. - mRootWindowContainer.resumeFocusedStacksTopActivities(); - } - } - - boolean processActivity(ActivityRecord r) { - mUpdateConfig |= r.ensureActivityConfiguration(0 /*globalChanges*/, mPreserveWindow); - mBehindFullscreen |= r.occludesParent(); - return mBehindFullscreen; - } - } - - // TODO: Can we just loop through WindowProcessController#mActivities instead of doing this? - private final RemoveHistoryRecordsForApp mRemoveHistoryRecordsForApp = - new RemoveHistoryRecordsForApp(); - private class RemoveHistoryRecordsForApp { - private boolean mHasVisibleActivities; - private boolean mIsProcessRemoved; - private WindowProcessController mApp; - private ArrayList<ActivityRecord> mToRemove = new ArrayList<>(); - - boolean process(WindowProcessController app) { - mToRemove.clear(); - mHasVisibleActivities = false; - mApp = app; - mIsProcessRemoved = app.isRemoved(); - if (mIsProcessRemoved) { - // The package of the died process should be force-stopped, so make its activities - // as finishing to prevent the process from being started again if the next top - // (or being visible) activity also resides in the same process. - app.makeFinishingForProcessRemoved(); - } - - final PooledConsumer c = PooledLambda.obtainConsumer( - RemoveHistoryRecordsForApp::addActivityToRemove, this, - PooledLambda.__(ActivityRecord.class)); - forAllActivities(c); - c.recycle(); - - while (!mToRemove.isEmpty()) { - processActivity(mToRemove.remove(0)); - } - - mApp = null; - return mHasVisibleActivities; - } - - private void addActivityToRemove(ActivityRecord r) { - if (r.app == mApp) { - mToRemove.add(r); - } - } - - private void processActivity(ActivityRecord r) { - if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record " + r + ": app=" + r.app); - - if (r.app != mApp) { - return; - } - if (r.isVisible() || r.mVisibleRequested) { - // While an activity launches a new activity, it's possible that the old - // activity is already requested to be hidden (mVisibleRequested=false), but - // this visibility is not yet committed, so isVisible()=true. - mHasVisibleActivities = true; - } - final boolean remove; - if ((r.mRelaunchReason == RELAUNCH_REASON_WINDOWING_MODE_RESIZE - || r.mRelaunchReason == RELAUNCH_REASON_FREE_RESIZE) - && r.launchCount < 3 && !r.finishing) { - // If the process crashed during a resize, always try to relaunch it, unless - // it has failed more than twice. Skip activities that's already finishing - // cleanly by itself. - remove = false; - } else if ((!r.hasSavedState() && !r.stateNotNeeded - && !r.isState(ActivityState.RESTARTING_PROCESS)) || r.finishing) { - // Don't currently have state for the activity, or - // it is finishing -- always remove it. - remove = true; - } else if (!r.mVisibleRequested && r.launchCount > 2 - && r.lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) { - // We have launched this activity too many times since it was - // able to run, so give up and remove it. - // (Note if the activity is visible, we don't remove the record. - // We leave the dead window on the screen but the process will - // not be restarted unless user explicitly tap on it.) - remove = true; - } else { - // The process may be gone, but the activity lives on! - remove = false; - } - if (remove) { - if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE, - "Removing activity " + r + " from stack " - + ": hasSavedState=" + r.hasSavedState() - + " stateNotNeeded=" + r.stateNotNeeded - + " finishing=" + r.finishing - + " state=" + r.getState() + " callers=" + Debug.getCallers(5)); - if (!r.finishing || mIsProcessRemoved) { - Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); - EventLogTags.writeWmFinishActivity(r.mUserId, - System.identityHashCode(r), r.getTask().mTaskId, - r.shortComponentName, "proc died without state saved"); - } - } else { - // We have the current state for this activity, so - // it can be restarted later when needed. - if (DEBUG_ALL) Slog.v(TAG, "Keeping entry, setting app to null"); - if (DEBUG_APP) Slog.v(TAG_APP, - "Clearing app during removeHistory for activity " + r); - r.app = null; - // Set nowVisible to previous visible state. If the app was visible while - // it died, we leave the dead window on screen so it's basically visible. - // This is needed when user later tap on the dead window, we need to stop - // other apps when user transfers focus to the restarted activity. - r.nowVisible = r.mVisibleRequested; - } - r.cleanUp(true /* cleanServices */, true /* setState */); - if (remove) { - r.removeFromHistory("appDied"); - } - } - } - - ActivityStack(ActivityTaskManagerService atmService, int id, int activityType, - ActivityInfo info, Intent intent, boolean createdByOrganizer) { - this(atmService, id, info, intent, null /*voiceSession*/, null /*voiceInteractor*/, - null /*taskDescription*/, null /*stack*/); - mCreatedByOrganizer = createdByOrganizer; - setActivityType(activityType); - } - - ActivityStack(ActivityTaskManagerService atmService, int id, ActivityInfo info, Intent _intent, - IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor, - ActivityManager.TaskDescription _taskDescription, ActivityStack stack) { - this(atmService, id, _intent, null /*_affinityIntent*/, null /*_affinity*/, - null /*_rootAffinity*/, null /*_realActivity*/, null /*_origActivity*/, - false /*_rootWasReset*/, false /*_autoRemoveRecents*/, false /*_askedCompatMode*/, - UserHandle.getUserId(info.applicationInfo.uid), 0 /*_effectiveUid*/, - null /*_lastDescription*/, System.currentTimeMillis(), - true /*neverRelinquishIdentity*/, - _taskDescription != null ? _taskDescription : new ActivityManager.TaskDescription(), - id, INVALID_TASK_ID, INVALID_TASK_ID, - info.applicationInfo.uid, info.packageName, null, info.resizeMode, - info.supportsPictureInPicture(), false /*_realActivitySuspended*/, - false /*userSetupComplete*/, INVALID_MIN_SIZE, INVALID_MIN_SIZE, info, - _voiceSession, _voiceInteractor, stack); - } - - ActivityStack(ActivityTaskManagerService atmService, int id, Intent _intent, - Intent _affinityIntent, String _affinity, String _rootAffinity, - ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset, - boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId, int _effectiveUid, - String _lastDescription, long lastTimeMoved, boolean neverRelinquishIdentity, - ActivityManager.TaskDescription _lastTaskDescription, int taskAffiliation, - int prevTaskId, int nextTaskId, int callingUid, - String callingPackage, @Nullable String callingFeatureId, int resizeMode, - boolean supportsPictureInPicture, boolean _realActivitySuspended, - boolean userSetupComplete, int minWidth, int minHeight, - ActivityInfo info, IVoiceInteractionSession _voiceSession, - IVoiceInteractor _voiceInteractor, ActivityStack stack) { - super(atmService, id, _intent, _affinityIntent, _affinity, _rootAffinity, - _realActivity, _origActivity, _rootWasReset, _autoRemoveRecents, _askedCompatMode, - _userId, _effectiveUid, _lastDescription, lastTimeMoved, neverRelinquishIdentity, - _lastTaskDescription, taskAffiliation, prevTaskId, nextTaskId, - callingUid, callingPackage, callingFeatureId, resizeMode, supportsPictureInPicture, - _realActivitySuspended, userSetupComplete, minWidth, minHeight, info, _voiceSession, - _voiceInteractor, stack); - - EventLogTags.writeWmStackCreated(id); - mHandler = new ActivityStackHandler(mStackSupervisor.mLooper); - mCurrentUser = mAtmService.mAmInternal.getCurrentUserId(); - } - - @Override - public void onConfigurationChanged(Configuration newParentConfig) { - // Calling Task#onConfigurationChanged() for leaf task since the ops in this method are - // particularly for ActivityStack, like preventing bounds changes when inheriting certain - // windowing mode. - if (!isRootTask()) { - super.onConfigurationChanged(newParentConfig); - return; - } - - final int prevWindowingMode = getWindowingMode(); - final boolean prevIsAlwaysOnTop = isAlwaysOnTop(); - final int prevRotation = getWindowConfiguration().getRotation(); - final Rect newBounds = mTmpRect; - // Initialize the new bounds by previous bounds as the input and output for calculating - // override bounds in pinned (pip) or split-screen mode. - getBounds(newBounds); - - super.onConfigurationChanged(newParentConfig); - - final TaskDisplayArea taskDisplayArea = getDisplayArea(); - if (taskDisplayArea == null) { - return; - } - - if (prevWindowingMode != getWindowingMode()) { - taskDisplayArea.onStackWindowingModeChanged(this); - } - - final DisplayContent display = getDisplay(); - if (display == null ) { - return; - } - - final boolean windowingModeChanged = prevWindowingMode != getWindowingMode(); - final int overrideWindowingMode = getRequestedOverrideWindowingMode(); - // Update bounds if applicable - boolean hasNewOverrideBounds = false; - // Use override windowing mode to prevent extra bounds changes if inheriting the mode. - if ((overrideWindowingMode != WINDOWING_MODE_PINNED) - && !getRequestedOverrideBounds().isEmpty()) { - // If the parent (display) has rotated, rotate our bounds to best-fit where their - // bounds were on the pre-rotated display. - final int newRotation = getWindowConfiguration().getRotation(); - final boolean rotationChanged = prevRotation != newRotation; - if (rotationChanged) { - display.mDisplayContent.rotateBounds( - newParentConfig.windowConfiguration.getBounds(), prevRotation, newRotation, - newBounds); - hasNewOverrideBounds = true; - } - } - - if (windowingModeChanged) { - taskDisplayArea.onStackWindowingModeChanged(this); - } - if (hasNewOverrideBounds) { - if (inSplitScreenWindowingMode()) { - setBounds(newBounds); - } else if (overrideWindowingMode != WINDOWING_MODE_PINNED) { - // For pinned stack, resize is now part of the {@link WindowContainerTransaction} - resize(new Rect(newBounds), PRESERVE_WINDOWS, true /* deferResume */); - } - } - if (prevIsAlwaysOnTop != isAlwaysOnTop()) { - // Since always on top is only on when the stack is freeform or pinned, the state - // can be toggled when the windowing mode changes. We must make sure the stack is - // placed properly when always on top state changes. - taskDisplayArea.positionStackAtTop(this, false /* includingParents */); - } - } - - @Override - public void setWindowingMode(int windowingMode) { - // Reset the cached result of toString() - stringName = null; - - // Calling Task#setWindowingMode() for leaf task since this is the a specialization of - // {@link #setWindowingMode(int)} for ActivityStack. - if (!isRootTask()) { - super.setWindowingMode(windowingMode); - return; - } - - setWindowingMode(windowingMode, false /* creating */); - } - - /** - * Specialization of {@link #setWindowingMode(int)} for this subclass. - * - * @param preferredWindowingMode the preferred windowing mode. This may not be honored depending - * on the state of things. For example, WINDOWING_MODE_UNDEFINED will resolve to the - * previous non-transient mode if this stack is currently in a transient mode. - * @param creating {@code true} if this is being run during ActivityStack construction. - */ - void setWindowingMode(int preferredWindowingMode, boolean creating) { - mWmService.inSurfaceTransaction(() -> setWindowingModeInSurfaceTransaction( - preferredWindowingMode, creating)); - } - - private void setWindowingModeInSurfaceTransaction(int preferredWindowingMode, - boolean creating) { - final TaskDisplayArea taskDisplayArea = getDisplayArea(); - if (taskDisplayArea == null) { - Slog.d(TAG, "taskDisplayArea is null, bail early"); - return; - } - final int currentMode = getWindowingMode(); - final int currentOverrideMode = getRequestedOverrideWindowingMode(); - final Task topTask = getTopMostTask(); - int windowingMode = preferredWindowingMode; - - // Need to make sure windowing mode is supported. If we in the process of creating the stack - // no need to resolve the windowing mode again as it is already resolved to the right mode. - if (!creating) { - if (!taskDisplayArea.isValidWindowingMode(windowingMode, null /* ActivityRecord */, - topTask, getActivityType())) { - windowingMode = WINDOWING_MODE_UNDEFINED; - } - } - - final boolean alreadyInSplitScreenMode = taskDisplayArea.isSplitScreenModeActivated(); - - if (creating && alreadyInSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN - && isActivityTypeStandardOrUndefined()) { - // If the stack is being created explicitly in fullscreen mode, dismiss split-screen - // and display a warning toast about it. - mAtmService.getTaskChangeNotificationController() - .notifyActivityDismissingDockedStack(); - taskDisplayArea.onSplitScreenModeDismissed(this); - } - - if (currentMode == windowingMode) { - // You are already in the window mode, so we can skip most of the work below. However, - // it's possible that we have inherited the current windowing mode from a parent. So, - // fulfill this method's contract by setting the override mode directly. - getRequestedOverrideConfiguration().windowConfiguration.setWindowingMode(windowingMode); - return; - } - - final ActivityRecord topActivity = getTopNonFinishingActivity(); - - // For now, assume that the Stack's windowing mode is what will actually be used - // by it's activities. In the future, there may be situations where this doesn't - // happen; so at that point, this message will need to handle that. - int likelyResolvedMode = windowingMode; - if (windowingMode == WINDOWING_MODE_UNDEFINED) { - final ConfigurationContainer parent = getParent(); - likelyResolvedMode = parent != null ? parent.getWindowingMode() - : WINDOWING_MODE_FULLSCREEN; - } - if (currentMode == WINDOWING_MODE_PINNED) { - mAtmService.getTaskChangeNotificationController().notifyActivityUnpinned(); - } - if (likelyResolvedMode == WINDOWING_MODE_PINNED - && taskDisplayArea.getRootPinnedTask() != null) { - // Can only have 1 pip at a time, so replace an existing pip - taskDisplayArea.getRootPinnedTask().dismissPip(); - } - if (likelyResolvedMode != WINDOWING_MODE_FULLSCREEN - && topActivity != null && !topActivity.noDisplay - && topActivity.isNonResizableOrForcedResizable(likelyResolvedMode)) { - // Inform the user that they are starting an app that may not work correctly in - // multi-window mode. - final String packageName = topActivity.info.applicationInfo.packageName; - mAtmService.getTaskChangeNotificationController().notifyActivityForcedResizable( - topTask.mTaskId, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN, packageName); - } - - mAtmService.deferWindowLayout(); - try { - if (topActivity != null) { - mStackSupervisor.mNoAnimActivities.add(topActivity); - } - super.setWindowingMode(windowingMode); - // setWindowingMode triggers an onConfigurationChanged cascade which can result in a - // different resolved windowing mode (usually when preferredWindowingMode is UNDEFINED). - windowingMode = getWindowingMode(); - - if (creating) { - // Nothing else to do if we don't have a window container yet. E.g. call from ctor. - return; - } - - if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && alreadyInSplitScreenMode) { - // We already have a split-screen stack in this display, so just move the tasks over. - // TODO: Figure-out how to do all the stuff in - // AMS.setTaskWindowingModeSplitScreenPrimary - throw new IllegalArgumentException("Setting primary split-screen windowing mode" - + " while there is already one isn't currently supported"); - //return; - } - } finally { - mAtmService.continueWindowLayout(); - } - - mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); - mRootWindowContainer.resumeFocusedStacksTopActivities(); - } - - @Override - public boolean isCompatible(int windowingMode, int activityType) { - // TODO: Should we just move this to ConfigurationContainer? - if (activityType == ACTIVITY_TYPE_UNDEFINED) { - // Undefined activity types end up in a standard stack once the stack is created on a - // display, so they should be considered compatible. - activityType = ACTIVITY_TYPE_STANDARD; - } - return super.isCompatible(windowingMode, activityType); - } - - /** Resume next focusable stack after reparenting to another display. */ - void postReparent() { - adjustFocusToNextFocusableTask("reparent", true /* allowFocusSelf */, - true /* moveDisplayToTop */); - mRootWindowContainer.resumeFocusedStacksTopActivities(); - // Update visibility of activities before notifying WM. This way it won't try to resize - // windows that are no longer visible. - mRootWindowContainer.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, - !PRESERVE_WINDOWS); - } - - DisplayContent getDisplay() { - return getDisplayContent(); - } - - /** @return true if the stack can only contain one task */ - boolean isSingleTaskInstance() { - final DisplayContent display = getDisplay(); - return display != null && display.isSingleTaskInstance(); - } - - final boolean isHomeOrRecentsStack() { - return isActivityTypeHome() || isActivityTypeRecents(); - } - - final boolean isOnHomeDisplay() { - return getDisplayId() == DEFAULT_DISPLAY; - } - - void moveToFront(String reason) { - moveToFront(reason, null); - } - - /** - * @param reason The reason for moving the stack to the front. - * @param task If non-null, the task will be moved to the top of the stack. - * */ - void moveToFront(String reason, Task task) { - if (!isAttached()) { - return; - } - - final TaskDisplayArea taskDisplayArea = getDisplayArea(); - - if (inSplitScreenSecondaryWindowingMode()) { - // If the stack is in split-screen secondary mode, we need to make sure we move the - // primary split-screen stack forward in the case it is currently behind a fullscreen - // stack so both halves of the split-screen appear on-top and the fullscreen stack isn't - // cutting between them. - // TODO(b/70677280): This is a workaround until we can fix as part of b/70677280. - final ActivityStack topFullScreenStack = - taskDisplayArea.getTopStackInWindowingMode(WINDOWING_MODE_FULLSCREEN); - if (topFullScreenStack != null) { - final ActivityStack primarySplitScreenStack = - taskDisplayArea.getRootSplitScreenPrimaryTask(); - if (primarySplitScreenStack != null - && taskDisplayArea.getIndexOf(topFullScreenStack) - > taskDisplayArea.getIndexOf(primarySplitScreenStack)) { - primarySplitScreenStack.moveToFront(reason + " splitScreenToTop"); - } - } - } - - if (!isActivityTypeHome() && returnsToHomeStack()) { - // Make sure the home stack is behind this stack since that is where we should return to - // when this stack is no longer visible. - taskDisplayArea.moveHomeStackToFront(reason + " returnToHome"); - } - - if (isRootTask()) { - taskDisplayArea.positionStackAtTop(this, false /* includingParents */, reason); - } - if (task == null) { - task = this; - } - task.getParent().positionChildAt(POSITION_TOP, task, true /* includingParents */); - } - - /** - * This moves 'task' to the back of this task and also recursively moves this task to the back - * of its parents (if applicable). - * - * @param reason The reason for moving the stack to the back. - * @param task If non-null, the task will be moved to the bottom of the stack. - **/ - void moveToBack(String reason, Task task) { - if (!isAttached()) { - return; - } - final TaskDisplayArea displayArea = getDisplayArea(); - if (!mCreatedByOrganizer) { - // If this is just a normal task, so move to back of parent and then move 'task' to - // back of this. - final WindowContainer parent = getParent(); - final Task parentTask = parent != null ? parent.asTask() : null; - if (parentTask != null) { - ((ActivityStack) parentTask).moveToBack(reason, this); - } else { - displayArea.positionStackAtBottom(this, reason); - } - if (task != null && task != this) { - positionChildAtBottom(task); - } - return; - } - if (task == null || task == this) { - return; - } - // This is a created-by-organizer task. In this case, let the organizer deal with this - // task's ordering. However, we still need to move 'task' to back. The intention is that - // this ends up behind the home-task so that it is made invisible; so, if the home task - // is not a child of this, reparent 'task' to the back of the home task's actual parent. - displayArea.positionTaskBehindHome((ActivityStack) task); - } - - // TODO: Should each user have there own stacks? - @Override - void switchUser(int userId) { - if (mCurrentUser == userId) { - return; - } - mCurrentUser = userId; - - super.switchUser(userId); - forAllLeafTasks((t) -> { - if (t.showToCurrentUser() && t != this) { - mChildren.remove(t); - mChildren.add(t); - } - }, true /* traverseTopToBottom */); - } - - void minimalResumeActivityLocked(ActivityRecord r) { - if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + r + " (starting new instance)" - + " callers=" + Debug.getCallers(5)); - r.setState(RESUMED, "minimalResumeActivityLocked"); - r.completeResumeLocked(); - } - - private void clearLaunchTime(ActivityRecord r) { - // Make sure that there is no activity waiting for this to launch. - if (!mStackSupervisor.mWaitingActivityLaunched.isEmpty()) { - mStackSupervisor.removeIdleTimeoutForActivity(r); - mStackSupervisor.scheduleIdleTimeout(r); - } - } - - void awakeFromSleepingLocked() { - // Ensure activities are no longer sleeping. - forAllActivities((Consumer<ActivityRecord>) (r) -> r.setSleeping(false)); - if (mPausingActivity != null) { - Slog.d(TAG, "awakeFromSleepingLocked: previously pausing activity didn't pause"); - mPausingActivity.activityPaused(true); - } - } - - void checkReadyForSleep() { - if (shouldSleepActivities() && goToSleepIfPossible(false /* shuttingDown */)) { - mStackSupervisor.checkReadyForSleepLocked(true /* allowDelay */); - } - } - - /** - * Tries to put the activities in the stack to sleep. - * - * If the stack is not in a state where its activities can be put to sleep, this function will - * start any necessary actions to move the stack into such a state. It is expected that this - * function get called again when those actions complete. - * - * @param shuttingDown true when the called because the device is shutting down. - * @return true if the stack finished going to sleep, false if the stack only started the - * process of going to sleep (checkReadyForSleep will be called when that process finishes). - */ - boolean goToSleepIfPossible(boolean shuttingDown) { - boolean shouldSleep = true; - - if (mResumedActivity != null) { - // Still have something resumed; can't sleep until it is paused. - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity); - if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, - "Sleep => pause with userLeaving=false"); - - startPausingLocked(false /* userLeaving */, true /* uiSleeping */, null /* resuming */); - shouldSleep = false ; - } else if (mPausingActivity != null) { - // Still waiting for something to pause; can't sleep yet. - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still waiting to pause " + mPausingActivity); - shouldSleep = false; - } - - if (!shuttingDown) { - if (containsActivityFromStack(mStackSupervisor.mStoppingActivities)) { - // Still need to tell some activities to stop; can't sleep yet. - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop " - + mStackSupervisor.mStoppingActivities.size() + " activities"); - - mStackSupervisor.scheduleIdle(); - shouldSleep = false; - } - } - - if (shouldSleep) { - goToSleep(); - } - - return shouldSleep; - } - - void goToSleep() { - // Make sure all visible activities are now sleeping. This will update the activity's - // visibility and onStop() will be called. - forAllActivities((r) -> { - if (r.isState(STARTED, RESUMED, PAUSING, PAUSED, STOPPING, STOPPED)) { - r.setSleeping(true); - } - }); - - // Ensure visibility after updating sleep states without updating configuration, - // as activities are about to be sent to sleep. - ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, - !PRESERVE_WINDOWS); - } - - private boolean containsActivityFromStack(List<ActivityRecord> rs) { - for (ActivityRecord r : rs) { - if (r.getRootTask() == this) { - return true; - } - } - return false; - } - - /** - * Start pausing the currently resumed activity. It is an error to call this if there - * is already an activity being paused or there is no resumed activity. - * - * @param userLeaving True if this should result in an onUserLeaving to the current activity. - * @param uiSleeping True if this is happening with the user interface going to sleep (the - * screen turning off). - * @param resuming The activity we are currently trying to resume or null if this is not being - * called as part of resuming the top activity, so we shouldn't try to instigate - * a resume here if not null. - * @return Returns true if an activity now is in the PAUSING state, and we are waiting for - * it to tell us when it is done. - */ - final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, - ActivityRecord resuming) { - if (mPausingActivity != null) { - Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity - + " state=" + mPausingActivity.getState()); - if (!shouldSleepActivities()) { - // Avoid recursion among check for sleep and complete pause during sleeping. - // Because activity will be paused immediately after resume, just let pause - // be completed by the order of activity paused from clients. - completePauseLocked(false, resuming); - } - } - ActivityRecord prev = mResumedActivity; - - if (prev == null) { - if (resuming == null) { - Slog.wtf(TAG, "Trying to pause when nothing is resumed"); - mRootWindowContainer.resumeFocusedStacksTopActivities(); - } - return false; - } - - if (prev == resuming) { - Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed"); - return false; - } - - if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev); - else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev); - mPausingActivity = prev; - mLastPausedActivity = prev; - mLastNoHistoryActivity = prev.isNoHistory() ? prev : null; - prev.setState(PAUSING, "startPausingLocked"); - prev.getTask().touchActiveTime(); - clearLaunchTime(prev); - - mAtmService.updateCpuStats(); - - boolean pauseImmediately = false; - if (resuming != null && (resuming.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0) { - // If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous - // activity to be paused, while at the same time resuming the new resume activity - // only if the previous activity can't go into Pip since we want to give Pip - // activities a chance to enter Pip before resuming the next activity. - final boolean lastResumedCanPip = prev != null && prev.checkEnterPictureInPictureState( - "shouldResumeWhilePausing", userLeaving); - if (!lastResumedCanPip) { - pauseImmediately = true; - } - } - - if (prev.attachedToProcess()) { - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev); - try { - EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev), - prev.shortComponentName, "userLeaving=" + userLeaving); - - mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(), - prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving, - prev.configChangeFlags, pauseImmediately)); - } catch (Exception e) { - // Ignore exception, if process died other code will cleanup. - Slog.w(TAG, "Exception thrown during pause", e); - mPausingActivity = null; - mLastPausedActivity = null; - mLastNoHistoryActivity = null; - } - } else { - mPausingActivity = null; - mLastPausedActivity = null; - mLastNoHistoryActivity = null; - } - - // If we are not going to sleep, we want to ensure the device is - // awake until the next activity is started. - if (!uiSleeping && !mAtmService.isSleepingOrShuttingDownLocked()) { - mStackSupervisor.acquireLaunchWakelock(); - } - - if (mPausingActivity != null) { - // Have the window manager pause its key dispatching until the new - // activity has started. If we're pausing the activity just because - // the screen is being turned off and the UI is sleeping, don't interrupt - // key dispatch; the same activity will pick it up again on wakeup. - if (!uiSleeping) { - prev.pauseKeyDispatchingLocked(); - } else if (DEBUG_PAUSE) { - Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off"); - } - - if (pauseImmediately) { - // If the caller said they don't want to wait for the pause, then complete - // the pause now. - completePauseLocked(false, resuming); - return false; - - } else { - prev.schedulePauseTimeout(); - return true; - } - - } else { - // This activity failed to schedule the - // pause, so just treat it as being paused now. - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next."); - if (resuming == null) { - mRootWindowContainer.resumeFocusedStacksTopActivities(); - } - return false; - } - } - - @VisibleForTesting - void completePauseLocked(boolean resumeNext, ActivityRecord resuming) { - ActivityRecord prev = mPausingActivity; - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev); - - if (prev != null) { - prev.setWillCloseOrEnterPip(false); - final boolean wasStopping = prev.isState(STOPPING); - prev.setState(PAUSED, "completePausedLocked"); - if (prev.finishing) { - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev); - prev = prev.completeFinishing("completePausedLocked"); - } else if (prev.hasProcess()) { - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev - + " wasStopping=" + wasStopping - + " visibleRequested=" + prev.mVisibleRequested); - if (prev.deferRelaunchUntilPaused) { - // Complete the deferred relaunch that was waiting for pause to complete. - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev); - prev.relaunchActivityLocked(prev.preserveWindowOnDeferredRelaunch); - } else if (wasStopping) { - // We are also stopping, the stop request must have gone soon after the pause. - // We can't clobber it, because the stop confirmation will not be handled. - // We don't need to schedule another stop, we only need to let it happen. - prev.setState(STOPPING, "completePausedLocked"); - } else if (!prev.mVisibleRequested || shouldSleepOrShutDownActivities()) { - // Clear out any deferred client hide we might currently have. - prev.setDeferHidingClient(false); - // If we were visible then resumeTopActivities will release resources before - // stopping. - prev.addToStopping(true /* scheduleIdle */, false /* idleDelayed */, - "completePauseLocked"); - } - } else { - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev); - prev = null; - } - // It is possible the activity was freezing the screen before it was paused. - // In that case go ahead and remove the freeze this activity has on the screen - // since it is no longer visible. - if (prev != null) { - prev.stopFreezingScreenLocked(true /*force*/); - } - mPausingActivity = null; - } - - if (resumeNext) { - final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack(); - if (topStack != null && !topStack.shouldSleepOrShutDownActivities()) { - mRootWindowContainer.resumeFocusedStacksTopActivities(topStack, prev, null); - } else { - checkReadyForSleep(); - final ActivityRecord top = topStack != null ? topStack.topRunningActivity() : null; - if (top == null || (prev != null && top != prev)) { - // If there are no more activities available to run, do resume anyway to start - // something. Also if the top activity on the stack is not the just paused - // activity, we need to go ahead and resume it to ensure we complete an - // in-flight app switch. - mRootWindowContainer.resumeFocusedStacksTopActivities(); - } - } - } - - if (prev != null) { - prev.resumeKeyDispatchingLocked(); - - if (prev.hasProcess() && prev.cpuTimeAtResume > 0) { - final long diff = prev.app.getCpuTime() - prev.cpuTimeAtResume; - if (diff > 0) { - final Runnable r = PooledLambda.obtainRunnable( - ActivityManagerInternal::updateForegroundTimeIfOnBattery, - mAtmService.mAmInternal, prev.info.packageName, - prev.info.applicationInfo.uid, - diff); - mAtmService.mH.post(r); - } - } - prev.cpuTimeAtResume = 0; // reset it - } - - mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS); - - // Notify when the task stack has changed, but only if visibilities changed (not just - // focus). Also if there is an active pinned stack - we always want to notify it about - // task stack changes, because its positioning may depend on it. - if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause - || (getDisplayArea() != null && getDisplayArea().hasPinnedTask())) { - mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged(); - mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false; - } - } - - boolean isTopStackInDisplayArea() { - final TaskDisplayArea taskDisplayArea = getDisplayArea(); - return taskDisplayArea != null && taskDisplayArea.isTopStack(this); - } - - /** - * @return {@code true} if this is the focused stack on its current display, {@code false} - * otherwise. - */ - boolean isFocusedStackOnDisplay() { - final DisplayContent display = getDisplay(); - return display != null && this == display.getFocusedStack(); - } - - /** - * Make sure that all activities that need to be visible in the stack (that is, they - * currently can be seen by the user) actually are and update their configuration. - * @param starting The top most activity in the task. - * The activity is either starting or resuming. - * Caller should ensure starting activity is visible. - * @param preserveWindows Flag indicating whether windows should be preserved when updating - * configuration in {@link mEnsureActivitiesVisibleHelper}. - * @param configChanges Parts of the configuration that changed for this activity for evaluating - * if the screen should be frozen as part of - * {@link mEnsureActivitiesVisibleHelper}. - * - */ - void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges, - boolean preserveWindows) { - ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */); - } - - /** - * Ensure visibility with an option to also update the configuration of visible activities. - * @see #ensureActivitiesVisible(ActivityRecord, int, boolean) - * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean) - * @param starting The top most activity in the task. - * The activity is either starting or resuming. - * Caller should ensure starting activity is visible. - * @param notifyClients Flag indicating whether the visibility updates should be sent to the - * clients in {@link mEnsureActivitiesVisibleHelper}. - * @param preserveWindows Flag indicating whether windows should be preserved when updating - * configuration in {@link mEnsureActivitiesVisibleHelper}. - * @param configChanges Parts of the configuration that changed for this activity for evaluating - * if the screen should be frozen as part of - * {@link mEnsureActivitiesVisibleHelper}. - */ - // TODO: Should be re-worked based on the fact that each task as a stack in most cases. - void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges, - boolean preserveWindows, boolean notifyClients) { - mTopActivityOccludesKeyguard = false; - mTopDismissingKeyguardActivity = null; - mStackSupervisor.beginActivityVisibilityUpdate(); - try { - mEnsureActivitiesVisibleHelper.process( - starting, configChanges, preserveWindows, notifyClients); - - if (mTranslucentActivityWaiting != null && - mUndrawnActivitiesBelowTopTranslucent.isEmpty()) { - // Nothing is getting drawn or everything was already visible, don't wait for timeout. - notifyActivityDrawnLocked(null); - } - } finally { - mStackSupervisor.endActivityVisibilityUpdate(); - } - } - - /** - * @return true if the top visible activity wants to occlude the Keyguard, false otherwise - */ - boolean topActivityOccludesKeyguard() { - return mTopActivityOccludesKeyguard; - } - - /** - * Returns true if this stack should be resized to match the bounds specified by - * {@link ActivityOptions#setLaunchBounds} when launching an activity into the stack. - */ - boolean shouldResizeStackWithLaunchBounds() { - return inPinnedWindowingMode(); - } - - // TODO(NOW!) - /** - * Returns {@code true} if this is the top-most split-screen-primary or - * split-screen-secondary stack, {@code false} otherwise. - */ - boolean isTopSplitScreenStack() { - return inSplitScreenWindowingMode() - && this == getDisplayArea().getTopStackInWindowingMode(getWindowingMode()); - } - - /** - * @return the top most visible activity that wants to dismiss Keyguard - */ - ActivityRecord getTopDismissingKeyguardActivity() { - return mTopDismissingKeyguardActivity; - } - - /** - * Checks whether {@param r} should be visible depending on Keyguard state and updates - * {@link #mTopActivityOccludesKeyguard} and {@link #mTopDismissingKeyguardActivity} if - * necessary. - * - * @return true if {@param r} is visible taken Keyguard state into account, false otherwise - */ - boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible, boolean isTop) { - int displayId = getDisplayId(); - if (displayId == INVALID_DISPLAY) displayId = DEFAULT_DISPLAY; - - final boolean keyguardOrAodShowing = mStackSupervisor.getKeyguardController() - .isKeyguardOrAodShowing(displayId); - final boolean keyguardLocked = mStackSupervisor.getKeyguardController().isKeyguardLocked(); - final boolean showWhenLocked = r.canShowWhenLocked(); - final boolean dismissKeyguard = r.containsDismissKeyguardWindow(); - if (shouldBeVisible) { - if (dismissKeyguard && mTopDismissingKeyguardActivity == null) { - mTopDismissingKeyguardActivity = r; - } - - // Only the top activity may control occluded, as we can't occlude the Keyguard if the - // top app doesn't want to occlude it. - if (isTop) { - mTopActivityOccludesKeyguard |= showWhenLocked; - } - - final boolean canShowWithKeyguard = canShowWithInsecureKeyguard() - && mStackSupervisor.getKeyguardController().canDismissKeyguard(); - if (canShowWithKeyguard) { - return true; - } - } - if (keyguardOrAodShowing) { - // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard - // right away and AOD isn't visible. - return shouldBeVisible && mStackSupervisor.getKeyguardController() - .canShowActivityWhileKeyguardShowing(r, dismissKeyguard); - } else if (keyguardLocked) { - return shouldBeVisible && mStackSupervisor.getKeyguardController().canShowWhileOccluded( - dismissKeyguard, showWhenLocked); - } else { - return shouldBeVisible; - } - } - - /** - * Check if the display to which this stack is attached has - * {@link Display#FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD} applied. - */ - boolean canShowWithInsecureKeyguard() { - final DisplayContent displayContent = getDisplay(); - if (displayContent == null) { - throw new IllegalStateException("Stack is not attached to any display, stackId=" - + getRootTaskId()); - } - - final int flags = displayContent.mDisplay.getFlags(); - return (flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0; - } - - void checkTranslucentActivityWaiting(ActivityRecord top) { - if (mTranslucentActivityWaiting != top) { - mUndrawnActivitiesBelowTopTranslucent.clear(); - if (mTranslucentActivityWaiting != null) { - // Call the callback with a timeout indication. - notifyActivityDrawnLocked(null); - mTranslucentActivityWaiting = null; - } - mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG); - } - } - - void convertActivityToTranslucent(ActivityRecord r) { - mTranslucentActivityWaiting = r; - mUndrawnActivitiesBelowTopTranslucent.clear(); - mHandler.sendEmptyMessageDelayed(TRANSLUCENT_TIMEOUT_MSG, TRANSLUCENT_CONVERSION_TIMEOUT); - } - - /** - * Called as activities below the top translucent activity are redrawn. When the last one is - * redrawn notify the top activity by calling - * {@link Activity#onTranslucentConversionComplete}. - * - * @param r The most recent background activity to be drawn. Or, if r is null then a timeout - * occurred and the activity will be notified immediately. - */ - void notifyActivityDrawnLocked(ActivityRecord r) { - if ((r == null) - || (mUndrawnActivitiesBelowTopTranslucent.remove(r) && - mUndrawnActivitiesBelowTopTranslucent.isEmpty())) { - // The last undrawn activity below the top has just been drawn. If there is an - // opaque activity at the top, notify it that it can become translucent safely now. - final ActivityRecord waitingActivity = mTranslucentActivityWaiting; - mTranslucentActivityWaiting = null; - mUndrawnActivitiesBelowTopTranslucent.clear(); - mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG); - - if (waitingActivity != null) { - mWmService.setWindowOpaqueLocked(waitingActivity.appToken, false); - if (waitingActivity.attachedToProcess()) { - try { - waitingActivity.app.getThread().scheduleTranslucentConversionComplete( - waitingActivity.appToken, r != null); - } catch (RemoteException e) { - } - } - } - } - } - - /** - * Ensure that the top activity in the stack is resumed. - * - * @param prev The previously resumed activity, for when in the process - * of pausing; can be null to call from elsewhere. - * @param options Activity options. - * - * @return Returns true if something is being resumed, or false if - * nothing happened. - * - * NOTE: It is not safe to call this method directly as it can cause an activity in a - * non-focused stack to be resumed. - * Use {@link RootWindowContainer#resumeFocusedStacksTopActivities} to resume the - * right activity for the current system state. - */ - @GuardedBy("mService") - boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { - if (mInResumeTopActivity) { - // Don't even start recursing. - return false; - } - - boolean result = false; - try { - // Protect against recursion. - mInResumeTopActivity = true; - result = resumeTopActivityInnerLocked(prev, options); - - // When resuming the top activity, it may be necessary to pause the top activity (for - // example, returning to the lock screen. We suppress the normal pause logic in - // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the - // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here - // to ensure any necessary pause logic occurs. In the case where the Activity will be - // shown regardless of the lock screen, the call to - // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped. - final ActivityRecord next = topRunningActivity(true /* focusableOnly */); - if (next == null || !next.canTurnScreenOn()) { - checkReadyForSleep(); - } - } finally { - mInResumeTopActivity = false; - } - - return result; - } - - @GuardedBy("mService") - private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { - if (!mAtmService.isBooting() && !mAtmService.isBooted()) { - // Not ready yet! - return false; - } - - // Find the next top-most activity to resume in this stack that is not finishing and is - // focusable. If it is not focusable, we will fall into the case below to resume the - // top activity in the next focusable task. - ActivityRecord next = topRunningActivity(true /* focusableOnly */); - - final boolean hasRunningActivity = next != null; - - // TODO: Maybe this entire condition can get removed? - if (hasRunningActivity && !isAttached()) { - return false; - } - - mRootWindowContainer.cancelInitializingActivities(); - - // Remember how we'll process this pause/resume situation, and ensure - // that the state is reset however we wind up proceeding. - boolean userLeaving = mStackSupervisor.mUserLeaving; - mStackSupervisor.mUserLeaving = false; - - if (!hasRunningActivity) { - // There are no activities left in the stack, let's look somewhere else. - return resumeNextFocusableActivityWhenStackIsEmpty(prev, options); - } - - next.delayedResume = false; - final TaskDisplayArea taskDisplayArea = getDisplayArea(); - - // If the top activity is the resumed one, nothing to do. - if (mResumedActivity == next && next.isState(RESUMED) - && taskDisplayArea.allResumedActivitiesComplete()) { - // Make sure we have executed any pending transitions, since there - // should be nothing left to do at this point. - executeAppTransition(options); - if (DEBUG_STATES) Slog.d(TAG_STATES, - "resumeTopActivityLocked: Top activity resumed " + next); - return false; - } - - if (!next.canResumeByCompat()) { - return false; - } - - // If we are currently pausing an activity, then don't do anything until that is done. - final boolean allPausedComplete = mRootWindowContainer.allPausedActivitiesComplete(); - if (!allPausedComplete) { - if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) { - Slog.v(TAG_PAUSE, "resumeTopActivityLocked: Skip resume: some activity pausing."); - } - return false; - } - - // If we are sleeping, and there is no resumed activity, and the top activity is paused, - // well that is the state we want. - if (shouldSleepOrShutDownActivities() - && mLastPausedActivity == next - && mRootWindowContainer.allPausedActivitiesComplete()) { - // If the current top activity may be able to occlude keyguard but the occluded state - // has not been set, update visibility and check again if we should continue to resume. - boolean nothingToResume = true; - if (!mAtmService.mShuttingDown) { - final boolean canShowWhenLocked = !mTopActivityOccludesKeyguard - && next.canShowWhenLocked(); - final boolean mayDismissKeyguard = mTopDismissingKeyguardActivity != next - && next.containsDismissKeyguardWindow(); - - if (canShowWhenLocked || mayDismissKeyguard) { - ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, - !PRESERVE_WINDOWS); - nothingToResume = shouldSleepActivities(); - } else if (next.currentLaunchCanTurnScreenOn() && next.canTurnScreenOn()) { - nothingToResume = false; - } - } - if (nothingToResume) { - // Make sure we have executed any pending transitions, since there - // should be nothing left to do at this point. - executeAppTransition(options); - if (DEBUG_STATES) Slog.d(TAG_STATES, - "resumeTopActivityLocked: Going to sleep and all paused"); - return false; - } - } - - // Make sure that the user who owns this activity is started. If not, - // we will just leave it as is because someone should be bringing - // another user's activities to the top of the stack. - if (!mAtmService.mAmInternal.hasStartedUserState(next.mUserId)) { - Slog.w(TAG, "Skipping resume of top activity " + next - + ": user " + next.mUserId + " is stopped"); - return false; - } - - // The activity may be waiting for stop, but that is no longer - // appropriate for it. - mStackSupervisor.mStoppingActivities.remove(next); - next.setSleeping(false); - - if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next); - - // If we are currently pausing an activity, then don't do anything until that is done. - if (!mRootWindowContainer.allPausedActivitiesComplete()) { - if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE, - "resumeTopActivityLocked: Skip resume: some activity pausing."); - - return false; - } - - mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid); - - ActivityRecord lastResumed = null; - final ActivityStack lastFocusedStack = taskDisplayArea.getLastFocusedStack(); - if (lastFocusedStack != null && lastFocusedStack != this) { - // So, why aren't we using prev here??? See the param comment on the method. prev doesn't - // represent the last resumed activity. However, the last focus stack does if it isn't null. - lastResumed = lastFocusedStack.mResumedActivity; - if (userLeaving && inMultiWindowMode() && lastFocusedStack.shouldBeVisible(next)) { - // The user isn't leaving if this stack is the multi-window mode and the last - // focused stack should still be visible. - if(DEBUG_USER_LEAVING) Slog.i(TAG_USER_LEAVING, "Overriding userLeaving to false" - + " next=" + next + " lastResumed=" + lastResumed); - userLeaving = false; - } - } - - boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next); - if (mResumedActivity != null) { - if (DEBUG_STATES) Slog.d(TAG_STATES, - "resumeTopActivityLocked: Pausing " + mResumedActivity); - pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next); - } - if (pausing) { - if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES, - "resumeTopActivityLocked: Skip resume: need to start pausing"); - // At this point we want to put the upcoming activity's process - // at the top of the LRU list, since we know we will be needing it - // very soon and it would be a waste to let it get killed if it - // happens to be sitting towards the end. - if (next.attachedToProcess()) { - next.app.updateProcessInfo(false /* updateServiceConnectionActivities */, - true /* activityChange */, false /* updateOomAdj */, - false /* addPendingTopUid */); - } else if (!next.isProcessRunning()) { - // Since the start-process is asynchronous, if we already know the process of next - // activity isn't running, we can start the process earlier to save the time to wait - // for the current activity to be paused. - final boolean isTop = this == taskDisplayArea.getFocusedStack(); - mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop, - isTop ? "pre-top-activity" : "pre-activity"); - } - if (lastResumed != null) { - lastResumed.setWillCloseOrEnterPip(true); - } - return true; - } else if (mResumedActivity == next && next.isState(RESUMED) - && taskDisplayArea.allResumedActivitiesComplete()) { - // It is possible for the activity to be resumed when we paused back stacks above if the - // next activity doesn't have to wait for pause to complete. - // So, nothing else to-do except: - // Make sure we have executed any pending transitions, since there - // should be nothing left to do at this point. - executeAppTransition(options); - if (DEBUG_STATES) Slog.d(TAG_STATES, - "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next); - return true; - } - - // If the most recent activity was noHistory but was only stopped rather - // than stopped+finished because the device went to sleep, we need to make - // sure to finish it as we're making a new activity topmost. - if (shouldSleepActivities() && mLastNoHistoryActivity != null && - !mLastNoHistoryActivity.finishing) { - if (DEBUG_STATES) Slog.d(TAG_STATES, - "no-history finish of " + mLastNoHistoryActivity + " on new resume"); - mLastNoHistoryActivity.finishIfPossible("resume-no-history", false /* oomAdj */); - mLastNoHistoryActivity = null; - } - - if (prev != null && prev != next && next.nowVisible) { - - // The next activity is already visible, so hide the previous - // activity's windows right now so we can show the new one ASAP. - // We only do this if the previous is finishing, which should mean - // it is on top of the one being resumed so hiding it quickly - // is good. Otherwise, we want to do the normal route of allowing - // the resumed activity to be shown so we can decide if the - // previous should actually be hidden depending on whether the - // new one is found to be full-screen or not. - if (prev.finishing) { - prev.setVisibility(false); - if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, - "Not waiting for visible to hide: " + prev - + ", nowVisible=" + next.nowVisible); - } else { - if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, - "Previous already visible but still waiting to hide: " + prev - + ", nowVisible=" + next.nowVisible); - } - - } - - // Launching this app's activity, make sure the app is no longer - // considered stopped. - try { - mAtmService.getPackageManager().setPackageStoppedState( - next.packageName, false, next.mUserId); /* TODO: Verify if correct userid */ - } catch (RemoteException e1) { - } catch (IllegalArgumentException e) { - Slog.w(TAG, "Failed trying to unstop package " - + next.packageName + ": " + e); - } - - // We are starting up the next activity, so tell the window manager - // that the previous one will be hidden soon. This way it can know - // to ignore it when computing the desired screen orientation. - boolean anim = true; - final DisplayContent dc = taskDisplayArea.mDisplayContent; - if (prev != null) { - if (prev.finishing) { - if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, - "Prepare close transition: prev=" + prev); - if (mStackSupervisor.mNoAnimActivities.contains(prev)) { - anim = false; - dc.prepareAppTransition(TRANSIT_NONE, false); - } else { - dc.prepareAppTransition( - prev.getTask() == next.getTask() ? TRANSIT_ACTIVITY_CLOSE - : TRANSIT_TASK_CLOSE, false); - } - prev.setVisibility(false); - } else { - if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, - "Prepare open transition: prev=" + prev); - if (mStackSupervisor.mNoAnimActivities.contains(next)) { - anim = false; - dc.prepareAppTransition(TRANSIT_NONE, false); - } else { - dc.prepareAppTransition( - prev.getTask() == next.getTask() ? TRANSIT_ACTIVITY_OPEN - : next.mLaunchTaskBehind ? TRANSIT_TASK_OPEN_BEHIND - : TRANSIT_TASK_OPEN, false); - } - } - } else { - if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous"); - if (mStackSupervisor.mNoAnimActivities.contains(next)) { - anim = false; - dc.prepareAppTransition(TRANSIT_NONE, false); - } else { - dc.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false); - } - } - - if (anim) { - next.applyOptionsLocked(); - } else { - next.clearOptionsLocked(); - } - - mStackSupervisor.mNoAnimActivities.clear(); - - if (next.attachedToProcess()) { - if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next - + " stopped=" + next.stopped - + " visibleRequested=" + next.mVisibleRequested); - - // If the previous activity is translucent, force a visibility update of - // the next activity, so that it's added to WM's opening app list, and - // transition animation can be set up properly. - // For example, pressing Home button with a translucent activity in focus. - // Launcher is already visible in this case. If we don't add it to opening - // apps, maybeUpdateTransitToWallpaper() will fail to identify this as a - // TRANSIT_WALLPAPER_OPEN animation, and run some funny animation. - final boolean lastActivityTranslucent = lastFocusedStack != null - && (lastFocusedStack.inMultiWindowMode() - || (lastFocusedStack.mLastPausedActivity != null - && !lastFocusedStack.mLastPausedActivity.occludesParent())); - - // This activity is now becoming visible. - if (!next.mVisibleRequested || next.stopped || lastActivityTranslucent) { - next.setVisibility(true); - } - - // schedule launch ticks to collect information about slow apps. - next.startLaunchTickingLocked(); - - ActivityRecord lastResumedActivity = - lastFocusedStack == null ? null : lastFocusedStack.mResumedActivity; - final ActivityState lastState = next.getState(); - - mAtmService.updateCpuStats(); - - if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next - + " (in existing)"); - - next.setState(RESUMED, "resumeTopActivityInnerLocked"); - - next.app.updateProcessInfo(false /* updateServiceConnectionActivities */, - true /* activityChange */, true /* updateOomAdj */, - true /* addPendingTopUid */); - - // Have the window manager re-evaluate the orientation of - // the screen based on the new activity order. - boolean notUpdated = true; - - // Activity should also be visible if set mLaunchTaskBehind to true (see - // ActivityRecord#shouldBeVisibleIgnoringKeyguard()). - if (shouldBeVisible(next)) { - // We have special rotation behavior when here is some active activity that - // requests specific orientation or Keyguard is locked. Make sure all activity - // visibilities are set correctly as well as the transition is updated if needed - // to get the correct rotation behavior. Otherwise the following call to update - // the orientation may cause incorrect configurations delivered to client as a - // result of invisible window resize. - // TODO: Remove this once visibilities are set correctly immediately when - // starting an activity. - notUpdated = !mRootWindowContainer.ensureVisibilityAndConfig(next, getDisplayId(), - true /* markFrozenIfConfigChanged */, false /* deferResume */); - } - - if (notUpdated) { - // The configuration update wasn't able to keep the existing - // instance of the activity, and instead started a new one. - // We should be all done, but let's just make sure our activity - // is still at the top and schedule another run if something - // weird happened. - ActivityRecord nextNext = topRunningActivity(); - if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES, - "Activity config changed during resume: " + next - + ", new next: " + nextNext); - if (nextNext != next) { - // Do over! - mStackSupervisor.scheduleResumeTopActivities(); - } - if (!next.mVisibleRequested || next.stopped) { - next.setVisibility(true); - } - next.completeResumeLocked(); - return true; - } - - try { - final ClientTransaction transaction = - ClientTransaction.obtain(next.app.getThread(), next.appToken); - // Deliver all pending results. - ArrayList<ResultInfo> a = next.results; - if (a != null) { - final int N = a.size(); - if (!next.finishing && N > 0) { - if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, - "Delivering results to " + next + ": " + a); - transaction.addCallback(ActivityResultItem.obtain(a)); - } - } - - if (next.newIntents != null) { - transaction.addCallback( - NewIntentItem.obtain(next.newIntents, true /* resume */)); - } - - // Well the app will no longer be stopped. - // Clear app token stopped state in window manager if needed. - next.notifyAppResumed(next.stopped); - - EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next), - next.getTask().mTaskId, next.shortComponentName); - - next.setSleeping(false); - mAtmService.getAppWarningsLocked().onResumeActivity(next); - next.app.setPendingUiCleanAndForceProcessStateUpTo(mAtmService.mTopProcessState); - next.clearOptionsLocked(); - transaction.setLifecycleStateRequest( - ResumeActivityItem.obtain(next.app.getReportedProcState(), - dc.isNextTransitionForward())); - mAtmService.getLifecycleManager().scheduleTransaction(transaction); - - if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed " - + next); - } catch (Exception e) { - // Whoops, need to restart this activity! - if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to " - + lastState + ": " + next); - next.setState(lastState, "resumeTopActivityInnerLocked"); - - // lastResumedActivity being non-null implies there is a lastStack present. - if (lastResumedActivity != null) { - lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked"); - } - - Slog.i(TAG, "Restarting because process died: " + next); - if (!next.hasBeenLaunched) { - next.hasBeenLaunched = true; - } else if (SHOW_APP_STARTING_PREVIEW && lastFocusedStack != null - && lastFocusedStack.isTopStackInDisplayArea()) { - next.showStartingWindow(null /* prev */, false /* newTask */, - false /* taskSwitch */); - } - mStackSupervisor.startSpecificActivity(next, true, false); - return true; - } - - // From this point on, if something goes wrong there is no way - // to recover the activity. - try { - next.completeResumeLocked(); - } catch (Exception e) { - // If any exception gets thrown, toss away this - // activity and try the next one. - Slog.w(TAG, "Exception thrown during resume of " + next, e); - next.finishIfPossible("resume-exception", true /* oomAdj */); - return true; - } - } else { - // Whoops, need to restart this activity! - if (!next.hasBeenLaunched) { - next.hasBeenLaunched = true; - } else { - if (SHOW_APP_STARTING_PREVIEW) { - next.showStartingWindow(null /* prev */, false /* newTask */, - false /* taskSwich */); - } - if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next); - } - if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next); - mStackSupervisor.startSpecificActivity(next, true, true); - } - - return true; - } - - /** - * Resume the next eligible activity in a focusable stack when this one does not have any - * running activities left. The focus will be adjusted to the next focusable stack and - * top running activities will be resumed in all focusable stacks. However, if the current stack - * is a home stack - we have to keep it focused, start and resume a home activity on the current - * display instead to make sure that the display is not empty. - */ - private boolean resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev, - ActivityOptions options) { - final String reason = "noMoreActivities"; - - if (!isActivityTypeHome()) { - final ActivityStack nextFocusedStack = adjustFocusToNextFocusableTask(reason); - if (nextFocusedStack != null) { - // Try to move focus to the next visible stack with a running activity if this - // stack is not covering the entire screen or is on a secondary display with no home - // stack. - return mRootWindowContainer.resumeFocusedStacksTopActivities(nextFocusedStack, - prev, null /* targetOptions */); - } - } - - // If the current stack is a home stack, or if focus didn't switch to a different stack - - // just start up the Launcher... - ActivityOptions.abort(options); - if (DEBUG_STATES) Slog.d(TAG_STATES, - "resumeNextFocusableActivityWhenStackIsEmpty: " + reason + ", go home"); - return mRootWindowContainer.resumeHomeActivity(prev, reason, getDisplayArea()); - } - - void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity, - boolean newTask, boolean keepCurTransition, ActivityOptions options) { - Task rTask = r.getTask(); - final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront(); - final boolean isOrhasTask = rTask == this || hasChild(rTask); - // mLaunchTaskBehind tasks get placed at the back of the task stack. - if (!r.mLaunchTaskBehind && allowMoveToFront && (!isOrhasTask || newTask)) { - // Last activity in task had been removed or ActivityManagerService is reusing task. - // Insert or replace. - // Might not even be in. - positionChildAtTop(rTask); - } - Task task = null; - if (!newTask && isOrhasTask) { - // Starting activity cannot be occluding activity, otherwise starting window could be - // remove immediately without transferring to starting activity. - final ActivityRecord occludingActivity = getOccludingActivityAbove(r); - if (occludingActivity != null) { - // Here it is! Now, if this is not yet visible (occluded by another task) to the - // user, then just add it without starting; it will get started when the user - // navigates back to it. - if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task " + task, - new RuntimeException("here").fillInStackTrace()); - rTask.positionChildAtTop(r); - ActivityOptions.abort(options); - return; - } - } - - // Place a new activity at top of stack, so it is next to interact with the user. - - // If we are not placing the new activity frontmost, we do not want to deliver the - // onUserLeaving callback to the actual frontmost activity - final Task activityTask = r.getTask(); - if (task == activityTask && mChildren.indexOf(task) != (getChildCount() - 1)) { - mStackSupervisor.mUserLeaving = false; - if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, - "startActivity() behind front, mUserLeaving=false"); - } - - task = activityTask; - - // Slot the activity into the history stack and proceed - if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task, - new RuntimeException("here").fillInStackTrace()); - task.positionChildAtTop(r); - - // The transition animation and starting window are not needed if {@code allowMoveToFront} - // is false, because the activity won't be visible. - if ((!isHomeOrRecentsStack() || hasActivity()) && allowMoveToFront) { - final DisplayContent dc = getDisplay().mDisplayContent; - if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, - "Prepare open transition: starting " + r); - if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { - dc.prepareAppTransition(TRANSIT_NONE, keepCurTransition); - mStackSupervisor.mNoAnimActivities.add(r); - } else { - int transit = TRANSIT_ACTIVITY_OPEN; - if (newTask) { - if (r.mLaunchTaskBehind) { - transit = TRANSIT_TASK_OPEN_BEHIND; - } else if (getDisplay().isSingleTaskInstance()) { - // If a new task is being launched in a single task display, we don't need - // to play normal animation, but need to trigger a callback when an app - // transition is actually handled. So ignore already prepared activity, and - // override it. - transit = TRANSIT_SHOW_SINGLE_TASK_DISPLAY; - keepCurTransition = false; - } else { - // If a new task is being launched, then mark the existing top activity as - // supporting picture-in-picture while pausing only if the starting activity - // would not be considered an overlay on top of the current activity - // (eg. not fullscreen, or the assistant) - if (canEnterPipOnTaskSwitch(focusedTopActivity, - null /* toFrontTask */, r, options)) { - focusedTopActivity.supportsEnterPipOnTaskSwitch = true; - } - transit = TRANSIT_TASK_OPEN; - } - } - dc.prepareAppTransition(transit, keepCurTransition); - mStackSupervisor.mNoAnimActivities.remove(r); - } - boolean doShow = true; - if (newTask) { - // Even though this activity is starting fresh, we still need - // to reset it to make sure we apply affinities to move any - // existing activities from other tasks in to it. - // If the caller has requested that the target task be - // reset, then do so. - if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { - resetTaskIfNeeded(r, r); - doShow = topRunningNonDelayedActivityLocked(null) == r; - } - } else if (options != null && options.getAnimationType() - == ActivityOptions.ANIM_SCENE_TRANSITION) { - doShow = false; - } - if (r.mLaunchTaskBehind) { - // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we - // tell WindowManager that r is visible even though it is at the back of the stack. - r.setVisibility(true); - ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); - // Go ahead to execute app transition for this activity since the app transition - // will not be triggered through the resume channel. - getDisplay().mDisplayContent.executeAppTransition(); - } else if (SHOW_APP_STARTING_PREVIEW && doShow) { - // Figure out if we are transitioning from another activity that is - // "has the same starting icon" as the next one. This allows the - // window manager to keep the previous window it had previously - // created, if it still had one. - Task prevTask = r.getTask(); - ActivityRecord prev = prevTask.topActivityWithStartingWindow(); - if (prev != null) { - // We don't want to reuse the previous starting preview if: - // (1) The current activity is in a different task. - if (prev.getTask() != prevTask) { - prev = null; - } - // (2) The current activity is already displayed. - else if (prev.nowVisible) { - prev = null; - } - } - r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity)); - } - } else { - // If this is the first activity, don't do any fancy animations, - // because there is nothing for it to animate on top of. - ActivityOptions.abort(options); - } - } - - /** - * @return Whether the switch to another task can trigger the currently running activity to - * enter PiP while it is pausing (if supported). Only one of {@param toFrontTask} or - * {@param toFrontActivity} should be set. - */ - private boolean canEnterPipOnTaskSwitch(ActivityRecord pipCandidate, - Task toFrontTask, ActivityRecord toFrontActivity, ActivityOptions opts) { - if (opts != null && opts.disallowEnterPictureInPictureWhileLaunching()) { - // Ensure the caller has requested not to trigger auto-enter PiP - return false; - } - if (pipCandidate == null || pipCandidate.inPinnedWindowingMode()) { - // Ensure that we do not trigger entering PiP an activity on the pinned stack - return false; - } - final ActivityStack targetStack = toFrontTask != null - ? toFrontTask.getStack() : toFrontActivity.getRootTask(); - if (targetStack != null && targetStack.isActivityTypeAssistant()) { - // Ensure the task/activity being brought forward is not the assistant - return false; - } - return true; - } - - private boolean isTaskSwitch(ActivityRecord r, ActivityRecord topFocusedActivity) { - return topFocusedActivity != null && r.getTask() != topFocusedActivity.getTask(); - } - - /** - * Reset the task by reparenting the activities that have same affinity to the task or - * reparenting the activities that have different affinityies out of the task, while these - * activities allow task reparenting. - * - * @param taskTop Top activity of the task might be reset. - * @param newActivity The activity that going to be started. - * @return The non-finishing top activity of the task after reset or the original task top - * activity if all activities within the task are finishing. - */ - ActivityRecord resetTaskIfNeeded(ActivityRecord taskTop, ActivityRecord newActivity) { - final boolean forceReset = - (newActivity.info.flags & ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0; - final Task task = taskTop.getTask(); - - // If ActivityOptions are moved out and need to be aborted or moved to taskTop. - final ActivityOptions topOptions = sResetTargetTaskHelper.process(task, forceReset); - - if (mChildren.contains(task)) { - final ActivityRecord newTop = task.getTopNonFinishingActivity(); - if (newTop != null) { - taskTop = newTop; - } - } - - if (topOptions != null) { - // If we got some ActivityOptions from an activity on top that - // was removed from the task, propagate them to the new real top. - taskTop.updateOptionsLocked(topOptions); - } - - return taskTop; - } - - /** - * Finish the topmost activity that belongs to the crashed app. We may also finish the activity - * that requested launch of the crashed one to prevent launch-crash loop. - * @param app The app that crashed. - * @param reason Reason to perform this action. - * @return The task that was finished in this stack, {@code null} if top running activity does - * not belong to the crashed app. - */ - final Task finishTopCrashedActivityLocked(WindowProcessController app, String reason) { - final ActivityRecord r = topRunningActivity(); - if (r == null || r.app != app) { - return null; - } - if (r.isActivityTypeHome() && mAtmService.mHomeProcess == app) { - // Home activities should not be force-finished as we have nothing else to go - // back to. AppErrors will get to it after two crashes in MIN_CRASH_INTERVAL. - Slog.w(TAG, " Not force finishing home activity " - + r.intent.getComponent().flattenToShortString()); - return null; - } - Slog.w(TAG, " Force finishing activity " - + r.intent.getComponent().flattenToShortString()); - Task finishedTask = r.getTask(); - getDisplay().mDisplayContent.prepareAppTransition( - TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */); - r.finishIfPossible(reason, false /* oomAdj */); - - // Also terminate any activities below it that aren't yet stopped, to avoid a situation - // where one will get re-start our crashing activity once it gets resumed again. - final ActivityRecord activityBelow = getActivityBelow(r); - if (activityBelow != null) { - if (activityBelow.isState(STARTED, RESUMED, PAUSING, PAUSED)) { - if (!activityBelow.isActivityTypeHome() - || mAtmService.mHomeProcess != activityBelow.app) { - Slog.w(TAG, " Force finishing activity " - + activityBelow.intent.getComponent().flattenToShortString()); - activityBelow.finishIfPossible(reason, false /* oomAdj */); - } - } - } - - return finishedTask; - } - - void finishVoiceTask(IVoiceInteractionSession session) { - final PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::finishIfVoiceTask, - PooledLambda.__(Task.class), session.asBinder()); - forAllLeafTasks(c, true /* traverseTopToBottom */); - c.recycle(); - } - - private static void finishIfVoiceTask(Task tr, IBinder binder) { - if (tr.voiceSession != null && tr.voiceSession.asBinder() == binder) { - tr.forAllActivities((r) -> { - if (r.finishing) return; - r.finishIfPossible("finish-voice", false /* oomAdj */); - tr.mAtmService.updateOomAdj(); - }); - } else { - // Check if any of the activities are using voice - final PooledFunction f = PooledLambda.obtainFunction( - ActivityStack::finishIfVoiceActivity, PooledLambda.__(ActivityRecord.class), - binder); - tr.forAllActivities(f); - f.recycle(); - } - } - - private static boolean finishIfVoiceActivity(ActivityRecord r, IBinder binder) { - if (r.voiceSession == null || r.voiceSession.asBinder() != binder) return false; - // Inform of cancellation - r.clearVoiceSessionLocked(); - try { - r.app.getThread().scheduleLocalVoiceInteractionStarted(r.appToken, null); - } catch (RemoteException re) { - // Ok Boomer... - } - r.mAtmService.finishRunningVoiceLocked(); - return true; - } - - /** Finish all activities in the stack without waiting. */ - void finishAllActivitiesImmediately() { - if (!hasChild()) { - removeIfPossible(); - return; - } - forAllActivities((r) -> { - Slog.d(TAG, "finishAllActivitiesImmediatelyLocked: finishing " + r); - r.destroyIfPossible("finishAllActivitiesImmediately"); - }); - } - - /** @return true if the stack behind this one is a standard activity type. */ - private boolean inFrontOfStandardStack() { - final TaskDisplayArea taskDisplayArea = getDisplayArea(); - if (taskDisplayArea == null) { - return false; - } - final int index = taskDisplayArea.getIndexOf(this); - if (index == 0) { - return false; - } - final ActivityStack stackBehind = taskDisplayArea.getChildAt(index - 1); - return stackBehind.isActivityTypeStandard(); - } - - boolean shouldUpRecreateTaskLocked(ActivityRecord srec, String destAffinity) { - // Basic case: for simple app-centric recents, we need to recreate - // the task if the affinity has changed. - - final String affinity = ActivityRecord.getTaskAffinityWithUid(destAffinity, srec.getUid()); - if (srec == null || srec.getTask().affinity == null - || !srec.getTask().affinity.equals(affinity)) { - return true; - } - // Document-centric case: an app may be split in to multiple documents; - // they need to re-create their task if this current activity is the root - // of a document, unless simply finishing it will return them to the the - // correct app behind. - final Task task = srec.getTask(); - if (srec.isRootOfTask() && task.getBaseIntent() != null - && task.getBaseIntent().isDocument()) { - // Okay, this activity is at the root of its task. What to do, what to do... - if (!inFrontOfStandardStack()) { - // Finishing won't return to an application, so we need to recreate. - return true; - } - // We now need to get the task below it to determine what to do. - final Task prevTask = getTaskBelow(task); - if (prevTask == null) { - Slog.w(TAG, "shouldUpRecreateTask: task not in history for " + srec); - return false; - } - if (!task.affinity.equals(prevTask.affinity)) { - // These are different apps, so need to recreate. - return true; - } - } - return false; - } - - boolean navigateUpTo(ActivityRecord srec, Intent destIntent, NeededUriGrants destGrants, - int resultCode, Intent resultData, NeededUriGrants resultGrants) { - if (!srec.attachedToProcess()) { - // Nothing to do if the caller is not attached, because this method should be called - // from an alive activity. - return false; - } - final Task task = srec.getTask(); - if (!srec.isDescendantOf(this)) { - return false; - } - - ActivityRecord parent = task.getActivityBelow(srec); - boolean foundParentInTask = false; - final ComponentName dest = destIntent.getComponent(); - if (task.getBottomMostActivity() != srec && dest != null) { - final ActivityRecord candidate = task.getActivity((ar) -> - ar.info.packageName.equals(dest.getPackageName()) && - ar.info.name.equals(dest.getClassName()), srec, false /*includeBoundary*/, - true /*traverseTopToBottom*/); - if (candidate != null) { - parent = candidate; - foundParentInTask = true; - } - } - - // TODO: There is a dup. of this block of code in ActivityTaskManagerService.finishActivity - // We should consolidate. - IActivityController controller = mAtmService.mController; - if (controller != null) { - ActivityRecord next = topRunningActivity(srec.appToken, INVALID_TASK_ID); - if (next != null) { - // ask watcher if this is allowed - boolean resumeOK = true; - try { - resumeOK = controller.activityResuming(next.packageName); - } catch (RemoteException e) { - mAtmService.mController = null; - Watchdog.getInstance().setActivityController(null); - } - - if (!resumeOK) { - return false; - } - } - } - final long origId = Binder.clearCallingIdentity(); - - final int[] resultCodeHolder = new int[1]; - resultCodeHolder[0] = resultCode; - final Intent[] resultDataHolder = new Intent[1]; - resultDataHolder[0] = resultData; - final NeededUriGrants[] resultGrantsHolder = new NeededUriGrants[1]; - resultGrantsHolder[0] = resultGrants; - final ActivityRecord finalParent = parent; - task.forAllActivities((ar) -> { - if (ar == finalParent) return true; - - ar.finishIfPossible(resultCodeHolder[0], resultDataHolder[0], resultGrantsHolder[0], - "navigate-up", true /* oomAdj */); - // Only return the supplied result for the first activity finished - resultCodeHolder[0] = Activity.RESULT_CANCELED; - resultDataHolder[0] = null; - return false; - }, srec, true, true); - resultCode = resultCodeHolder[0]; - resultData = resultDataHolder[0]; - - if (parent != null && foundParentInTask) { - final int callingUid = srec.info.applicationInfo.uid; - final int parentLaunchMode = parent.info.launchMode; - final int destIntentFlags = destIntent.getFlags(); - if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || - parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || - parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || - (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { - parent.deliverNewIntentLocked(callingUid, destIntent, destGrants, srec.packageName); - } else { - try { - ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( - destIntent.getComponent(), ActivityManagerService.STOCK_PM_FLAGS, - srec.mUserId); - // TODO(b/64750076): Check if calling pid should really be -1. - final int res = mAtmService.getActivityStartController() - .obtainStarter(destIntent, "navigateUpTo") - .setCaller(srec.app.getThread()) - .setActivityInfo(aInfo) - .setResultTo(parent.appToken) - .setCallingPid(-1) - .setCallingUid(callingUid) - .setCallingPackage(srec.packageName) - .setCallingFeatureId(parent.launchedFromFeatureId) - .setRealCallingPid(-1) - .setRealCallingUid(callingUid) - .setComponentSpecified(true) - .execute(); - foundParentInTask = res == ActivityManager.START_SUCCESS; - } catch (RemoteException e) { - foundParentInTask = false; - } - parent.finishIfPossible(resultCode, resultData, resultGrants, - "navigate-top", true /* oomAdj */); - } - } - Binder.restoreCallingIdentity(origId); - return foundParentInTask; - } - - void removeLaunchTickMessages() { - forAllActivities(ActivityRecord::removeLaunchTickRunnable); - } - - private void updateTransitLocked(int transit, ActivityOptions options, boolean forceOverride) { - if (options != null) { - ActivityRecord r = topRunningActivity(); - if (r != null && !r.isState(RESUMED)) { - r.updateOptionsLocked(options); - } else { - ActivityOptions.abort(options); - } - } - getDisplay().mDisplayContent.prepareAppTransition(transit, false, - 0 /* flags */, forceOverride); - } - - final void moveTaskToFront(Task tr, boolean noAnimation, ActivityOptions options, - AppTimeTracker timeTracker, String reason) { - moveTaskToFront(tr, noAnimation, options, timeTracker, !DEFER_RESUME, reason); - } - - final void moveTaskToFront(Task tr, boolean noAnimation, ActivityOptions options, - AppTimeTracker timeTracker, boolean deferResume, String reason) { - if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr); - - final ActivityStack topStack = getDisplayArea().getTopStack(); - final ActivityRecord topActivity = topStack != null - ? topStack.getTopNonFinishingActivity() : null; - - if (tr != this && !tr.isDescendantOf(this)) { - // nothing to do! - if (noAnimation) { - ActivityOptions.abort(options); - } else if (isSingleTaskInstance()) { - // When a task is moved front on the display which can only contain one task, start - // a special transition. - // {@link AppTransitionController#handleAppTransitionReady} later picks up the - // transition, and schedules - // {@link ITaskStackListener#onSingleTaskDisplayDrawn} callback which is triggered - // after contents are drawn on the display. - updateTransitLocked(TRANSIT_SHOW_SINGLE_TASK_DISPLAY, options, - true /* forceOverride */); - } else { - updateTransitLocked(TRANSIT_TASK_TO_FRONT, options, false /* forceOverride */); - } - return; - } - - if (timeTracker != null) { - // The caller wants a time tracker associated with this task. - final PooledConsumer c = PooledLambda.obtainConsumer(ActivityRecord::setAppTimeTracker, - PooledLambda.__(ActivityRecord.class), timeTracker); - tr.forAllActivities(c); - c.recycle(); - } - - try { - // Defer updating the IME target since the new IME target will try to get computed - // before updating all closing and opening apps, which can cause the ime target to - // get calculated incorrectly. - getDisplay().deferUpdateImeTarget(); - - // Shift all activities with this task up to the top - // of the stack, keeping them in the same internal order. - positionChildAtTop(tr); - - // Don't refocus if invisible to current user - final ActivityRecord top = tr.getTopNonFinishingActivity(); - if (top == null || !top.okToShowLocked()) { - if (top != null) { - mStackSupervisor.mRecentTasks.add(top.getTask()); - } - ActivityOptions.abort(options); - return; - } - - // Set focus to the top running activity of this stack. - final ActivityRecord r = topRunningActivity(); - if (r != null) { - r.moveFocusableActivityToTop(reason); - } - - if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr); - if (noAnimation) { - getDisplay().mDisplayContent.prepareAppTransition(TRANSIT_NONE, false); - if (r != null) { - mStackSupervisor.mNoAnimActivities.add(r); - } - ActivityOptions.abort(options); - } else if (isSingleTaskInstance()) { - updateTransitLocked(TRANSIT_SHOW_SINGLE_TASK_DISPLAY, options, - true /* forceOverride */); - } else { - updateTransitLocked(TRANSIT_TASK_TO_FRONT, options, false /* forceOverride */); - } - - // If a new task is moved to the front, then mark the existing top activity as - // supporting - - // picture-in-picture while paused only if the task would not be considered an oerlay - // on top - // of the current activity (eg. not fullscreen, or the assistant) - if (canEnterPipOnTaskSwitch(topActivity, tr, null /* toFrontActivity */, - options)) { - topActivity.supportsEnterPipOnTaskSwitch = true; - } - - if (!deferResume) { - mRootWindowContainer.resumeFocusedStacksTopActivities(); - } - EventLogTags.writeWmTaskToFront(tr.mUserId, tr.mTaskId); - mAtmService.getTaskChangeNotificationController() - .notifyTaskMovedToFront(tr.getTaskInfo()); - } finally { - getDisplay().continueUpdateImeTarget(); - } - } - - /** - * Worker method for rearranging history stack. Implements the function of moving all - * activities for a specific task (gathering them if disjoint) into a single group at the - * bottom of the stack. - * - * If a watcher is installed, the action is preflighted and the watcher has an opportunity - * to premeptively cancel the move. - * - * @param tr The task to collect and move to the bottom. - * @return Returns true if the move completed, false if not. - */ - boolean moveTaskToBack(Task tr) { - Slog.i(TAG, "moveTaskToBack: " + tr); - - // In LockTask mode, moving a locked task to the back of the stack may expose unlocked - // ones. Therefore we need to check if this operation is allowed. - if (!mAtmService.getLockTaskController().canMoveTaskToBack(tr)) { - return false; - } - - // If we have a watcher, preflight the move before committing to it. First check - // for *other* available tasks, but if none are available, then try again allowing the - // current task to be selected. - if (isTopStackInDisplayArea() && mAtmService.mController != null) { - ActivityRecord next = topRunningActivity(null, tr.mTaskId); - if (next == null) { - next = topRunningActivity(null, INVALID_TASK_ID); - } - if (next != null) { - // ask watcher if this is allowed - boolean moveOK = true; - try { - moveOK = mAtmService.mController.activityResuming(next.packageName); - } catch (RemoteException e) { - mAtmService.mController = null; - Watchdog.getInstance().setActivityController(null); - } - if (!moveOK) { - return false; - } - } - } - - if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task=" - + tr.mTaskId); - - getDisplay().mDisplayContent.prepareAppTransition(TRANSIT_TASK_TO_BACK, false); - moveToBack("moveTaskToBackLocked", tr); - - if (inPinnedWindowingMode()) { - mStackSupervisor.removeStack(this); - return true; - } - - ActivityRecord topActivity = getDisplayArea().topRunningActivity(); - ActivityStack topStack = topActivity.getRootTask(); - if (topStack != null && topStack != this && topActivity.isState(RESUMED)) { - // The new top activity is already resumed, so there's a good chance that nothing will - // get resumed below. So, update visibility now in case the transition is closed - // prematurely. - mRootWindowContainer.ensureVisibilityAndConfig(null /* starting */, - getDisplay().mDisplayId, false /* markFrozenIfConfigChanged */, - false /* deferResume */); - // Usually resuming a top activity triggers the next app transition, but nothing's got - // resumed in this case, so we need to execute it explicitly. - getDisplay().mDisplayContent.executeAppTransition(); - } else { - mRootWindowContainer.resumeFocusedStacksTopActivities(); - } - return true; - } - - /** - * Ensures all visible activities at or below the input activity have the right configuration. - */ - void ensureVisibleActivitiesConfiguration(ActivityRecord start, boolean preserveWindow) { - mEnsureVisibleActivitiesConfigHelper.process(start, preserveWindow); - } - - // TODO: Can only be called from special methods in ActivityStackSupervisor. - // Need to consolidate those calls points into this resize method so anyone can call directly. - void resize(Rect displayedBounds, boolean preserveWindows, boolean deferResume) { - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "stack.resize_" + getRootTaskId()); - mAtmService.deferWindowLayout(); - try { - // TODO: Why not just set this on the stack directly vs. on each tasks? - // Update override configurations of all tasks in the stack. - final PooledConsumer c = PooledLambda.obtainConsumer( - ActivityStack::processTaskResizeBounds, PooledLambda.__(Task.class), - displayedBounds); - forAllTasks(c, true /* traverseTopToBottom */); - c.recycle(); - - if (mBoundsAnimating) { - // Force to update task surface bounds and relayout windows, since configBounds - // remains unchanged during bounds animation. - updateSurfaceBounds(); - getDisplay().setLayoutNeeded(); - mWmService.requestTraversal(); - } - - if (!deferResume) { - ensureVisibleActivitiesConfiguration(topRunningActivity(), preserveWindows); - } - } finally { - mAtmService.continueWindowLayout(); - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - } - } - - private static void processTaskResizeBounds(Task task, Rect displayedBounds) { - if (!task.isResizeable()) return; - - task.setBounds(displayedBounds); - } - - /** - * Until we can break this "set task bounds to same as stack bounds" behavior, this - * basically resizes both stack and task bounds to the same bounds. - */ - private void setTaskBounds(Rect bounds) { - final PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::setTaskBounds, - PooledLambda.__(Task.class), bounds); - forAllLeafTasks(c, true /* traverseTopToBottom */); - c.recycle(); - } - - private static void setTaskBounds(Task task, Rect bounds) { - task.setBounds(task.isResizeable() ? bounds : null); - } - - boolean willActivityBeVisible(IBinder token) { - final ActivityRecord r = ActivityRecord.forTokenLocked(token); - if (r == null) { - return false; - } - - // See if there is an occluding activity on-top of this one. - final ActivityRecord occludingActivity = getOccludingActivityAbove(r); - if (occludingActivity != null) return false; - - if (r.finishing) Slog.e(TAG, "willActivityBeVisible: Returning false," - + " would have returned true for r=" + r); - return !r.finishing; - } - - void unhandledBackLocked() { - final ActivityRecord topActivity = getTopMostActivity(); - if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, - "Performing unhandledBack(): top activity: " + topActivity); - if (topActivity != null) { - topActivity.finishIfPossible("unhandled-back", true /* oomAdj */); - } - } - - /** - * Reset local parameters because an app's activity died. - * @param app The app of the activity that died. - * @return result from removeHistoryRecordsForAppLocked. - */ - boolean handleAppDied(WindowProcessController app) { - if (mPausingActivity != null && mPausingActivity.app == app) { - if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE, - "App died while pausing: " + mPausingActivity); - mPausingActivity = null; - } - if (mLastPausedActivity != null && mLastPausedActivity.app == app) { - mLastPausedActivity = null; - mLastNoHistoryActivity = null; - } - - mStackSupervisor.removeHistoryRecords(app); - return mRemoveHistoryRecordsForApp.process(app); - } - - boolean dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, - String dumpPackage, final boolean needSep) { - Runnable headerPrinter = () -> { - if (needSep) { - pw.println(); - } - pw.println(" Stack #" + getRootTaskId() - + ": type=" + activityTypeToString(getActivityType()) - + " mode=" + windowingModeToString(getWindowingMode())); - pw.println(" isSleeping=" + shouldSleepActivities()); - pw.println(" mBounds=" + getRequestedOverrideBounds()); - }; - - boolean printed = false; - - if (dumpPackage == null) { - // If we are not filtering by package, we want to print absolutely everything, - // so always print the header even if there are no tasks/activities inside. - headerPrinter.run(); - headerPrinter = null; - printed = true; - } - - printed |= printThisActivity(pw, mPausingActivity, dumpPackage, false, - " mPausingActivity: ", null); - printed |= printThisActivity(pw, getResumedActivity(), dumpPackage, false, - " mResumedActivity: ", null); - if (dumpAll) { - printed |= printThisActivity(pw, mLastPausedActivity, dumpPackage, false, - " mLastPausedActivity: ", null); - printed |= printThisActivity(pw, mLastNoHistoryActivity, dumpPackage, - false, " mLastNoHistoryActivity: ", null); - } - - printed |= dumpActivities(fd, pw, dumpAll, dumpClient, dumpPackage, false, headerPrinter); - - return printed; - } - - private boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, - boolean dumpClient, String dumpPackage, boolean needSep, Runnable header) { - if (!hasChild()) { - return false; - } - final AtomicBoolean printedHeader = new AtomicBoolean(false); - final AtomicBoolean printed = new AtomicBoolean(false); - forAllLeafTasks((task) -> { - final String prefix = " "; - Runnable headerPrinter = () -> { - printed.set(true); - if (!printedHeader.get()) { - if (needSep) { - pw.println(""); - } - if (header != null) { - header.run(); - } - printedHeader.set(true); - } - pw.print(prefix); pw.print("* "); pw.println(task); - pw.print(prefix); pw.print(" mBounds="); - pw.println(task.getRequestedOverrideBounds()); - pw.print(prefix); pw.print(" mMinWidth="); pw.print(task.mMinWidth); - pw.print(" mMinHeight="); pw.println(task.mMinHeight); - if (mLastNonFullscreenBounds != null) { - pw.print(prefix); - pw.print(" mLastNonFullscreenBounds="); - pw.println(task.mLastNonFullscreenBounds); - } - task.dump(pw, prefix + " "); - }; - if (dumpPackage == null) { - // If we are not filtering by package, we want to print absolutely everything, - // so always print the header even if there are no activities inside. - headerPrinter.run(); - headerPrinter = null; - } - final ArrayList<ActivityRecord> activities = new ArrayList<>(); - // Add activities by traversing the hierarchy from bottom to top, since activities - // are dumped in reverse order in {@link ActivityStackSupervisor#dumpHistoryList()}. - task.forAllActivities((Consumer<ActivityRecord>) activities::add, - false /* traverseTopToBottom */); - dumpHistoryList(fd, pw, activities, prefix, "Hist", true, !dumpAll, dumpClient, - dumpPackage, false, headerPrinter, task); - }, true /* traverseTopToBottom */); - return printed.get(); - } - - ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { - ArrayList<ActivityRecord> activities = new ArrayList<>(); - - if ("all".equals(name)) { - forAllActivities((Consumer<ActivityRecord>) activities::add); - } else if ("top".equals(name)) { - final ActivityRecord topActivity = getTopMostActivity(); - if (topActivity != null) { - activities.add(topActivity); - } - } else { - ItemMatcher matcher = new ItemMatcher(); - matcher.build(name); - - forAllActivities((r) -> { - if (matcher.match(r, r.intent.getComponent())) { - activities.add(r); - } - }); - } - - return activities; - } - - ActivityRecord restartPackage(String packageName) { - ActivityRecord starting = topRunningActivity(); - - // All activities that came from the package must be - // restarted as if there was a config change. - PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::restartPackage, - PooledLambda.__(ActivityRecord.class), starting, packageName); - forAllActivities(c); - c.recycle(); - - return starting; - } - - private static void restartPackage( - ActivityRecord r, ActivityRecord starting, String packageName) { - if (r.info.packageName.equals(packageName)) { - r.forceNewConfig = true; - if (starting != null && r == starting && r.mVisibleRequested) { - r.startFreezingScreenLocked(CONFIG_SCREEN_LAYOUT); - } - } - } - - Task reuseOrCreateTask(ActivityInfo info, Intent intent, boolean toTop) { - return reuseOrCreateTask(info, intent, null /*voiceSession*/, null /*voiceInteractor*/, - toTop, null /*activity*/, null /*source*/, null /*options*/); - } - // TODO: Can be removed once we change callpoints creating stacks to be creating tasks. - /** Either returns this current task to be re-used or creates a new child task. */ - Task reuseOrCreateTask(ActivityInfo info, Intent intent, IVoiceInteractionSession voiceSession, - IVoiceInteractor voiceInteractor, boolean toTop, ActivityRecord activity, - ActivityRecord source, ActivityOptions options) { - - Task task; - if (DisplayContent.alwaysCreateStack(getWindowingMode(), getActivityType())) { - // This stack will only contain one task, so just return itself since all stacks ara now - // tasks and all tasks are now stacks. - task = reuseAsLeafTask(voiceSession, voiceInteractor, intent, info, activity); - } else { - // Create child task since this stack can contain multiple tasks. - final int taskId = activity != null - ? mStackSupervisor.getNextTaskIdForUser(activity.mUserId) - : mStackSupervisor.getNextTaskIdForUser(); - task = new ActivityStack(mAtmService, taskId, info, intent, voiceSession, - voiceInteractor, null /* taskDescription */, this); - - // add the task to stack first, mTaskPositioner might need the stack association - addChild(task, toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0); - } - - int displayId = getDisplayId(); - if (displayId == INVALID_DISPLAY) displayId = DEFAULT_DISPLAY; - final boolean isLockscreenShown = mAtmService.mStackSupervisor.getKeyguardController() - .isKeyguardOrAodShowing(displayId); - if (!mStackSupervisor.getLaunchParamsController() - .layoutTask(task, info.windowLayout, activity, source, options) - && !getRequestedOverrideBounds().isEmpty() - && task.isResizeable() && !isLockscreenShown) { - task.setBounds(getRequestedOverrideBounds()); - } - - return task; - } - - void addChild(WindowContainer child, final boolean toTop, boolean showForAllUsers) { - if (isSingleTaskInstance() && hasChild()) { - throw new IllegalStateException("Can only have one child on stack=" + this); - } - - Task task = child.asTask(); - try { - if (task != null) { - task.setForceShowForAllUsers(showForAllUsers); - } - // We only want to move the parents to the parents if we are creating this task at the - // top of its stack. - addChild(child, toTop ? MAX_VALUE : 0, toTop /*moveParents*/); - } finally { - if (task != null) { - task.setForceShowForAllUsers(false); - } - } - } - - void positionChildAt(Task task, int position) { - if (task.getStack() != this) { - throw new IllegalArgumentException("AS.positionChildAt: task=" + task - + " is not a child of stack=" + this + " current parent=" + task.getStack()); - } - - task.updateOverrideConfigurationForStack(this); - - final ActivityRecord topRunningActivity = task.topRunningActivityLocked(); - final boolean wasResumed = topRunningActivity == task.getStack().mResumedActivity; - - boolean toTop = position >= getChildCount(); - boolean includingParents = toTop || getDisplayArea().getNextFocusableStack(this, - true /* ignoreCurrent */) == null; - if (WindowManagerDebugConfig.DEBUG_STACK) { - Slog.i(TAG_WM, "positionChildAt: positioning task=" + task + " at " + position); - } - positionChildAt(position, task, includingParents); - task.updateTaskMovement(toTop); - getDisplayContent().layoutAndAssignWindowLayersIfNeeded(); - - - // TODO: Investigate if this random code is really needed. - if (task.voiceSession != null) { - try { - task.voiceSession.taskStarted(task.intent, task.mTaskId); - } catch (RemoteException e) { - } - } - - if (wasResumed) { - if (mResumedActivity != null) { - Log.wtf(TAG, "mResumedActivity was already set when moving mResumedActivity from" - + " other stack to this stack mResumedActivity=" + mResumedActivity - + " other mResumedActivity=" + topRunningActivity); - } - topRunningActivity.setState(RESUMED, "positionChildAt"); - } - - // The task might have already been running and its visibility needs to be synchronized with - // the visibility of the stack / windows. - ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); - mRootWindowContainer.resumeFocusedStacksTopActivities(); - } - - public void setAlwaysOnTop(boolean alwaysOnTop) { - if (isAlwaysOnTop() == alwaysOnTop) { - return; - } - super.setAlwaysOnTop(alwaysOnTop); - final TaskDisplayArea taskDisplayArea = getDisplayArea(); - // positionChildAtTop() must be called even when always on top gets turned off because we - // need to make sure that the stack is moved from among always on top windows to below other - // always on top windows. Since the position the stack should be inserted into is calculated - // properly in {@link DisplayContent#getTopInsertPosition()} in both cases, we can just - // request that the stack is put at top here. - taskDisplayArea.positionStackAtTop(this, false /* includingParents */); - } - - /** NOTE: Should only be called from {@link Task#reparent}. */ - void moveToFrontAndResumeStateIfNeeded(ActivityRecord r, boolean moveToFront, boolean setResume, - boolean setPause, String reason) { - if (!moveToFront) { - return; - } - - final ActivityState origState = r.getState(); - // If the activity owns the last resumed activity, transfer that together, - // so that we don't resume the same activity again in the new stack. - // Apps may depend on onResume()/onPause() being called in pairs. - if (setResume) { - r.setState(RESUMED, "moveToFrontAndResumeStateIfNeeded"); - } - // If the activity was previously pausing, then ensure we transfer that as well - if (setPause) { - mPausingActivity = r; - r.schedulePauseTimeout(); - } - // Move the stack in which we are placing the activity to the front. - moveToFront(reason); - // If the original state is resumed, there is no state change to update focused app. - // So here makes sure the activity focus is set if it is the top. - if (origState == RESUMED && r == mRootWindowContainer.getTopResumedActivity()) { - mAtmService.setResumedActivityUncheckLocked(r, reason); - } - } - - void dismissPip() { - if (!isActivityTypeStandardOrUndefined()) { - throw new IllegalArgumentException( - "You can't move tasks from non-standard stacks."); - } - if (getWindowingMode() != WINDOWING_MODE_PINNED) { - throw new IllegalArgumentException( - "Can't exit pinned mode if it's not pinned already."); - } - - mWmService.inSurfaceTransaction(() -> { - final Task task = getBottomMostTask(); - setWindowingMode(WINDOWING_MODE_UNDEFINED); - - getDisplayArea().positionStackAtTop(this, false /* includingParents */); - - mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, this); - MetricsLoggerWrapper.logPictureInPictureFullScreen(mAtmService.mContext, - task.effectiveUid, task.realActivity.flattenToString()); - }); - } - - void prepareFreezingTaskBounds() { - forAllLeafTasks(Task::prepareFreezingBounds, true /* traverseTopToBottom */); - } - - @Override - public int setBounds(Rect bounds) { - // Calling Task#setBounds() for leaf task since this is the a specialization of - // {@link #setBounds(int)} for ActivityStack. - if (!isRootTask()) { - return super.setBounds(bounds); - } else { - return setBounds(getRequestedOverrideBounds(), bounds); - } - } - - private int setBounds(Rect existing, Rect bounds) { - if (equivalentBounds(existing, bounds)) { - return BOUNDS_CHANGE_NONE; - } - - final int result = super.setBounds(!inMultiWindowMode() ? null : bounds); - - updateSurfaceBounds(); - return result; - } - - /** Bounds of the stack without adjusting for other factors in the system like visibility - * of docked stack. - * Most callers should be using {@link ConfigurationContainer#getRequestedOverrideBounds} a - * it takes into consideration other system factors. */ - void getRawBounds(Rect out) { - out.set(getRawBounds()); - } - - private Rect getRawBounds() { - return super.getBounds(); - } - - @Override - public void getBounds(Rect bounds) { - bounds.set(getBounds()); - } - - /** - * @return the final bounds for the bounds animation. - */ - void getFinalAnimationBounds(Rect outBounds) { - outBounds.set(mBoundsAnimationTarget); - } - - /** - * @return the final source bounds for the bounds animation. - */ - void getFinalAnimationSourceHintBounds(Rect outBounds) { - outBounds.set(mBoundsAnimationSourceHintBounds); - } - - /** Bounds of the stack with other system factors taken into consideration. */ - void getDimBounds(Rect out) { - getBounds(out); - } - - /** - * Put a Task in this stack. Used for adding only. - * When task is added to top of the stack, the entire branch of the hierarchy (including stack - * and display) will be brought to top. - * @param child The child to add. - * @param position Target position to add the task to. - */ - private void addChild(WindowContainer child, int position, boolean moveParents) { - // Add child task. - addChild(child, null); - - // Move child to a proper position, as some restriction for position might apply. - positionChildAt(position, child, moveParents /* includingParents */); - } - - void positionChildAtTop(Task child) { - if (child == null) { - // TODO: Fix the call-points that cause this to happen. - return; - } - - if (child == this) { - // TODO: Fix call-points - moveToFront("positionChildAtTop"); - return; - } - - positionChildAt(POSITION_TOP, child, true /* includingParents */); - child.updateTaskMovement(true); - - final DisplayContent displayContent = getDisplayContent(); - displayContent.layoutAndAssignWindowLayersIfNeeded(); - } - - void positionChildAtBottom(Task child) { - // If there are other focusable stacks on the display, the z-order of the display should not - // be changed just because a task was placed at the bottom. E.g. if it is moving the topmost - // task to bottom, the next focusable stack on the same display should be focused. - final ActivityStack nextFocusableStack = getDisplayArea().getNextFocusableStack( - child.getStack(), true /* ignoreCurrent */); - positionChildAtBottom(child, nextFocusableStack == null /* includingParents */); - child.updateTaskMovement(true); - } - - @VisibleForTesting - void positionChildAtBottom(Task child, boolean includingParents) { - if (child == null) { - // TODO: Fix the call-points that cause this to happen. - return; - } - - positionChildAt(POSITION_BOTTOM, child, includingParents); - getDisplayContent().layoutAndAssignWindowLayersIfNeeded(); - } - - @Override - void onChildPositionChanged(WindowContainer child) { - if (isOrganized()) { - mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, false /* force */); - } - - if (!mChildren.contains(child)) { - return; - } - - final boolean isTop = getTopChild() == child; - - final Task task = child.asTask(); - if (task != null) { - task.updateTaskMovement(isTop); - } - - if (isTop) { - final DisplayContent displayContent = getDisplayContent(); - displayContent.layoutAndAssignWindowLayersIfNeeded(); - } - } - - @Override - void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) { - final DisplayContent display = newParent != null - ? ((WindowContainer) newParent).getDisplayContent() : null; - final DisplayContent oldDisplay = oldParent != null - ? ((WindowContainer) oldParent).getDisplayContent() : null; - super.onParentChanged(newParent, oldParent); - - // Resume next focusable stack after reparenting to another display if we aren't removing - // the prevous display. - if (oldDisplay != null && oldDisplay.isRemoving()) { - postReparent(); - } - } - - void reparent(TaskDisplayArea newParent, boolean onTop) { - reparent(newParent, onTop ? POSITION_TOP : POSITION_BOTTOM); - } - - private void updateSurfaceBounds() { - updateSurfaceSize(getSyncTransaction()); - updateSurfacePosition(); - scheduleAnimation(); - } - - @Override - void getRelativePosition(Point outPos) { - super.getRelativePosition(outPos); - final int outset = getTaskOutset(); - outPos.x -= outset; - outPos.y -= outset; - } - - @Override - void onDisplayChanged(DisplayContent dc) { - super.onDisplayChanged(dc); - if (isRootTask()) { - updateSurfaceBounds(); - } - } - - boolean shouldIgnoreInput() { - if (inSplitScreenPrimaryWindowingMode() && !isFocusable()) { - return true; - } - if (mAtmService.mHasLeanbackFeature && inPinnedWindowingMode() - && !isFocusedStackOnDisplay()) { - // Preventing Picture-in-Picture stack from receiving input on TVs. - return true; - } - return false; - } - - @Override - void dump(PrintWriter pw, String prefix, boolean dumpAll) { - super.dump(pw, prefix, dumpAll); - if (!mExitingActivities.isEmpty()) { - pw.println(); - pw.println(prefix + "Exiting application tokens:"); - final String doublePrefix = prefix + " "; - for (int i = mExitingActivities.size() - 1; i >= 0; i--) { - WindowToken token = mExitingActivities.get(i); - pw.print(doublePrefix + "Exiting App #" + i); - pw.print(' '); pw.print(token); - pw.println(':'); - token.dump(pw, doublePrefix, dumpAll); - } - pw.println(); - } - mAnimatingActivityRegistry.dump(pw, "AnimatingApps:", prefix); - } - - /** - * Sets the current picture-in-picture aspect ratio. - */ - void setPictureInPictureAspectRatio(float aspectRatio) { - if (!mWmService.mAtmService.mSupportsPictureInPicture) { - return; - } - - final DisplayContent displayContent = getDisplayContent(); - if (displayContent == null) { - return; - } - - if (!inPinnedWindowingMode()) { - return; - } - - final PinnedStackController pinnedStackController = - getDisplayContent().getPinnedStackController(); - - if (Float.compare(aspectRatio, pinnedStackController.getAspectRatio()) == 0) { - return; - } - - // Notify the pinned stack controller about aspect ratio change. - // This would result a callback delivered from SystemUI to WM to start animation, - // if the bounds are ought to be altered due to aspect ratio change. - pinnedStackController.setAspectRatio( - pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio) - ? aspectRatio : -1f); - } - - /** - * Sets the current picture-in-picture actions. - */ - void setPictureInPictureActions(List<RemoteAction> actions) { - if (!mWmService.mAtmService.mSupportsPictureInPicture) { - return; - } - - if (!inPinnedWindowingMode()) { - return; - } - - getDisplayContent().getPinnedStackController().setActions(actions); - } - - public boolean isForceScaled() { - return mBoundsAnimating; - } - - /** Returns true if a removal action is still being deferred. */ - boolean handleCompleteDeferredRemoval() { - if (isAnimating(TRANSITION | CHILDREN)) { - return true; - } - - return super.handleCompleteDeferredRemoval(); - } - - public DisplayInfo getDisplayInfo() { - return mDisplayContent.getDisplayInfo(); - } - - AnimatingActivityRegistry getAnimatingActivityRegistry() { - return mAnimatingActivityRegistry; - } - - void executeAppTransition(ActivityOptions options) { - getDisplay().mDisplayContent.executeAppTransition(); - ActivityOptions.abort(options); - } - - boolean shouldSleepActivities() { - final DisplayContent display = getDisplay(); - - // Do not sleep activities in this stack if we're marked as focused and the keyguard - // is in the process of going away. - if (isFocusedStackOnDisplay() - && mStackSupervisor.getKeyguardController().isKeyguardGoingAway()) { - return false; - } - - return display != null ? display.isSleeping() : mAtmService.isSleepingLocked(); - } - - boolean shouldSleepOrShutDownActivities() { - return shouldSleepActivities() || mAtmService.mShuttingDown; - } - - @Override - public void dumpDebug(ProtoOutputStream proto, long fieldId, - @WindowTraceLogLevel int logLevel) { - if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) { - return; - } - - final long token = proto.start(fieldId); - super.dumpDebug(proto, WINDOW_CONTAINER, logLevel); - - proto.write(TaskProto.ID, mTaskId); - proto.write(DISPLAY_ID, getDisplayId()); - proto.write(ROOT_TASK_ID, getRootTaskId()); - - if (mResumedActivity != null) { - mResumedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY); - } - if (realActivity != null) { - proto.write(REAL_ACTIVITY, realActivity.flattenToShortString()); - } - if (origActivity != null) { - proto.write(ORIG_ACTIVITY, origActivity.flattenToShortString()); - } - proto.write(ACTIVITY_TYPE, getActivityType()); - proto.write(RESIZE_MODE, mResizeMode); - proto.write(MIN_WIDTH, mMinWidth); - proto.write(MIN_HEIGHT, mMinHeight); - - proto.write(FILLS_PARENT, matchParentBounds()); - getRawBounds().dumpDebug(proto, BOUNDS); - - if (mLastNonFullscreenBounds != null) { - mLastNonFullscreenBounds.dumpDebug(proto, LAST_NON_FULLSCREEN_BOUNDS); - } - - proto.write(ANIMATING_BOUNDS, mBoundsAnimating); - - if (mSurfaceControl != null) { - proto.write(SURFACE_WIDTH, mSurfaceControl.getWidth()); - proto.write(SURFACE_HEIGHT, mSurfaceControl.getHeight()); - } - - proto.write(CREATED_BY_ORGANIZER, mCreatedByOrganizer); - - proto.end(token); - } -} diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index 8666a9efaeeb..0cd7ffce2ed4 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -46,9 +46,6 @@ import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.TYPE_VIRTUAL; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSED; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSING; -import static com.android.server.wm.ActivityStack.TAG_CLEANUP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_IDLE; @@ -74,11 +71,14 @@ import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_ import static com.android.server.wm.RootWindowContainer.TAG_STATES; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS; +import static com.android.server.wm.Task.ActivityState.PAUSED; +import static com.android.server.wm.Task.ActivityState.PAUSING; import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK; import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE; import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; import static com.android.server.wm.Task.LOCK_TASK_AUTH_WHITELISTED; import static com.android.server.wm.Task.REPARENT_KEEP_STACK_AT_FRONT; +import static com.android.server.wm.Task.TAG_CLEANUP; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowContainer.POSITION_TOP; @@ -380,12 +380,12 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { final ActivityRecord r; final ActivityRecord sourceRecord; final int startFlags; - final ActivityStack stack; + final Task stack; final WindowProcessController callerApp; final NeededUriGrants intentGrants; PendingActivityLaunch(ActivityRecord r, ActivityRecord sourceRecord, - int startFlags, ActivityStack stack, WindowProcessController callerApp, + int startFlags, Task stack, WindowProcessController callerApp, NeededUriGrants intentGrants) { this.r = r; this.sourceRecord = sourceRecord; @@ -493,7 +493,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { } void moveRecentsStackToFront(String reason) { - final ActivityStack recentsStack = mRootWindowContainer.getDefaultTaskDisplayArea() + final Task recentsStack = mRootWindowContainer.getDefaultTaskDisplayArea() .getStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS); if (recentsStack != null) { recentsStack.moveToFront(reason); @@ -729,7 +729,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { } final Task task = r.getTask(); - final ActivityStack stack = task.getStack(); + final Task rootTask = task.getRootTask(); beginDeferResume(); @@ -905,7 +905,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { if (andResume && readyToResume()) { // As part of the process of launching, ActivityThread also performs // a resume. - stack.minimalResumeActivityLocked(r); + rootTask.minimalResumeActivityLocked(r); } else { // This activity is not starting in the resumed state... which should look like we asked // it to pause+stop (but remain visible), and it has done so and reported back the @@ -923,7 +923,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // launching the initial activity (that is, home), so that it can have // a chance to initialize itself while in the background, making the // switch back to it faster and look better. - if (mRootWindowContainer.isTopDisplayFocusedStack(stack)) { + if (mRootWindowContainer.isTopDisplayFocusedStack(rootTask)) { mService.getActivityStartController().startSetupActivity(); } @@ -990,7 +990,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { int requestCode, int callingPid, int callingUid, String callingPackage, @Nullable String callingFeatureId, boolean ignoreTargetSecurity, boolean launchingInTask, WindowProcessController callerApp, ActivityRecord resultRecord, - ActivityStack resultStack) { + Task resultStack) { final boolean isCallerRecents = mService.getRecentTasks() != null && mService.getRecentTasks().isCallerRecents(callingUid); final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid, @@ -1332,7 +1332,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { /** This doesn't just find a task, it also moves the task to front. */ void findTaskToMoveToFront(Task task, int flags, ActivityOptions options, String reason, boolean forceNonResizeable) { - ActivityStack currentStack = task.getStack(); + Task currentStack = task.getRootTask(); if (currentStack == null) { Slog.e(TAG, "findTaskToMoveToFront: can't move task=" + task + " to front. Stack is null"); @@ -1349,7 +1349,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { final Rect bounds = options.getLaunchBounds(); task.setBounds(bounds); - ActivityStack stack = + Task stack = mRootWindowContainer.getLaunchStack(null, options, task, ON_TOP); if (stack != currentStack) { @@ -1388,7 +1388,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { private void moveHomeStackToFrontIfNeeded(int flags, TaskDisplayArea taskDisplayArea, String reason) { - final ActivityStack focusedStack = taskDisplayArea.getFocusedStack(); + final Task focusedStack = taskDisplayArea.getFocusedStack(); if ((taskDisplayArea.getWindowingMode() == WINDOWING_MODE_FULLSCREEN && (flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) @@ -1423,7 +1423,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { mWindowManager.setDockedStackResizing(resizing); } - private void removePinnedStackInSurfaceTransaction(ActivityStack stack) { + private void removePinnedStackInSurfaceTransaction(Task stack) { /** * Workaround: Force-stop all the activities in the pinned stack before we reparent them * to the fullscreen stack. This is to guarantee that when we are removing a stack, @@ -1459,7 +1459,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { } } - private void removeStackInSurfaceTransaction(ActivityStack stack) { + private void removeStackInSurfaceTransaction(Task stack) { if (stack.getWindowingMode() == WINDOWING_MODE_PINNED) { removePinnedStackInSurfaceTransaction(stack); } else { @@ -1479,7 +1479,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { * pinned stack, then its tasks are not explicitly removed when the stack is destroyed, but * instead moved back onto the fullscreen stack. */ - void removeStack(ActivityStack stack) { + void removeStack(Task stack) { mWindowManager.inSurfaceTransaction(() -> removeStackInSurfaceTransaction(stack)); } @@ -1597,7 +1597,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { * @return true if the task has been restored successfully. */ boolean restoreRecentTaskLocked(Task task, ActivityOptions aOptions, boolean onTop) { - final ActivityStack stack = + final Task stack = mRootWindowContainer.getLaunchStack(null, aOptions, task, onTop); final WindowContainer parent = task.getParent(); @@ -1639,8 +1639,8 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { * the various checks on tasks that are going to be reparented from one stack to another. */ // TODO: Look into changing users to this method to DisplayContent.resolveWindowingMode() - ActivityStack getReparentTargetStack(Task task, ActivityStack stack, boolean toTop) { - final ActivityStack prevStack = task.getStack(); + Task getReparentTargetStack(Task task, Task stack, boolean toTop) { + final Task prevStack = task.getRootTask(); final int rootTaskId = stack.mTaskId; final boolean inMultiWindowMode = stack.inMultiWindowMode(); @@ -1769,7 +1769,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // A resumed activity cannot be stopping. remove from list mStoppingActivities.remove(r); - final ActivityStack stack = r.getRootTask(); + final Task stack = r.getRootTask(); if (stack.getDisplayArea().allResumedActivitiesComplete()) { mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); // Make sure activity & window visibility should be identical @@ -1783,15 +1783,15 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // Called when WindowManager has finished animating the launchingBehind activity to the back. private void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) { final Task task = r.getTask(); - final ActivityStack stack = task.getStack(); + final Task rootTask = task.getRootTask(); mRecentTasks.add(task); mService.getTaskChangeNotificationController().notifyTaskStackChanged(); - stack.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); + rootTask.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); // When launching tasks behind, update the last active time of the top task after the new // task has been shown briefly - final ActivityRecord top = stack.getTopNonFinishingActivity(); + final ActivityRecord top = rootTask.getTopNonFinishingActivity(); if (top != null) { top.getTask().touchActiveTime(); } @@ -2028,7 +2028,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { */ void updateTopResumedActivityIfNeeded() { final ActivityRecord prevTopActivity = mTopResumedActivity; - final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack(); + final Task topStack = mRootWindowContainer.getTopDisplayFocusedStack(); if (topStack == null || topStack.mResumedActivity == prevTopActivity) { return; } @@ -2124,13 +2124,13 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { } void handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode, - TaskDisplayArea preferredTaskDisplayArea, ActivityStack actualStack) { + TaskDisplayArea preferredTaskDisplayArea, Task actualStack) { handleNonResizableTaskIfNeeded(task, preferredWindowingMode, preferredTaskDisplayArea, actualStack, false /* forceNonResizable */); } void handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode, - TaskDisplayArea preferredTaskDisplayArea, ActivityStack actualStack, + TaskDisplayArea preferredTaskDisplayArea, Task actualStack, boolean forceNonResizable) { final boolean isSecondaryDisplayPreferred = preferredTaskDisplayArea != null && preferredTaskDisplayArea.getDisplayId() != DEFAULT_DISPLAY; @@ -2186,7 +2186,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // split-screen in split-screen. mService.getTaskChangeNotificationController() .notifyActivityDismissingDockedStack(); - taskDisplayArea.onSplitScreenModeDismissed((ActivityStack) task); + taskDisplayArea.onSplitScreenModeDismissed(task); taskDisplayArea.mDisplayContent.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS, true /* notifyClients */); } @@ -2242,14 +2242,14 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { } } - void scheduleUpdatePictureInPictureModeIfNeeded(Task task, ActivityStack prevStack) { - final ActivityStack stack = task.getStack(); - if ((prevStack == null || (prevStack != stack - && !prevStack.inPinnedWindowingMode() && !stack.inPinnedWindowingMode()))) { + void scheduleUpdatePictureInPictureModeIfNeeded(Task task, Task prevStack) { + final Task rootTask = task.getRootTask(); + if ((prevStack == null || (prevStack != rootTask + && !prevStack.inPinnedWindowingMode() && !rootTask.inPinnedWindowingMode()))) { return; } - scheduleUpdatePictureInPictureModeIfNeeded(task, stack.getRequestedOverrideBounds()); + scheduleUpdatePictureInPictureModeIfNeeded(task, rootTask.getRequestedOverrideBounds()); } private void scheduleUpdatePictureInPictureModeIfNeeded(Task task, Rect targetStackBounds) { @@ -2281,7 +2281,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { final PooledConsumer c = PooledLambda.obtainConsumer( ActivityRecord::updatePictureInPictureMode, PooledLambda.__(ActivityRecord.class), targetStackBounds, forceUpdate); - task.getStack().setBounds(targetStackBounds); + task.getRootTask().setBounds(targetStackBounds); task.forAllActivities(c); c.recycle(); } @@ -2349,7 +2349,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { int uid = 0; synchronized (mService.mGlobalLock) { if (r.attachedToProcess() - && r.isState(ActivityStack.ActivityState.RESTARTING_PROCESS)) { + && r.isState(Task.ActivityState.RESTARTING_PROCESS)) { processName = r.app.mName; uid = r.app.mUid; } @@ -2516,7 +2516,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { mService.getActivityStartController().postStartActivityProcessingForLastStarter( task.getTopNonFinishingActivity(), ActivityManager.START_TASK_TO_FRONT, - task.getStack()); + task.getRootTask()); return ActivityManager.START_TASK_TO_FRONT; } callingPackage = task.mCallingPackage; diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java index 16ca60d1519b..e944faed6494 100644 --- a/services/core/java/com/android/server/wm/ActivityStartController.java +++ b/services/core/java/com/android/server/wm/ActivityStartController.java @@ -164,7 +164,7 @@ public class ActivityStartController { * last starter for an arbitrary task record. Re-evaluate whether we can remove. */ void postStartActivityProcessingForLastStarter(ActivityRecord r, int result, - ActivityStack targetStack) { + Task targetStack) { if (mLastStarter == null) { return; } @@ -190,7 +190,7 @@ public class ActivityStartController { // The home activity will be started later, defer resuming to avoid unneccerary operations // (e.g. start home recursively) when creating home stack. mSupervisor.beginDeferResume(); - final ActivityStack homeStack; + final Task homeStack; try { // Make sure home stack exists on display area. homeStack = taskDisplayArea.getOrCreateRootHomeTask(ON_TOP); diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index a8818b2775e2..751d0c8be24a 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -56,7 +56,6 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Process.INVALID_UID; import static android.view.Display.DEFAULT_DISPLAY; -import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME; import static com.android.server.wm.ActivityStackSupervisor.ON_TOP; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; @@ -76,6 +75,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS import static com.android.server.wm.ActivityTaskManagerService.ANIMATE; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY; +import static com.android.server.wm.Task.ActivityState.RESUMED; import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT; import static com.android.server.wm.WindowContainer.POSITION_TOP; @@ -180,8 +180,8 @@ class ActivityStarter { private ActivityInfo mNewTaskInfo; private Intent mNewTaskIntent; - private ActivityStack mSourceStack; - private ActivityStack mTargetStack; + private Task mSourceStack; + private Task mTargetStack; // The task that the last activity was started into. We currently reset the actual start // activity's task and as a result may not have a reference to the task in all cases private Task mTargetTask; @@ -651,7 +651,7 @@ class ActivityStarter { synchronized (mService.mGlobalLock) { final boolean globalConfigWillChange = mRequest.globalConfig != null && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0; - final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack(); + final Task stack = mRootWindowContainer.getTopDisplayFocusedStack(); if (stack != null) { stack.mConfigWillChange = globalConfigWillChange; } @@ -984,7 +984,7 @@ class ActivityStarter { } } - final ActivityStack resultStack = resultRecord == null + final Task resultStack = resultRecord == null ? null : resultRecord.getRootTask(); if (err != START_SUCCESS) { @@ -1122,7 +1122,7 @@ class ActivityStarter { null /*profilerInfo*/); if (DEBUG_PERMISSIONS_REVIEW) { - final ActivityStack focusedStack = + final Task focusedStack = mRootWindowContainer.getTopDisplayFocusedStack(); Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) + "} from uid " + callingUid + " on display " @@ -1163,7 +1163,7 @@ class ActivityStarter { r.appTimeTracker = sourceRecord.appTimeTracker; } - final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack(); + final Task stack = mRootWindowContainer.getTopDisplayFocusedStack(); // If we are starting an activity that is not from the same uid as the currently resumed // one, check whether app switches are allowed. @@ -1445,7 +1445,7 @@ class ActivityStarter { } void postStartActivityProcessing(ActivityRecord r, int result, - ActivityStack startedActivityStack) { + Task startedActivityStack) { if (!ActivityManager.isStartResultSuccessful(result)) { if (mFrozeTaskList) { // If we specifically froze the task list as part of starting an activity, then @@ -1479,7 +1479,7 @@ class ActivityStarter { // The activity was already running so it wasn't started, but either brought to the // front or the new intent was delivered to it since it was already in front. Notify // anyone interested in this piece of information. - final ActivityStack homeStack = targetTask.getDisplayArea().getRootHomeTask(); + final Task homeStack = targetTask.getDisplayArea().getRootHomeTask(); final boolean homeTaskVisible = homeStack != null && homeStack.shouldBeVisible(null); mService.getTaskChangeNotificationController().notifyActivityRestartAttempt( targetTask.getTaskInfo(), homeTaskVisible, clearedTask, @@ -1514,7 +1514,7 @@ class ActivityStarter { int startFlags, boolean doResume, ActivityOptions options, Task inTask, boolean restrictedBgActivity, NeededUriGrants intentGrants) { int result = START_CANCELED; - final ActivityStack startedActivityStack; + final Task startedActivityStack; try { mService.deferWindowLayout(); Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner"); @@ -1537,9 +1537,9 @@ class ActivityStarter { * * @return the stack where the successful started activity resides. */ - private @Nullable ActivityStack handleStartResult(@NonNull ActivityRecord started, int result) { - final ActivityStack currentStack = started.getRootTask(); - ActivityStack startedActivityStack = currentStack != null ? currentStack : mTargetStack; + private @Nullable Task handleStartResult(@NonNull ActivityRecord started, int result) { + final Task currentStack = started.getRootTask(); + Task startedActivityStack = currentStack != null ? currentStack : mTargetStack; if (ActivityManager.isStartResultSuccessful(result)) { if (startedActivityStack != null) { @@ -1559,7 +1559,7 @@ class ActivityStarter { // If we are not able to proceed, disassociate the activity from the task. Leaving an // activity in an incomplete state can lead to issues, such as performing operations // without a window container. - final ActivityStack stack = mStartActivity.getRootTask(); + final Task stack = mStartActivity.getRootTask(); if (stack != null) { mStartActivity.finishIfPossible("startActivity", true /* oomAdj */); } @@ -1634,7 +1634,7 @@ class ActivityStarter { // If the activity being launched is the same as the one currently at the top, then // we need to check if it should only be launched once. - final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack(); + final Task topStack = mRootWindowContainer.getTopDisplayFocusedStack(); if (topStack != null) { startResult = deliverToCurrentTopIfNeeded(topStack, intentGrants); if (startResult != START_SUCCESS) { @@ -1659,7 +1659,7 @@ class ActivityStarter { } if (!mAvoidMoveToFront && mDoResume) { - mTargetStack.getStack().moveToFront("reuseOrNewTask", targetTask); + mTargetStack.getRootTask().moveToFront("reuseOrNewTask", targetTask); if (mOptions != null) { if (mOptions.getTaskAlwaysOnTop()) { mTargetStack.setAlwaysOnTop(true); @@ -1752,7 +1752,7 @@ class ActivityStarter { } else if (mInTask != null) { return mInTask; } else { - final ActivityStack stack = getLaunchStack(mStartActivity, mLaunchFlags, + final Task stack = getLaunchStack(mStartActivity, mLaunchFlags, null /* task */, mOptions); final ActivityRecord top = stack.getTopNonFinishingActivity(); if (top != null) { @@ -1767,7 +1767,7 @@ class ActivityStarter { private void computeLaunchParams(ActivityRecord r, ActivityRecord sourceRecord, Task targetTask) { - final ActivityStack sourceStack = mSourceStack != null ? mSourceStack + final Task sourceStack = mSourceStack != null ? mSourceStack : mRootWindowContainer.getTopDisplayFocusedStack(); if (sourceStack != null && sourceStack.inSplitScreenWindowingMode() && (mOptions == null @@ -1851,7 +1851,7 @@ class ActivityStarter { // Should not recycle task which is from a different user, just adding the starting // activity to the task. if (targetTask.mUserId != mStartActivity.mUserId) { - mTargetStack = targetTask.getStack(); + mTargetStack = targetTask.getRootTask(); mAddingToTask = true; return START_SUCCESS; } @@ -1949,7 +1949,7 @@ class ActivityStarter { * Check if the activity being launched is the same as the one currently at the top and it * should only be launched once. */ - private int deliverToCurrentTopIfNeeded(ActivityStack topStack, NeededUriGrants intentGrants) { + private int deliverToCurrentTopIfNeeded(Task topStack, NeededUriGrants intentGrants) { final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop); final boolean dontStart = top != null && mStartActivity.resultTo == null && top.mActivityComponent.equals(mStartActivity.mActivityComponent) @@ -2042,7 +2042,7 @@ class ActivityStarter { // running, and the caller has asked to clear the current task to have this // activity at the top. mAddingToTask = true; - if (targetTask.getStack() == null) { + if (targetTask.getRootTask() == null) { // Target stack got cleared when we all activities were removed above. // Go ahead and reset it. mTargetStack = @@ -2262,7 +2262,7 @@ class ActivityStarter { if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { ActivityRecord checkedCaller = sourceRecord; if (checkedCaller == null) { - ActivityStack topFocusedStack = mRootWindowContainer.getTopDisplayFocusedStack(); + Task topFocusedStack = mRootWindowContainer.getTopDisplayFocusedStack(); if (topFocusedStack != null) { checkedCaller = topFocusedStack.topRunningNonDelayedActivityLocked(mNotTop); } @@ -2299,7 +2299,7 @@ class ActivityStarter { private void computeLaunchingTaskFlags() { // If the caller is not coming from another activity, but has given us an explicit task into // which they would like us to launch the new activity, then let's see about doing that. - if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) { + if (mSourceRecord == null && mInTask != null && mInTask.getRootTask() != null) { final Intent baseIntent = mInTask.getBaseIntent(); final ActivityRecord root = mInTask.getRootActivity(); if (baseIntent == null) { @@ -2482,7 +2482,7 @@ class ActivityStarter { // to the front if the caller is not itself in the front. final boolean differentTopTask; if (mTargetStack.getDisplayArea() == mPreferredTaskDisplayArea) { - final ActivityStack focusStack = mTargetStack.getDisplay().getFocusedStack(); + final Task focusStack = mTargetStack.getDisplay().getFocusedStack(); final ActivityRecord curTop = (focusStack == null) ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop); final Task topTask = curTop != null ? curTop.getTask() : null; @@ -2503,7 +2503,7 @@ class ActivityStarter { intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask()); } - final ActivityStack launchStack = + final Task launchStack = getLaunchStack(mStartActivity, mLaunchFlags, intentTask, mOptions); if (launchStack == null || launchStack == mTargetStack) { // Do not set mMovedToFront to true below for split-screen-top stack, or @@ -2616,11 +2616,11 @@ class ActivityStarter { return launchFlags; } - private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, Task task, + private Task getLaunchStack(ActivityRecord r, int launchFlags, Task task, ActivityOptions aOptions) { // We are reusing a task, keep the stack! if (mReuseTask != null) { - return mReuseTask.getStack(); + return mReuseTask.getRootTask(); } final boolean onTop = diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java index d5df9068e81d..a903bcd3d728 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java @@ -125,20 +125,30 @@ public abstract class ActivityTaskManagerInternal { * Sleep tokens cause the activity manager to put the top activity to sleep. * They are used by components such as dreams that may hide and block interaction * with underlying activities. + * The Acquirer provides an interface that encapsulates the underlying work, so the user does + * not need to handle the token by him/herself. */ - public static abstract class SleepToken { + public interface SleepTokenAcquirer { - /** Releases the sleep token. */ - public abstract void release(); + /** + * Acquires a sleep token. + * @param displayId The display to apply to. + */ + void acquire(int displayId); + + /** + * Releases the sleep token. + * @param displayId The display to apply to. + */ + void release(int displayId); } /** - * Acquires a sleep token for the specified display with the specified tag. + * Creates a sleep token acquirer for the specified display with the specified tag. * - * @param tag A string identifying the purpose of the token (eg. "Dream"). - * @param displayId The display to apply the sleep token to. + * @param tag A string identifying the purpose (eg. "Dream"). */ - public abstract SleepToken acquireSleepToken(@NonNull String tag, int displayId); + public abstract SleepTokenAcquirer createSleepTokenAcquirer(@NonNull String tag); /** * Returns home activity for the specified user. diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 4e1d789bebd8..029b5547ae29 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -86,8 +86,6 @@ import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.Scr import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE; import static com.android.server.am.EventLogTags.writeBootProgressEnableScreen; import static com.android.server.am.EventLogTags.writeConfigurationChanged; -import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED; -import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING; import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME; import static com.android.server.wm.ActivityStackSupervisor.ON_TOP; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; @@ -120,6 +118,8 @@ import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_P import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_ONLY; import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS; +import static com.android.server.wm.Task.ActivityState.DESTROYED; +import static com.android.server.wm.Task.ActivityState.DESTROYING; import static com.android.server.wm.Task.LOCK_TASK_AUTH_DONT_LOCK; import static com.android.server.wm.Task.REPARENT_KEEP_STACK_AT_FRONT; import static com.android.server.wm.Task.REPARENT_LEAVE_STACK_IN_PLACE; @@ -1119,7 +1119,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { // If this is coming from the currently resumed activity, it is // effectively saying that app switches are allowed at this point. - final ActivityStack stack = getTopDisplayFocusedStack(); + final Task stack = getTopDisplayFocusedStack(); if (stack != null && stack.mResumedActivity != null && stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { mAppSwitchesAllowedTime = 0; @@ -1868,7 +1868,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { r = ActivityRecord.isInStackLocked(token); if (r != null) { if (r.attachedToProcess() - && r.isState(ActivityStack.ActivityState.RESTARTING_PROCESS)) { + && r.isState(Task.ActivityState.RESTARTING_PROCESS)) { // The activity was requested to restart from // {@link #restartActivityProcessIfVisible}. restartingName = r.app.mName; @@ -1996,7 +1996,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public boolean isTopActivityImmersive() { enforceNotIsolatedCaller("isTopActivityImmersive"); synchronized (mGlobalLock) { - final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); + final Task topFocusedStack = getTopDisplayFocusedStack(); if (topFocusedStack == null) { return false; } @@ -2018,7 +2018,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final long origId = Binder.clearCallingIdentity(); if (self.isState( - ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) { + Task.ActivityState.RESUMED, Task.ActivityState.PAUSING)) { self.getDisplay().mDisplayContent.mAppTransition.overridePendingAppTransition( packageName, enterAnim, exitAnim, null, null); } @@ -2031,7 +2031,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public int getFrontActivityScreenCompatMode() { enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); synchronized (mGlobalLock) { - final ActivityStack stack = getTopDisplayFocusedStack(); + final Task stack = getTopDisplayFocusedStack(); final ActivityRecord r = stack != null ? stack.topRunningActivity() : null; if (r == null) { return ActivityManager.COMPAT_MODE_UNKNOWN; @@ -2046,7 +2046,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { "setFrontActivityScreenCompatMode"); ApplicationInfo ai; synchronized (mGlobalLock) { - final ActivityStack stack = getTopDisplayFocusedStack(); + final Task stack = getTopDisplayFocusedStack(); final ActivityRecord r = stack != null ? stack.topRunningActivity() : null; if (r == null) { Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity"); @@ -2143,7 +2143,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public int getDisplayId(IBinder activityToken) throws RemoteException { synchronized (mGlobalLock) { - final ActivityStack stack = ActivityRecord.getStackLocked(activityToken); + final Task stack = ActivityRecord.getStackLocked(activityToken); if (stack != null) { final int displayId = stack.getDisplayId(); return displayId != INVALID_DISPLAY ? displayId : DEFAULT_DISPLAY; @@ -2158,7 +2158,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { - ActivityStack focusedStack = getTopDisplayFocusedStack(); + Task focusedStack = getTopDisplayFocusedStack(); if (focusedStack != null) { return mRootWindowContainer.getStackInfo(focusedStack.mTaskId); } @@ -2176,7 +2176,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final long callingId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { - final ActivityStack stack = mRootWindowContainer.getStack(stackId); + final Task stack = mRootWindowContainer.getStack(stackId); if (stack == null) { Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId); return; @@ -2393,7 +2393,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { + windowingMode); } - final ActivityStack stack = task.getStack(); + final Task stack = task.getRootTask(); if (toTop) { stack.moveToFront("setTaskWindowingMode", task); } @@ -2453,7 +2453,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { final long origId = Binder.clearCallingIdentity(); try { - final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); + final Task topFocusedStack = getTopDisplayFocusedStack(); if (topFocusedStack != null) { topFocusedStack.unhandledBackLocked(); } @@ -2470,7 +2470,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (r == null) { return; } - ActivityStack stack = r.getRootTask(); + Task stack = r.getRootTask(); final TaskOrganizerController taskOrgController = mWindowOrganizerController.mTaskOrganizerController; if (taskOrgController.handleInterceptBackPressedOnTaskRoot(stack)) { @@ -2727,7 +2727,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public boolean willActivityBeVisible(IBinder token) { synchronized (mGlobalLock) { - ActivityStack stack = ActivityRecord.getStackLocked(token); + Task stack = ActivityRecord.getStackLocked(token); if (stack != null) { return stack.willActivityBeVisible(token); } @@ -2750,7 +2750,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId + " to stackId=" + stackId + " toTop=" + toTop); - final ActivityStack stack = mRootWindowContainer.getStack(stackId); + final Task stack = mRootWindowContainer.getStack(stackId); if (stack == null) { throw new IllegalStateException( "moveTaskToStack: No stack for stackId=" + stackId); @@ -2829,7 +2829,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { void moveTaskToSplitScreenPrimaryTask(Task task, boolean toTop) { final TaskDisplayArea taskDisplayArea = task.getDisplayArea(); - final ActivityStack primarySplitTask = taskDisplayArea.getRootSplitScreenPrimaryTask(); + final Task primarySplitTask = taskDisplayArea.getRootSplitScreenPrimaryTask(); if (primarySplitTask == null) { throw new IllegalStateException("Can't enter split without associated organized task"); } @@ -2841,8 +2841,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { WindowContainerTransaction wct = new WindowContainerTransaction(); // Clear out current windowing mode before reparenting to split taks. wct.setWindowingMode( - task.getStack().mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_UNDEFINED); - wct.reparent(task.getStack().mRemoteToken.toWindowContainerToken(), + task.getRootTask().mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_UNDEFINED); + wct.reparent(task.getRootTask().mRemoteToken.toWindowContainerToken(), primarySplitTask.mRemoteToken.toWindowContainerToken(), toTop); mWindowOrganizerController.applyTransaction(wct); } @@ -2990,7 +2990,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } // When starting lock task mode the stack must be in front and focused - task.getStack().moveToFront("startSystemLockTaskMode"); + task.getRootTask().moveToFront("startSystemLockTaskMode"); startLockTaskModeLocked(task, true /* isSystemCaller */); } } finally { @@ -3025,7 +3025,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return; } - final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack(); + final Task stack = mRootWindowContainer.getTopDisplayFocusedStack(); if (stack == null || task != stack.getTopMostTask()) { throw new IllegalArgumentException("Invalid task, not in foreground"); } @@ -3299,7 +3299,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); } - final ActivityStack stack = r.getRootTask(); + final Task stack = r.getRootTask(); final Task task = stack.getDisplayArea().createStack(stack.getWindowingMode(), stack.getActivityType(), !ON_TOP, ainfo, intent, false /* createdByOrganizer */); @@ -3460,7 +3460,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { final long ident = Binder.clearCallingIdentity(); try { - final ActivityStack stack = mRootWindowContainer.getStack(stackId); + final Task stack = mRootWindowContainer.getStack(stackId); if (stack == null) { Slog.w(TAG, "removeStack: No stack with id=" + stackId); return; @@ -3504,7 +3504,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { + token); } - final ActivityStack stack = r.getRootTask(); + final Task stack = r.getRootTask(); if (stack == null) { throw new IllegalStateException("toggleFreeformWindowingMode: the activity " + "doesn't have a stack"); @@ -3668,7 +3668,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { "enqueueAssistContext()"); synchronized (mGlobalLock) { - final ActivityStack stack = getTopDisplayFocusedStack(); + final Task stack = getTopDisplayFocusedStack(); ActivityRecord activity = stack != null ? stack.getTopNonFinishingActivity() : null; if (activity == null) { Slog.w(TAG, "getAssistContextExtras failed: no top activity"); @@ -3797,7 +3797,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public boolean isAssistDataAllowedOnCurrentActivity() { int userId; synchronized (mGlobalLock) { - final ActivityStack focusedStack = getTopDisplayFocusedStack(); + final Task focusedStack = getTopDisplayFocusedStack(); if (focusedStack == null || focusedStack.isActivityTypeAssistant()) { return false; } @@ -3970,7 +3970,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { + taskId); } - final ActivityStack stack = mRootWindowContainer.getStack(stackId); + final Task stack = mRootWindowContainer.getStack(stackId); if (stack == null) { throw new IllegalArgumentException("positionTaskInStack: no stack for id=" @@ -3983,7 +3983,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // TODO: Have the callers of this API call a separate reparent method if that is // what they intended to do vs. having this method also do reparenting. - if (task.getStack() == stack) { + if (task.getRootTask() == stack) { // Change position in current stack. stack.positionChildAt(task, position); } else { @@ -4089,7 +4089,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final List<RemoteAction> actions = r.pictureInPictureArgs.getActions(); mRootWindowContainer.moveActivityToPinnedStack( r, "enterPictureInPictureMode"); - final ActivityStack stack = r.getRootTask(); + final Task stack = r.getRootTask(); stack.setPictureInPictureAspectRatio(aspectRatio); stack.setPictureInPictureActions(actions); MetricsLoggerWrapper.logPictureInPictureEnter(mContext, @@ -4134,7 +4134,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // If the activity is already in picture-in-picture, update the pinned stack now // if it is not already expanding to fullscreen. Otherwise, the arguments will // be used the next time the activity enters PiP - final ActivityStack stack = r.getRootTask(); + final Task stack = r.getRootTask(); stack.setPictureInPictureAspectRatio( r.pictureInPictureArgs.getAspectRatio()); stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions()); @@ -4798,7 +4798,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - ActivityStack getTopDisplayFocusedStack() { + Task getTopDisplayFocusedStack() { return mRootWindowContainer.getTopDisplayFocusedStack(); } @@ -5070,7 +5070,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final long sleepToken = proto.start(ActivityManagerServiceDumpProcessesProto.SLEEP_STATUS); proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.WAKEFULNESS, PowerManagerInternal.wakefulnessToProtoEnum(wakeFullness)); - for (ActivityTaskManagerInternal.SleepToken st : mRootWindowContainer.mSleepTokens) { + final int tokenSize = mRootWindowContainer.mSleepTokens.size(); + for (int i = 0; i < tokenSize; i++) { + final RootWindowContainer.SleepToken st = + mRootWindowContainer.mSleepTokens.valueAt(i); proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString()); } @@ -5504,12 +5507,35 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { reason); } - ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) { - synchronized (mGlobalLock) { - final ActivityTaskManagerInternal.SleepToken token = - mRootWindowContainer.createSleepToken(tag, displayId); - updateSleepIfNeededLocked(); - return token; + final class SleepTokenAcquirerImpl implements ActivityTaskManagerInternal.SleepTokenAcquirer { + private final String mTag; + private final SparseArray<RootWindowContainer.SleepToken> mSleepTokens = + new SparseArray<>(); + + SleepTokenAcquirerImpl(@NonNull String tag) { + mTag = tag; + } + + @Override + public void acquire(int displayId) { + synchronized (mGlobalLock) { + if (!mSleepTokens.contains(displayId)) { + mSleepTokens.append(displayId, + mRootWindowContainer.createSleepToken(mTag, displayId)); + updateSleepIfNeededLocked(); + } + } + } + + @Override + public void release(int displayId) { + synchronized (mGlobalLock) { + final RootWindowContainer.SleepToken token = mSleepTokens.get(displayId); + if (token != null) { + mRootWindowContainer.removeSleepToken(token); + mSleepTokens.remove(displayId); + } + } } } @@ -5769,7 +5795,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** Applies latest configuration and/or visibility updates if needed. */ boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) { boolean kept = true; - final ActivityStack mainStack = mRootWindowContainer.getTopDisplayFocusedStack(); + final Task mainStack = mRootWindowContainer.getTopDisplayFocusedStack(); // mainStack is null during startup. if (mainStack != null) { if (changes != 0 && starting == null) { @@ -6068,9 +6094,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final class LocalService extends ActivityTaskManagerInternal { @Override - public SleepToken acquireSleepToken(String tag, int displayId) { + public SleepTokenAcquirer createSleepTokenAcquirer(@NonNull String tag) { Objects.requireNonNull(tag); - return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId); + return new SleepTokenAcquirerImpl(tag); } @Override @@ -6820,7 +6846,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { // Clean-up disabled activities. if (mRootWindowContainer.finishDisabledPackageActivities( - packageName, disabledClasses, true, false, userId) && booted) { + packageName, disabledClasses, true /* doit */, false /* evenPersistent */, + userId, false /* onlyRemoveNoProcess */) && booted) { mRootWindowContainer.resumeFocusedStacksTopActivities(); mStackSupervisor.scheduleIdle(); } @@ -6839,7 +6866,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { boolean didSomething = getActivityStartController().clearPendingActivityLaunches(packageName); didSomething |= mRootWindowContainer.finishDisabledPackageActivities(packageName, - null, doit, evenPersistent, userId); + null /* filterByClasses */, doit, evenPersistent, userId, + // Only remove the activities without process because the activities with + // attached process will be removed when handling process died with + // WindowProcessController#isRemoved == true. + true /* onlyRemoveNoProcess */); return didSomething; } } @@ -7024,7 +7055,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mRootWindowContainer.dumpDisplayConfigs(pw, " "); } if (dumpAll) { - final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); + final Task topFocusedStack = getTopDisplayFocusedStack(); if (dumpPackage == null && topFocusedStack != null) { pw.println(" mConfigWillChange: " + topFocusedStack.mConfigWillChange); } @@ -7107,7 +7138,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { if (dumpPackage == null) { getGlobalConfiguration().dumpDebug(proto, GLOBAL_CONFIGURATION); - final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); + final Task topFocusedStack = getTopDisplayFocusedStack(); if (topFocusedStack != null) { proto.write(CONFIG_WILL_CHANGE, topFocusedStack.mConfigWillChange); } diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java index 123fb6c9d8e3..c1447553ba31 100644 --- a/services/core/java/com/android/server/wm/BarController.java +++ b/services/core/java/com/android/server/wm/BarController.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static com.android.server.wm.BarControllerProto.STATE; import static com.android.server.wm.BarControllerProto.TRANSIENT_STATE; +import android.annotation.NonNull; import android.app.StatusBarManager; import android.graphics.Rect; import android.os.Handler; @@ -169,13 +170,23 @@ public class BarController { return vis; } + private Rect getContentFrame(@NonNull WindowState win) { + final Rect rotatedContentFrame = win.mToken.getFixedRotationBarContentFrame(mWindowType); + return rotatedContentFrame != null ? rotatedContentFrame : mContentFrame; + } + + boolean isLightAppearanceAllowed(WindowState win) { + if (win == null) { + return true; + } + return !win.isLetterboxedOverlappingWith(getContentFrame(win)); + } + boolean isTransparentAllowed(WindowState win) { if (win == null) { return true; } - final Rect rotatedContentFrame = win.mToken.getFixedRotationBarContentFrame(mWindowType); - final Rect contentFrame = rotatedContentFrame != null ? rotatedContentFrame : mContentFrame; - return !win.isLetterboxedOverlappingWith(contentFrame); + return win.letterboxNotIntersectsOrFullyContains(getContentFrame(win)); } boolean setBarShowingLw(final boolean show) { diff --git a/services/core/java/com/android/server/wm/CompatModePackages.java b/services/core/java/com/android/server/wm/CompatModePackages.java index 320ca65d215b..167afab9db0e 100644 --- a/services/core/java/com/android/server/wm/CompatModePackages.java +++ b/services/core/java/com/android/server/wm/CompatModePackages.java @@ -22,20 +22,6 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFI import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - -import com.android.internal.util.FastXmlSerializer; - import android.app.ActivityManager; import android.app.AppGlobals; import android.content.pm.ApplicationInfo; @@ -51,6 +37,20 @@ import android.util.Slog; import android.util.SparseArray; import android.util.Xml; +import com.android.internal.util.FastXmlSerializer; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + public final class CompatModePackages { private static final String TAG = TAG_WITH_CLASS_NAME ? "CompatModePackages" : TAG_ATM; private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; @@ -321,7 +321,7 @@ public final class CompatModePackages { scheduleWrite(); - final ActivityStack stack = mService.getTopDisplayFocusedStack(); + final Task stack = mService.getTopDisplayFocusedStack(); ActivityRecord starting = stack.restartPackage(packageName); // Tell all processes that loaded this package about the change. diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java index fbb2fcb15aee..546c5d4c29de 100644 --- a/services/core/java/com/android/server/wm/DisplayArea.java +++ b/services/core/java/com/android/server/wm/DisplayArea.java @@ -93,7 +93,7 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { // Verify that we have proper ordering Type.checkChild(mType, Type.typeOf(child)); - if (child instanceof ActivityStack) { + if (child instanceof Task) { // TODO(display-area): ActivityStacks are type ANY, but are allowed to have siblings. // They might need a separate type. return; @@ -487,7 +487,7 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { return ((DisplayArea) c).mType; } else if (c instanceof WindowToken && !(c instanceof ActivityRecord)) { return typeOf((WindowToken) c); - } else if (c instanceof ActivityStack) { + } else if (c instanceof Task) { return ANY; } else { throw new IllegalArgumentException("Unknown container: " + c); diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java index 59c32045000b..33eb3ce57373 100644 --- a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java @@ -17,12 +17,19 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY; +import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; +import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; +import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER; +import static android.window.DisplayAreaOrganizer.FEATURE_FULLSCREEN_MAGNIFICATION; import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED; import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION; +import static com.android.server.wm.DisplayAreaPolicyBuilder.Feature; +import static com.android.server.wm.DisplayAreaPolicyBuilder.HierarchyBuilder; + import android.content.res.Resources; import android.text.TextUtils; @@ -81,21 +88,27 @@ public abstract class DisplayAreaPolicy { // Define the features that will be supported under the root of the whole logical // display. The policy will build the DisplayArea hierarchy based on this. - DisplayAreaPolicyBuilder.HierarchyBuilder rootHierarchy = - new DisplayAreaPolicyBuilder.HierarchyBuilder(root) - .addFeature(new DisplayAreaPolicyBuilder.Feature.Builder(wmService.mPolicy, - "WindowedMagnification", FEATURE_WINDOWED_MAGNIFICATION) + HierarchyBuilder rootHierarchy = new HierarchyBuilder(root) + .addFeature(new Feature.Builder(wmService.mPolicy, "WindowedMagnification", + FEATURE_WINDOWED_MAGNIFICATION) .upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY) .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY) // Make the DA dimmable so that the magnify window also mirrors the dim // layer .setNewDisplayAreaSupplier(DisplayArea.Dimmable::new) .build()) - .addFeature(new DisplayAreaPolicyBuilder.Feature.Builder(wmService.mPolicy, - "OneHanded", FEATURE_ONE_HANDED) + .addFeature(new Feature.Builder(wmService.mPolicy, "OneHanded", + FEATURE_ONE_HANDED) .all() .except(TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL) .build()) + .addFeature(new Feature.Builder(wmService.mPolicy, "FullscreenMagnification", + FEATURE_FULLSCREEN_MAGNIFICATION) + .all() + .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, TYPE_INPUT_METHOD, + TYPE_INPUT_METHOD_DIALOG, TYPE_MAGNIFICATION_OVERLAY, + TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL) + .build()) .setImeContainer(imeContainer) .setTaskDisplayAreas(tdaList); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 8fff81a1e8c4..127e10a6966b 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -78,7 +78,6 @@ import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_A import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG; 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.ActivityStack.ActivityState.RESUMED; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK; import static com.android.server.wm.DisplayContentProto.APP_TRANSITION; import static com.android.server.wm.DisplayContentProto.CLOSING_APPS; @@ -103,6 +102,7 @@ import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_IME; 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.Task.ActivityState.RESUMED; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowContainerChildProto.DISPLAY_CONTENT; @@ -585,9 +585,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp private IntArray mDisplayAccessUIDs = new IntArray(); /** All tokens used to put activities on this stack to sleep (including mOffToken) */ - final ArrayList<ActivityTaskManagerInternal.SleepToken> mAllSleepTokens = new ArrayList<>(); - /** The token acquired by ActivityStackSupervisor to put stacks on the display to sleep */ - ActivityTaskManagerInternal.SleepToken mOffToken; + final ArrayList<RootWindowContainer.SleepToken> mAllSleepTokens = new ArrayList<>(); + /** The token acquirer to put stacks on the display to sleep */ + private final ActivityTaskManagerInternal.SleepTokenAcquirer mOffTokenAcquirer; private boolean mSleeping; @@ -923,6 +923,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mAtmService = mWmService.mAtmService; mDisplay = display; mDisplayId = display.getDisplayId(); + mOffTokenAcquirer = mRootWindowContainer.mDisplayOffTokenAcquirer; mWallpaperController = new WallpaperController(mWmService, this); display.getDisplayInfo(mDisplayInfo); display.getMetrics(mDisplayMetrics); @@ -2193,13 +2194,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp * activity type. Null is no compatible stack on the display. */ @Nullable - ActivityStack getStack(int windowingMode, int activityType) { + Task getStack(int windowingMode, int activityType) { return getItemFromTaskDisplayAreas(taskDisplayArea -> taskDisplayArea.getStack(windowingMode, activityType)); } @Nullable - ActivityStack getStack(int rootTaskId) { + Task getStack(int rootTaskId) { return getItemFromTaskDisplayAreas(taskDisplayArea -> taskDisplayArea.getStack(rootTaskId)); } @@ -2211,7 +2212,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp @VisibleForTesting @Nullable - ActivityStack getTopStack() { + Task getTopStack() { return getItemFromTaskDisplayAreas(TaskDisplayArea::getTopStack); } @@ -2831,7 +2832,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } proto.write(SINGLE_TASK_INSTANCE, mSingleTaskInstance); - final ActivityStack focusedStack = getFocusedStack(); + final Task focusedStack = getFocusedStack(); if (focusedStack != null) { proto.write(FOCUSED_ROOT_TASK_ID, focusedStack.getRootTaskId()); final ActivityRecord focusedActivity = focusedStack.getDisplayArea() @@ -2956,26 +2957,26 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp pw.println(); // Dump stack references - final ActivityStack homeStack = getDefaultTaskDisplayArea().getRootHomeTask(); + final Task homeStack = getDefaultTaskDisplayArea().getRootHomeTask(); if (homeStack != null) { pw.println(prefix + "homeStack=" + homeStack.getName()); } - final ActivityStack pinnedStack = getDefaultTaskDisplayArea().getRootPinnedTask(); + final Task pinnedStack = getDefaultTaskDisplayArea().getRootPinnedTask(); if (pinnedStack != null) { pw.println(prefix + "pinnedStack=" + pinnedStack.getName()); } - final ActivityStack splitScreenPrimaryStack = getDefaultTaskDisplayArea() + final Task splitScreenPrimaryStack = getDefaultTaskDisplayArea() .getRootSplitScreenPrimaryTask(); if (splitScreenPrimaryStack != null) { pw.println(prefix + "splitScreenPrimaryStack=" + splitScreenPrimaryStack.getName()); } // TODO: Support recents on non-default task containers - final ActivityStack recentsStack = getDefaultTaskDisplayArea().getStack( + final Task recentsStack = getDefaultTaskDisplayArea().getStack( WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS); if (recentsStack != null) { pw.println(prefix + "recentsStack=" + recentsStack.getName()); } - final ActivityStack dreamStack = + final Task dreamStack = getStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_DREAM); if (dreamStack != null) { pw.println(prefix + "dreamStack=" + dreamStack.getName()); @@ -4139,7 +4140,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } private boolean processTask(Task task) { - if (!task.getStack().getWindowConfiguration().canResizeTask()) { + if (!task.getRootTask().getWindowConfiguration().canResizeTask()) { return true; } @@ -4931,11 +4932,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp final int displayId = mDisplay.getDisplayId(); if (displayId != DEFAULT_DISPLAY) { final int displayState = mDisplay.getState(); - if (displayState == Display.STATE_OFF && mOffToken == null) { - mOffToken = mAtmService.acquireSleepToken("Display-off", displayId); - } else if (displayState == Display.STATE_ON && mOffToken != null) { - mOffToken.release(); - mOffToken = null; + if (displayState == Display.STATE_OFF) { + mOffTokenAcquirer.acquire(mDisplayId); + } else if (displayState == Display.STATE_ON) { + mOffTokenAcquirer.release(mDisplayId); } } mWmService.requestTraversal(); @@ -4953,7 +4953,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } @Nullable - ActivityStack getFocusedStack() { + Task getFocusedStack() { return getItemFromTaskDisplayAreas(TaskDisplayArea::getFocusedStack); } @@ -5150,12 +5150,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp void remove() { mRemoving = true; - ActivityStack lastReparentedStack; + Task lastReparentedStack; mRootWindowContainer.mStackSupervisor.beginDeferResume(); try { lastReparentedStack = reduceOnAllTaskDisplayAreas((taskDisplayArea, stack) -> { - final ActivityStack lastReparentedStackFromArea = taskDisplayArea.remove(); + final Task lastReparentedStackFromArea = taskDisplayArea.remove(); if (lastReparentedStackFromArea != null) { return lastReparentedStackFromArea; } @@ -5175,7 +5175,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mDisplayPolicy.release(); if (!mAllSleepTokens.isEmpty()) { - mRootWindowContainer.mSleepTokens.removeAll(mAllSleepTokens); + mAllSleepTokens.forEach(token -> + mRootWindowContainer.mSleepTokens.remove(token.mHashKey)); mAllSleepTokens.clear(); mAtmService.updateSleepIfNeededLocked(); } @@ -5191,7 +5192,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp if (taskDisplayArea.getStackCount() != 1) { return true; } - final ActivityStack stack = taskDisplayArea.getStackAt(0); + final Task stack = taskDisplayArea.getStackAt(0); return !stack.isActivityTypeHome() || stack.hasChild(); }); if (!hasNonEmptyHomeStack) { @@ -5294,7 +5295,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp + this); } if (stackCount > 0) { - final ActivityStack stack = getDefaultTaskDisplayArea().getStackAt(0); + final Task stack = getDefaultTaskDisplayArea().getStackAt(0); if (stack.getChildCount() > 1) { throw new IllegalArgumentException("Display stack already has multiple tasks." + " display=" + this + " stack=" + stack); @@ -5311,7 +5312,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp @VisibleForTesting void removeAllTasks() { - forAllTasks((t) -> { t.getStack().removeChild(t, "removeAllTasks"); }); + forAllTasks((t) -> { t.getRootTask().removeChild(t, "removeAllTasks"); }); } /** diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index e6cf85d6b265..53f16a7241fc 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -102,6 +102,11 @@ import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManagerGlobal.ADD_OKAY; import static android.view.WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_BOTTOM; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_LEFT; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_RIGHT; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_TOP; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_UNKNOWN; import static android.view.WindowManagerPolicyConstants.EXTRA_HDMI_PLUGGED_STATE; import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM; import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT; @@ -314,6 +319,17 @@ public class DisplayPolicy { private int[] mNavigationBarHeightForRotationInCarMode = new int[4]; private int[] mNavigationBarWidthForRotationInCarMode = new int[4]; + // Alternative status bar for when flexible insets mapping is used to place the status bar on + // another side of the screen. + private WindowState mStatusBarAlt = null; + @WindowManagerPolicy.AltBarPosition + private int mStatusBarAltPosition = ALT_BAR_UNKNOWN; + // Alternative navigation bar for when flexible insets mapping is used to place the navigation + // bar elsewhere on the screen. + private WindowState mNavigationBarAlt = null; + @WindowManagerPolicy.AltBarPosition + private int mNavigationBarAltPosition = ALT_BAR_UNKNOWN; + /** See {@link #getNavigationBarFrameHeight} */ private int[] mNavigationBarFrameHeightForRotationDefault = new int[4]; @@ -434,7 +450,7 @@ public class DisplayPolicy { case MSG_REQUEST_TRANSIENT_BARS: synchronized (mLock) { WindowState targetBar = (msg.arg1 == MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS) - ? mStatusBar : mNavigationBar; + ? getStatusBar() : getNavigationBar(); if (targetBar != null) { requestTransientBars(targetBar); } @@ -497,6 +513,7 @@ public class DisplayPolicy { if (mStatusBar != null) { requestTransientBars(mStatusBar); } + checkAltBarSwipeForTransientBars(ALT_BAR_TOP); } } @@ -507,6 +524,7 @@ public class DisplayPolicy { && mNavigationBarPosition == NAV_BAR_BOTTOM) { requestTransientBars(mNavigationBar); } + checkAltBarSwipeForTransientBars(ALT_BAR_BOTTOM); } } @@ -523,6 +541,7 @@ public class DisplayPolicy { excludedRegion)) { requestTransientBars(mNavigationBar); } + checkAltBarSwipeForTransientBars(ALT_BAR_RIGHT); } excludedRegion.recycle(); } @@ -540,6 +559,7 @@ public class DisplayPolicy { excludedRegion)) { requestTransientBars(mNavigationBar); } + checkAltBarSwipeForTransientBars(ALT_BAR_LEFT); } excludedRegion.recycle(); } @@ -641,6 +661,15 @@ public class DisplayPolicy { mHandler.post(mGestureNavigationSettingsObserver::register); } + private void checkAltBarSwipeForTransientBars(@WindowManagerPolicy.AltBarPosition int pos) { + if (mStatusBarAlt != null && mStatusBarAltPosition == pos) { + requestTransientBars(mStatusBarAlt); + } + if (mNavigationBarAlt != null && mNavigationBarAltPosition == pos) { + requestTransientBars(mNavigationBarAlt); + } + } + void systemReady() { mSystemGestures.systemReady(); if (mService.mPointerLocationEnabled) { @@ -902,6 +931,14 @@ public class DisplayPolicy { } break; } + + // Check if alternate bars positions were updated. + if (mStatusBarAlt == win) { + mStatusBarAltPosition = getAltBarPosition(attrs); + } + if (mNavigationBarAlt == win) { + mNavigationBarAltPosition = getAltBarPosition(attrs); + } } /** @@ -946,10 +983,9 @@ public class DisplayPolicy { mContext.enforcePermission( android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid, "DisplayPolicy"); - if (mStatusBar != null) { - if (mStatusBar.isAlive()) { - return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; - } + if ((mStatusBar != null && mStatusBar.isAlive()) + || (mStatusBarAlt != null && mStatusBarAlt.isAlive())) { + return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; } break; case TYPE_NOTIFICATION_SHADE: @@ -966,10 +1002,9 @@ public class DisplayPolicy { mContext.enforcePermission( android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid, "DisplayPolicy"); - if (mNavigationBar != null) { - if (mNavigationBar.isAlive()) { - return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; - } + if ((mNavigationBar != null && mNavigationBar.isAlive()) + || (mNavigationBarAlt != null && mNavigationBarAlt.isAlive())) { + return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; } break; case TYPE_NAVIGATION_BAR_PANEL: @@ -996,6 +1031,23 @@ public class DisplayPolicy { android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid, "DisplayPolicy"); enforceSingleInsetsTypeCorrespondingToWindowType(attrs.providesInsetsTypes); + + for (@InternalInsetsType int insetType : attrs.providesInsetsTypes) { + switch (insetType) { + case ITYPE_STATUS_BAR: + if ((mStatusBar != null && mStatusBar.isAlive()) + || (mStatusBarAlt != null && mStatusBarAlt.isAlive())) { + return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; + } + break; + case ITYPE_NAVIGATION_BAR: + if ((mNavigationBar != null && mNavigationBar.isAlive()) + || (mNavigationBarAlt != null && mNavigationBarAlt.isAlive())) { + return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; + } + break; + } + } } return ADD_OKAY; } @@ -1101,7 +1153,19 @@ public class DisplayPolicy { break; default: if (attrs.providesInsetsTypes != null) { - for (int insetsType : attrs.providesInsetsTypes) { + for (@InternalInsetsType int insetsType : attrs.providesInsetsTypes) { + switch (insetsType) { + case ITYPE_STATUS_BAR: + mStatusBarAlt = win; + mStatusBarController.setWindow(mStatusBarAlt); + mStatusBarAltPosition = getAltBarPosition(attrs); + break; + case ITYPE_NAVIGATION_BAR: + mNavigationBarAlt = win; + mNavigationBarController.setWindow(mNavigationBarAlt); + mNavigationBarAltPosition = getAltBarPosition(attrs); + break; + } mDisplayContent.setInsetProvider(insetsType, win, null); } } @@ -1109,6 +1173,22 @@ public class DisplayPolicy { } } + @WindowManagerPolicy.AltBarPosition + private int getAltBarPosition(WindowManager.LayoutParams params) { + switch (params.gravity) { + case Gravity.LEFT: + return ALT_BAR_LEFT; + case Gravity.RIGHT: + return ALT_BAR_RIGHT; + case Gravity.BOTTOM: + return ALT_BAR_BOTTOM; + case Gravity.TOP: + return ALT_BAR_TOP; + default: + return ALT_BAR_UNKNOWN; + } + } + TriConsumer<DisplayFrames, WindowState, Rect> getImeSourceFrameProvider() { return (displayFrames, windowState, inOutFrame) -> { if (mNavigationBar != null && navigationBarPosition(displayFrames.mDisplayWidth, @@ -1149,12 +1229,14 @@ public class DisplayPolicy { * @param win The window being removed. */ void removeWindowLw(WindowState win) { - if (mStatusBar == win) { + if (mStatusBar == win || mStatusBarAlt == win) { mStatusBar = null; + mStatusBarAlt = null; mStatusBarController.setWindow(null); mDisplayContent.setInsetProvider(ITYPE_STATUS_BAR, null, null); - } else if (mNavigationBar == win) { + } else if (mNavigationBar == win || mNavigationBarAlt == win) { mNavigationBar = null; + mNavigationBarAlt = null; mNavigationBarController.setWindow(null); mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, null, null); } else if (mNotificationShade == win) { @@ -1180,7 +1262,7 @@ public class DisplayPolicy { } WindowState getStatusBar() { - return mStatusBar; + return mStatusBar != null ? mStatusBar : mStatusBarAlt; } WindowState getNotificationShade() { @@ -1188,7 +1270,7 @@ public class DisplayPolicy { } WindowState getNavigationBar() { - return mNavigationBar; + return mNavigationBar != null ? mNavigationBar : mNavigationBarAlt; } /** @@ -1250,6 +1332,46 @@ public class DisplayPolicy { return R.anim.dock_left_enter; } } + } else if (win == mStatusBarAlt || win == mNavigationBarAlt) { + if (win.getAttrs().windowAnimations != 0) { + return ANIMATION_STYLEABLE; + } + + int pos = (win == mStatusBarAlt) ? mStatusBarAltPosition : mNavigationBarAltPosition; + + boolean isExitOrHide = transit == TRANSIT_EXIT || transit == TRANSIT_HIDE; + boolean isEnterOrShow = transit == TRANSIT_ENTER || transit == TRANSIT_SHOW; + + switch (pos) { + case ALT_BAR_LEFT: + if (isExitOrHide) { + return R.anim.dock_left_exit; + } else if (isEnterOrShow) { + return R.anim.dock_left_enter; + } + break; + case ALT_BAR_RIGHT: + if (isExitOrHide) { + return R.anim.dock_right_exit; + } else if (isEnterOrShow) { + return R.anim.dock_right_enter; + } + break; + case ALT_BAR_BOTTOM: + if (isExitOrHide) { + return R.anim.dock_bottom_exit; + } else if (isEnterOrShow) { + return R.anim.dock_bottom_enter; + } + break; + case ALT_BAR_TOP: + if (isExitOrHide) { + return R.anim.dock_top_exit; + } else if (isEnterOrShow) { + return R.anim.dock_top_enter; + } + break; + } } if (transit == TRANSIT_PREVIEW_DONE) { @@ -1608,7 +1730,7 @@ public class DisplayPolicy { mInputConsumer = null; Slog.v(TAG, INPUT_CONSUMER_NAVIGATION + " dismissed."); } - } else if (mInputConsumer == null && mStatusBar != null && canHideNavigationBar()) { + } else if (mInputConsumer == null && getStatusBar() != null && canHideNavigationBar()) { mInputConsumer = mDisplayContent.getInputMonitor().createInputConsumer( mHandler.getLooper(), INPUT_CONSUMER_NAVIGATION, @@ -2698,10 +2820,10 @@ public class DisplayPolicy { mDreamingLockscreen = mService.mPolicy.isKeyguardShowingAndNotOccluded(); } - if (mStatusBar != null) { + if (getStatusBar() != null) { if (DEBUG_LAYOUT) Slog.i(TAG, "force=" + mForceStatusBar + " top=" + mTopFullscreenOpaqueWindowState); - final boolean forceShowStatusBar = (mStatusBar.getAttrs().privateFlags + final boolean forceShowStatusBar = (getStatusBar().getAttrs().privateFlags & PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR) != 0; final boolean notificationShadeForcesShowingNavigation = mNotificationShade != null @@ -3187,6 +3309,16 @@ public class DisplayPolicy { return mNavigationBarPosition; } + @WindowManagerPolicy.AltBarPosition + int getAlternateStatusBarPosition() { + return mStatusBarAltPosition; + } + + @WindowManagerPolicy.AltBarPosition + int getAlternateNavBarPosition() { + return mNavigationBarAltPosition; + } + /** * A new window has been focused. */ @@ -3296,7 +3428,7 @@ public class DisplayPolicy { // keys, we let it keep controlling the visibility. final boolean lastFocusCanReceiveKeys = (mLastFocusedWindow != null && mLastFocusedWindow.canReceiveKeys()); - winCandidate = isKeyguardShowing() ? mNotificationShade + winCandidate = isKeyguardShowing() && !isKeyguardOccluded() ? mNotificationShade : lastFocusCanReceiveKeys ? mLastFocusedWindow : mTopFullscreenOpaqueWindowState; if (winCandidate == null) { @@ -3348,8 +3480,8 @@ public class DisplayPolicy { final boolean isFullscreen = (visibility & (View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)) != 0 || (PolicyControl.getWindowFlags(win, win.mAttrs) & FLAG_FULLSCREEN) != 0 - || (mStatusBar != null && insetsPolicy.isHidden(ITYPE_STATUS_BAR)) - || (mNavigationBar != null && insetsPolicy.isHidden( + || (getStatusBar() != null && insetsPolicy.isHidden(ITYPE_STATUS_BAR)) + || (getNavigationBar() != null && insetsPolicy.isHidden( ITYPE_NAVIGATION_BAR)); final int behavior = win.mAttrs.insetsFlags.behavior; final boolean isImmersive = (visibility & (View.SYSTEM_UI_FLAG_IMMERSIVE @@ -3441,17 +3573,22 @@ public class DisplayPolicy { WindowState opaqueOrDimming) { final boolean onKeyguard = isKeyguardShowing() && !isKeyguardOccluded(); final WindowState statusColorWin = onKeyguard ? mNotificationShade : opaqueOrDimming; - if (statusColorWin != null && (statusColorWin == opaque || onKeyguard)) { - // If the top fullscreen-or-dimming window is also the top fullscreen, respect - // its light flag. - appearance &= ~APPEARANCE_LIGHT_STATUS_BARS; - final int legacyAppearance = InsetsFlags.getAppearance( - PolicyControl.getSystemUiVisibility(statusColorWin, null)); - appearance |= (statusColorWin.mAttrs.insetsFlags.appearance | legacyAppearance) - & APPEARANCE_LIGHT_STATUS_BARS; - } else if (statusColorWin != null && statusColorWin.isDimming()) { - // Otherwise if it's dimming, clear the light flag. - appearance &= ~APPEARANCE_LIGHT_STATUS_BARS; + if (statusColorWin != null) { + if (statusColorWin == opaque || onKeyguard) { + // If the top fullscreen-or-dimming window is also the top fullscreen, respect + // its light flag. + appearance &= ~APPEARANCE_LIGHT_STATUS_BARS; + final int legacyAppearance = InsetsFlags.getAppearance( + PolicyControl.getSystemUiVisibility(statusColorWin, null)); + appearance |= (statusColorWin.mAttrs.insetsFlags.appearance | legacyAppearance) + & APPEARANCE_LIGHT_STATUS_BARS; + } else if (statusColorWin.isDimming()) { + // Otherwise if it's dimming, clear the light flag. + appearance &= ~APPEARANCE_LIGHT_STATUS_BARS; + } + if (!mStatusBarController.isLightAppearanceAllowed(statusColorWin)) { + appearance &= ~APPEARANCE_LIGHT_STATUS_BARS; + } } return appearance; } @@ -3516,8 +3653,7 @@ public class DisplayPolicy { return vis; } - @VisibleForTesting - static int updateLightNavigationBarAppearanceLw(int appearance, WindowState opaque, + private int updateLightNavigationBarAppearanceLw(int appearance, WindowState opaque, WindowState opaqueOrDimming, WindowState imeWindow, WindowState navColorWin) { if (navColorWin != null) { @@ -3530,6 +3666,9 @@ public class DisplayPolicy { // Clear the light flag for dimming window. appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS; } + if (!mNavigationBarController.isLightAppearanceAllowed(navColorWin)) { + appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS; + } } return appearance; } @@ -3604,7 +3743,7 @@ public class DisplayPolicy { final boolean hideNavBarSysui = (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0; - final boolean transientStatusBarAllowed = mStatusBar != null + final boolean transientStatusBarAllowed = getStatusBar() != null && (notificationShadeHasFocus || (!mForceShowSystemBars && (hideStatusBarWM || (hideStatusBarSysui && immersiveSticky)))); @@ -3762,7 +3901,7 @@ public class DisplayPolicy { // TODO(b/118118435): Remove this after migration private boolean isImmersiveMode(int vis) { final int flags = View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; - return mNavigationBar != null + return getNavigationBar() != null && (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0 && (vis & flags) != 0 && canHideNavigationBar(); @@ -3770,7 +3909,7 @@ public class DisplayPolicy { private boolean isImmersiveMode(WindowState win) { final int behavior = win.mAttrs.insetsFlags.behavior; - return mNavigationBar != null + return getNavigationBar() != null && canHideNavigationBar() && (behavior == BEHAVIOR_SHOW_BARS_BY_SWIPE || behavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) @@ -3851,8 +3990,8 @@ public class DisplayPolicy { public void takeScreenshot(int screenshotType, int source) { if (mScreenshotHelper != null) { mScreenshotHelper.takeScreenshot(screenshotType, - mStatusBar != null && mStatusBar.isVisibleLw(), - mNavigationBar != null && mNavigationBar.isVisibleLw(), + getStatusBar() != null && getStatusBar().isVisibleLw(), + getNavigationBar() != null && getNavigationBar().isVisibleLw(), source, mHandler, null /* completionConsumer */); } } @@ -3890,6 +4029,11 @@ public class DisplayPolicy { if (mStatusBar != null) { pw.print(prefix); pw.print("mStatusBar="); pw.print(mStatusBar); } + if (mStatusBarAlt != null) { + pw.print(prefix); pw.print("mStatusBarAlt="); pw.print(mStatusBarAlt); + pw.print(prefix); pw.print("mStatusBarAltPosition="); + pw.println(mStatusBarAltPosition); + } if (mNotificationShade != null) { pw.print(prefix); pw.print("mExpandedPanel="); pw.print(mNotificationShade); } @@ -3901,6 +4045,11 @@ public class DisplayPolicy { pw.print(prefix); pw.print("mNavigationBarPosition="); pw.println(mNavigationBarPosition); } + if (mNavigationBarAlt != null) { + pw.print(prefix); pw.print("mNavigationBarAlt="); pw.println(mNavigationBarAlt); + pw.print(prefix); pw.print("mNavigationBarAltPosition="); + pw.println(mNavigationBarAltPosition); + } if (mFocusedWindow != null) { pw.print(prefix); pw.print("mFocusedWindow="); pw.println(mFocusedWindow); } diff --git a/services/core/java/com/android/server/wm/DragResizeMode.java b/services/core/java/com/android/server/wm/DragResizeMode.java index 71beb5032914..eb27b046b9ab 100644 --- a/services/core/java/com/android/server/wm/DragResizeMode.java +++ b/services/core/java/com/android/server/wm/DragResizeMode.java @@ -35,7 +35,7 @@ class DragResizeMode { */ static final int DRAG_RESIZE_MODE_DOCKED_DIVIDER = 1; - static boolean isModeAllowedForStack(ActivityStack stack, int mode) { + static boolean isModeAllowedForStack(Task stack, int mode) { switch (mode) { case DRAG_RESIZE_MODE_FREEFORM: return stack.getWindowingMode() == WINDOWING_MODE_FREEFORM; diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java index c4e03f5c65f5..c7cba77f6797 100644 --- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java +++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java @@ -18,8 +18,8 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; -import static com.android.server.wm.ActivityStack.TAG_VISIBILITY; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY; +import static com.android.server.wm.Task.TAG_VISIBILITY; import android.annotation.Nullable; import android.util.Slog; @@ -29,7 +29,7 @@ import com.android.internal.util.function.pooled.PooledLambda; /** Helper class to ensure activities are in the right visible state for a container. */ class EnsureActivitiesVisibleHelper { - private final ActivityStack mContiner; + private final Task mContiner; private ActivityRecord mTop; private ActivityRecord mStarting; private boolean mAboveTop; @@ -39,7 +39,7 @@ class EnsureActivitiesVisibleHelper { private boolean mPreserveWindows; private boolean mNotifyClients; - EnsureActivitiesVisibleHelper(ActivityStack container) { + EnsureActivitiesVisibleHelper(Task container) { mContiner = container; } @@ -69,7 +69,7 @@ class EnsureActivitiesVisibleHelper { /** * Ensure visibility with an option to also update the configuration of visible activities. - * @see ActivityStack#ensureActivitiesVisible(ActivityRecord, int, boolean) + * @see Task#ensureActivitiesVisible(ActivityRecord, int, boolean) * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean) * @param starting The top most activity in the task. * The activity is either starting or resuming. diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java index 76f236534b69..c36a75b01293 100644 --- a/services/core/java/com/android/server/wm/KeyguardController.java +++ b/services/core/java/com/android/server/wm/KeyguardController.java @@ -50,7 +50,6 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.server.policy.WindowManagerPolicy; -import com.android.server.wm.ActivityTaskManagerInternal.SleepToken; import java.io.PrintWriter; @@ -74,11 +73,14 @@ class KeyguardController { private final SparseArray<KeyguardDisplayState> mDisplayStates = new SparseArray<>(); private final ActivityTaskManagerService mService; private RootWindowContainer mRootWindowContainer; + private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer; + KeyguardController(ActivityTaskManagerService service, ActivityStackSupervisor stackSupervisor) { mService = service; mStackSupervisor = stackSupervisor; + mSleepTokenAcquirer = mService.new SleepTokenAcquirerImpl("keyguard"); } void setWindowManager(WindowManagerService windowManager) { @@ -412,17 +414,17 @@ class KeyguardController { private void updateKeyguardSleepToken(int displayId) { final KeyguardDisplayState state = getDisplay(displayId); - if (isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken == null) { - state.acquiredSleepToken(); - } else if (!isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken != null) { - state.releaseSleepToken(); + if (isKeyguardUnoccludedOrAodShowing(displayId)) { + state.mSleepTokenAcquirer.acquire(displayId); + } else if (!isKeyguardUnoccludedOrAodShowing(displayId)) { + state.mSleepTokenAcquirer.release(displayId); } } private KeyguardDisplayState getDisplay(int displayId) { KeyguardDisplayState state = mDisplayStates.get(displayId); if (state == null) { - state = new KeyguardDisplayState(mService, displayId); + state = new KeyguardDisplayState(mService, displayId, mSleepTokenAcquirer); mDisplayStates.append(displayId, state); } return state; @@ -443,29 +445,18 @@ class KeyguardController { private ActivityRecord mDismissingKeyguardActivity; private boolean mRequestDismissKeyguard; private final ActivityTaskManagerService mService; - private SleepToken mSleepToken; + private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer; - KeyguardDisplayState(ActivityTaskManagerService service, int displayId) { + KeyguardDisplayState(ActivityTaskManagerService service, int displayId, + ActivityTaskManagerInternal.SleepTokenAcquirer acquirer) { mService = service; mDisplayId = displayId; + mSleepTokenAcquirer = acquirer; } void onRemoved() { mDismissingKeyguardActivity = null; - releaseSleepToken(); - } - - void acquiredSleepToken() { - if (mSleepToken == null) { - mSleepToken = mService.acquireSleepToken("keyguard", mDisplayId); - } - } - - void releaseSleepToken() { - if (mSleepToken != null) { - mSleepToken.release(); - mSleepToken = null; - } + mSleepTokenAcquirer.release(mDisplayId); } void visibilitiesUpdated(KeyguardController controller, DisplayContent display) { @@ -475,7 +466,7 @@ class KeyguardController { mOccluded = false; mDismissingKeyguardActivity = null; - final ActivityStack stack = getStackForControllingOccluding(display); + final Task stack = getStackForControllingOccluding(display); if (stack != null) { final ActivityRecord topDismissing = stack.getTopDismissingKeyguardActivity(); mOccluded = stack.topActivityOccludesKeyguard() || (topDismissing != null @@ -516,10 +507,10 @@ class KeyguardController { * occlusion state. */ @Nullable - private ActivityStack getStackForControllingOccluding(DisplayContent display) { + private Task getStackForControllingOccluding(DisplayContent display) { return display.getItemFromTaskDisplayAreas(taskDisplayArea -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); if (stack != null && stack.isFocusableAndVisible() && !stack.inPinnedWindowingMode()) { return stack; diff --git a/services/core/java/com/android/server/wm/LaunchParamsController.java b/services/core/java/com/android/server/wm/LaunchParamsController.java index 513be7a6becc..56e1187d51da 100644 --- a/services/core/java/com/android/server/wm/LaunchParamsController.java +++ b/services/core/java/com/android/server/wm/LaunchParamsController.java @@ -145,10 +145,10 @@ class LaunchParamsController { } if (mTmpParams.hasWindowingMode() - && mTmpParams.mWindowingMode != task.getStack().getWindowingMode()) { + && mTmpParams.mWindowingMode != task.getRootTask().getWindowingMode()) { final int activityType = activity != null ? activity.getActivityType() : task.getActivityType(); - task.getStack().setWindowingMode(task.getDisplayArea().validateWindowingMode( + task.getRootTask().setWindowingMode(task.getDisplayArea().validateWindowingMode( mTmpParams.mWindowingMode, activity, task, activityType)); } @@ -156,7 +156,7 @@ class LaunchParamsController { return false; } - if (task.getStack().inFreeformWindowingMode()) { + if (task.getRootTask().inFreeformWindowingMode()) { // Only set bounds if it's in freeform mode. task.setBounds(mTmpParams.mBounds); return true; diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java index a685886da032..28dcbcdf3cc7 100644 --- a/services/core/java/com/android/server/wm/Letterbox.java +++ b/services/core/java/com/android/server/wm/Letterbox.java @@ -77,10 +77,10 @@ public class Letterbox { mOuter.set(outer); mInner.set(inner); - mTop.layout(outer.left, outer.top, inner.right, inner.top, surfaceOrigin); - mLeft.layout(outer.left, inner.top, inner.left, outer.bottom, surfaceOrigin); - mBottom.layout(inner.left, inner.bottom, outer.right, outer.bottom, surfaceOrigin); - mRight.layout(inner.right, outer.top, outer.right, inner.bottom, surfaceOrigin); + mTop.layout(outer.left, outer.top, outer.right, inner.top, surfaceOrigin); + mLeft.layout(outer.left, outer.top, inner.left, outer.bottom, surfaceOrigin); + mBottom.layout(outer.left, inner.bottom, outer.right, outer.bottom, surfaceOrigin); + mRight.layout(inner.right, outer.top, outer.right, outer.bottom, surfaceOrigin); } @@ -101,6 +101,31 @@ public class Letterbox { } /** + * Returns {@code true} if the letterbox does not overlap with the bar, or the letterbox can + * fully cover the window frame. + * + * @param rect The area of the window frame. + */ + boolean notIntersectsOrFullyContains(Rect rect) { + int emptyCount = 0; + int noOverlappingCount = 0; + for (LetterboxSurface surface : mSurfaces) { + final Rect surfaceRect = surface.mLayoutFrameGlobal; + if (surfaceRect.isEmpty()) { + // empty letterbox + emptyCount++; + } else if (!Rect.intersects(surfaceRect, rect)) { + // no overlapping + noOverlappingCount++; + } else if (surfaceRect.contains(rect)) { + // overlapping and covered + return true; + } + } + return (emptyCount + noOverlappingCount) == mSurfaces.length; + } + + /** * Returns true if any part of the letterbox overlaps with the given {@code rect}. */ public boolean isOverlappingWith(Rect rect) { diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java index 892ee717e21f..c7a438d527ad 100644 --- a/services/core/java/com/android/server/wm/LockTaskController.java +++ b/services/core/java/com/android/server/wm/LockTaskController.java @@ -151,7 +151,7 @@ public class LockTaskController { * The first task in the list, which started the current LockTask session, is called the root * task. It coincides with the Home task in a typical multi-app kiosk deployment. When there are * more than one locked tasks, the root task can't be finished. Nor can it be moved to the back - * of the stack by {@link ActivityStack#moveTaskToBack(Task)}; + * of the stack by {@link Task#moveTaskToBack(Task)}; * * Calling {@link Activity#stopLockTask()} on the root task will finish all tasks but itself in * this list, and the device will exit LockTask mode. @@ -252,7 +252,7 @@ public class LockTaskController { /** * @return whether the given task can be moved to the back of the stack with - * {@link ActivityStack#moveTaskToBack(Task)} + * {@link Task#moveTaskToBack(Task)} * @see #mLockTaskModeTasks */ boolean canMoveTaskToBack(Task task) { @@ -617,14 +617,14 @@ public class LockTaskController { mSupervisor.findTaskToMoveToFront(task, 0, null, reason, lockTaskModeState != LOCK_TASK_MODE_NONE); mSupervisor.mRootWindowContainer.resumeFocusedStacksTopActivities(); - final ActivityStack stack = task.getStack(); - if (stack != null) { - stack.getDisplay().mDisplayContent.executeAppTransition(); + final Task rootTask = task.getRootTask(); + if (rootTask != null) { + rootTask.getDisplay().mDisplayContent.executeAppTransition(); } } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) { mSupervisor.handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED, mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea(), - task.getStack(), true /* forceNonResizable */); + task.getRootTask(), true /* forceNonResizable */); } } diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index 851b533a550d..ba2c0b6dc0ac 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -215,7 +215,7 @@ class RecentTasks { final RootWindowContainer rac = mService.mRootWindowContainer; final DisplayContent dc = rac.getDisplayContent(displayId).mDisplayContent; if (dc.pointWithinAppWindow(x, y)) { - final ActivityStack stack = mService.getTopDisplayFocusedStack(); + final Task stack = mService.getTopDisplayFocusedStack(); final Task topTask = stack != null ? stack.getTopMostTask() : null; resetFreezeTaskListReordering(topTask); } @@ -323,7 +323,7 @@ class RecentTasks { @VisibleForTesting void resetFreezeTaskListReorderingOnTimeout() { synchronized (mService.mGlobalLock) { - final ActivityStack focusedStack = mService.getTopDisplayFocusedStack(); + final Task focusedStack = mService.getTopDisplayFocusedStack(); final Task topTask = focusedStack != null ? focusedStack.getTopMostTask() : null; resetFreezeTaskListReordering(topTask); } @@ -520,9 +520,9 @@ class RecentTasks { * Kicks off the task persister to write any pending tasks to disk. */ void notifyTaskPersisterLocked(Task task, boolean flush) { - final ActivityStack stack = task != null ? task.getStack() : null; - if (stack != null && stack.isHomeOrRecentsStack()) { - // Never persist the home or recents stack. + final Task rootTask = task != null ? task.getRootTask() : null; + if (rootTask != null && rootTask.isHomeOrRecentsStack()) { + // Never persist the home or recents task. return; } syncPersistentTaskIdsLocked(); @@ -554,8 +554,8 @@ class RecentTasks { } private static boolean shouldPersistTaskLocked(Task task) { - final ActivityStack stack = task.getStack(); - return task.isPersistable && (stack == null || !stack.isHomeOrRecentsStack()); + final Task rootTask = task.getRootTask(); + return task.isPersistable && (rootTask == null || !rootTask.isHomeOrRecentsStack()); } void onSystemReadyLocked() { @@ -975,9 +975,9 @@ class RecentTasks { final Task task = mTasks.get(i); if (TaskPersister.DEBUG) Slog.d(TAG, "LazyTaskWriter: task=" + task + " persistable=" + task.isPersistable); - final ActivityStack stack = task.getStack(); + final Task rootTask = task.getRootTask(); if ((task.isPersistable || task.inRecents) - && (stack == null || !stack.isHomeOrRecentsStack())) { + && (rootTask == null || !rootTask.isHomeOrRecentsStack())) { if (TaskPersister.DEBUG) Slog.d(TAG, "adding to persistentTaskIds task=" + task); persistentTaskIds.add(task.mTaskId); } else { @@ -1325,10 +1325,10 @@ class RecentTasks { return false; case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY: if (DEBUG_RECENTS_TRIM_TASKS) { - Slog.d(TAG, "\ttop=" + task.getStack().getTopMostTask()); + Slog.d(TAG, "\ttop=" + task.getRootTask().getTopMostTask()); } - final ActivityStack stack = task.getStack(); - if (stack != null && stack.getTopMostTask() == task) { + final Task rootTask = task.getRootTask(); + if (rootTask != null && rootTask.getTopMostTask() == task) { // Only the non-top task of the primary split screen mode is visible return false; } @@ -1344,9 +1344,9 @@ class RecentTasks { // Tasks managed by/associated with an ActivityView should be excluded from recents. // singleTaskInstance is set on the VirtualDisplay managed by ActivityView // TODO(b/126185105): Find a different signal to use besides isSingleTaskInstance - final ActivityStack stack = task.getStack(); - if (stack != null) { - DisplayContent display = stack.getDisplay(); + final Task rootTask = task.getRootTask(); + if (rootTask != null) { + DisplayContent display = rootTask.getDisplay(); if (display != null && display.isSingleTaskInstance()) { return false; } @@ -1400,21 +1400,21 @@ class RecentTasks { /** @return whether the given task can be trimmed even if it is outside the visible range. */ protected boolean isTrimmable(Task task) { - final ActivityStack stack = task.getStack(); + final Task rootTask = task.getRootTask(); // No stack for task, just trim it - if (stack == null) { + if (rootTask == null) { return true; } // Ignore tasks from different displays // TODO (b/115289124): No Recents on non-default displays. - if (!stack.isOnHomeDisplay()) { + if (!rootTask.isOnHomeDisplay()) { return false; } - final ActivityStack rootHomeTask = stack.getDisplayArea().getRootHomeTask(); - // Home stack does not exist. Don't trim the task. + final Task rootHomeTask = rootTask.getDisplayArea().getRootHomeTask(); + // Home task does not exist. Don't trim the task. if (rootHomeTask == null) { return false; } diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java index 00272ad57be4..d7b43bc5537d 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimation.java +++ b/services/core/java/com/android/server/wm/RecentsAnimation.java @@ -76,7 +76,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, private ActivityRecord mLaunchedTargetActivity; // The stack to restore the target stack behind when the animation is finished - private ActivityStack mRestoreTargetBehindStack; + private Task mRestoreTargetBehindStack; RecentsAnimation(ActivityTaskManagerService atm, ActivityStackSupervisor stackSupervisor, ActivityStartController activityStartController, WindowManagerService wm, @@ -107,7 +107,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, void preloadRecentsActivity() { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Preload recents with %s", mTargetIntent); - ActivityStack targetStack = mDefaultTaskDisplayArea.getStack(WINDOWING_MODE_UNDEFINED, + Task targetStack = mDefaultTaskDisplayArea.getStack(WINDOWING_MODE_UNDEFINED, mTargetActivityType); ActivityRecord targetActivity = getTargetActivity(targetStack); if (targetActivity != null) { @@ -150,8 +150,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks, // Invisible activity should be stopped. If the recents activity is alive and its doesn't // need to relaunch by current configuration, then it may be already in stopped state. - if (!targetActivity.isState(ActivityStack.ActivityState.STOPPING, - ActivityStack.ActivityState.STOPPED)) { + if (!targetActivity.isState(Task.ActivityState.STOPPING, + Task.ActivityState.STOPPED)) { // Add to stopping instead of stop immediately. So the client has the chance to perform // traversal in non-stopped state (ViewRootImpl.mStopped) that would initialize more // things (e.g. the measure can be done earlier). The actual stop will be performed when @@ -166,7 +166,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "RecentsAnimation#startRecentsActivity"); // If the activity is associated with the recents stack, then try and get that first - ActivityStack targetStack = mDefaultTaskDisplayArea.getStack(WINDOWING_MODE_UNDEFINED, + Task targetStack = mDefaultTaskDisplayArea.getStack(WINDOWING_MODE_UNDEFINED, mTargetActivityType); ActivityRecord targetActivity = getTargetActivity(targetStack); final boolean hasExistingActivity = targetActivity != null; @@ -299,7 +299,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, try { mWindowManager.cleanupRecentsAnimation(reorderMode); - final ActivityStack targetStack = mDefaultTaskDisplayArea.getStack( + final Task targetStack = mDefaultTaskDisplayArea.getStack( WINDOWING_MODE_UNDEFINED, mTargetActivityType); // Prefer to use the original target activity instead of top activity because // we may have moved another task to top (starting 3p launcher). @@ -333,7 +333,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, } if (WM_DEBUG_RECENTS_ANIMATIONS.isLogToAny()) { - final ActivityStack topStack = getTopNonAlwaysOnTopStack(); + final Task topStack = getTopNonAlwaysOnTopStack(); if (topStack != targetStack) { ProtoLog.w(WM_DEBUG_RECENTS_ANIMATIONS, "Expected target stack=%s" @@ -347,7 +347,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, taskDisplayArea.moveStackBehindStack(targetStack, mRestoreTargetBehindStack); if (WM_DEBUG_RECENTS_ANIMATIONS.isLogToAny()) { - final ActivityStack aboveTargetStack = getStackAbove(targetStack); + final Task aboveTargetStack = getStackAbove(targetStack); if (mRestoreTargetBehindStack != null && aboveTargetStack != mRestoreTargetBehindStack) { ProtoLog.w(WM_DEBUG_RECENTS_ANIMATIONS, @@ -411,7 +411,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, } @Override - public void onStackOrderChanged(ActivityStack stack) { + public void onStackOrderChanged(Task stack) { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "onStackOrderChanged(): stack=%s", stack); if (mDefaultTaskDisplayArea.getIndexOf(stack) == -1 || !stack.shouldBeVisible(null)) { // The stack is not visible, so ignore this change @@ -466,9 +466,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks, /** * @return The top stack that is not always-on-top. */ - private ActivityStack getTopNonAlwaysOnTopStack() { + private Task getTopNonAlwaysOnTopStack() { for (int i = mDefaultTaskDisplayArea.getStackCount() - 1; i >= 0; i--) { - final ActivityStack s = mDefaultTaskDisplayArea.getStackAt(i); + final Task s = mDefaultTaskDisplayArea.getStackAt(i); if (s.getWindowConfiguration().isAlwaysOnTop()) { continue; } @@ -481,7 +481,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, * @return the top activity in the {@param targetStack} matching the {@param component}, or just * the top activity of the top task if no task matches the component. */ - private ActivityRecord getTargetActivity(ActivityStack targetStack) { + private ActivityRecord getTargetActivity(Task targetStack) { if (targetStack == null) { return null; } diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 55bca2ee2791..f5bd4cd866a6 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -362,7 +362,7 @@ public class RecentsAnimationController implements DeathRecipient { // TODO(b/153090560): Support Recents on multiple task display areas final ArrayList<Task> visibleTasks = mDisplayContent.getDefaultTaskDisplayArea() .getVisibleTasks(); - final ActivityStack targetStack = mDisplayContent.getDefaultTaskDisplayArea() + final Task targetStack = mDisplayContent.getDefaultTaskDisplayArea() .getStack(WINDOWING_MODE_UNDEFINED, targetActivityType); if (targetStack != null) { final PooledConsumer c = PooledLambda.obtainConsumer((t, outList) -> @@ -406,7 +406,7 @@ public class RecentsAnimationController implements DeathRecipient { } // Save the minimized home height - final ActivityStack rootHomeTask = + final Task rootHomeTask = mDisplayContent.getDefaultTaskDisplayArea().getRootHomeTask(); mMinimizedHomeBounds = rootHomeTask != null ? rootHomeTask.getBounds() : null; diff --git a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java index 32de699eaae9..cc5ed36e0f47 100644 --- a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java +++ b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java @@ -16,10 +16,10 @@ package com.android.server.wm; -import static com.android.server.wm.ActivityStack.TAG_ADD_REMOVE; -import static com.android.server.wm.ActivityStack.TAG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; +import static com.android.server.wm.Task.TAG_ADD_REMOVE; +import static com.android.server.wm.Task.TAG_TASKS; import android.app.ActivityOptions; import android.content.Intent; @@ -37,7 +37,7 @@ import java.util.ArrayList; class ResetTargetTaskHelper { private Task mTask; private Task mTargetTask; - private ActivityStack mTargetStack; + private Task mTargetStack; private ActivityRecord mRoot; private boolean mForceReset; private boolean mCanMoveOptions; @@ -61,7 +61,7 @@ class ResetTargetTaskHelper { mForceReset = forceReset; mTargetTask = targetTask; mTargetTaskFound = false; - mTargetStack = targetTask.getStack(); + mTargetStack = targetTask.getRootTask(); mActivityReparentPosition = -1; final PooledConsumer c = PooledLambda.obtainConsumer( diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index f3e23169fee0..b7ee27e1609e 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -39,15 +39,11 @@ import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE; import static android.view.WindowManager.TRANSIT_NONE; import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY; +import static android.view.WindowManager.TRANSIT_TASK_TO_BACK; import static com.android.server.policy.PhoneWindowManager.SYSTEM_DIALOG_REASON_ASSIST; 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.ActivityStack.ActivityState.FINISHING; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSED; -import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; -import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; -import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME; import static com.android.server.wm.ActivityStackSupervisor.ON_TOP; import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList; @@ -73,6 +69,11 @@ import static com.android.server.wm.RootWindowContainerProto.IS_HOME_RECENTS_COM import static com.android.server.wm.RootWindowContainerProto.KEYGUARD_CONTROLLER; import static com.android.server.wm.RootWindowContainerProto.PENDING_ACTIVITIES; import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER; +import static com.android.server.wm.Task.ActivityState.FINISHING; +import static com.android.server.wm.Task.ActivityState.PAUSED; +import static com.android.server.wm.Task.ActivityState.RESUMED; +import static com.android.server.wm.Task.ActivityState.STOPPED; +import static com.android.server.wm.Task.ActivityState.STOPPING; import static com.android.server.wm.Task.REPARENT_LEAVE_STACK_IN_PLACE; import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; @@ -219,6 +220,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // transaction from the global transaction. private final SurfaceControl.Transaction mDisplayTransaction; + /** The token acquirer to put stacks on the displays to sleep */ + final ActivityTaskManagerInternal.SleepTokenAcquirer mDisplayOffTokenAcquirer; + /** * The modes which affect which tasks are returned when calling * {@link RootWindowContainer#anyTaskForId(int)}. @@ -258,7 +262,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> * They are used by components that may hide and block interaction with underlying * activities. */ - final ArrayList<ActivityTaskManagerInternal.SleepToken> mSleepTokens = new ArrayList<>(); + final SparseArray<SleepToken> mSleepTokens = new SparseArray<>(); /** Set when a power mode launch has started, but not ended. */ private boolean mPowerModeLaunchStarted; @@ -313,7 +317,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> * Returns the top activity in any existing task matching the given Intent in the input * result. Returns null if no such task is found. */ - void process(ActivityRecord target, ActivityStack parent) { + void process(ActivityRecord target, Task parent) { mTarget = target; intent = target.intent; @@ -443,6 +447,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> mService = service.mAtmService; mStackSupervisor = mService.mStackSupervisor; mStackSupervisor.mRootWindowContainer = this; + mDisplayOffTokenAcquirer = mService.new SleepTokenAcquirerImpl("Display-off"); } boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) { @@ -1474,7 +1479,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> boolean fromHomeKey) { // Fallback to top focused display or default display if the displayId is invalid. if (displayId == INVALID_DISPLAY) { - final ActivityStack stack = getTopDisplayFocusedStack(); + final Task stack = getTopDisplayFocusedStack(); displayId = stack != null ? stack.getDisplayId() : DEFAULT_DISPLAY; } @@ -1500,7 +1505,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> boolean allowInstrumenting, boolean fromHomeKey) { // Fallback to top focused display area if the provided one is invalid. if (taskDisplayArea == null) { - final ActivityStack stack = getTopDisplayFocusedStack(); + final Task stack = getTopDisplayFocusedStack(); taskDisplayArea = stack != null ? stack.getDisplayArea() : getDefaultTaskDisplayArea(); } @@ -1817,12 +1822,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent> */ List<IBinder> getTopVisibleActivities() { final ArrayList<IBinder> topActivityTokens = new ArrayList<>(); - final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); + final Task topFocusedStack = getTopDisplayFocusedStack(); // Traverse all displays. forAllTaskDisplayAreas(taskDisplayArea -> { // Traverse all stacks on a display area. for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); // Get top activity from a visible stack and add it to the list. if (stack.shouldBeVisible(null /* starting */)) { final ActivityRecord top = stack.getTopNonFinishingActivity(); @@ -1840,9 +1845,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } @Nullable - ActivityStack getTopDisplayFocusedStack() { + Task getTopDisplayFocusedStack() { for (int i = getChildCount() - 1; i >= 0; --i) { - final ActivityStack focusedStack = getChildAt(i).getFocusedStack(); + final Task focusedStack = getChildAt(i).getFocusedStack(); if (focusedStack != null) { return focusedStack; } @@ -1852,7 +1857,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> @Nullable ActivityRecord getTopResumedActivity() { - final ActivityStack focusedStack = getTopDisplayFocusedStack(); + final Task focusedStack = getTopDisplayFocusedStack(); if (focusedStack == null) { return null; } @@ -1865,7 +1870,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return getItemFromTaskDisplayAreas(TaskDisplayArea::getFocusedActivity); } - boolean isTopDisplayFocusedStack(ActivityStack stack) { + boolean isTopDisplayFocusedStack(Task stack) { return stack != null && stack == getTopDisplayFocusedStack(); } @@ -1878,7 +1883,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // foreground. WindowProcessController fgApp = reduceOnAllTaskDisplayAreas((taskDisplayArea, app) -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); if (isTopDisplayFocusedStack(stack)) { final ActivityRecord resumedActivity = stack.getResumedActivity(); if (resumedActivity != null) { @@ -1906,7 +1911,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> boolean didSomething = false; for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { final DisplayContent display = getChildAt(displayNdx); - final ActivityStack stack = display.getFocusedStack(); + final Task stack = display.getFocusedStack(); if (stack == null) { continue; } @@ -1983,7 +1988,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } boolean switchUser(int userId, UserState uss) { - final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); + final Task topFocusedStack = getTopDisplayFocusedStack(); final int focusStackId = topFocusedStack != null ? topFocusedStack.getRootTaskId() : INVALID_TASK_ID; // We dismiss the docked stack whenever we switch users. @@ -2001,13 +2006,13 @@ class RootWindowContainer extends WindowContainer<DisplayContent> mStackSupervisor.mStartingUsers.add(uss); forAllTaskDisplayAreas(taskDisplayArea -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); stack.switchUser(userId); } }); final int restoreStackId = mUserStackInFront.get(userId); - ActivityStack stack = getStack(restoreStackId); + Task stack = getStack(restoreStackId); if (stack == null) { stack = getDefaultTaskDisplayArea().getOrCreateRootHomeTask(); } @@ -2029,7 +2034,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> * Update the last used stack id for non-current user (current user's last * used stack is the focused stack) */ - void updateUserStack(int userId, ActivityStack stack) { + void updateUserStack(int userId, Task stack) { if (userId != mCurrentUser) { if (stack == null) { stack = getDefaultTaskDisplayArea().getOrCreateRootHomeTask(); @@ -2046,7 +2051,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> * @param onTop Indicates whether container should be place on top or on bottom. */ void moveStackToTaskDisplayArea(int stackId, TaskDisplayArea taskDisplayArea, boolean onTop) { - final ActivityStack stack = getStack(stackId); + final Task stack = getStack(stackId); if (stack == null) { throw new IllegalArgumentException("moveStackToTaskDisplayArea: Unknown stackId=" + stackId); @@ -2095,7 +2100,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } boolean moveTopStackActivityToPinnedStack(int stackId) { - final ActivityStack stack = getStack(stackId); + final Task stack = getStack(stackId); if (stack == null) { throw new IllegalArgumentException( "moveTopStackActivityToPinnedStack: Unknown stackId=" + stackId); @@ -2125,7 +2130,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> try { final Task task = r.getTask(); - final ActivityStack pinnedStack = taskDisplayArea.getRootPinnedTask(); + final Task pinnedStack = taskDisplayArea.getRootPinnedTask(); // This will change the pinned stack's windowing mode to its original mode, ensuring // we only have one stack that is in pinned mode. @@ -2138,9 +2143,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> r.getDisplayContent().prepareAppTransition(TRANSIT_NONE, false); final boolean singleActivity = task.getChildCount() == 1; - final ActivityStack stack; + final Task stack; if (singleActivity) { - stack = (ActivityStack) task; + stack = task; } else { // In the case of multiple activities, we will create a new task for it and then // move the PIP activity into the task. @@ -2156,6 +2161,20 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // On the other hand, ActivityRecord#onParentChanged takes care of setting the // up-to-dated pinned stack information on this newly created stack. r.reparent(stack, MAX_VALUE, reason); + + // In the case of this activity entering PIP due to it being moved to the back, + // the old activity would have a TRANSIT_TASK_TO_BACK transition that needs to be + // ran. But, since its visibility did not change (note how it was STOPPED/not + // visible, and with it now at the back stack, it remains not visible), the logic to + // add the transition is automatically skipped. We then add this activity manually + // to the list of apps being closed, and request its transition to be ran. + final ActivityRecord oldTopActivity = task.getTopMostActivity(); + if (oldTopActivity != null && oldTopActivity.isState(STOPPED) + && task.getDisplayContent().mAppTransition.getAppTransition() + == TRANSIT_TASK_TO_BACK) { + task.getDisplayContent().mClosingApps.add(oldTopActivity); + oldTopActivity.mRequestForceTransition = true; + } } // The intermediate windowing mode to be set on the ActivityRecord later. // This needs to happen before the re-parenting, otherwise we will always set the @@ -2233,13 +2252,13 @@ class RootWindowContainer extends WindowContainer<DisplayContent> * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished. */ int finishTopCrashedActivities(WindowProcessController app, String reason) { - ActivityStack focusedStack = getTopDisplayFocusedStack(); + Task focusedStack = getTopDisplayFocusedStack(); Task finishedTask = reduceOnAllTaskDisplayAreas((taskDisplayArea, task) -> { // It is possible that request to finish activity might also remove its task and // stack, so we need to be careful with indexes in the loop and check child count // every time. for (int stackNdx = 0; stackNdx < taskDisplayArea.getStackCount(); ++stackNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(stackNdx); + final Task stack = taskDisplayArea.getStackAt(stackNdx); final Task t = stack.finishTopCrashedActivityLocked(app, reason); if (stack == focusedStack || task == null) { task = t; @@ -2255,7 +2274,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } boolean resumeFocusedStacksTopActivities( - ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { + Task targetStack, ActivityRecord target, ActivityOptions targetOptions) { if (!mStackSupervisor.readyToResume()) { return false; @@ -2277,7 +2296,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> boolean resumedOnDisplay = display.reduceOnAllTaskDisplayAreas( (taskDisplayArea, resumed) -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); final ActivityRecord topRunningActivity = stack.topRunningActivity(); if (!stack.isFocusableAndVisible() || topRunningActivity == null) { continue; @@ -2307,7 +2326,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // crashed) it's possible that nothing was resumed on a display. Requesting resume // of top activity in focused stack explicitly will make sure that at least home // activity is started and resumed, and no recursion occurs. - final ActivityStack focusedStack = display.getFocusedStack(); + final Task focusedStack = display.getFocusedStack(); if (focusedStack != null) { result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions); } else if (targetStack == null) { @@ -2337,7 +2356,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // Set the sleeping state of the stacks on the display. display.forAllTaskDisplayAreas(taskDisplayArea -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); if (displayShouldSleep) { stack.goToSleepIfPossible(false /* shuttingDown */); } else { @@ -2378,9 +2397,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } } - protected ActivityStack getStack(int stackId) { + protected Task getStack(int stackId) { for (int i = getChildCount() - 1; i >= 0; --i) { - final ActivityStack stack = getChildAt(i).getStack(stackId); + final Task stack = getChildAt(i).getStack(stackId); if (stack != null) { return stack; } @@ -2389,9 +2408,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } /** @see DisplayContent#getStack(int, int) */ - ActivityStack getStack(int windowingMode, int activityType) { + Task getStack(int windowingMode, int activityType) { for (int i = getChildCount() - 1; i >= 0; --i) { - final ActivityStack stack = getChildAt(i).getStack(windowingMode, activityType); + final Task stack = getChildAt(i).getStack(windowingMode, activityType); if (stack != null) { return stack; } @@ -2399,7 +2418,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return null; } - private ActivityStack getStack(int windowingMode, int activityType, + private Task getStack(int windowingMode, int activityType, int displayId) { DisplayContent display = getDisplayContent(displayId); if (display == null) { @@ -2408,7 +2427,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return display.getStack(windowingMode, activityType); } - private ActivityManager.StackInfo getStackInfo(ActivityStack stack) { + private ActivityManager.StackInfo getStackInfo(Task stack) { final TaskDisplayArea taskDisplayArea = stack.getDisplayArea(); ActivityManager.StackInfo info = new ActivityManager.StackInfo(); stack.getBounds(info.bounds); @@ -2454,7 +2473,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } ActivityManager.StackInfo getStackInfo(int stackId) { - ActivityStack stack = getStack(stackId); + Task stack = getStack(stackId); if (stack != null) { return getStackInfo(stack); } @@ -2462,12 +2481,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) { - final ActivityStack stack = getStack(windowingMode, activityType); + final Task stack = getStack(windowingMode, activityType); return (stack != null) ? getStackInfo(stack) : null; } ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType, int displayId) { - final ActivityStack stack = getStack(windowingMode, activityType, displayId); + final Task stack = getStack(windowingMode, activityType, displayId); return (stack != null) ? getStackInfo(stack) : null; } @@ -2477,7 +2496,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> if (displayId == INVALID_DISPLAY) { forAllTaskDisplayAreas(taskDisplayArea -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); list.add(getStackInfo(stack)); } }); @@ -2489,7 +2508,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } display.forAllTaskDisplayAreas(taskDisplayArea -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); list.add(getStackInfo(stack)); } }); @@ -2561,7 +2580,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs); } - ActivityStack findStackBehind(ActivityStack stack) { + Task findStackBehind(Task stack) { final TaskDisplayArea taskDisplayArea = stack.getDisplayArea(); if (taskDisplayArea != null) { for (int i = taskDisplayArea.getStackCount() - 1; i >= 0; i--) { @@ -2604,20 +2623,29 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } } - ActivityTaskManagerInternal.SleepToken createSleepToken(String tag, int displayId) { + SleepToken createSleepToken(String tag, int displayId) { final DisplayContent display = getDisplayContent(displayId); if (display == null) { throw new IllegalArgumentException("Invalid display: " + displayId); } - final SleepTokenImpl token = new SleepTokenImpl(tag, displayId); - mSleepTokens.add(token); - display.mAllSleepTokens.add(token); + final int tokenKey = makeSleepTokenKey(tag, displayId); + SleepToken token = mSleepTokens.get(tokenKey); + if (token == null) { + token = new SleepToken(tag, displayId); + mSleepTokens.put(tokenKey, token); + display.mAllSleepTokens.add(token); + } else { + throw new RuntimeException("Create the same sleep token twice: " + token); + } return token; } - private void removeSleepToken(SleepTokenImpl token) { - mSleepTokens.remove(token); + void removeSleepToken(SleepToken token) { + if (!mSleepTokens.contains(token.mHashKey)) { + Slog.d(TAG, "Remove non-exist sleep token: " + token + " from " + Debug.getCallers(6)); + } + mSleepTokens.remove(token.mHashKey); final DisplayContent display = getDisplayContent(token.mDisplayId); if (display != null) { @@ -2701,7 +2729,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> if (sNdx >= taskDisplayArea.getStackCount()) { continue; } - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); if (allowDelay) { result &= stack.goToSleepIfPossible(shuttingDown); } else { @@ -2772,7 +2800,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return false; } - ActivityStack getLaunchStack(@Nullable ActivityRecord r, + Task getLaunchStack(@Nullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop) { return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */, -1 /* no realCallingPid */, -1 /* no realCallingUid */); @@ -2790,7 +2818,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> * * @return The stack to use for the launch or INVALID_STACK_ID. */ - ActivityStack getLaunchStack(@Nullable ActivityRecord r, + Task getLaunchStack(@Nullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop, @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid, int realCallingUid) { @@ -2816,12 +2844,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent> MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop); options.setLaunchTaskId(taskId); if (task != null) { - return task.getStack(); + return task.getRootTask(); } } final int activityType = resolveActivityType(r, options, candidateTask); - ActivityStack stack = null; + Task stack = null; // Next preference for stack goes to the taskDisplayArea candidate. if (launchParams != null && launchParams.mPreferredTaskDisplayArea != null) { @@ -2843,7 +2871,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> realCallingPid, realCallingUid, r.info); if (canLaunchOnDisplayFromStartRequest || canLaunchOnDisplay(r, tdaDisplayId)) { if (r != null) { - final ActivityStack result = getValidLaunchStackInTaskDisplayArea( + final Task result = getValidLaunchStackInTaskDisplayArea( taskDisplayArea, r, candidateTask, options, launchParams); if (result != null) { return result; @@ -2863,7 +2891,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // mode we want to launch into. TaskDisplayArea container = null; if (candidateTask != null) { - stack = candidateTask.getStack(); + stack = candidateTask.getRootTask(); } if (stack == null && r != null) { stack = r.getRootTask(); @@ -2925,7 +2953,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null. */ @VisibleForTesting - ActivityStack getValidLaunchStackInTaskDisplayArea(@NonNull TaskDisplayArea taskDisplayArea, + Task getValidLaunchStackInTaskDisplayArea(@NonNull TaskDisplayArea taskDisplayArea, @NonNull ActivityRecord r, @Nullable Task candidateTask, @Nullable ActivityOptions options, @Nullable LaunchParamsController.LaunchParams launchParams) { @@ -2941,12 +2969,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final TaskDisplayArea attachedTaskDisplayArea = r.getTask() != null ? r.getTask().getDisplayArea() : r.getDisplayArea(); if (attachedTaskDisplayArea == null || attachedTaskDisplayArea == taskDisplayArea) { - return candidateTask.getStack(); + return candidateTask.getRootTask(); } // Or the candidate task is already a root task that can be reused by reparenting // it to the target display. if (candidateTask.isRootTask()) { - final ActivityStack stack = candidateTask.getStack(); + final Task stack = candidateTask.getRootTask(); stack.reparent(taskDisplayArea, true /* onTop */); return stack; } @@ -2967,7 +2995,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // Return the topmost valid stack on the display. for (int i = taskDisplayArea.getStackCount() - 1; i >= 0; --i) { - final ActivityStack stack = taskDisplayArea.getStackAt(i); + final Task stack = taskDisplayArea.getStackAt(i); if (isValidLaunchStack(stack, r, windowingMode)) { return stack; } @@ -2987,7 +3015,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } // TODO: Can probably be consolidated into getLaunchStack()... - private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode) { + private boolean isValidLaunchStack(Task stack, ActivityRecord r, int windowingMode) { switch (stack.getActivityType()) { case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome(); case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents(); @@ -3035,9 +3063,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> * @param currentFocus The stack that previously had focus. * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next * candidate. - * @return Next focusable {@link ActivityStack}, {@code null} if not found. + * @return Next focusable {@link Task}, {@code null} if not found. */ - ActivityStack getNextFocusableStack(@NonNull ActivityStack currentFocus, + Task getNextFocusableStack(@NonNull Task currentFocus, boolean ignoreCurrent) { // First look for next focusable stack on the same display TaskDisplayArea preferredDisplayArea = currentFocus.getDisplayArea(); @@ -3047,7 +3075,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> preferredDisplayArea = getDisplayContent(currentFocus.mPrevDisplayId) .getDefaultTaskDisplayArea(); } - final ActivityStack preferredFocusableStack = preferredDisplayArea.getNextFocusableStack( + final Task preferredFocusableStack = preferredDisplayArea.getNextFocusableStack( currentFocus, ignoreCurrent); if (preferredFocusableStack != null) { return preferredFocusableStack; @@ -3066,7 +3094,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // We've already checked this one continue; } - final ActivityStack nextFocusableStack = display.getDefaultTaskDisplayArea() + final Task nextFocusableStack = display.getDefaultTaskDisplayArea() .getNextFocusableStack(currentFocus, ignoreCurrent); if (nextFocusableStack != null) { return nextFocusableStack; @@ -3077,9 +3105,15 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } boolean handleAppDied(WindowProcessController app) { + if (app.isRemoved()) { + // The package of the died process should be force-stopped, so make its activities as + // finishing to prevent the process from being started again if the next top (or being + // visible) activity also resides in the same process. + app.makeFinishingForProcessRemoved(); + } return reduceOnAllTaskDisplayAreas((taskDisplayArea, result) -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); result |= stack.handleAppDied(app); } return result; @@ -3114,24 +3148,26 @@ class RootWindowContainer extends WindowContainer<DisplayContent> private boolean mDoit; private boolean mEvenPersistent; private int mUserId; + private boolean mOnlyRemoveNoProcess; private Task mLastTask; private ComponentName mHomeActivity; private void reset(String packageName, Set<String> filterByClasses, - boolean doit, boolean evenPersistent, int userId) { + boolean doit, boolean evenPersistent, int userId, boolean onlyRemoveNoProcess) { mDidSomething = false; mPackageName = packageName; mFilterByClasses = filterByClasses; mDoit = doit; mEvenPersistent = evenPersistent; mUserId = userId; + mOnlyRemoveNoProcess = onlyRemoveNoProcess; mLastTask = null; mHomeActivity = null; } boolean process(String packageName, Set<String> filterByClasses, - boolean doit, boolean evenPersistent, int userId) { - reset(packageName, filterByClasses, doit, evenPersistent, userId); + boolean doit, boolean evenPersistent, int userId, boolean onlyRemoveNoProcess) { + reset(packageName, filterByClasses, doit, evenPersistent, userId, onlyRemoveNoProcess); final PooledFunction f = PooledLambda.obtainFunction( FinishDisabledPackageActivitiesHelper::processActivity, this, @@ -3146,9 +3182,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent> (r.packageName.equals(mPackageName) && (mFilterByClasses == null || mFilterByClasses.contains(r.mActivityComponent.getClassName()))) || (mPackageName == null && r.mUserId == mUserId); + final boolean noProcess = !r.hasProcess(); if ((mUserId == UserHandle.USER_ALL || r.mUserId == mUserId) && (sameComponent || r.getTask() == mLastTask) - && (r.app == null || mEvenPersistent || !r.app.isPersistent())) { + && (noProcess || mEvenPersistent || !r.app.isPersistent())) { if (!mDoit) { if (r.finishing) { // If this activity is just finishing, then it is not @@ -3165,10 +3202,19 @@ class RootWindowContainer extends WindowContainer<DisplayContent> mHomeActivity = r.mActivityComponent; } } - mDidSomething = true; - Slog.i(TAG, " Force finishing activity " + r); + if (mOnlyRemoveNoProcess) { + if (noProcess) { + mDidSomething = true; + Slog.i(TAG, " Force removing " + r); + r.cleanUp(false /* cleanServices */, false /* setState */); + r.removeFromHistory("force-stop"); + } + } else { + mDidSomething = true; + Slog.i(TAG, " Force finishing " + r); + r.finishIfPossible("force-stop", true /* oomAdj */); + } mLastTask = r.getTask(); - r.finishIfPossible("force-stop", true); } return false; @@ -3177,9 +3223,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> /** @return true if some activity was finished (or would have finished if doit were true). */ boolean finishDisabledPackageActivities(String packageName, Set<String> filterByClasses, - boolean doit, boolean evenPersistent, int userId) { + boolean doit, boolean evenPersistent, int userId, boolean onlyRemoveNoProcess) { return mFinishDisabledPackageActivitiesHelper.process(packageName, filterByClasses, doit, - evenPersistent, userId); + evenPersistent, userId, onlyRemoveNoProcess); } void updateActivityApplicationInfo(ApplicationInfo aInfo) { @@ -3203,7 +3249,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> forAllTaskDisplayAreas(taskDisplayArea -> { final int numStacks = taskDisplayArea.getStackCount(); for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(stackNdx); + final Task stack = taskDisplayArea.getStackAt(stackNdx); stack.finishVoiceTask(session); } }); @@ -3246,7 +3292,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // If the focused stack is not null or not empty, there should have some activities // resuming or resumed. Make sure these activities are idle. - final ActivityStack stack = display.getFocusedStack(); + final Task stack = display.getFocusedStack(); if (stack == null || !stack.hasActivity()) { continue; } @@ -3269,7 +3315,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final boolean foundInvisibleResumedActivity = forAllTaskDisplayAreas( taskDisplayArea -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); final ActivityRecord r = stack.getResumedActivity(); if (r != null) { if (!r.nowVisible) { @@ -3291,7 +3337,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final boolean hasActivityNotCompleted = forAllTaskDisplayAreas( taskDisplayArea -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); final ActivityRecord r = stack.mPausingActivity; if (r != null && !r.isState(PAUSED, STOPPED, STOPPING, FINISHING)) { if (DEBUG_STATES) { @@ -3397,9 +3443,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> if (aOptions != null) { // Resolve the stack the task should be placed in now based on options // and reparent if needed. - final ActivityStack launchStack = + final Task launchStack = getLaunchStack(null, aOptions, task, onTop); - if (launchStack != null && task.getStack() != launchStack) { + if (launchStack != null && task.getRootTask() != launchStack) { final int reparentMode = onTop ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE; task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME, @@ -3511,7 +3557,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) { if (dumpFocusedStackOnly) { - final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); + final Task topFocusedStack = getTopDisplayFocusedStack(); if (topFocusedStack != null) { return topFocusedStack.getDumpActivitiesLocked(name); } else { @@ -3521,7 +3567,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> ArrayList<ActivityRecord> activities = new ArrayList<>(); forAllTaskDisplayAreas(taskDisplayArea -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) { activities.addAll(stack.getDumpActivitiesLocked(name)); } @@ -3570,7 +3616,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> pw.println(" (activities from top to bottom):"); displayContent.forAllTaskDisplayAreas(taskDisplayArea -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); if (needSep[0]) { pw.println(); } @@ -3598,22 +3644,22 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return printed[0]; } - private final class SleepTokenImpl extends ActivityTaskManagerInternal.SleepToken { + private static int makeSleepTokenKey(String tag, int displayId) { + final String tokenKey = tag + displayId; + return tokenKey.hashCode(); + } + + static final class SleepToken { private final String mTag; private final long mAcquireTime; private final int mDisplayId; + final int mHashKey; - public SleepTokenImpl(String tag, int displayId) { + SleepToken(String tag, int displayId) { mTag = tag; mDisplayId = displayId; mAcquireTime = SystemClock.uptimeMillis(); - } - - @Override - public void release() { - synchronized (mService.mGlobalLock) { - removeSleepToken(this); - } + mHashKey = makeSleepTokenKey(mTag, mDisplayId); } @Override diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java index 3509ba72d058..6cf9432089b4 100644 --- a/services/core/java/com/android/server/wm/RunningTasks.java +++ b/services/core/java/com/android/server/wm/RunningTasks.java @@ -48,7 +48,7 @@ class RunningTasks { private ArraySet<Integer> mProfileIds; private boolean mAllowed; private boolean mFilterOnlyVisibleRecents; - private ActivityStack mTopDisplayFocusStack; + private Task mTopDisplayFocusStack; private RecentTasks mRecentTasks; void getTasks(int maxNum, List<RunningTaskInfo> list, boolean filterOnlyVisibleRecents, @@ -114,7 +114,7 @@ class RunningTasks { return; } - final ActivityStack stack = task.getStack(); + final Task stack = task.getRootTask(); if (stack == mTopDisplayFocusStack && stack.getTopMostTask() == task) { // For the focused stack top task, update the last stack active time so that it can be // used to determine the order of the tasks (it may not be set for newly created tasks) diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 970520aff81f..49fafbb3907c 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED; import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION; +import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN; import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; @@ -28,6 +29,7 @@ import static android.app.WindowConfiguration.PINNED_WINDOWING_MODE_ELEVATION_IN import static android.app.WindowConfiguration.ROTATION_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; @@ -37,7 +39,10 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; +import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT; import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY; +import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING; +import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED; @@ -55,36 +60,91 @@ import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.provider.Settings.Secure.USER_SETUP_COMPLETE; +import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD; import static android.view.Display.INVALID_DISPLAY; import static android.view.SurfaceControl.METADATA_TASK_ID; +import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE; +import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN; +import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE; +import static android.view.WindowManager.TRANSIT_NONE; +import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY; import static android.view.WindowManager.TRANSIT_TASK_CHANGE_WINDOWING_MODE; +import static android.view.WindowManager.TRANSIT_TASK_CLOSE; +import static android.view.WindowManager.TRANSIT_TASK_OPEN; +import static android.view.WindowManager.TRANSIT_TASK_OPEN_BEHIND; +import static android.view.WindowManager.TRANSIT_TASK_TO_BACK; +import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; import static com.android.internal.policy.DecorView.DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP; import static com.android.internal.policy.DecorView.DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP; import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN; -import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; -import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_INVISIBLE; -import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE; -import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT; +import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME; import static com.android.server.wm.ActivityStackSupervisor.ON_TOP; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS; +import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList; +import static com.android.server.wm.ActivityStackSupervisor.printThisActivity; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_APP; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_APP; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CLEANUP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TRANSITION; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY; 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.ActivityTaskManagerService.TAG_STACK; +import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_ACTIVITY_STACK_MSG; +import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE; +import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE; 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_RECENTS_ANIMATIONS; +import static com.android.server.wm.Task.ActivityState.PAUSED; +import static com.android.server.wm.Task.ActivityState.PAUSING; +import static com.android.server.wm.Task.ActivityState.RESUMED; +import static com.android.server.wm.Task.ActivityState.STARTED; +import static com.android.server.wm.Task.ActivityState.STOPPED; +import static com.android.server.wm.Task.ActivityState.STOPPING; +import static com.android.server.wm.TaskProto.ACTIVITY_TYPE; +import static com.android.server.wm.TaskProto.ANIMATING_BOUNDS; +import static com.android.server.wm.TaskProto.BOUNDS; +import static com.android.server.wm.TaskProto.CREATED_BY_ORGANIZER; +import static com.android.server.wm.TaskProto.DISPLAY_ID; +import static com.android.server.wm.TaskProto.FILLS_PARENT; +import static com.android.server.wm.TaskProto.LAST_NON_FULLSCREEN_BOUNDS; +import static com.android.server.wm.TaskProto.MIN_HEIGHT; +import static com.android.server.wm.TaskProto.MIN_WIDTH; +import static com.android.server.wm.TaskProto.ORIG_ACTIVITY; +import static com.android.server.wm.TaskProto.REAL_ACTIVITY; +import static com.android.server.wm.TaskProto.RESIZE_MODE; +import static com.android.server.wm.TaskProto.RESUMED_ACTIVITY; +import static com.android.server.wm.TaskProto.ROOT_TASK_ID; +import static com.android.server.wm.TaskProto.SURFACE_HEIGHT; +import static com.android.server.wm.TaskProto.SURFACE_WIDTH; +import static com.android.server.wm.TaskProto.WINDOW_CONTAINER; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowContainerChildProto.TASK; @@ -103,11 +163,20 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.TaskDescription; import android.app.ActivityManager.TaskSnapshot; +import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.app.AppGlobals; +import android.app.IActivityController; +import android.app.RemoteAction; +import android.app.ResultInfo; import android.app.TaskInfo; import android.app.WindowConfiguration; +import android.app.servertransaction.ActivityResultItem; +import android.app.servertransaction.ClientTransaction; +import android.app.servertransaction.NewIntentItem; +import android.app.servertransaction.PauseActivityItem; +import android.app.servertransaction.ResumeActivityItem; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -117,8 +186,12 @@ import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; +import android.os.Binder; import android.os.Debug; +import android.os.Handler; import android.os.IBinder; +import android.os.Looper; +import android.os.Message; import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; @@ -127,8 +200,10 @@ import android.provider.Settings; import android.service.voice.IVoiceInteractionSession; import android.util.ArraySet; import android.util.DisplayMetrics; +import android.util.Log; import android.util.Slog; import android.util.proto.ProtoOutputStream; +import android.view.Display; import android.view.DisplayInfo; import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationTarget; @@ -137,36 +212,54 @@ import android.view.SurfaceControl; import android.view.WindowManager; import android.window.ITaskOrganizer; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IVoiceInteractor; +import com.android.internal.os.logging.MetricsLoggerWrapper; import com.android.internal.util.XmlUtils; import com.android.internal.util.function.pooled.PooledConsumer; import com.android.internal.util.function.pooled.PooledFunction; import com.android.internal.util.function.pooled.PooledLambda; import com.android.internal.util.function.pooled.PooledPredicate; +import com.android.server.Watchdog; +import com.android.server.am.ActivityManagerService; +import com.android.server.am.AppTimeTracker; import com.android.server.protolog.common.ProtoLog; -import com.android.server.wm.ActivityStack.ActivityState; +import com.android.server.uri.NeededUriGrants; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.List; import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; class Task extends WindowContainer<WindowContainer> { private static final String TAG = TAG_WITH_CLASS_NAME ? "Task" : TAG_ATM; - private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE; + static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE; private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; - private static final String TAG_TASKS = TAG + POSTFIX_TASKS; + static final String TAG_TASKS = TAG + POSTFIX_TASKS; + private static final String TAG_APP = TAG + POSTFIX_APP; + static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP; + private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE; + private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS; + private static final String TAG_STACK = TAG + POSTFIX_STACK; + private static final String TAG_STATES = TAG + POSTFIX_STATES; + private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH; + private static final String TAG_TRANSITION = TAG + POSTFIX_TRANSITION; + private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING; + static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY; private static final String ATTR_TASKID = "task_id"; private static final String TAG_INTENT = "intent"; @@ -202,6 +295,14 @@ class Task extends WindowContainer<WindowContainer> { private static final String ATTR_PERSIST_TASK_VERSION = "persist_task_version"; private static final String ATTR_WINDOW_LAYOUT_AFFINITY = "window_layout_affinity"; + // Set to false to disable the preview that is shown while a new activity + // is being started. + private static final boolean SHOW_APP_STARTING_PREVIEW = true; + + // How long to wait for all background Activities to redraw following a call to + // convertToTranslucent(). + private static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000; + // Current version of the task record we persist. Used to check if we need to run any upgrade // code. static final int PERSIST_TASK_VERSION = 1; @@ -226,6 +327,58 @@ class Task extends WindowContainer<WindowContainer> { // Do not move the stack as a part of reparenting static final int REPARENT_LEAVE_STACK_IN_PLACE = 2; + @IntDef(prefix = {"STACK_VISIBILITY"}, value = { + STACK_VISIBILITY_VISIBLE, + STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT, + STACK_VISIBILITY_INVISIBLE, + }) + @interface StackVisibility {} + + /** Stack is visible. No other stacks on top that fully or partially occlude it. */ + static final int STACK_VISIBILITY_VISIBLE = 0; + + /** Stack is partially occluded by other translucent stack(s) on top of it. */ + static final int STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT = 1; + + /** Stack is completely invisible. */ + static final int STACK_VISIBILITY_INVISIBLE = 2; + + enum ActivityState { + INITIALIZING, + STARTED, + RESUMED, + PAUSING, + PAUSED, + STOPPING, + STOPPED, + FINISHING, + DESTROYING, + DESTROYED, + RESTARTING_PROCESS + } + + // The topmost Activity passed to convertToTranslucent(). When non-null it means we are + // waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they + // are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the + // Activity in mTranslucentActivityWaiting is notified via + // Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last + // background activity being drawn then the same call will be made with a true value. + ActivityRecord mTranslucentActivityWaiting = null; + ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent = new ArrayList<>(); + + /** + * Set when we know we are going to be calling updateConfiguration() + * soon, so want to skip intermediate config checks. + */ + boolean mConfigWillChange; + + /** + * Used to keep resumeTopActivityUncheckedLocked() from being entered recursively + */ + boolean mInResumeTopActivity = false; + + int mCurrentUser; + String affinity; // The affinity name for this task, or null; may change identity. String rootAffinity; // Initial base affinity, or null; does not change from initial root. String mWindowLayoutAffinity; // Launch param affinity of this task or null. Used when saving @@ -447,6 +600,268 @@ class Task extends WindowContainer<WindowContainer> { SurfaceControl.Transaction mMainWindowSizeChangeTransaction; Task mMainWindowSizeChangeTask; + // If this is true, we are in the bounds animating mode. The task will be down or upscaled to + // perfectly fit the region it would have been cropped to. We may also avoid certain logic we + // would otherwise apply while resizing, while resizing in the bounds animating mode. + private boolean mBoundsAnimating = false; + // Set when an animation has been requested but has not yet started from the UI thread. This is + // cleared when the animation actually starts. + private boolean mBoundsAnimatingRequested = false; + private Rect mBoundsAnimationTarget = new Rect(); + private Rect mBoundsAnimationSourceHintBounds = new Rect(); + + Rect mPreAnimationBounds = new Rect(); + + private final AnimatingActivityRegistry mAnimatingActivityRegistry = + new AnimatingActivityRegistry(); + + private boolean mTopActivityOccludesKeyguard; + private ActivityRecord mTopDismissingKeyguardActivity; + + private static final int TRANSLUCENT_TIMEOUT_MSG = FIRST_ACTIVITY_STACK_MSG + 1; + + private final Handler mHandler; + + private class ActivityStackHandler extends Handler { + + ActivityStackHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case TRANSLUCENT_TIMEOUT_MSG: { + synchronized (mAtmService.mGlobalLock) { + notifyActivityDrawnLocked(null); + } + } break; + } + } + } + + private static final ResetTargetTaskHelper sResetTargetTaskHelper = new ResetTargetTaskHelper(); + private final EnsureActivitiesVisibleHelper mEnsureActivitiesVisibleHelper = + new EnsureActivitiesVisibleHelper(this); + private final EnsureVisibleActivitiesConfigHelper mEnsureVisibleActivitiesConfigHelper = + new EnsureVisibleActivitiesConfigHelper(); + private class EnsureVisibleActivitiesConfigHelper { + private boolean mUpdateConfig; + private boolean mPreserveWindow; + private boolean mBehindFullscreen; + + void reset(boolean preserveWindow) { + mPreserveWindow = preserveWindow; + mUpdateConfig = false; + mBehindFullscreen = false; + } + + void process(ActivityRecord start, boolean preserveWindow) { + if (start == null || !start.mVisibleRequested) { + return; + } + reset(preserveWindow); + + final PooledFunction f = PooledLambda.obtainFunction( + EnsureVisibleActivitiesConfigHelper::processActivity, this, + PooledLambda.__(ActivityRecord.class)); + forAllActivities(f, start, true /*includeBoundary*/, true /*traverseTopToBottom*/); + f.recycle(); + + if (mUpdateConfig) { + // Ensure the resumed state of the focus activity if we updated the configuration of + // any activity. + mRootWindowContainer.resumeFocusedStacksTopActivities(); + } + } + + boolean processActivity(ActivityRecord r) { + mUpdateConfig |= r.ensureActivityConfiguration(0 /*globalChanges*/, mPreserveWindow); + mBehindFullscreen |= r.occludesParent(); + return mBehindFullscreen; + } + } + + private final CheckBehindFullscreenActivityHelper mCheckBehindFullscreenActivityHelper = + new CheckBehindFullscreenActivityHelper(); + private class CheckBehindFullscreenActivityHelper { + private boolean mAboveTop; + private boolean mBehindFullscreenActivity; + private ActivityRecord mToCheck; + private Consumer<ActivityRecord> mHandleBehindFullscreenActivity; + private boolean mHandlingOccluded; + + private void reset(ActivityRecord toCheck, + Consumer<ActivityRecord> handleBehindFullscreenActivity) { + mToCheck = toCheck; + mHandleBehindFullscreenActivity = handleBehindFullscreenActivity; + mAboveTop = true; + mBehindFullscreenActivity = false; + + if (!shouldBeVisible(null)) { + // The stack is not visible, so no activity in it should be displaying a starting + // window. Mark all activities below top and behind fullscreen. + mAboveTop = false; + mBehindFullscreenActivity = true; + } + + mHandlingOccluded = mToCheck == null && mHandleBehindFullscreenActivity != null; + } + + boolean process(ActivityRecord toCheck, + Consumer<ActivityRecord> handleBehindFullscreenActivity) { + reset(toCheck, handleBehindFullscreenActivity); + + if (!mHandlingOccluded && mBehindFullscreenActivity) { + return true; + } + + final ActivityRecord topActivity = topRunningActivity(); + final PooledFunction f = PooledLambda.obtainFunction( + CheckBehindFullscreenActivityHelper::processActivity, this, + PooledLambda.__(ActivityRecord.class), topActivity); + forAllActivities(f); + f.recycle(); + + return mBehindFullscreenActivity; + } + + /** Returns {@code true} to stop the outer loop and indicate the result is computed. */ + private boolean processActivity(ActivityRecord r, ActivityRecord topActivity) { + if (mAboveTop) { + if (r == topActivity) { + if (r == mToCheck) { + // It is the top activity in a visible stack. + mBehindFullscreenActivity = false; + return true; + } + mAboveTop = false; + } + mBehindFullscreenActivity |= r.occludesParent(); + return false; + } + + if (mHandlingOccluded) { + // Iterating through all occluded activities. + if (mBehindFullscreenActivity) { + mHandleBehindFullscreenActivity.accept(r); + } + } else if (r == mToCheck) { + return true; + } else if (mBehindFullscreenActivity) { + // It is occluded before {@param toCheck} is found. + return true; + } + mBehindFullscreenActivity |= r.occludesParent(); + return false; + } + } + + // TODO: Can we just loop through WindowProcessController#mActivities instead of doing this? + private final RemoveHistoryRecordsForApp mRemoveHistoryRecordsForApp = + new RemoveHistoryRecordsForApp(); + private class RemoveHistoryRecordsForApp { + private boolean mHasVisibleActivities; + private boolean mIsProcessRemoved; + private WindowProcessController mApp; + private ArrayList<ActivityRecord> mToRemove = new ArrayList<>(); + + boolean process(WindowProcessController app) { + mToRemove.clear(); + mHasVisibleActivities = false; + mApp = app; + mIsProcessRemoved = app.isRemoved(); + + final PooledConsumer c = PooledLambda.obtainConsumer( + RemoveHistoryRecordsForApp::addActivityToRemove, this, + PooledLambda.__(ActivityRecord.class)); + forAllActivities(c); + c.recycle(); + + while (!mToRemove.isEmpty()) { + processActivity(mToRemove.remove(0)); + } + + mApp = null; + return mHasVisibleActivities; + } + + private void addActivityToRemove(ActivityRecord r) { + if (r.app == mApp) { + mToRemove.add(r); + } + } + + private void processActivity(ActivityRecord r) { + if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record " + r + ": app=" + r.app); + + if (r.app != mApp) { + return; + } + if (r.isVisible() || r.mVisibleRequested) { + // While an activity launches a new activity, it's possible that the old + // activity is already requested to be hidden (mVisibleRequested=false), but + // this visibility is not yet committed, so isVisible()=true. + mHasVisibleActivities = true; + } + final boolean remove; + if ((r.mRelaunchReason == RELAUNCH_REASON_WINDOWING_MODE_RESIZE + || r.mRelaunchReason == RELAUNCH_REASON_FREE_RESIZE) + && r.launchCount < 3 && !r.finishing) { + // If the process crashed during a resize, always try to relaunch it, unless + // it has failed more than twice. Skip activities that's already finishing + // cleanly by itself. + remove = false; + } else if ((!r.hasSavedState() && !r.stateNotNeeded + && !r.isState(ActivityState.RESTARTING_PROCESS)) || r.finishing) { + // Don't currently have state for the activity, or + // it is finishing -- always remove it. + remove = true; + } else if (!r.mVisibleRequested && r.launchCount > 2 + && r.lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) { + // We have launched this activity too many times since it was + // able to run, so give up and remove it. + // (Note if the activity is visible, we don't remove the record. + // We leave the dead window on the screen but the process will + // not be restarted unless user explicitly tap on it.) + remove = true; + } else { + // The process may be gone, but the activity lives on! + remove = false; + } + if (remove) { + if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE, + "Removing activity " + r + " from stack " + + ": hasSavedState=" + r.hasSavedState() + + " stateNotNeeded=" + r.stateNotNeeded + + " finishing=" + r.finishing + + " state=" + r.getState() + " callers=" + Debug.getCallers(5)); + if (!r.finishing || mIsProcessRemoved) { + Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); + EventLogTags.writeWmFinishActivity(r.mUserId, + System.identityHashCode(r), r.getTask().mTaskId, + r.shortComponentName, "proc died without state saved"); + } + } else { + // We have the current state for this activity, so + // it can be restarted later when needed. + if (DEBUG_ALL) Slog.v(TAG, "Keeping entry, setting app to null"); + if (DEBUG_APP) Slog.v(TAG_APP, + "Clearing app during removeHistory for activity " + r); + r.app = null; + // Set nowVisible to previous visible state. If the app was visible while + // it died, we leave the dead window on screen so it's basically visible. + // This is needed when user later tap on the dead window, we need to stop + // other apps when user transfers focus to the restarted activity. + r.nowVisible = r.mVisibleRequested; + } + r.cleanUp(true /* cleanServices */, true /* setState */); + if (remove) { + r.removeFromHistory("appDied"); + } + } + } + private final FindRootHelper mFindRootHelper = new FindRootHelper(); private class FindRootHelper { private ActivityRecord mRoot; @@ -507,12 +922,22 @@ class Task extends WindowContainer<WindowContainer> { boolean mCreatedByOrganizer; /** - * Don't use constructor directly. Use {@link #create(ActivityTaskManagerService, int, - * ActivityInfo, Intent, TaskDescription)} instead. + * Don't use constructor directly. Use {@link TaskDisplayArea#createStackUnchecked()} instead. + */ + Task(ActivityTaskManagerService atmService, int id, int activityType, + ActivityInfo info, Intent intent, boolean createdByOrganizer) { + this(atmService, id, info, intent, null /*voiceSession*/, null /*voiceInteractor*/, + null /*taskDescription*/, null /*stack*/); + mCreatedByOrganizer = createdByOrganizer; + setActivityType(activityType); + } + + /** + * Don't use constructor directly. Use {@link Task#reuseOrCreateTask()} instead. */ Task(ActivityTaskManagerService atmService, int _taskId, ActivityInfo info, Intent _intent, IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor, - TaskDescription _taskDescription, ActivityStack stack) { + TaskDescription _taskDescription, Task stack) { this(atmService, _taskId, _intent, null /*_affinityIntent*/, null /*_affinity*/, null /*_rootAffinity*/, null /*_realActivity*/, null /*_origActivity*/, false /*_rootWasReset*/, false /*_autoRemoveRecents*/, false /*_askedCompatMode*/, @@ -538,7 +963,7 @@ class Task extends WindowContainer<WindowContainer> { @Nullable String callingFeatureId, int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended, boolean userSetupComplete, int minWidth, int minHeight, ActivityInfo info, IVoiceInteractionSession _voiceSession, - IVoiceInteractor _voiceInteractor, ActivityStack stack) { + IVoiceInteractor _voiceInteractor, Task stack) { super(atmService.mWindowManager); EventLogTags.writeWmTaskCreated(_taskId, stack != null ? getRootTaskId() : INVALID_TASK_ID); @@ -587,6 +1012,8 @@ class Task extends WindowContainer<WindowContainer> { mMinHeight = minHeight; } mAtmService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity); + mHandler = new ActivityStackHandler(mStackSupervisor.mLooper); + mCurrentUser = mAtmService.mAmInternal.getCurrentUserId(); } Task reuseAsLeafTask(IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor, @@ -727,7 +1154,7 @@ class Task extends WindowContainer<WindowContainer> { } /** Convenience method to reparent a task to the top or bottom position of the stack. */ - boolean reparent(ActivityStack preferredStack, boolean toTop, + boolean reparent(Task preferredStack, boolean toTop, @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume, String reason) { return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate, deferResume, @@ -738,7 +1165,7 @@ class Task extends WindowContainer<WindowContainer> { * Convenience method to reparent a task to the top or bottom position of the stack, with * an option to skip scheduling the picture-in-picture mode change. */ - boolean reparent(ActivityStack preferredStack, boolean toTop, + boolean reparent(Task preferredStack, boolean toTop, @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume, boolean schedulePictureInPictureModeChange, String reason) { return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate, @@ -746,7 +1173,7 @@ class Task extends WindowContainer<WindowContainer> { } /** Convenience method to reparent a task to a specific position of the stack. */ - boolean reparent(ActivityStack preferredStack, int position, + boolean reparent(Task preferredStack, int position, @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume, String reason) { return reparent(preferredStack, position, moveStackMode, animate, deferResume, @@ -772,14 +1199,14 @@ class Task extends WindowContainer<WindowContainer> { */ // TODO: Inspect all call sites and change to just changing windowing mode of the stack vs. // re-parenting the task. Can only be done when we are no longer using static stack Ids. - boolean reparent(ActivityStack preferredStack, int position, + boolean reparent(Task preferredStack, int position, @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume, boolean schedulePictureInPictureModeChange, String reason) { final ActivityStackSupervisor supervisor = mStackSupervisor; final RootWindowContainer root = mRootWindowContainer; final WindowManagerService windowManager = mAtmService.mWindowManager; - final ActivityStack sourceStack = getStack(); - final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStack, + final Task sourceStack = getRootTask(); + final Task toStack = supervisor.getReparentTargetStack(this, preferredStack, position == MAX_VALUE); if (toStack == sourceStack) { return false; @@ -1172,6 +1599,12 @@ class Task extends WindowContainer<WindowContainer> { } mRootWindowContainer.updateUIDsPresentOnDisplay(); + + // Resume next focusable stack after reparenting to another display if we aren't removing + // the prevous display. + if (oldDisplay != null && oldDisplay.isRemoving()) { + postReparent(); + } } void cleanUpActivityReferences(ActivityRecord r) { @@ -1370,7 +1803,7 @@ class Task extends WindowContainer<WindowContainer> { // A rootable task that is now being added to be the child of an organized task. Making // sure the stack references is keep updated. if (mTaskOrganizer != null && mCreatedByOrganizer && child.asTask() != null) { - getDisplayArea().addStackReferenceIfNeeded((ActivityStack) child); + getDisplayArea().addStackReferenceIfNeeded((Task) child); } // Make sure the list of display UID whitelists is updated @@ -1420,7 +1853,7 @@ class Task extends WindowContainer<WindowContainer> { // A rootable child task that is now being removed from an organized task. Making sure // the stack references is keep updated. if (mCreatedByOrganizer && r.asTask() != null) { - getDisplayArea().removeStackReferenceIfNeeded((ActivityStack) r); + getDisplayArea().removeStackReferenceIfNeeded((Task) r); } if (!mChildren.contains(r)) { Slog.e(TAG, "removeChild: r=" + r + " not found in t=" + this); @@ -1460,7 +1893,7 @@ class Task extends WindowContainer<WindowContainer> { // Remove entire task if it doesn't have any activity left and it isn't marked for reuse // or created by task organizer. if (!isRootTask()) { - getStack().removeChild(this, reason); + getRootTask().removeChild(this, reason); } EventLogTags.writeWmTaskRemoved(mTaskId, "removeChild: last r=" + r + " in t=" + this); @@ -1502,7 +1935,7 @@ class Task extends WindowContainer<WindowContainer> { /** Completely remove all activities associated with an existing task. */ void performClearTask(String reason) { // Broken down into to cases to avoid object create due to capturing mStack. - if (getStack() == null) { + if (getRootTask() == null) { forAllActivities((r) -> { if (r.finishing) return; // Task was restored from persistent storage. @@ -1881,8 +2314,7 @@ class Task extends WindowContainer<WindowContainer> { } } - @Override - public void onConfigurationChanged(Configuration newParentConfig) { + private void onConfigurationChangedInner(Configuration newParentConfig) { // Check if the new configuration supports persistent bounds (eg. is Freeform) and if so // restore the last recorded non-fullscreen bounds. final boolean prevPersistTaskBounds = getWindowConfiguration().persistTaskBounds(); @@ -1910,7 +2342,7 @@ class Task extends WindowContainer<WindowContainer> { final boolean pipChanging = wasInPictureInPicture != inPinnedWindowingMode(); if (pipChanging) { - mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, getStack()); + mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, getRootTask()); } else if (wasInMultiWindowMode != inMultiWindowMode()) { mStackSupervisor.scheduleUpdateMultiWindowMode(this); } @@ -1959,6 +2391,78 @@ class Task extends WindowContainer<WindowContainer> { } } + @Override + public void onConfigurationChanged(Configuration newParentConfig) { + // Calling Task#onConfigurationChanged() for leaf task since the ops in this method are + // particularly for ActivityStack, like preventing bounds changes when inheriting certain + // windowing mode. + if (!isRootTask()) { + onConfigurationChangedInner(newParentConfig); + return; + } + + final int prevWindowingMode = getWindowingMode(); + final boolean prevIsAlwaysOnTop = isAlwaysOnTop(); + final int prevRotation = getWindowConfiguration().getRotation(); + final Rect newBounds = mTmpRect; + // Initialize the new bounds by previous bounds as the input and output for calculating + // override bounds in pinned (pip) or split-screen mode. + getBounds(newBounds); + + onConfigurationChangedInner(newParentConfig); + + final TaskDisplayArea taskDisplayArea = getDisplayArea(); + if (taskDisplayArea == null) { + return; + } + + if (prevWindowingMode != getWindowingMode()) { + taskDisplayArea.onStackWindowingModeChanged(this); + } + + final DisplayContent display = getDisplay(); + if (display == null ) { + return; + } + + final boolean windowingModeChanged = prevWindowingMode != getWindowingMode(); + final int overrideWindowingMode = getRequestedOverrideWindowingMode(); + // Update bounds if applicable + boolean hasNewOverrideBounds = false; + // Use override windowing mode to prevent extra bounds changes if inheriting the mode. + if ((overrideWindowingMode != WINDOWING_MODE_PINNED) + && !getRequestedOverrideBounds().isEmpty()) { + // If the parent (display) has rotated, rotate our bounds to best-fit where their + // bounds were on the pre-rotated display. + final int newRotation = getWindowConfiguration().getRotation(); + final boolean rotationChanged = prevRotation != newRotation; + if (rotationChanged) { + display.mDisplayContent.rotateBounds( + newParentConfig.windowConfiguration.getBounds(), prevRotation, newRotation, + newBounds); + hasNewOverrideBounds = true; + } + } + + if (windowingModeChanged) { + taskDisplayArea.onStackWindowingModeChanged(this); + } + if (hasNewOverrideBounds) { + if (inSplitScreenWindowingMode()) { + setBounds(newBounds); + } else if (overrideWindowingMode != WINDOWING_MODE_PINNED) { + // For pinned stack, resize is now part of the {@link WindowContainerTransaction} + resize(new Rect(newBounds), PRESERVE_WINDOWS, true /* deferResume */); + } + } + if (prevIsAlwaysOnTop != isAlwaysOnTop()) { + // Since always on top is only on when the stack is freeform or pinned, the state + // can be toggled when the windowing mode changes. We must make sure the stack is + // placed properly when always on top state changes. + taskDisplayArea.positionStackAtTop(this, false /* includingParents */); + } + } + /** * Initializes a change transition. See {@link SurfaceFreezer} for more information. */ @@ -2191,10 +2695,11 @@ class Task extends WindowContainer<WindowContainer> { DisplayInfo displayInfo) { outNonDecorBounds.set(bounds); outStableBounds.set(bounds); - if (getStack() == null || getStack().getDisplay() == null) { + final Task rootTask = getRootTask(); + if (rootTask == null || rootTask.getDisplay() == null) { return; } - DisplayPolicy policy = getStack().getDisplay().mDisplayContent.getDisplayPolicy(); + DisplayPolicy policy = rootTask.getDisplay().mDisplayContent.getDisplayPolicy(); if (policy == null) { return; } @@ -2533,8 +3038,8 @@ class Task extends WindowContainer<WindowContainer> { /** Updates the task's bounds and override configuration to match what is expected for the * input stack. */ - void updateOverrideConfigurationForStack(ActivityStack inStack) { - final ActivityStack stack = getStack(); + void updateOverrideConfigurationForStack(Task inStack) { + final Task stack = getRootTask(); if (stack != null && stack == inStack) { return; @@ -2547,7 +3052,7 @@ class Task extends WindowContainer<WindowContainer> { /** Returns the bounds that should be used to launch this task. */ Rect getLaunchBounds() { - final ActivityStack stack = getStack(); + final Task stack = getRootTask(); if (stack == null) { return null; } @@ -2582,7 +3087,7 @@ class Task extends WindowContainer<WindowContainer> { @Override DisplayContent getDisplayContent() { // TODO: Why aren't we just using our own display content vs. parent's??? - final ActivityStack stack = getStack(); + final Task stack = getRootTask(); return stack != null && stack != this ? stack.getDisplayContent() : super.getDisplayContent(); } @@ -2592,11 +3097,6 @@ class Task extends WindowContainer<WindowContainer> { return dc != null ? dc.mDisplayId : INVALID_DISPLAY; } - // TODO: Migrate callers to getRootTask() - ActivityStack getStack() { - return (ActivityStack) getRootTask(); - } - /** @return Id of root task. */ int getRootTaskId() { return getRootTask().mTaskId; @@ -2637,7 +3137,7 @@ class Task extends WindowContainer<WindowContainer> { * Find next proper focusable stack and make it focused. * @return The stack that now got the focus, {@code null} if none found. */ - ActivityStack adjustFocusToNextFocusableTask(String reason) { + Task adjustFocusToNextFocusableTask(String reason) { return adjustFocusToNextFocusableTask(reason, false /* allowFocusSelf */, true /* moveDisplayToTop */); } @@ -2650,7 +3150,7 @@ class Task extends WindowContainer<WindowContainer> { } final Task focusableTask = parent.getTask((task) -> (allowFocusSelf || task != this) - && ((ActivityStack) task).isFocusableAndVisible()); + && ((Task) task).isFocusableAndVisible()); if (focusableTask == null && parent.asTask() != null) { return parent.asTask().getNextFocusableTask(allowFocusSelf); } else { @@ -2665,18 +3165,17 @@ class Task extends WindowContainer<WindowContainer> { * @param moveDisplayToTop Whether to move display to top while making the task focused. * @return The root task that now got the focus, {@code null} if none found. */ - ActivityStack adjustFocusToNextFocusableTask(String reason, boolean allowFocusSelf, + Task adjustFocusToNextFocusableTask(String reason, boolean allowFocusSelf, boolean moveDisplayToTop) { - ActivityStack focusableTask = (ActivityStack) getNextFocusableTask(allowFocusSelf); + Task focusableTask = getNextFocusableTask(allowFocusSelf); if (focusableTask == null) { - focusableTask = mRootWindowContainer.getNextFocusableStack((ActivityStack) this, - !allowFocusSelf); + focusableTask = mRootWindowContainer.getNextFocusableStack(this, !allowFocusSelf); } if (focusableTask == null) { return null; } - final ActivityStack rootTask = (ActivityStack) focusableTask.getRootTask(); + final Task rootTask = focusableTask.getRootTask(); if (!moveDisplayToTop) { // There may be multiple task layers above this task, so when relocating the task to the // top, we should move this task and each of its parent task that below display area to @@ -2807,7 +3306,7 @@ class Task extends WindowContainer<WindowContainer> { // No reason to defer removal of a Task that doesn't have any child. return false; } - return hasWindowsAlive() && getStack().isAnimating(TRANSITION | CHILDREN); + return hasWindowsAlive() && getRootTask().isAnimating(TRANSITION | CHILDREN); } @Override @@ -2826,9 +3325,9 @@ class Task extends WindowContainer<WindowContainer> { } // TODO: Consolidate this with Task.reparent() - void reparent(ActivityStack stack, int position, boolean moveParents, String reason) { + void reparent(Task stack, int position, boolean moveParents, String reason) { if (DEBUG_STACK) Slog.i(TAG, "reParentTask: removing taskId=" + mTaskId - + " from stack=" + getStack()); + + " from stack=" + getRootTask()); EventLogTags.writeWmTaskRemoved(mTaskId, "reParentTask:" + reason); reparent(stack, position); @@ -2855,9 +3354,13 @@ class Task extends WindowContainer<WindowContainer> { /** Set the task bounds. Passing in null sets the bounds to fullscreen. */ @Override public int setBounds(Rect bounds) { + if (isRootTask()) { + return setBounds(getRequestedOverrideBounds(), bounds); + } + int rotation = Surface.ROTATION_0; - final DisplayContent displayContent = getStack() != null - ? getStack().getDisplayContent() : null; + final DisplayContent displayContent = getRootTask() != null + ? getRootTask().getDisplayContent() : null; if (displayContent != null) { rotation = displayContent.getDisplayInfo().rotation; } @@ -2869,6 +3372,17 @@ class Task extends WindowContainer<WindowContainer> { } @Override + public boolean isCompatible(int windowingMode, int activityType) { + // TODO: Should we just move this to ConfigurationContainer? + if (activityType == ACTIVITY_TYPE_UNDEFINED) { + // Undefined activity types end up in a standard stack once the stack is created on a + // display, so they should be considered compatible. + activityType = ACTIVITY_TYPE_STANDARD; + } + return super.isCompatible(windowingMode, activityType); + } + + @Override public boolean onDescendantOrientationChanged(IBinder freezeDisplayToken, ConfigurationContainer requestingContainer) { if (super.onDescendantOrientationChanged(freezeDisplayToken, requestingContainer)) { @@ -2902,6 +3416,9 @@ class Task extends WindowContainer<WindowContainer> { mWmService.mAtmService.getTaskChangeNotificationController().notifyTaskDisplayChanged( mTaskId, displayId); } + if (isRootTask()) { + updateSurfaceBounds(); + } } boolean isResizeable(boolean checkSupportsPip) { @@ -2992,7 +3509,13 @@ class Task extends WindowContainer<WindowContainer> { /** Bounds of the task to be used for dimming, as well as touch related tests. */ void getDimBounds(Rect out) { - final DisplayContent displayContent = getStack().getDisplayContent(); + if (isRootTask()) { + getBounds(out); + return; + } + + final Task rootTask = getRootTask(); + final DisplayContent displayContent = rootTask.getDisplayContent(); // It doesn't matter if we in particular are part of the resize, since we couldn't have // a DimLayer anyway if we weren't visible. final boolean dockedResizing = displayContent != null @@ -3016,9 +3539,9 @@ class Task extends WindowContainer<WindowContainer> { // stack bounds and so we don't even want to use them. Even if the app should not be // resized the Dim should keep up with the divider. if (dockedResizing) { - getStack().getBounds(out); + rootTask.getBounds(out); } else { - getStack().getBounds(mTmpRect); + rootTask.getBounds(mTmpRect); mTmpRect.intersect(getBounds()); out.set(mTmpRect); } @@ -3031,7 +3554,8 @@ class Task extends WindowContainer<WindowContainer> { void setDragResizing(boolean dragResizing, int dragResizeMode) { if (mDragResizing != dragResizing) { // No need to check if the mode is allowed if it's leaving dragResize - if (dragResizing && !DragResizeMode.isModeAllowedForStack(getStack(), dragResizeMode)) { + if (dragResizing + && !DragResizeMode.isModeAllowedForStack(getRootTask(), dragResizeMode)) { throw new IllegalArgumentException("Drag resize mode not allow for stack stackId=" + getRootTaskId() + " dragResizeMode=" + dragResizeMode); } @@ -3221,9 +3745,9 @@ class Task extends WindowContainer<WindowContainer> { @Override Rect getAnimationBounds(int appStackClipMode) { // TODO(b/131661052): we should remove appStackClipMode with hierarchical animations. - if (appStackClipMode == STACK_CLIP_BEFORE_ANIM && getStack() != null) { + if (appStackClipMode == STACK_CLIP_BEFORE_ANIM && getRootTask() != null) { // Using the stack bounds here effectively applies the clipping before animation. - return getStack().getBounds(); + return getRootTask().getBounds(); } return super.getAnimationBounds(appStackClipMode); } @@ -3573,6 +4097,20 @@ class Task extends WindowContainer<WindowContainer> { child.dump(pw, doublePrefix, dumpAll); } } + + if (!mExitingActivities.isEmpty()) { + pw.println(); + pw.println(prefix + "Exiting application tokens:"); + for (int i = mExitingActivities.size() - 1; i >= 0; i--) { + WindowToken token = mExitingActivities.get(i); + pw.print(doublePrefix + "Exiting App #" + i); + pw.print(' '); pw.print(token); + pw.println(':'); + token.dump(pw, doublePrefix, dumpAll); + } + pw.println(); + } + mAnimatingActivityRegistry.dump(pw, "AnimatingApps:", prefix); } @@ -3668,7 +4206,7 @@ class Task extends WindowContainer<WindowContainer> { * * @param starting The currently starting activity or null if there is none. */ - @ActivityStack.StackVisibility + @Task.StackVisibility int getVisibility(ActivityRecord starting) { if (!isAttached() || isForceHidden()) { return STACK_VISIBILITY_INVISIBLE; @@ -4289,7 +4827,7 @@ class Task extends WindowContainer<WindowContainer> { } } - final Task task = new ActivityStack(stackSupervisor.mService, taskId, intent, + final Task task = new Task(stackSupervisor.mService, taskId, intent, affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset, autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription, lastTimeOnTop, neverRelinquishIdentity, taskDescription, taskAffiliation, @@ -4604,4 +5142,2656 @@ class Task extends WindowContainer<WindowContainer> { return TASK; } + @Override + public void setWindowingMode(int windowingMode) { + // Reset the cached result of toString() + stringName = null; + + // Calling Task#setWindowingMode() for leaf task since this is the a specialization of + // {@link #setWindowingMode(int)} for ActivityStack. + if (!isRootTask()) { + super.setWindowingMode(windowingMode); + return; + } + + setWindowingMode(windowingMode, false /* creating */); + } + + /** + * Specialization of {@link #setWindowingMode(int)} for this subclass. + * + * @param preferredWindowingMode the preferred windowing mode. This may not be honored depending + * on the state of things. For example, WINDOWING_MODE_UNDEFINED will resolve to the + * previous non-transient mode if this stack is currently in a transient mode. + * @param creating {@code true} if this is being run during ActivityStack construction. + */ + void setWindowingMode(int preferredWindowingMode, boolean creating) { + mWmService.inSurfaceTransaction(() -> setWindowingModeInSurfaceTransaction( + preferredWindowingMode, creating)); + } + + private void setWindowingModeInSurfaceTransaction(int preferredWindowingMode, + boolean creating) { + final TaskDisplayArea taskDisplayArea = getDisplayArea(); + if (taskDisplayArea == null) { + Slog.d(TAG, "taskDisplayArea is null, bail early"); + return; + } + final int currentMode = getWindowingMode(); + final int currentOverrideMode = getRequestedOverrideWindowingMode(); + final Task topTask = getTopMostTask(); + int windowingMode = preferredWindowingMode; + + // Need to make sure windowing mode is supported. If we in the process of creating the stack + // no need to resolve the windowing mode again as it is already resolved to the right mode. + if (!creating) { + if (!taskDisplayArea.isValidWindowingMode(windowingMode, null /* ActivityRecord */, + topTask, getActivityType())) { + windowingMode = WINDOWING_MODE_UNDEFINED; + } + } + + final boolean alreadyInSplitScreenMode = taskDisplayArea.isSplitScreenModeActivated(); + + if (creating && alreadyInSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN + && isActivityTypeStandardOrUndefined()) { + // If the stack is being created explicitly in fullscreen mode, dismiss split-screen + // and display a warning toast about it. + mAtmService.getTaskChangeNotificationController() + .notifyActivityDismissingDockedStack(); + taskDisplayArea.onSplitScreenModeDismissed(this); + } + + if (currentMode == windowingMode) { + // You are already in the window mode, so we can skip most of the work below. However, + // it's possible that we have inherited the current windowing mode from a parent. So, + // fulfill this method's contract by setting the override mode directly. + getRequestedOverrideConfiguration().windowConfiguration.setWindowingMode(windowingMode); + return; + } + + final ActivityRecord topActivity = getTopNonFinishingActivity(); + + // For now, assume that the Stack's windowing mode is what will actually be used + // by it's activities. In the future, there may be situations where this doesn't + // happen; so at that point, this message will need to handle that. + int likelyResolvedMode = windowingMode; + if (windowingMode == WINDOWING_MODE_UNDEFINED) { + final ConfigurationContainer parent = getParent(); + likelyResolvedMode = parent != null ? parent.getWindowingMode() + : WINDOWING_MODE_FULLSCREEN; + } + if (currentMode == WINDOWING_MODE_PINNED) { + mAtmService.getTaskChangeNotificationController().notifyActivityUnpinned(); + } + if (likelyResolvedMode == WINDOWING_MODE_PINNED + && taskDisplayArea.getRootPinnedTask() != null) { + // Can only have 1 pip at a time, so replace an existing pip + taskDisplayArea.getRootPinnedTask().dismissPip(); + } + if (likelyResolvedMode != WINDOWING_MODE_FULLSCREEN + && topActivity != null && !topActivity.noDisplay + && topActivity.isNonResizableOrForcedResizable(likelyResolvedMode)) { + // Inform the user that they are starting an app that may not work correctly in + // multi-window mode. + final String packageName = topActivity.info.applicationInfo.packageName; + mAtmService.getTaskChangeNotificationController().notifyActivityForcedResizable( + topTask.mTaskId, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN, packageName); + } + + mAtmService.deferWindowLayout(); + try { + if (topActivity != null) { + mStackSupervisor.mNoAnimActivities.add(topActivity); + } + super.setWindowingMode(windowingMode); + // setWindowingMode triggers an onConfigurationChanged cascade which can result in a + // different resolved windowing mode (usually when preferredWindowingMode is UNDEFINED). + windowingMode = getWindowingMode(); + + if (creating) { + // Nothing else to do if we don't have a window container yet. E.g. call from ctor. + return; + } + + if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && alreadyInSplitScreenMode) { + // We already have a split-screen stack in this display, so just move the tasks over. + // TODO: Figure-out how to do all the stuff in + // AMS.setTaskWindowingModeSplitScreenPrimary + throw new IllegalArgumentException("Setting primary split-screen windowing mode" + + " while there is already one isn't currently supported"); + //return; + } + } finally { + mAtmService.continueWindowLayout(); + } + + mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); + mRootWindowContainer.resumeFocusedStacksTopActivities(); + } + + /** Resume next focusable stack after reparenting to another display. */ + void postReparent() { + adjustFocusToNextFocusableTask("reparent", true /* allowFocusSelf */, + true /* moveDisplayToTop */); + mRootWindowContainer.resumeFocusedStacksTopActivities(); + // Update visibility of activities before notifying WM. This way it won't try to resize + // windows that are no longer visible. + mRootWindowContainer.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, + !PRESERVE_WINDOWS); + } + + DisplayContent getDisplay() { + return getDisplayContent(); + } + + /** @return true if the stack can only contain one task */ + boolean isSingleTaskInstance() { + final DisplayContent display = getDisplay(); + return display != null && display.isSingleTaskInstance(); + } + + final boolean isHomeOrRecentsStack() { + return isActivityTypeHome() || isActivityTypeRecents(); + } + + final boolean isOnHomeDisplay() { + return getDisplayId() == DEFAULT_DISPLAY; + } + + void moveToFront(String reason) { + moveToFront(reason, null); + } + + /** + * @param reason The reason for moving the stack to the front. + * @param task If non-null, the task will be moved to the top of the stack. + */ + void moveToFront(String reason, Task task) { + if (!isAttached()) { + return; + } + + final TaskDisplayArea taskDisplayArea = getDisplayArea(); + + if (inSplitScreenSecondaryWindowingMode()) { + // If the stack is in split-screen secondary mode, we need to make sure we move the + // primary split-screen stack forward in the case it is currently behind a fullscreen + // stack so both halves of the split-screen appear on-top and the fullscreen stack isn't + // cutting between them. + // TODO(b/70677280): This is a workaround until we can fix as part of b/70677280. + final Task topFullScreenStack = + taskDisplayArea.getTopStackInWindowingMode(WINDOWING_MODE_FULLSCREEN); + if (topFullScreenStack != null) { + final Task primarySplitScreenStack = + taskDisplayArea.getRootSplitScreenPrimaryTask(); + if (primarySplitScreenStack != null + && taskDisplayArea.getIndexOf(topFullScreenStack) + > taskDisplayArea.getIndexOf(primarySplitScreenStack)) { + primarySplitScreenStack.moveToFront(reason + " splitScreenToTop"); + } + } + } + + if (!isActivityTypeHome() && returnsToHomeStack()) { + // Make sure the home stack is behind this stack since that is where we should return to + // when this stack is no longer visible. + taskDisplayArea.moveHomeStackToFront(reason + " returnToHome"); + } + + if (isRootTask()) { + taskDisplayArea.positionStackAtTop(this, false /* includingParents */, reason); + } + if (task == null) { + task = this; + } + task.getParent().positionChildAt(POSITION_TOP, task, true /* includingParents */); + } + + /** + * This moves 'task' to the back of this task and also recursively moves this task to the back + * of its parents (if applicable). + * + * @param reason The reason for moving the stack to the back. + * @param task If non-null, the task will be moved to the bottom of the stack. + **/ + void moveToBack(String reason, Task task) { + if (!isAttached()) { + return; + } + final TaskDisplayArea displayArea = getDisplayArea(); + if (!mCreatedByOrganizer) { + // If this is just a normal task, so move to back of parent and then move 'task' to + // back of this. + final WindowContainer parent = getParent(); + final Task parentTask = parent != null ? parent.asTask() : null; + if (parentTask != null) { + parentTask.moveToBack(reason, this); + } else { + displayArea.positionStackAtBottom(this, reason); + } + if (task != null && task != this) { + positionChildAtBottom(task); + } + return; + } + if (task == null || task == this) { + return; + } + // This is a created-by-organizer task. In this case, let the organizer deal with this + // task's ordering. However, we still need to move 'task' to back. The intention is that + // this ends up behind the home-task so that it is made invisible; so, if the home task + // is not a child of this, reparent 'task' to the back of the home task's actual parent. + displayArea.positionTaskBehindHome(task); + } + + // TODO: Should each user have there own stacks? + @Override + void switchUser(int userId) { + if (mCurrentUser == userId) { + return; + } + mCurrentUser = userId; + + super.switchUser(userId); + forAllLeafTasks((t) -> { + if (t.showToCurrentUser() && t != this) { + mChildren.remove(t); + mChildren.add(t); + } + }, true /* traverseTopToBottom */); + } + + void minimalResumeActivityLocked(ActivityRecord r) { + if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + r + " (starting new instance)" + + " callers=" + Debug.getCallers(5)); + r.setState(RESUMED, "minimalResumeActivityLocked"); + r.completeResumeLocked(); + } + + private void clearLaunchTime(ActivityRecord r) { + // Make sure that there is no activity waiting for this to launch. + if (!mStackSupervisor.mWaitingActivityLaunched.isEmpty()) { + mStackSupervisor.removeIdleTimeoutForActivity(r); + mStackSupervisor.scheduleIdleTimeout(r); + } + } + + void awakeFromSleepingLocked() { + // Ensure activities are no longer sleeping. + forAllActivities((Consumer<ActivityRecord>) (r) -> r.setSleeping(false)); + if (mPausingActivity != null) { + Slog.d(TAG, "awakeFromSleepingLocked: previously pausing activity didn't pause"); + mPausingActivity.activityPaused(true); + } + } + + void checkReadyForSleep() { + if (shouldSleepActivities() && goToSleepIfPossible(false /* shuttingDown */)) { + mStackSupervisor.checkReadyForSleepLocked(true /* allowDelay */); + } + } + + /** + * Tries to put the activities in the stack to sleep. + * + * If the stack is not in a state where its activities can be put to sleep, this function will + * start any necessary actions to move the stack into such a state. It is expected that this + * function get called again when those actions complete. + * + * @param shuttingDown true when the called because the device is shutting down. + * @return true if the stack finished going to sleep, false if the stack only started the + * process of going to sleep (checkReadyForSleep will be called when that process finishes). + */ + boolean goToSleepIfPossible(boolean shuttingDown) { + boolean shouldSleep = true; + + if (mResumedActivity != null) { + // Still have something resumed; can't sleep until it is paused. + if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity); + if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, + "Sleep => pause with userLeaving=false"); + + startPausingLocked(false /* userLeaving */, true /* uiSleeping */, null /* resuming */); + shouldSleep = false ; + } else if (mPausingActivity != null) { + // Still waiting for something to pause; can't sleep yet. + if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still waiting to pause " + mPausingActivity); + shouldSleep = false; + } + + if (!shuttingDown) { + if (containsActivityFromStack(mStackSupervisor.mStoppingActivities)) { + // Still need to tell some activities to stop; can't sleep yet. + if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop " + + mStackSupervisor.mStoppingActivities.size() + " activities"); + + mStackSupervisor.scheduleIdle(); + shouldSleep = false; + } + } + + if (shouldSleep) { + goToSleep(); + } + + return shouldSleep; + } + + void goToSleep() { + // Make sure all visible activities are now sleeping. This will update the activity's + // visibility and onStop() will be called. + forAllActivities((r) -> { + if (r.isState(STARTED, RESUMED, PAUSING, PAUSED, STOPPING, STOPPED)) { + r.setSleeping(true); + } + }); + + // Ensure visibility after updating sleep states without updating configuration, + // as activities are about to be sent to sleep. + ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, + !PRESERVE_WINDOWS); + } + + private boolean containsActivityFromStack(List<ActivityRecord> rs) { + for (ActivityRecord r : rs) { + if (r.getRootTask() == this) { + return true; + } + } + return false; + } + + /** + * Start pausing the currently resumed activity. It is an error to call this if there + * is already an activity being paused or there is no resumed activity. + * + * @param userLeaving True if this should result in an onUserLeaving to the current activity. + * @param uiSleeping True if this is happening with the user interface going to sleep (the + * screen turning off). + * @param resuming The activity we are currently trying to resume or null if this is not being + * called as part of resuming the top activity, so we shouldn't try to instigate + * a resume here if not null. + * @return Returns true if an activity now is in the PAUSING state, and we are waiting for + * it to tell us when it is done. + */ + final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, + ActivityRecord resuming) { + if (mPausingActivity != null) { + Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity + + " state=" + mPausingActivity.getState()); + if (!shouldSleepActivities()) { + // Avoid recursion among check for sleep and complete pause during sleeping. + // Because activity will be paused immediately after resume, just let pause + // be completed by the order of activity paused from clients. + completePauseLocked(false, resuming); + } + } + ActivityRecord prev = mResumedActivity; + + if (prev == null) { + if (resuming == null) { + Slog.wtf(TAG, "Trying to pause when nothing is resumed"); + mRootWindowContainer.resumeFocusedStacksTopActivities(); + } + return false; + } + + if (prev == resuming) { + Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed"); + return false; + } + + if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev); + else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev); + mPausingActivity = prev; + mLastPausedActivity = prev; + mLastNoHistoryActivity = prev.isNoHistory() ? prev : null; + prev.setState(PAUSING, "startPausingLocked"); + prev.getTask().touchActiveTime(); + clearLaunchTime(prev); + + mAtmService.updateCpuStats(); + + boolean pauseImmediately = false; + if (resuming != null && (resuming.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0) { + // If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous + // activity to be paused, while at the same time resuming the new resume activity + // only if the previous activity can't go into Pip since we want to give Pip + // activities a chance to enter Pip before resuming the next activity. + final boolean lastResumedCanPip = prev != null && prev.checkEnterPictureInPictureState( + "shouldResumeWhilePausing", userLeaving); + if (!lastResumedCanPip) { + pauseImmediately = true; + } + } + + if (prev.attachedToProcess()) { + if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev); + try { + EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev), + prev.shortComponentName, "userLeaving=" + userLeaving); + + mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(), + prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving, + prev.configChangeFlags, pauseImmediately)); + } catch (Exception e) { + // Ignore exception, if process died other code will cleanup. + Slog.w(TAG, "Exception thrown during pause", e); + mPausingActivity = null; + mLastPausedActivity = null; + mLastNoHistoryActivity = null; + } + } else { + mPausingActivity = null; + mLastPausedActivity = null; + mLastNoHistoryActivity = null; + } + + // If we are not going to sleep, we want to ensure the device is + // awake until the next activity is started. + if (!uiSleeping && !mAtmService.isSleepingOrShuttingDownLocked()) { + mStackSupervisor.acquireLaunchWakelock(); + } + + if (mPausingActivity != null) { + // Have the window manager pause its key dispatching until the new + // activity has started. If we're pausing the activity just because + // the screen is being turned off and the UI is sleeping, don't interrupt + // key dispatch; the same activity will pick it up again on wakeup. + if (!uiSleeping) { + prev.pauseKeyDispatchingLocked(); + } else if (DEBUG_PAUSE) { + Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off"); + } + + if (pauseImmediately) { + // If the caller said they don't want to wait for the pause, then complete + // the pause now. + completePauseLocked(false, resuming); + return false; + + } else { + prev.schedulePauseTimeout(); + return true; + } + + } else { + // This activity failed to schedule the + // pause, so just treat it as being paused now. + if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next."); + if (resuming == null) { + mRootWindowContainer.resumeFocusedStacksTopActivities(); + } + return false; + } + } + + @VisibleForTesting + void completePauseLocked(boolean resumeNext, ActivityRecord resuming) { + ActivityRecord prev = mPausingActivity; + if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev); + + if (prev != null) { + prev.setWillCloseOrEnterPip(false); + final boolean wasStopping = prev.isState(STOPPING); + prev.setState(PAUSED, "completePausedLocked"); + if (prev.finishing) { + if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev); + prev = prev.completeFinishing("completePausedLocked"); + } else if (prev.hasProcess()) { + if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev + + " wasStopping=" + wasStopping + + " visibleRequested=" + prev.mVisibleRequested); + if (prev.deferRelaunchUntilPaused) { + // Complete the deferred relaunch that was waiting for pause to complete. + if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev); + prev.relaunchActivityLocked(prev.preserveWindowOnDeferredRelaunch); + } else if (wasStopping) { + // We are also stopping, the stop request must have gone soon after the pause. + // We can't clobber it, because the stop confirmation will not be handled. + // We don't need to schedule another stop, we only need to let it happen. + prev.setState(STOPPING, "completePausedLocked"); + } else if (!prev.mVisibleRequested || shouldSleepOrShutDownActivities()) { + // Clear out any deferred client hide we might currently have. + prev.setDeferHidingClient(false); + // If we were visible then resumeTopActivities will release resources before + // stopping. + prev.addToStopping(true /* scheduleIdle */, false /* idleDelayed */, + "completePauseLocked"); + } + } else { + if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev); + prev = null; + } + // It is possible the activity was freezing the screen before it was paused. + // In that case go ahead and remove the freeze this activity has on the screen + // since it is no longer visible. + if (prev != null) { + prev.stopFreezingScreenLocked(true /*force*/); + } + mPausingActivity = null; + } + + if (resumeNext) { + final Task topStack = mRootWindowContainer.getTopDisplayFocusedStack(); + if (topStack != null && !topStack.shouldSleepOrShutDownActivities()) { + mRootWindowContainer.resumeFocusedStacksTopActivities(topStack, prev, null); + } else { + checkReadyForSleep(); + final ActivityRecord top = topStack != null ? topStack.topRunningActivity() : null; + if (top == null || (prev != null && top != prev)) { + // If there are no more activities available to run, do resume anyway to start + // something. Also if the top activity on the stack is not the just paused + // activity, we need to go ahead and resume it to ensure we complete an + // in-flight app switch. + mRootWindowContainer.resumeFocusedStacksTopActivities(); + } + } + } + + if (prev != null) { + prev.resumeKeyDispatchingLocked(); + + if (prev.hasProcess() && prev.cpuTimeAtResume > 0) { + final long diff = prev.app.getCpuTime() - prev.cpuTimeAtResume; + if (diff > 0) { + final Runnable r = PooledLambda.obtainRunnable( + ActivityManagerInternal::updateForegroundTimeIfOnBattery, + mAtmService.mAmInternal, prev.info.packageName, + prev.info.applicationInfo.uid, + diff); + mAtmService.mH.post(r); + } + } + prev.cpuTimeAtResume = 0; // reset it + } + + mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS); + + // Notify when the task stack has changed, but only if visibilities changed (not just + // focus). Also if there is an active pinned stack - we always want to notify it about + // task stack changes, because its positioning may depend on it. + if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause + || (getDisplayArea() != null && getDisplayArea().hasPinnedTask())) { + mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged(); + mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false; + } + } + + boolean isTopStackInDisplayArea() { + final TaskDisplayArea taskDisplayArea = getDisplayArea(); + return taskDisplayArea != null && taskDisplayArea.isTopStack(this); + } + + /** + * @return {@code true} if this is the focused stack on its current display, {@code false} + * otherwise. + */ + boolean isFocusedStackOnDisplay() { + final DisplayContent display = getDisplay(); + return display != null && this == display.getFocusedStack(); + } + + /** + * Make sure that all activities that need to be visible in the stack (that is, they + * currently can be seen by the user) actually are and update their configuration. + * @param starting The top most activity in the task. + * The activity is either starting or resuming. + * Caller should ensure starting activity is visible. + * @param preserveWindows Flag indicating whether windows should be preserved when updating + * configuration in {@link mEnsureActivitiesVisibleHelper}. + * @param configChanges Parts of the configuration that changed for this activity for evaluating + * if the screen should be frozen as part of + * {@link mEnsureActivitiesVisibleHelper}. + * + */ + void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges, + boolean preserveWindows) { + ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */); + } + + /** + * Ensure visibility with an option to also update the configuration of visible activities. + * @see #ensureActivitiesVisible(ActivityRecord, int, boolean) + * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean) + * @param starting The top most activity in the task. + * The activity is either starting or resuming. + * Caller should ensure starting activity is visible. + * @param notifyClients Flag indicating whether the visibility updates should be sent to the + * clients in {@link mEnsureActivitiesVisibleHelper}. + * @param preserveWindows Flag indicating whether windows should be preserved when updating + * configuration in {@link mEnsureActivitiesVisibleHelper}. + * @param configChanges Parts of the configuration that changed for this activity for evaluating + * if the screen should be frozen as part of + * {@link mEnsureActivitiesVisibleHelper}. + */ + // TODO: Should be re-worked based on the fact that each task as a stack in most cases. + void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges, + boolean preserveWindows, boolean notifyClients) { + mTopActivityOccludesKeyguard = false; + mTopDismissingKeyguardActivity = null; + mStackSupervisor.beginActivityVisibilityUpdate(); + try { + mEnsureActivitiesVisibleHelper.process( + starting, configChanges, preserveWindows, notifyClients); + + if (mTranslucentActivityWaiting != null && + mUndrawnActivitiesBelowTopTranslucent.isEmpty()) { + // Nothing is getting drawn or everything was already visible, don't wait for timeout. + notifyActivityDrawnLocked(null); + } + } finally { + mStackSupervisor.endActivityVisibilityUpdate(); + } + } + + /** + * @return true if the top visible activity wants to occlude the Keyguard, false otherwise + */ + boolean topActivityOccludesKeyguard() { + return mTopActivityOccludesKeyguard; + } + + /** + * Returns true if this stack should be resized to match the bounds specified by + * {@link ActivityOptions#setLaunchBounds} when launching an activity into the stack. + */ + boolean shouldResizeStackWithLaunchBounds() { + return inPinnedWindowingMode(); + } + + // TODO(NOW!) + /** + * Returns {@code true} if this is the top-most split-screen-primary or + * split-screen-secondary stack, {@code false} otherwise. + */ + boolean isTopSplitScreenStack() { + return inSplitScreenWindowingMode() + && this == getDisplayArea().getTopStackInWindowingMode(getWindowingMode()); + } + + /** + * @return the top most visible activity that wants to dismiss Keyguard + */ + ActivityRecord getTopDismissingKeyguardActivity() { + return mTopDismissingKeyguardActivity; + } + + /** + * Checks whether {@param r} should be visible depending on Keyguard state and updates + * {@link #mTopActivityOccludesKeyguard} and {@link #mTopDismissingKeyguardActivity} if + * necessary. + * + * @return true if {@param r} is visible taken Keyguard state into account, false otherwise + */ + boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible, boolean isTop) { + int displayId = getDisplayId(); + if (displayId == INVALID_DISPLAY) displayId = DEFAULT_DISPLAY; + + final boolean keyguardOrAodShowing = mStackSupervisor.getKeyguardController() + .isKeyguardOrAodShowing(displayId); + final boolean keyguardLocked = mStackSupervisor.getKeyguardController().isKeyguardLocked(); + final boolean showWhenLocked = r.canShowWhenLocked(); + final boolean dismissKeyguard = r.containsDismissKeyguardWindow(); + if (shouldBeVisible) { + if (dismissKeyguard && mTopDismissingKeyguardActivity == null) { + mTopDismissingKeyguardActivity = r; + } + + // Only the top activity may control occluded, as we can't occlude the Keyguard if the + // top app doesn't want to occlude it. + if (isTop) { + mTopActivityOccludesKeyguard |= showWhenLocked; + } + + final boolean canShowWithKeyguard = canShowWithInsecureKeyguard() + && mStackSupervisor.getKeyguardController().canDismissKeyguard(); + if (canShowWithKeyguard) { + return true; + } + } + if (keyguardOrAodShowing) { + // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard + // right away and AOD isn't visible. + return shouldBeVisible && mStackSupervisor.getKeyguardController() + .canShowActivityWhileKeyguardShowing(r, dismissKeyguard); + } else if (keyguardLocked) { + return shouldBeVisible && mStackSupervisor.getKeyguardController().canShowWhileOccluded( + dismissKeyguard, showWhenLocked); + } else { + return shouldBeVisible; + } + } + + /** + * Check if the display to which this stack is attached has + * {@link Display#FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD} applied. + */ + boolean canShowWithInsecureKeyguard() { + final DisplayContent displayContent = getDisplay(); + if (displayContent == null) { + throw new IllegalStateException("Stack is not attached to any display, stackId=" + + getRootTaskId()); + } + + final int flags = displayContent.mDisplay.getFlags(); + return (flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0; + } + + void checkTranslucentActivityWaiting(ActivityRecord top) { + if (mTranslucentActivityWaiting != top) { + mUndrawnActivitiesBelowTopTranslucent.clear(); + if (mTranslucentActivityWaiting != null) { + // Call the callback with a timeout indication. + notifyActivityDrawnLocked(null); + mTranslucentActivityWaiting = null; + } + mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG); + } + } + + void convertActivityToTranslucent(ActivityRecord r) { + mTranslucentActivityWaiting = r; + mUndrawnActivitiesBelowTopTranslucent.clear(); + mHandler.sendEmptyMessageDelayed(TRANSLUCENT_TIMEOUT_MSG, TRANSLUCENT_CONVERSION_TIMEOUT); + } + + /** + * Called as activities below the top translucent activity are redrawn. When the last one is + * redrawn notify the top activity by calling + * {@link Activity#onTranslucentConversionComplete}. + * + * @param r The most recent background activity to be drawn. Or, if r is null then a timeout + * occurred and the activity will be notified immediately. + */ + void notifyActivityDrawnLocked(ActivityRecord r) { + if ((r == null) + || (mUndrawnActivitiesBelowTopTranslucent.remove(r) && + mUndrawnActivitiesBelowTopTranslucent.isEmpty())) { + // The last undrawn activity below the top has just been drawn. If there is an + // opaque activity at the top, notify it that it can become translucent safely now. + final ActivityRecord waitingActivity = mTranslucentActivityWaiting; + mTranslucentActivityWaiting = null; + mUndrawnActivitiesBelowTopTranslucent.clear(); + mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG); + + if (waitingActivity != null) { + mWmService.setWindowOpaqueLocked(waitingActivity.appToken, false); + if (waitingActivity.attachedToProcess()) { + try { + waitingActivity.app.getThread().scheduleTranslucentConversionComplete( + waitingActivity.appToken, r != null); + } catch (RemoteException e) { + } + } + } + } + } + + /** @see ActivityRecord#cancelInitializing() */ + void cancelInitializingActivities() { + // We don't want to clear starting window for activities that aren't behind fullscreen + // activities as we need to display their starting window until they are done initializing. + checkBehindFullscreenActivity(null /* toCheck */, ActivityRecord::cancelInitializing); + } + + /** + * If an activity {@param toCheck} is given, this method returns {@code true} if the activity + * is occluded by any fullscreen activity. If there is no {@param toCheck} and the handling + * function {@param handleBehindFullscreenActivity} is given, this method will pass all occluded + * activities to the function. + */ + boolean checkBehindFullscreenActivity(ActivityRecord toCheck, + Consumer<ActivityRecord> handleBehindFullscreenActivity) { + return mCheckBehindFullscreenActivityHelper.process( + toCheck, handleBehindFullscreenActivity); + } + + /** + * Ensure that the top activity in the stack is resumed. + * + * @param prev The previously resumed activity, for when in the process + * of pausing; can be null to call from elsewhere. + * @param options Activity options. + * + * @return Returns true if something is being resumed, or false if + * nothing happened. + * + * NOTE: It is not safe to call this method directly as it can cause an activity in a + * non-focused stack to be resumed. + * Use {@link RootWindowContainer#resumeFocusedStacksTopActivities} to resume the + * right activity for the current system state. + */ + @GuardedBy("mService") + boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { + if (mInResumeTopActivity) { + // Don't even start recursing. + return false; + } + + boolean result = false; + try { + // Protect against recursion. + mInResumeTopActivity = true; + result = resumeTopActivityInnerLocked(prev, options); + + // When resuming the top activity, it may be necessary to pause the top activity (for + // example, returning to the lock screen. We suppress the normal pause logic in + // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the + // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here + // to ensure any necessary pause logic occurs. In the case where the Activity will be + // shown regardless of the lock screen, the call to + // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped. + final ActivityRecord next = topRunningActivity(true /* focusableOnly */); + if (next == null || !next.canTurnScreenOn()) { + checkReadyForSleep(); + } + } finally { + mInResumeTopActivity = false; + } + + return result; + } + + @GuardedBy("mService") + private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { + if (!mAtmService.isBooting() && !mAtmService.isBooted()) { + // Not ready yet! + return false; + } + + // Find the next top-most activity to resume in this stack that is not finishing and is + // focusable. If it is not focusable, we will fall into the case below to resume the + // top activity in the next focusable task. + ActivityRecord next = topRunningActivity(true /* focusableOnly */); + + final boolean hasRunningActivity = next != null; + + // TODO: Maybe this entire condition can get removed? + if (hasRunningActivity && !isAttached()) { + return false; + } + + mRootWindowContainer.cancelInitializingActivities(); + + // Remember how we'll process this pause/resume situation, and ensure + // that the state is reset however we wind up proceeding. + boolean userLeaving = mStackSupervisor.mUserLeaving; + mStackSupervisor.mUserLeaving = false; + + if (!hasRunningActivity) { + // There are no activities left in the stack, let's look somewhere else. + return resumeNextFocusableActivityWhenStackIsEmpty(prev, options); + } + + next.delayedResume = false; + final TaskDisplayArea taskDisplayArea = getDisplayArea(); + + // If the top activity is the resumed one, nothing to do. + if (mResumedActivity == next && next.isState(RESUMED) + && taskDisplayArea.allResumedActivitiesComplete()) { + // Make sure we have executed any pending transitions, since there + // should be nothing left to do at this point. + executeAppTransition(options); + if (DEBUG_STATES) Slog.d(TAG_STATES, + "resumeTopActivityLocked: Top activity resumed " + next); + return false; + } + + if (!next.canResumeByCompat()) { + return false; + } + + // If we are currently pausing an activity, then don't do anything until that is done. + final boolean allPausedComplete = mRootWindowContainer.allPausedActivitiesComplete(); + if (!allPausedComplete) { + if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) { + Slog.v(TAG_PAUSE, "resumeTopActivityLocked: Skip resume: some activity pausing."); + } + return false; + } + + // If we are sleeping, and there is no resumed activity, and the top activity is paused, + // well that is the state we want. + if (shouldSleepOrShutDownActivities() + && mLastPausedActivity == next + && mRootWindowContainer.allPausedActivitiesComplete()) { + // If the current top activity may be able to occlude keyguard but the occluded state + // has not been set, update visibility and check again if we should continue to resume. + boolean nothingToResume = true; + if (!mAtmService.mShuttingDown) { + final boolean canShowWhenLocked = !mTopActivityOccludesKeyguard + && next.canShowWhenLocked(); + final boolean mayDismissKeyguard = mTopDismissingKeyguardActivity != next + && next.containsDismissKeyguardWindow(); + + if (canShowWhenLocked || mayDismissKeyguard) { + ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, + !PRESERVE_WINDOWS); + nothingToResume = shouldSleepActivities(); + } else if (next.currentLaunchCanTurnScreenOn() && next.canTurnScreenOn()) { + nothingToResume = false; + } + } + if (nothingToResume) { + // Make sure we have executed any pending transitions, since there + // should be nothing left to do at this point. + executeAppTransition(options); + if (DEBUG_STATES) Slog.d(TAG_STATES, + "resumeTopActivityLocked: Going to sleep and all paused"); + return false; + } + } + + // Make sure that the user who owns this activity is started. If not, + // we will just leave it as is because someone should be bringing + // another user's activities to the top of the stack. + if (!mAtmService.mAmInternal.hasStartedUserState(next.mUserId)) { + Slog.w(TAG, "Skipping resume of top activity " + next + + ": user " + next.mUserId + " is stopped"); + return false; + } + + // The activity may be waiting for stop, but that is no longer + // appropriate for it. + mStackSupervisor.mStoppingActivities.remove(next); + next.setSleeping(false); + + if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next); + + // If we are currently pausing an activity, then don't do anything until that is done. + if (!mRootWindowContainer.allPausedActivitiesComplete()) { + if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE, + "resumeTopActivityLocked: Skip resume: some activity pausing."); + + return false; + } + + mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid); + + ActivityRecord lastResumed = null; + final Task lastFocusedStack = taskDisplayArea.getLastFocusedStack(); + if (lastFocusedStack != null && lastFocusedStack != this) { + // So, why aren't we using prev here??? See the param comment on the method. prev + // doesn't represent the last resumed activity. However, the last focus stack does if + // it isn't null. + lastResumed = lastFocusedStack.mResumedActivity; + if (userLeaving && inMultiWindowMode() && lastFocusedStack.shouldBeVisible(next)) { + // The user isn't leaving if this stack is the multi-window mode and the last + // focused stack should still be visible. + if(DEBUG_USER_LEAVING) Slog.i(TAG_USER_LEAVING, "Overriding userLeaving to false" + + " next=" + next + " lastResumed=" + lastResumed); + userLeaving = false; + } + } + + boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next); + if (mResumedActivity != null) { + if (DEBUG_STATES) Slog.d(TAG_STATES, + "resumeTopActivityLocked: Pausing " + mResumedActivity); + pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next); + } + if (pausing) { + if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES, + "resumeTopActivityLocked: Skip resume: need to start pausing"); + // At this point we want to put the upcoming activity's process + // at the top of the LRU list, since we know we will be needing it + // very soon and it would be a waste to let it get killed if it + // happens to be sitting towards the end. + if (next.attachedToProcess()) { + next.app.updateProcessInfo(false /* updateServiceConnectionActivities */, + true /* activityChange */, false /* updateOomAdj */, + false /* addPendingTopUid */); + } else if (!next.isProcessRunning()) { + // Since the start-process is asynchronous, if we already know the process of next + // activity isn't running, we can start the process earlier to save the time to wait + // for the current activity to be paused. + final boolean isTop = this == taskDisplayArea.getFocusedStack(); + mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop, + isTop ? "pre-top-activity" : "pre-activity"); + } + if (lastResumed != null) { + lastResumed.setWillCloseOrEnterPip(true); + } + return true; + } else if (mResumedActivity == next && next.isState(RESUMED) + && taskDisplayArea.allResumedActivitiesComplete()) { + // It is possible for the activity to be resumed when we paused back stacks above if the + // next activity doesn't have to wait for pause to complete. + // So, nothing else to-do except: + // Make sure we have executed any pending transitions, since there + // should be nothing left to do at this point. + executeAppTransition(options); + if (DEBUG_STATES) Slog.d(TAG_STATES, + "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next); + return true; + } + + // If the most recent activity was noHistory but was only stopped rather + // than stopped+finished because the device went to sleep, we need to make + // sure to finish it as we're making a new activity topmost. + if (shouldSleepActivities() && mLastNoHistoryActivity != null && + !mLastNoHistoryActivity.finishing) { + if (DEBUG_STATES) Slog.d(TAG_STATES, + "no-history finish of " + mLastNoHistoryActivity + " on new resume"); + mLastNoHistoryActivity.finishIfPossible("resume-no-history", false /* oomAdj */); + mLastNoHistoryActivity = null; + } + + if (prev != null && prev != next && next.nowVisible) { + + // The next activity is already visible, so hide the previous + // activity's windows right now so we can show the new one ASAP. + // We only do this if the previous is finishing, which should mean + // it is on top of the one being resumed so hiding it quickly + // is good. Otherwise, we want to do the normal route of allowing + // the resumed activity to be shown so we can decide if the + // previous should actually be hidden depending on whether the + // new one is found to be full-screen or not. + if (prev.finishing) { + prev.setVisibility(false); + if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, + "Not waiting for visible to hide: " + prev + + ", nowVisible=" + next.nowVisible); + } else { + if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, + "Previous already visible but still waiting to hide: " + prev + + ", nowVisible=" + next.nowVisible); + } + + } + + // Launching this app's activity, make sure the app is no longer + // considered stopped. + try { + mAtmService.getPackageManager().setPackageStoppedState( + next.packageName, false, next.mUserId); /* TODO: Verify if correct userid */ + } catch (RemoteException e1) { + } catch (IllegalArgumentException e) { + Slog.w(TAG, "Failed trying to unstop package " + + next.packageName + ": " + e); + } + + // We are starting up the next activity, so tell the window manager + // that the previous one will be hidden soon. This way it can know + // to ignore it when computing the desired screen orientation. + boolean anim = true; + final DisplayContent dc = taskDisplayArea.mDisplayContent; + if (prev != null) { + if (prev.finishing) { + if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, + "Prepare close transition: prev=" + prev); + if (mStackSupervisor.mNoAnimActivities.contains(prev)) { + anim = false; + dc.prepareAppTransition(TRANSIT_NONE, false); + } else { + dc.prepareAppTransition( + prev.getTask() == next.getTask() ? TRANSIT_ACTIVITY_CLOSE + : TRANSIT_TASK_CLOSE, false); + } + prev.setVisibility(false); + } else { + if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, + "Prepare open transition: prev=" + prev); + if (mStackSupervisor.mNoAnimActivities.contains(next)) { + anim = false; + dc.prepareAppTransition(TRANSIT_NONE, false); + } else { + dc.prepareAppTransition( + prev.getTask() == next.getTask() ? TRANSIT_ACTIVITY_OPEN + : next.mLaunchTaskBehind ? TRANSIT_TASK_OPEN_BEHIND + : TRANSIT_TASK_OPEN, false); + } + } + } else { + if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous"); + if (mStackSupervisor.mNoAnimActivities.contains(next)) { + anim = false; + dc.prepareAppTransition(TRANSIT_NONE, false); + } else { + dc.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false); + } + } + + if (anim) { + next.applyOptionsLocked(); + } else { + next.clearOptionsLocked(); + } + + mStackSupervisor.mNoAnimActivities.clear(); + + if (next.attachedToProcess()) { + if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next + + " stopped=" + next.stopped + + " visibleRequested=" + next.mVisibleRequested); + + // If the previous activity is translucent, force a visibility update of + // the next activity, so that it's added to WM's opening app list, and + // transition animation can be set up properly. + // For example, pressing Home button with a translucent activity in focus. + // Launcher is already visible in this case. If we don't add it to opening + // apps, maybeUpdateTransitToWallpaper() will fail to identify this as a + // TRANSIT_WALLPAPER_OPEN animation, and run some funny animation. + final boolean lastActivityTranslucent = lastFocusedStack != null + && (lastFocusedStack.inMultiWindowMode() + || (lastFocusedStack.mLastPausedActivity != null + && !lastFocusedStack.mLastPausedActivity.occludesParent())); + + // This activity is now becoming visible. + if (!next.mVisibleRequested || next.stopped || lastActivityTranslucent) { + next.setVisibility(true); + } + + // schedule launch ticks to collect information about slow apps. + next.startLaunchTickingLocked(); + + ActivityRecord lastResumedActivity = + lastFocusedStack == null ? null : lastFocusedStack.mResumedActivity; + final ActivityState lastState = next.getState(); + + mAtmService.updateCpuStats(); + + if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next + + " (in existing)"); + + next.setState(RESUMED, "resumeTopActivityInnerLocked"); + + next.app.updateProcessInfo(false /* updateServiceConnectionActivities */, + true /* activityChange */, true /* updateOomAdj */, + true /* addPendingTopUid */); + + // Have the window manager re-evaluate the orientation of + // the screen based on the new activity order. + boolean notUpdated = true; + + // Activity should also be visible if set mLaunchTaskBehind to true (see + // ActivityRecord#shouldBeVisibleIgnoringKeyguard()). + if (shouldBeVisible(next)) { + // We have special rotation behavior when here is some active activity that + // requests specific orientation or Keyguard is locked. Make sure all activity + // visibilities are set correctly as well as the transition is updated if needed + // to get the correct rotation behavior. Otherwise the following call to update + // the orientation may cause incorrect configurations delivered to client as a + // result of invisible window resize. + // TODO: Remove this once visibilities are set correctly immediately when + // starting an activity. + notUpdated = !mRootWindowContainer.ensureVisibilityAndConfig(next, getDisplayId(), + true /* markFrozenIfConfigChanged */, false /* deferResume */); + } + + if (notUpdated) { + // The configuration update wasn't able to keep the existing + // instance of the activity, and instead started a new one. + // We should be all done, but let's just make sure our activity + // is still at the top and schedule another run if something + // weird happened. + ActivityRecord nextNext = topRunningActivity(); + if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES, + "Activity config changed during resume: " + next + + ", new next: " + nextNext); + if (nextNext != next) { + // Do over! + mStackSupervisor.scheduleResumeTopActivities(); + } + if (!next.mVisibleRequested || next.stopped) { + next.setVisibility(true); + } + next.completeResumeLocked(); + return true; + } + + try { + final ClientTransaction transaction = + ClientTransaction.obtain(next.app.getThread(), next.appToken); + // Deliver all pending results. + ArrayList<ResultInfo> a = next.results; + if (a != null) { + final int N = a.size(); + if (!next.finishing && N > 0) { + if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, + "Delivering results to " + next + ": " + a); + transaction.addCallback(ActivityResultItem.obtain(a)); + } + } + + if (next.newIntents != null) { + transaction.addCallback( + NewIntentItem.obtain(next.newIntents, true /* resume */)); + } + + // Well the app will no longer be stopped. + // Clear app token stopped state in window manager if needed. + next.notifyAppResumed(next.stopped); + + EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next), + next.getTask().mTaskId, next.shortComponentName); + + next.setSleeping(false); + mAtmService.getAppWarningsLocked().onResumeActivity(next); + next.app.setPendingUiCleanAndForceProcessStateUpTo(mAtmService.mTopProcessState); + next.clearOptionsLocked(); + transaction.setLifecycleStateRequest( + ResumeActivityItem.obtain(next.app.getReportedProcState(), + dc.isNextTransitionForward())); + mAtmService.getLifecycleManager().scheduleTransaction(transaction); + + if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed " + + next); + } catch (Exception e) { + // Whoops, need to restart this activity! + if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to " + + lastState + ": " + next); + next.setState(lastState, "resumeTopActivityInnerLocked"); + + // lastResumedActivity being non-null implies there is a lastStack present. + if (lastResumedActivity != null) { + lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked"); + } + + Slog.i(TAG, "Restarting because process died: " + next); + if (!next.hasBeenLaunched) { + next.hasBeenLaunched = true; + } else if (SHOW_APP_STARTING_PREVIEW && lastFocusedStack != null + && lastFocusedStack.isTopStackInDisplayArea()) { + next.showStartingWindow(null /* prev */, false /* newTask */, + false /* taskSwitch */); + } + mStackSupervisor.startSpecificActivity(next, true, false); + return true; + } + + // From this point on, if something goes wrong there is no way + // to recover the activity. + try { + next.completeResumeLocked(); + } catch (Exception e) { + // If any exception gets thrown, toss away this + // activity and try the next one. + Slog.w(TAG, "Exception thrown during resume of " + next, e); + next.finishIfPossible("resume-exception", true /* oomAdj */); + return true; + } + } else { + // Whoops, need to restart this activity! + if (!next.hasBeenLaunched) { + next.hasBeenLaunched = true; + } else { + if (SHOW_APP_STARTING_PREVIEW) { + next.showStartingWindow(null /* prev */, false /* newTask */, + false /* taskSwich */); + } + if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next); + } + if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next); + mStackSupervisor.startSpecificActivity(next, true, true); + } + + return true; + } + + /** + * Resume the next eligible activity in a focusable stack when this one does not have any + * running activities left. The focus will be adjusted to the next focusable stack and + * top running activities will be resumed in all focusable stacks. However, if the current stack + * is a home stack - we have to keep it focused, start and resume a home activity on the current + * display instead to make sure that the display is not empty. + */ + private boolean resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev, + ActivityOptions options) { + final String reason = "noMoreActivities"; + + if (!isActivityTypeHome()) { + final Task nextFocusedStack = adjustFocusToNextFocusableTask(reason); + if (nextFocusedStack != null) { + // Try to move focus to the next visible stack with a running activity if this + // stack is not covering the entire screen or is on a secondary display with no home + // stack. + return mRootWindowContainer.resumeFocusedStacksTopActivities(nextFocusedStack, + prev, null /* targetOptions */); + } + } + + // If the current stack is a home stack, or if focus didn't switch to a different stack - + // just start up the Launcher... + ActivityOptions.abort(options); + if (DEBUG_STATES) Slog.d(TAG_STATES, + "resumeNextFocusableActivityWhenStackIsEmpty: " + reason + ", go home"); + return mRootWindowContainer.resumeHomeActivity(prev, reason, getDisplayArea()); + } + + void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity, + boolean newTask, boolean keepCurTransition, ActivityOptions options) { + Task rTask = r.getTask(); + final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront(); + final boolean isOrhasTask = rTask == this || hasChild(rTask); + // mLaunchTaskBehind tasks get placed at the back of the task stack. + if (!r.mLaunchTaskBehind && allowMoveToFront && (!isOrhasTask || newTask)) { + // Last activity in task had been removed or ActivityManagerService is reusing task. + // Insert or replace. + // Might not even be in. + positionChildAtTop(rTask); + } + Task task = null; + if (!newTask && isOrhasTask) { + // Starting activity cannot be occluding activity, otherwise starting window could be + // remove immediately without transferring to starting activity. + final ActivityRecord occludingActivity = getOccludingActivityAbove(r); + if (occludingActivity != null) { + // Here it is! Now, if this is not yet visible (occluded by another task) to the + // user, then just add it without starting; it will get started when the user + // navigates back to it. + if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task " + task, + new RuntimeException("here").fillInStackTrace()); + rTask.positionChildAtTop(r); + ActivityOptions.abort(options); + return; + } + } + + // Place a new activity at top of stack, so it is next to interact with the user. + + // If we are not placing the new activity frontmost, we do not want to deliver the + // onUserLeaving callback to the actual frontmost activity + final Task activityTask = r.getTask(); + if (task == activityTask && mChildren.indexOf(task) != (getChildCount() - 1)) { + mStackSupervisor.mUserLeaving = false; + if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, + "startActivity() behind front, mUserLeaving=false"); + } + + task = activityTask; + + // Slot the activity into the history stack and proceed + if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task, + new RuntimeException("here").fillInStackTrace()); + task.positionChildAtTop(r); + + // The transition animation and starting window are not needed if {@code allowMoveToFront} + // is false, because the activity won't be visible. + if ((!isHomeOrRecentsStack() || hasActivity()) && allowMoveToFront) { + final DisplayContent dc = getDisplay().mDisplayContent; + if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, + "Prepare open transition: starting " + r); + if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { + dc.prepareAppTransition(TRANSIT_NONE, keepCurTransition); + mStackSupervisor.mNoAnimActivities.add(r); + } else { + int transit = TRANSIT_ACTIVITY_OPEN; + if (newTask) { + if (r.mLaunchTaskBehind) { + transit = TRANSIT_TASK_OPEN_BEHIND; + } else if (getDisplay().isSingleTaskInstance()) { + // If a new task is being launched in a single task display, we don't need + // to play normal animation, but need to trigger a callback when an app + // transition is actually handled. So ignore already prepared activity, and + // override it. + transit = TRANSIT_SHOW_SINGLE_TASK_DISPLAY; + keepCurTransition = false; + } else { + // If a new task is being launched, then mark the existing top activity as + // supporting picture-in-picture while pausing only if the starting activity + // would not be considered an overlay on top of the current activity + // (eg. not fullscreen, or the assistant) + if (canEnterPipOnTaskSwitch(focusedTopActivity, + null /* toFrontTask */, r, options)) { + focusedTopActivity.supportsEnterPipOnTaskSwitch = true; + } + transit = TRANSIT_TASK_OPEN; + } + } + dc.prepareAppTransition(transit, keepCurTransition); + mStackSupervisor.mNoAnimActivities.remove(r); + } + boolean doShow = true; + if (newTask) { + // Even though this activity is starting fresh, we still need + // to reset it to make sure we apply affinities to move any + // existing activities from other tasks in to it. + // If the caller has requested that the target task be + // reset, then do so. + if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { + resetTaskIfNeeded(r, r); + doShow = topRunningNonDelayedActivityLocked(null) == r; + } + } else if (options != null && options.getAnimationType() + == ActivityOptions.ANIM_SCENE_TRANSITION) { + doShow = false; + } + if (r.mLaunchTaskBehind) { + // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we + // tell WindowManager that r is visible even though it is at the back of the stack. + r.setVisibility(true); + ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); + // Go ahead to execute app transition for this activity since the app transition + // will not be triggered through the resume channel. + getDisplay().mDisplayContent.executeAppTransition(); + } else if (SHOW_APP_STARTING_PREVIEW && doShow) { + // Figure out if we are transitioning from another activity that is + // "has the same starting icon" as the next one. This allows the + // window manager to keep the previous window it had previously + // created, if it still had one. + Task prevTask = r.getTask(); + ActivityRecord prev = prevTask.topActivityWithStartingWindow(); + if (prev != null) { + // We don't want to reuse the previous starting preview if: + // (1) The current activity is in a different task. + if (prev.getTask() != prevTask) { + prev = null; + } + // (2) The current activity is already displayed. + else if (prev.nowVisible) { + prev = null; + } + } + r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity)); + } + } else { + // If this is the first activity, don't do any fancy animations, + // because there is nothing for it to animate on top of. + ActivityOptions.abort(options); + } + } + + /** + * @return Whether the switch to another task can trigger the currently running activity to + * enter PiP while it is pausing (if supported). Only one of {@param toFrontTask} or + * {@param toFrontActivity} should be set. + */ + private boolean canEnterPipOnTaskSwitch(ActivityRecord pipCandidate, + Task toFrontTask, ActivityRecord toFrontActivity, ActivityOptions opts) { + if (opts != null && opts.disallowEnterPictureInPictureWhileLaunching()) { + // Ensure the caller has requested not to trigger auto-enter PiP + return false; + } + if (pipCandidate == null || pipCandidate.inPinnedWindowingMode()) { + // Ensure that we do not trigger entering PiP an activity on the pinned stack + return false; + } + final Task targetStack = toFrontTask != null + ? toFrontTask.getRootTask() : toFrontActivity.getRootTask(); + if (targetStack != null && targetStack.isActivityTypeAssistant()) { + // Ensure the task/activity being brought forward is not the assistant + return false; + } + return true; + } + + private boolean isTaskSwitch(ActivityRecord r, ActivityRecord topFocusedActivity) { + return topFocusedActivity != null && r.getTask() != topFocusedActivity.getTask(); + } + + /** + * Reset the task by reparenting the activities that have same affinity to the task or + * reparenting the activities that have different affinityies out of the task, while these + * activities allow task reparenting. + * + * @param taskTop Top activity of the task might be reset. + * @param newActivity The activity that going to be started. + * @return The non-finishing top activity of the task after reset or the original task top + * activity if all activities within the task are finishing. + */ + ActivityRecord resetTaskIfNeeded(ActivityRecord taskTop, ActivityRecord newActivity) { + final boolean forceReset = + (newActivity.info.flags & ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0; + final Task task = taskTop.getTask(); + + // If ActivityOptions are moved out and need to be aborted or moved to taskTop. + final ActivityOptions topOptions = sResetTargetTaskHelper.process(task, forceReset); + + if (mChildren.contains(task)) { + final ActivityRecord newTop = task.getTopNonFinishingActivity(); + if (newTop != null) { + taskTop = newTop; + } + } + + if (topOptions != null) { + // If we got some ActivityOptions from an activity on top that + // was removed from the task, propagate them to the new real top. + taskTop.updateOptionsLocked(topOptions); + } + + return taskTop; + } + + /** + * Finish the topmost activity that belongs to the crashed app. We may also finish the activity + * that requested launch of the crashed one to prevent launch-crash loop. + * @param app The app that crashed. + * @param reason Reason to perform this action. + * @return The task that was finished in this stack, {@code null} if top running activity does + * not belong to the crashed app. + */ + final Task finishTopCrashedActivityLocked(WindowProcessController app, String reason) { + final ActivityRecord r = topRunningActivity(); + if (r == null || r.app != app) { + return null; + } + if (r.isActivityTypeHome() && mAtmService.mHomeProcess == app) { + // Home activities should not be force-finished as we have nothing else to go + // back to. AppErrors will get to it after two crashes in MIN_CRASH_INTERVAL. + Slog.w(TAG, " Not force finishing home activity " + + r.intent.getComponent().flattenToShortString()); + return null; + } + Slog.w(TAG, " Force finishing activity " + + r.intent.getComponent().flattenToShortString()); + Task finishedTask = r.getTask(); + getDisplay().mDisplayContent.prepareAppTransition( + TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */); + r.finishIfPossible(reason, false /* oomAdj */); + + // Also terminate any activities below it that aren't yet stopped, to avoid a situation + // where one will get re-start our crashing activity once it gets resumed again. + final ActivityRecord activityBelow = getActivityBelow(r); + if (activityBelow != null) { + if (activityBelow.isState(STARTED, RESUMED, PAUSING, PAUSED)) { + if (!activityBelow.isActivityTypeHome() + || mAtmService.mHomeProcess != activityBelow.app) { + Slog.w(TAG, " Force finishing activity " + + activityBelow.intent.getComponent().flattenToShortString()); + activityBelow.finishIfPossible(reason, false /* oomAdj */); + } + } + } + + return finishedTask; + } + + void finishVoiceTask(IVoiceInteractionSession session) { + final PooledConsumer c = PooledLambda.obtainConsumer(Task::finishIfVoiceTask, + PooledLambda.__(Task.class), session.asBinder()); + forAllLeafTasks(c, true /* traverseTopToBottom */); + c.recycle(); + } + + private static void finishIfVoiceTask(Task tr, IBinder binder) { + if (tr.voiceSession != null && tr.voiceSession.asBinder() == binder) { + tr.forAllActivities((r) -> { + if (r.finishing) return; + r.finishIfPossible("finish-voice", false /* oomAdj */); + tr.mAtmService.updateOomAdj(); + }); + } else { + // Check if any of the activities are using voice + final PooledFunction f = PooledLambda.obtainFunction( + Task::finishIfVoiceActivity, PooledLambda.__(ActivityRecord.class), + binder); + tr.forAllActivities(f); + f.recycle(); + } + } + + private static boolean finishIfVoiceActivity(ActivityRecord r, IBinder binder) { + if (r.voiceSession == null || r.voiceSession.asBinder() != binder) return false; + // Inform of cancellation + r.clearVoiceSessionLocked(); + try { + r.app.getThread().scheduleLocalVoiceInteractionStarted(r.appToken, null); + } catch (RemoteException re) { + // Ok Boomer... + } + r.mAtmService.finishRunningVoiceLocked(); + return true; + } + + /** Finish all activities in the stack without waiting. */ + void finishAllActivitiesImmediately() { + if (!hasChild()) { + removeIfPossible(); + return; + } + forAllActivities((r) -> { + Slog.d(TAG, "finishAllActivitiesImmediatelyLocked: finishing " + r); + r.destroyIfPossible("finishAllActivitiesImmediately"); + }); + } + + /** @return true if the stack behind this one is a standard activity type. */ + private boolean inFrontOfStandardStack() { + final TaskDisplayArea taskDisplayArea = getDisplayArea(); + if (taskDisplayArea == null) { + return false; + } + final int index = taskDisplayArea.getIndexOf(this); + if (index == 0) { + return false; + } + final Task stackBehind = taskDisplayArea.getChildAt(index - 1); + return stackBehind.isActivityTypeStandard(); + } + + boolean shouldUpRecreateTaskLocked(ActivityRecord srec, String destAffinity) { + // Basic case: for simple app-centric recents, we need to recreate + // the task if the affinity has changed. + + final String affinity = ActivityRecord.getTaskAffinityWithUid(destAffinity, srec.getUid()); + if (srec == null || srec.getTask().affinity == null + || !srec.getTask().affinity.equals(affinity)) { + return true; + } + // Document-centric case: an app may be split in to multiple documents; + // they need to re-create their task if this current activity is the root + // of a document, unless simply finishing it will return them to the + // correct app behind. + final Task task = srec.getTask(); + if (srec.isRootOfTask() && task.getBaseIntent() != null + && task.getBaseIntent().isDocument()) { + // Okay, this activity is at the root of its task. What to do, what to do... + if (!inFrontOfStandardStack()) { + // Finishing won't return to an application, so we need to recreate. + return true; + } + // We now need to get the task below it to determine what to do. + final Task prevTask = getTaskBelow(task); + if (prevTask == null) { + Slog.w(TAG, "shouldUpRecreateTask: task not in history for " + srec); + return false; + } + if (!task.affinity.equals(prevTask.affinity)) { + // These are different apps, so need to recreate. + return true; + } + } + return false; + } + + boolean navigateUpTo(ActivityRecord srec, Intent destIntent, NeededUriGrants destGrants, + int resultCode, Intent resultData, NeededUriGrants resultGrants) { + if (!srec.attachedToProcess()) { + // Nothing to do if the caller is not attached, because this method should be called + // from an alive activity. + return false; + } + final Task task = srec.getTask(); + if (!srec.isDescendantOf(this)) { + return false; + } + + ActivityRecord parent = task.getActivityBelow(srec); + boolean foundParentInTask = false; + final ComponentName dest = destIntent.getComponent(); + if (task.getBottomMostActivity() != srec && dest != null) { + final ActivityRecord candidate = task.getActivity( + (ar) -> ar.info.packageName.equals(dest.getPackageName()) + && ar.info.name.equals(dest.getClassName()), srec, + false /*includeBoundary*/, true /*traverseTopToBottom*/); + if (candidate != null) { + parent = candidate; + foundParentInTask = true; + } + } + + // TODO: There is a dup. of this block of code in ActivityTaskManagerService.finishActivity + // We should consolidate. + IActivityController controller = mAtmService.mController; + if (controller != null) { + ActivityRecord next = topRunningActivity(srec.appToken, INVALID_TASK_ID); + if (next != null) { + // ask watcher if this is allowed + boolean resumeOK = true; + try { + resumeOK = controller.activityResuming(next.packageName); + } catch (RemoteException e) { + mAtmService.mController = null; + Watchdog.getInstance().setActivityController(null); + } + + if (!resumeOK) { + return false; + } + } + } + final long origId = Binder.clearCallingIdentity(); + + final int[] resultCodeHolder = new int[1]; + resultCodeHolder[0] = resultCode; + final Intent[] resultDataHolder = new Intent[1]; + resultDataHolder[0] = resultData; + final NeededUriGrants[] resultGrantsHolder = new NeededUriGrants[1]; + resultGrantsHolder[0] = resultGrants; + final ActivityRecord finalParent = parent; + task.forAllActivities((ar) -> { + if (ar == finalParent) return true; + + ar.finishIfPossible(resultCodeHolder[0], resultDataHolder[0], resultGrantsHolder[0], + "navigate-up", true /* oomAdj */); + // Only return the supplied result for the first activity finished + resultCodeHolder[0] = Activity.RESULT_CANCELED; + resultDataHolder[0] = null; + return false; + }, srec, true, true); + resultCode = resultCodeHolder[0]; + resultData = resultDataHolder[0]; + + if (parent != null && foundParentInTask) { + final int callingUid = srec.info.applicationInfo.uid; + final int parentLaunchMode = parent.info.launchMode; + final int destIntentFlags = destIntent.getFlags(); + if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || + parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || + parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || + (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { + parent.deliverNewIntentLocked(callingUid, destIntent, destGrants, srec.packageName); + } else { + try { + ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( + destIntent.getComponent(), ActivityManagerService.STOCK_PM_FLAGS, + srec.mUserId); + // TODO(b/64750076): Check if calling pid should really be -1. + final int res = mAtmService.getActivityStartController() + .obtainStarter(destIntent, "navigateUpTo") + .setCaller(srec.app.getThread()) + .setActivityInfo(aInfo) + .setResultTo(parent.appToken) + .setCallingPid(-1) + .setCallingUid(callingUid) + .setCallingPackage(srec.packageName) + .setCallingFeatureId(parent.launchedFromFeatureId) + .setRealCallingPid(-1) + .setRealCallingUid(callingUid) + .setComponentSpecified(true) + .execute(); + foundParentInTask = res == ActivityManager.START_SUCCESS; + } catch (RemoteException e) { + foundParentInTask = false; + } + parent.finishIfPossible(resultCode, resultData, resultGrants, + "navigate-top", true /* oomAdj */); + } + } + Binder.restoreCallingIdentity(origId); + return foundParentInTask; + } + + void removeLaunchTickMessages() { + forAllActivities(ActivityRecord::removeLaunchTickRunnable); + } + + private void updateTransitLocked(int transit, ActivityOptions options, boolean forceOverride) { + if (options != null) { + ActivityRecord r = topRunningActivity(); + if (r != null && !r.isState(RESUMED)) { + r.updateOptionsLocked(options); + } else { + ActivityOptions.abort(options); + } + } + getDisplay().mDisplayContent.prepareAppTransition(transit, false, + 0 /* flags */, forceOverride); + } + + final void moveTaskToFront(Task tr, boolean noAnimation, ActivityOptions options, + AppTimeTracker timeTracker, String reason) { + moveTaskToFront(tr, noAnimation, options, timeTracker, !DEFER_RESUME, reason); + } + + final void moveTaskToFront(Task tr, boolean noAnimation, ActivityOptions options, + AppTimeTracker timeTracker, boolean deferResume, String reason) { + if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr); + + final Task topStack = getDisplayArea().getTopStack(); + final ActivityRecord topActivity = topStack != null + ? topStack.getTopNonFinishingActivity() : null; + + if (tr != this && !tr.isDescendantOf(this)) { + // nothing to do! + if (noAnimation) { + ActivityOptions.abort(options); + } else if (isSingleTaskInstance()) { + // When a task is moved front on the display which can only contain one task, start + // a special transition. + // {@link AppTransitionController#handleAppTransitionReady} later picks up the + // transition, and schedules + // {@link ITaskStackListener#onSingleTaskDisplayDrawn} callback which is triggered + // after contents are drawn on the display. + updateTransitLocked(TRANSIT_SHOW_SINGLE_TASK_DISPLAY, options, + true /* forceOverride */); + } else { + updateTransitLocked(TRANSIT_TASK_TO_FRONT, options, false /* forceOverride */); + } + return; + } + + if (timeTracker != null) { + // The caller wants a time tracker associated with this task. + final PooledConsumer c = PooledLambda.obtainConsumer(ActivityRecord::setAppTimeTracker, + PooledLambda.__(ActivityRecord.class), timeTracker); + tr.forAllActivities(c); + c.recycle(); + } + + try { + // Defer updating the IME target since the new IME target will try to get computed + // before updating all closing and opening apps, which can cause the ime target to + // get calculated incorrectly. + getDisplay().deferUpdateImeTarget(); + + // Shift all activities with this task up to the top + // of the stack, keeping them in the same internal order. + positionChildAtTop(tr); + + // Don't refocus if invisible to current user + final ActivityRecord top = tr.getTopNonFinishingActivity(); + if (top == null || !top.okToShowLocked()) { + if (top != null) { + mStackSupervisor.mRecentTasks.add(top.getTask()); + } + ActivityOptions.abort(options); + return; + } + + // Set focus to the top running activity of this stack. + final ActivityRecord r = topRunningActivity(); + if (r != null) { + r.moveFocusableActivityToTop(reason); + } + + if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr); + if (noAnimation) { + getDisplay().mDisplayContent.prepareAppTransition(TRANSIT_NONE, false); + if (r != null) { + mStackSupervisor.mNoAnimActivities.add(r); + } + ActivityOptions.abort(options); + } else if (isSingleTaskInstance()) { + updateTransitLocked(TRANSIT_SHOW_SINGLE_TASK_DISPLAY, options, + true /* forceOverride */); + } else { + updateTransitLocked(TRANSIT_TASK_TO_FRONT, options, false /* forceOverride */); + } + + // If a new task is moved to the front, then mark the existing top activity as + // supporting + + // picture-in-picture while paused only if the task would not be considered an oerlay + // on top + // of the current activity (eg. not fullscreen, or the assistant) + if (canEnterPipOnTaskSwitch(topActivity, tr, null /* toFrontActivity */, + options)) { + topActivity.supportsEnterPipOnTaskSwitch = true; + } + + if (!deferResume) { + mRootWindowContainer.resumeFocusedStacksTopActivities(); + } + EventLogTags.writeWmTaskToFront(tr.mUserId, tr.mTaskId); + mAtmService.getTaskChangeNotificationController() + .notifyTaskMovedToFront(tr.getTaskInfo()); + } finally { + getDisplay().continueUpdateImeTarget(); + } + } + + /** + * Worker method for rearranging history stack. Implements the function of moving all + * activities for a specific task (gathering them if disjoint) into a single group at the + * bottom of the stack. + * + * If a watcher is installed, the action is preflighted and the watcher has an opportunity + * to premeptively cancel the move. + * + * @param tr The task to collect and move to the bottom. + * @return Returns true if the move completed, false if not. + */ + boolean moveTaskToBack(Task tr) { + Slog.i(TAG, "moveTaskToBack: " + tr); + + // In LockTask mode, moving a locked task to the back of the stack may expose unlocked + // ones. Therefore we need to check if this operation is allowed. + if (!mAtmService.getLockTaskController().canMoveTaskToBack(tr)) { + return false; + } + + // If we have a watcher, preflight the move before committing to it. First check + // for *other* available tasks, but if none are available, then try again allowing the + // current task to be selected. + if (isTopStackInDisplayArea() && mAtmService.mController != null) { + ActivityRecord next = topRunningActivity(null, tr.mTaskId); + if (next == null) { + next = topRunningActivity(null, INVALID_TASK_ID); + } + if (next != null) { + // ask watcher if this is allowed + boolean moveOK = true; + try { + moveOK = mAtmService.mController.activityResuming(next.packageName); + } catch (RemoteException e) { + mAtmService.mController = null; + Watchdog.getInstance().setActivityController(null); + } + if (!moveOK) { + return false; + } + } + } + + if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task=" + + tr.mTaskId); + + getDisplay().mDisplayContent.prepareAppTransition(TRANSIT_TASK_TO_BACK, false); + moveToBack("moveTaskToBackLocked", tr); + + if (inPinnedWindowingMode()) { + mStackSupervisor.removeStack(this); + return true; + } + + mRootWindowContainer.ensureVisibilityAndConfig(null /* starting */, + getDisplay().mDisplayId, false /* markFrozenIfConfigChanged */, + false /* deferResume */); + + ActivityRecord topActivity = getDisplayArea().topRunningActivity(); + Task topStack = topActivity.getRootTask(); + if (topStack != null && topStack != this && topActivity.isState(RESUMED)) { + // Usually resuming a top activity triggers the next app transition, but nothing's got + // resumed in this case, so we need to execute it explicitly. + getDisplay().mDisplayContent.executeAppTransition(); + } else { + mRootWindowContainer.resumeFocusedStacksTopActivities(); + } + return true; + } + + /** + * Ensures all visible activities at or below the input activity have the right configuration. + */ + void ensureVisibleActivitiesConfiguration(ActivityRecord start, boolean preserveWindow) { + mEnsureVisibleActivitiesConfigHelper.process(start, preserveWindow); + } + + // TODO: Can only be called from special methods in ActivityStackSupervisor. + // Need to consolidate those calls points into this resize method so anyone can call directly. + void resize(Rect displayedBounds, boolean preserveWindows, boolean deferResume) { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "stack.resize_" + getRootTaskId()); + mAtmService.deferWindowLayout(); + try { + // TODO: Why not just set this on the stack directly vs. on each tasks? + // Update override configurations of all tasks in the stack. + final PooledConsumer c = PooledLambda.obtainConsumer( + Task::processTaskResizeBounds, PooledLambda.__(Task.class), + displayedBounds); + forAllTasks(c, true /* traverseTopToBottom */); + c.recycle(); + + if (mBoundsAnimating) { + // Force to update task surface bounds and relayout windows, since configBounds + // remains unchanged during bounds animation. + updateSurfaceBounds(); + getDisplay().setLayoutNeeded(); + mWmService.requestTraversal(); + } + + if (!deferResume) { + ensureVisibleActivitiesConfiguration(topRunningActivity(), preserveWindows); + } + } finally { + mAtmService.continueWindowLayout(); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } + } + + private static void processTaskResizeBounds(Task task, Rect displayedBounds) { + if (!task.isResizeable()) return; + + task.setBounds(displayedBounds); + } + + /** + * Until we can break this "set task bounds to same as stack bounds" behavior, this + * basically resizes both stack and task bounds to the same bounds. + */ + private void setTaskBounds(Rect bounds) { + final PooledConsumer c = PooledLambda.obtainConsumer(Task::setTaskBoundsInner, + PooledLambda.__(Task.class), bounds); + forAllLeafTasks(c, true /* traverseTopToBottom */); + c.recycle(); + } + + private static void setTaskBoundsInner(Task task, Rect bounds) { + task.setBounds(task.isResizeable() ? bounds : null); + } + + boolean willActivityBeVisible(IBinder token) { + final ActivityRecord r = ActivityRecord.forTokenLocked(token); + if (r == null) { + return false; + } + + // See if there is an occluding activity on-top of this one. + final ActivityRecord occludingActivity = getOccludingActivityAbove(r); + if (occludingActivity != null) return false; + + if (r.finishing) Slog.e(TAG, "willActivityBeVisible: Returning false," + + " would have returned true for r=" + r); + return !r.finishing; + } + + void unhandledBackLocked() { + final ActivityRecord topActivity = getTopMostActivity(); + if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, + "Performing unhandledBack(): top activity: " + topActivity); + if (topActivity != null) { + topActivity.finishIfPossible("unhandled-back", true /* oomAdj */); + } + } + + /** + * Reset local parameters because an app's activity died. + * @param app The app of the activity that died. + * @return result from removeHistoryRecordsForAppLocked. + */ + boolean handleAppDied(WindowProcessController app) { + if (mPausingActivity != null && mPausingActivity.app == app) { + if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE, + "App died while pausing: " + mPausingActivity); + mPausingActivity = null; + } + if (mLastPausedActivity != null && mLastPausedActivity.app == app) { + mLastPausedActivity = null; + mLastNoHistoryActivity = null; + } + + mStackSupervisor.removeHistoryRecords(app); + return mRemoveHistoryRecordsForApp.process(app); + } + + boolean dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, + String dumpPackage, final boolean needSep) { + Runnable headerPrinter = () -> { + if (needSep) { + pw.println(); + } + pw.println(" Stack #" + getRootTaskId() + + ": type=" + activityTypeToString(getActivityType()) + + " mode=" + windowingModeToString(getWindowingMode())); + pw.println(" isSleeping=" + shouldSleepActivities()); + pw.println(" mBounds=" + getRequestedOverrideBounds()); + }; + + boolean printed = false; + + if (dumpPackage == null) { + // If we are not filtering by package, we want to print absolutely everything, + // so always print the header even if there are no tasks/activities inside. + headerPrinter.run(); + headerPrinter = null; + printed = true; + } + + printed |= printThisActivity(pw, mPausingActivity, dumpPackage, false, + " mPausingActivity: ", null); + printed |= printThisActivity(pw, getResumedActivity(), dumpPackage, false, + " mResumedActivity: ", null); + if (dumpAll) { + printed |= printThisActivity(pw, mLastPausedActivity, dumpPackage, false, + " mLastPausedActivity: ", null); + printed |= printThisActivity(pw, mLastNoHistoryActivity, dumpPackage, + false, " mLastNoHistoryActivity: ", null); + } + + printed |= dumpActivities(fd, pw, dumpAll, dumpClient, dumpPackage, false, headerPrinter); + + return printed; + } + + private boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, + boolean dumpClient, String dumpPackage, boolean needSep, Runnable header) { + if (!hasChild()) { + return false; + } + final AtomicBoolean printedHeader = new AtomicBoolean(false); + final AtomicBoolean printed = new AtomicBoolean(false); + forAllLeafTasks((task) -> { + final String prefix = " "; + Runnable headerPrinter = () -> { + printed.set(true); + if (!printedHeader.get()) { + if (needSep) { + pw.println(""); + } + if (header != null) { + header.run(); + } + printedHeader.set(true); + } + pw.print(prefix); pw.print("* "); pw.println(task); + pw.print(prefix); pw.print(" mBounds="); + pw.println(task.getRequestedOverrideBounds()); + pw.print(prefix); pw.print(" mMinWidth="); pw.print(task.mMinWidth); + pw.print(" mMinHeight="); pw.println(task.mMinHeight); + if (mLastNonFullscreenBounds != null) { + pw.print(prefix); + pw.print(" mLastNonFullscreenBounds="); + pw.println(task.mLastNonFullscreenBounds); + } + task.dump(pw, prefix + " "); + }; + if (dumpPackage == null) { + // If we are not filtering by package, we want to print absolutely everything, + // so always print the header even if there are no activities inside. + headerPrinter.run(); + headerPrinter = null; + } + final ArrayList<ActivityRecord> activities = new ArrayList<>(); + // Add activities by traversing the hierarchy from bottom to top, since activities + // are dumped in reverse order in {@link ActivityStackSupervisor#dumpHistoryList()}. + task.forAllActivities((Consumer<ActivityRecord>) activities::add, + false /* traverseTopToBottom */); + dumpHistoryList(fd, pw, activities, prefix, "Hist", true, !dumpAll, dumpClient, + dumpPackage, false, headerPrinter, task); + }, true /* traverseTopToBottom */); + return printed.get(); + } + + ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { + ArrayList<ActivityRecord> activities = new ArrayList<>(); + + if ("all".equals(name)) { + forAllActivities((Consumer<ActivityRecord>) activities::add); + } else if ("top".equals(name)) { + final ActivityRecord topActivity = getTopMostActivity(); + if (topActivity != null) { + activities.add(topActivity); + } + } else { + ActivityManagerService.ItemMatcher matcher = new ActivityManagerService.ItemMatcher(); + matcher.build(name); + + forAllActivities((r) -> { + if (matcher.match(r, r.intent.getComponent())) { + activities.add(r); + } + }); + } + + return activities; + } + + ActivityRecord restartPackage(String packageName) { + ActivityRecord starting = topRunningActivity(); + + // All activities that came from the package must be + // restarted as if there was a config change. + PooledConsumer c = PooledLambda.obtainConsumer(Task::restartPackage, + PooledLambda.__(ActivityRecord.class), starting, packageName); + forAllActivities(c); + c.recycle(); + + return starting; + } + + private static void restartPackage( + ActivityRecord r, ActivityRecord starting, String packageName) { + if (r.info.packageName.equals(packageName)) { + r.forceNewConfig = true; + if (starting != null && r == starting && r.mVisibleRequested) { + r.startFreezingScreenLocked(CONFIG_SCREEN_LAYOUT); + } + } + } + + Task reuseOrCreateTask(ActivityInfo info, Intent intent, boolean toTop) { + return reuseOrCreateTask(info, intent, null /*voiceSession*/, null /*voiceInteractor*/, + toTop, null /*activity*/, null /*source*/, null /*options*/); + } + // TODO: Can be removed once we change callpoints creating stacks to be creating tasks. + /** Either returns this current task to be re-used or creates a new child task. */ + Task reuseOrCreateTask(ActivityInfo info, Intent intent, IVoiceInteractionSession voiceSession, + IVoiceInteractor voiceInteractor, boolean toTop, ActivityRecord activity, + ActivityRecord source, ActivityOptions options) { + + Task task; + if (DisplayContent.alwaysCreateStack(getWindowingMode(), getActivityType())) { + // This stack will only contain one task, so just return itself since all stacks ara now + // tasks and all tasks are now stacks. + task = reuseAsLeafTask(voiceSession, voiceInteractor, intent, info, activity); + } else { + // Create child task since this stack can contain multiple tasks. + final int taskId = activity != null + ? mStackSupervisor.getNextTaskIdForUser(activity.mUserId) + : mStackSupervisor.getNextTaskIdForUser(); + task = new Task(mAtmService, taskId, info, intent, voiceSession, + voiceInteractor, null /* taskDescription */, this); + + // add the task to stack first, mTaskPositioner might need the stack association + addChild(task, toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0); + } + + int displayId = getDisplayId(); + if (displayId == INVALID_DISPLAY) displayId = DEFAULT_DISPLAY; + final boolean isLockscreenShown = mAtmService.mStackSupervisor.getKeyguardController() + .isKeyguardOrAodShowing(displayId); + if (!mStackSupervisor.getLaunchParamsController() + .layoutTask(task, info.windowLayout, activity, source, options) + && !getRequestedOverrideBounds().isEmpty() + && task.isResizeable() && !isLockscreenShown) { + task.setBounds(getRequestedOverrideBounds()); + } + + return task; + } + + void addChild(WindowContainer child, final boolean toTop, boolean showForAllUsers) { + if (isSingleTaskInstance() && hasChild()) { + throw new IllegalStateException("Can only have one child on stack=" + this); + } + + Task task = child.asTask(); + try { + + if (task != null) { + task.setForceShowForAllUsers(showForAllUsers); + } + // We only want to move the parents to the parents if we are creating this task at the + // top of its stack. + addChild(child, toTop ? MAX_VALUE : 0, toTop /*moveParents*/); + } finally { + if (task != null) { + task.setForceShowForAllUsers(false); + } + } + } + + void positionChildAt(Task task, int position) { + if (task.getRootTask() != this) { + throw new IllegalArgumentException("AS.positionChildAt: task=" + task + + " is not a child of stack=" + this + " current parent=" + task.getRootTask()); + } + + task.updateOverrideConfigurationForStack(this); + + final ActivityRecord topRunningActivity = task.topRunningActivityLocked(); + final boolean wasResumed = topRunningActivity == task.getRootTask().mResumedActivity; + + boolean toTop = position >= getChildCount(); + boolean includingParents = toTop || getDisplayArea().getNextFocusableStack(this, + true /* ignoreCurrent */) == null; + if (WindowManagerDebugConfig.DEBUG_STACK) { + Slog.i(TAG_WM, "positionChildAt: positioning task=" + task + " at " + position); + } + positionChildAt(position, task, includingParents); + task.updateTaskMovement(toTop); + getDisplayContent().layoutAndAssignWindowLayersIfNeeded(); + + + // TODO: Investigate if this random code is really needed. + if (task.voiceSession != null) { + try { + task.voiceSession.taskStarted(task.intent, task.mTaskId); + } catch (RemoteException e) { + } + } + + if (wasResumed) { + if (mResumedActivity != null) { + Log.wtf(TAG, "mResumedActivity was already set when moving mResumedActivity from" + + " other stack to this stack mResumedActivity=" + mResumedActivity + + " other mResumedActivity=" + topRunningActivity); + } + topRunningActivity.setState(RESUMED, "positionChildAt"); + } + + // The task might have already been running and its visibility needs to be synchronized with + // the visibility of the stack / windows. + ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); + mRootWindowContainer.resumeFocusedStacksTopActivities(); + } + + public void setAlwaysOnTop(boolean alwaysOnTop) { + if (isAlwaysOnTop() == alwaysOnTop) { + return; + } + super.setAlwaysOnTop(alwaysOnTop); + final TaskDisplayArea taskDisplayArea = getDisplayArea(); + // positionChildAtTop() must be called even when always on top gets turned off because we + // need to make sure that the stack is moved from among always on top windows to below other + // always on top windows. Since the position the stack should be inserted into is calculated + // properly in {@link DisplayContent#getTopInsertPosition()} in both cases, we can just + // request that the stack is put at top here. + taskDisplayArea.positionStackAtTop(this, false /* includingParents */); + } + + /** NOTE: Should only be called from {@link Task#reparent}. */ + void moveToFrontAndResumeStateIfNeeded(ActivityRecord r, boolean moveToFront, boolean setResume, + boolean setPause, String reason) { + if (!moveToFront) { + return; + } + + final ActivityState origState = r.getState(); + // If the activity owns the last resumed activity, transfer that together, + // so that we don't resume the same activity again in the new stack. + // Apps may depend on onResume()/onPause() being called in pairs. + if (setResume) { + r.setState(RESUMED, "moveToFrontAndResumeStateIfNeeded"); + } + // If the activity was previously pausing, then ensure we transfer that as well + if (setPause) { + mPausingActivity = r; + r.schedulePauseTimeout(); + } + // Move the stack in which we are placing the activity to the front. + moveToFront(reason); + // If the original state is resumed, there is no state change to update focused app. + // So here makes sure the activity focus is set if it is the top. + if (origState == RESUMED && r == mRootWindowContainer.getTopResumedActivity()) { + mAtmService.setResumedActivityUncheckLocked(r, reason); + } + } + + void dismissPip() { + if (!isActivityTypeStandardOrUndefined()) { + throw new IllegalArgumentException( + "You can't move tasks from non-standard stacks."); + } + if (getWindowingMode() != WINDOWING_MODE_PINNED) { + throw new IllegalArgumentException( + "Can't exit pinned mode if it's not pinned already."); + } + + mWmService.inSurfaceTransaction(() -> { + final Task task = getBottomMostTask(); + setWindowingMode(WINDOWING_MODE_UNDEFINED); + + getDisplayArea().positionStackAtTop(this, false /* includingParents */); + + mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, this); + MetricsLoggerWrapper.logPictureInPictureFullScreen(mAtmService.mContext, + task.effectiveUid, task.realActivity.flattenToString()); + }); + } + + void prepareFreezingTaskBounds() { + forAllLeafTasks(Task::prepareFreezingBounds, true /* traverseTopToBottom */); + } + + private int setBounds(Rect existing, Rect bounds) { + if (equivalentBounds(existing, bounds)) { + return BOUNDS_CHANGE_NONE; + } + + final int result = super.setBounds(!inMultiWindowMode() ? null : bounds); + + updateSurfaceBounds(); + return result; + } + + @Override + public void getBounds(Rect bounds) { + bounds.set(getBounds()); + } + + /** + * @return the final bounds for the bounds animation. + */ + void getFinalAnimationBounds(Rect outBounds) { + outBounds.set(mBoundsAnimationTarget); + } + + /** + * @return the final source bounds for the bounds animation. + */ + void getFinalAnimationSourceHintBounds(Rect outBounds) { + outBounds.set(mBoundsAnimationSourceHintBounds); + } + + /** + * Put a Task in this stack. Used for adding only. + * When task is added to top of the stack, the entire branch of the hierarchy (including stack + * and display) will be brought to top. + * @param child The child to add. + * @param position Target position to add the task to. + */ + private void addChild(WindowContainer child, int position, boolean moveParents) { + // Add child task. + addChild(child, null); + + // Move child to a proper position, as some restriction for position might apply. + positionChildAt(position, child, moveParents /* includingParents */); + } + + void positionChildAtTop(Task child) { + if (child == null) { + // TODO: Fix the call-points that cause this to happen. + return; + } + + if (child == this) { + // TODO: Fix call-points + moveToFront("positionChildAtTop"); + return; + } + + positionChildAt(POSITION_TOP, child, true /* includingParents */); + child.updateTaskMovement(true); + + final DisplayContent displayContent = getDisplayContent(); + displayContent.layoutAndAssignWindowLayersIfNeeded(); + } + + void positionChildAtBottom(Task child) { + // If there are other focusable stacks on the display, the z-order of the display should not + // be changed just because a task was placed at the bottom. E.g. if it is moving the topmost + // task to bottom, the next focusable stack on the same display should be focused. + final Task nextFocusableStack = getDisplayArea().getNextFocusableStack( + child.getRootTask(), true /* ignoreCurrent */); + positionChildAtBottom(child, nextFocusableStack == null /* includingParents */); + child.updateTaskMovement(true); + } + + @VisibleForTesting + void positionChildAtBottom(Task child, boolean includingParents) { + if (child == null) { + // TODO: Fix the call-points that cause this to happen. + return; + } + + positionChildAt(POSITION_BOTTOM, child, includingParents); + getDisplayContent().layoutAndAssignWindowLayersIfNeeded(); + } + + @Override + void onChildPositionChanged(WindowContainer child) { + if (isOrganized()) { + mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, false /* force */); + } + + if (!mChildren.contains(child)) { + return; + } + + final boolean isTop = getTopChild() == child; + + final Task task = child.asTask(); + if (task != null) { + task.updateTaskMovement(isTop); + } + + if (isTop) { + final DisplayContent displayContent = getDisplayContent(); + displayContent.layoutAndAssignWindowLayersIfNeeded(); + } + } + + void reparent(TaskDisplayArea newParent, boolean onTop) { + reparent(newParent, onTop ? POSITION_TOP : POSITION_BOTTOM); + } + + private void updateSurfaceBounds() { + updateSurfaceSize(getSyncTransaction()); + updateSurfacePosition(); + scheduleAnimation(); + } + + @Override + void getRelativePosition(Point outPos) { + super.getRelativePosition(outPos); + final int outset = getTaskOutset(); + outPos.x -= outset; + outPos.y -= outset; + } + + boolean shouldIgnoreInput() { + if (inSplitScreenPrimaryWindowingMode() && !isFocusable()) { + return true; + } + if (mAtmService.mHasLeanbackFeature && inPinnedWindowingMode() + && !isFocusedStackOnDisplay()) { + // Preventing Picture-in-Picture stack from receiving input on TVs. + return true; + } + return false; + } + + /** + * Sets the current picture-in-picture aspect ratio. + */ + void setPictureInPictureAspectRatio(float aspectRatio) { + if (!mWmService.mAtmService.mSupportsPictureInPicture) { + return; + } + + final DisplayContent displayContent = getDisplayContent(); + if (displayContent == null) { + return; + } + + if (!inPinnedWindowingMode()) { + return; + } + + final PinnedStackController pinnedStackController = + getDisplayContent().getPinnedStackController(); + + if (Float.compare(aspectRatio, pinnedStackController.getAspectRatio()) == 0) { + return; + } + + // Notify the pinned stack controller about aspect ratio change. + // This would result a callback delivered from SystemUI to WM to start animation, + // if the bounds are ought to be altered due to aspect ratio change. + pinnedStackController.setAspectRatio( + pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio) + ? aspectRatio : -1f); + } + + /** + * Sets the current picture-in-picture actions. + */ + void setPictureInPictureActions(List<RemoteAction> actions) { + if (!mWmService.mAtmService.mSupportsPictureInPicture) { + return; + } + + if (!inPinnedWindowingMode()) { + return; + } + + getDisplayContent().getPinnedStackController().setActions(actions); + } + + public boolean isForceScaled() { + return mBoundsAnimating; + } + + /** Returns true if a removal action is still being deferred. */ + boolean handleCompleteDeferredRemoval() { + if (isAnimating(TRANSITION | CHILDREN)) { + return true; + } + + return super.handleCompleteDeferredRemoval(); + } + + public DisplayInfo getDisplayInfo() { + return mDisplayContent.getDisplayInfo(); + } + + AnimatingActivityRegistry getAnimatingActivityRegistry() { + return mAnimatingActivityRegistry; + } + + void executeAppTransition(ActivityOptions options) { + getDisplay().mDisplayContent.executeAppTransition(); + ActivityOptions.abort(options); + } + + boolean shouldSleepActivities() { + final DisplayContent display = getDisplay(); + + // Do not sleep activities in this stack if we're marked as focused and the keyguard + // is in the process of going away. + if (isFocusedStackOnDisplay() + && mStackSupervisor.getKeyguardController().isKeyguardGoingAway()) { + return false; + } + + return display != null ? display.isSleeping() : mAtmService.isSleepingLocked(); + } + + boolean shouldSleepOrShutDownActivities() { + return shouldSleepActivities() || mAtmService.mShuttingDown; + } + + /** Bounds of the stack without adjusting for other factors in the system like visibility + * of docked stack. + * Most callers should be using {@link ConfigurationContainer#getRequestedOverrideBounds} a + * it takes into consideration other system factors. */ + void getRawBounds(Rect out) { + out.set(getRawBounds()); + } + + private Rect getRawBounds() { + return super.getBounds(); + } + + @Override + public void dumpDebug(ProtoOutputStream proto, long fieldId, + @WindowTraceLogLevel int logLevel) { + if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) { + return; + } + + final long token = proto.start(fieldId); + super.dumpDebug(proto, WINDOW_CONTAINER, logLevel); + + proto.write(TaskProto.ID, mTaskId); + proto.write(DISPLAY_ID, getDisplayId()); + proto.write(ROOT_TASK_ID, getRootTaskId()); + + if (mResumedActivity != null) { + mResumedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY); + } + if (realActivity != null) { + proto.write(REAL_ACTIVITY, realActivity.flattenToShortString()); + } + if (origActivity != null) { + proto.write(ORIG_ACTIVITY, origActivity.flattenToShortString()); + } + proto.write(ACTIVITY_TYPE, getActivityType()); + proto.write(RESIZE_MODE, mResizeMode); + proto.write(MIN_WIDTH, mMinWidth); + proto.write(MIN_HEIGHT, mMinHeight); + + proto.write(FILLS_PARENT, matchParentBounds()); + getRawBounds().dumpDebug(proto, BOUNDS); + + if (mLastNonFullscreenBounds != null) { + mLastNonFullscreenBounds.dumpDebug(proto, LAST_NON_FULLSCREEN_BOUNDS); + } + + proto.write(ANIMATING_BOUNDS, mBoundsAnimating); + + if (mSurfaceControl != null) { + proto.write(SURFACE_WIDTH, mSurfaceControl.getWidth()); + proto.write(SURFACE_HEIGHT, mSurfaceControl.getHeight()); + } + + proto.write(CREATED_BY_ORGANIZER, mCreatedByOrganizer); + + proto.end(token); + } } diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index aba5b99f7481..4473bd69681b 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -32,8 +32,6 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; -import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; -import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE; import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; @@ -42,6 +40,8 @@ import static com.android.server.wm.DisplayContent.alwaysCreateStack; 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.RootWindowContainer.TAG_STATES; +import static com.android.server.wm.Task.ActivityState.RESUMED; +import static com.android.server.wm.Task.STACK_VISIBILITY_VISIBLE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -73,7 +73,7 @@ import java.util.function.Function; /** * {@link DisplayArea} that represents a section of a screen that contains app window containers. */ -final class TaskDisplayArea extends DisplayArea<ActivityStack> { +final class TaskDisplayArea extends DisplayArea<Task> { DisplayContent mDisplayContent; @@ -100,16 +100,16 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { // Cached reference to some special tasks we tend to get a lot so we don't need to loop // through the list to find them. - private ActivityStack mRootHomeTask; - private ActivityStack mRootPinnedTask; - private ActivityStack mRootSplitScreenPrimaryTask; + private Task mRootHomeTask; + private Task mRootPinnedTask; + private Task mRootSplitScreenPrimaryTask; // TODO(b/159029784): Remove when getStack() behavior is cleaned-up - private ActivityStack mRootRecentsTask; + private Task mRootRecentsTask; - private final ArrayList<ActivityStack> mTmpAlwaysOnTopStacks = new ArrayList<>(); - private final ArrayList<ActivityStack> mTmpNormalStacks = new ArrayList<>(); - private final ArrayList<ActivityStack> mTmpHomeStacks = new ArrayList<>(); + private final ArrayList<Task> mTmpAlwaysOnTopStacks = new ArrayList<>(); + private final ArrayList<Task> mTmpNormalStacks = new ArrayList<>(); + private final ArrayList<Task> mTmpHomeStacks = new ArrayList<>(); private final IntArray mTmpNeedsZBoostIndexes = new IntArray(); private int mTmpLayerForSplitScreenDividerAnchor; private int mTmpLayerForAnimationLayer; @@ -128,7 +128,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * have the topmost index, it is used as a preferred candidate to prevent being unable to resume * target stack properly when there are other focusable always-on-top stacks. */ - ActivityStack mPreferredTopFocusableStack; + Task mPreferredTopFocusableStack; private final RootWindowContainer.FindTaskResult mTmpFindTaskResult = new RootWindowContainer.FindTaskResult(); @@ -138,7 +138,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * stack has been resumed. If stacks are changing position this will hold the old stack until * the new stack becomes resumed after which it will be set to current focused stack. */ - ActivityStack mLastFocusedStack; + Task mLastFocusedStack; /** * All of the stacks on this display. Order matters, topmost stack is in front of all other * stacks, bottommost behind. Accessed directly by ActivityManager package classes. Any calls @@ -164,7 +164,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * Returns the topmost stack on the display that is compatible with the input windowing mode * and activity type. Null is no compatible stack on the display. */ - ActivityStack getStack(int windowingMode, int activityType) { + Task getStack(int windowingMode, int activityType) { if (activityType == ACTIVITY_TYPE_HOME) { return mRootHomeTask; } else if (activityType == ACTIVITY_TYPE_RECENTS) { @@ -176,7 +176,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { return mRootSplitScreenPrimaryTask; } for (int i = getChildCount() - 1; i >= 0; --i) { - final ActivityStack stack = getChildAt(i); + final Task stack = getChildAt(i); if (activityType == ACTIVITY_TYPE_UNDEFINED && windowingMode == stack.getWindowingMode()) { // Passing in undefined type means we want to match the topmost stack with the @@ -191,33 +191,33 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { } @VisibleForTesting - ActivityStack getTopStack() { + Task getTopStack() { final int count = getChildCount(); return count > 0 ? getChildAt(count - 1) : null; } // TODO: Figure-out a way to remove since it might be a source of confusion. - int getIndexOf(ActivityStack stack) { - return mChildren.indexOf(stack); + int getIndexOf(Task task) { + return mChildren.indexOf(task); } - @Nullable ActivityStack getRootHomeTask() { + @Nullable Task getRootHomeTask() { return mRootHomeTask; } - @Nullable ActivityStack getRootRecentsTask() { + @Nullable Task getRootRecentsTask() { return mRootRecentsTask; } - ActivityStack getRootPinnedTask() { + Task getRootPinnedTask() { return mRootPinnedTask; } - ActivityStack getRootSplitScreenPrimaryTask() { + Task getRootSplitScreenPrimaryTask() { return mRootSplitScreenPrimaryTask; } - ActivityStack getRootSplitScreenSecondaryTask() { + Task getRootSplitScreenSecondaryTask() { for (int i = mChildren.size() - 1; i >= 0; --i) { if (mChildren.get(i).inSplitScreenSecondaryWindowingMode()) { return mChildren.get(i); @@ -236,7 +236,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { return visibleTasks; } - void onStackWindowingModeChanged(ActivityStack stack) { + void onStackWindowingModeChanged(Task stack) { removeStackReferenceIfNeeded(stack); addStackReferenceIfNeeded(stack); if (stack == mRootPinnedTask && getTopStack() != stack) { @@ -245,7 +245,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { } } - void addStackReferenceIfNeeded(ActivityStack stack) { + void addStackReferenceIfNeeded(Task stack) { if (stack.isActivityTypeHome()) { if (mRootHomeTask != null) { if (!stack.isDescendantOf(mRootHomeTask)) { @@ -290,7 +290,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { } } - void removeStackReferenceIfNeeded(ActivityStack stack) { + void removeStackReferenceIfNeeded(Task stack) { if (stack == mRootHomeTask) { mRootHomeTask = null; } else if (stack == mRootRecentsTask) { @@ -303,7 +303,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { } @Override - void addChild(ActivityStack stack, int position) { + void addChild(Task stack, int position) { if (DEBUG_STACK) Slog.d(TAG_WM, "Set stack=" + stack + " on taskDisplayArea=" + this); addStackReferenceIfNeeded(stack); position = findPositionForStack(position, stack, true /* adding */); @@ -315,7 +315,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { } @Override - protected void removeChild(ActivityStack stack) { + protected void removeChild(Task stack) { super.removeChild(stack); onStackRemoved(stack); mAtmService.updateSleepIfNeededLocked(); @@ -329,7 +329,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { } @Override - void positionChildAt(int position, ActivityStack child, boolean includingParents) { + void positionChildAt(int position, Task child, boolean includingParents) { final boolean moveToTop = position >= getChildCount() - 1; final boolean moveToBottom = position <= 0; @@ -408,7 +408,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * * @return the priority of the stack */ - private int getPriority(ActivityStack stack) { + private int getPriority(Task stack) { if (mWmService.mAssistantOnTopOfDream && stack.isActivityTypeAssistant()) return 4; if (stack.isActivityTypeDream()) return 3; if (stack.inPinnedWindowingMode()) return 2; @@ -416,7 +416,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { return 0; } - private int findMinPositionForStack(ActivityStack stack) { + private int findMinPositionForStack(Task stack) { int minPosition = POSITION_BOTTOM; for (int i = 0; i < mChildren.size(); ++i) { if (getPriority(getStackAt(i)) < getPriority(stack)) { @@ -438,9 +438,9 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { return minPosition; } - private int findMaxPositionForStack(ActivityStack stack) { + private int findMaxPositionForStack(Task stack) { for (int i = mChildren.size() - 1; i >= 0; --i) { - final ActivityStack curr = getStackAt(i); + final Task curr = getStackAt(i); // Since a stack could be repositioned while still being one of the children, we check // if 'curr' is the same stack and skip it if so final boolean sameStack = curr == stack; @@ -470,7 +470,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * @param adding Flag indicates whether we're adding a new stack or positioning an existing. * @return The proper position for the stack. */ - private int findPositionForStack(int requestedPosition, ActivityStack stack, boolean adding) { + private int findPositionForStack(int requestedPosition, Task stack, boolean adding) { // The max possible position we can insert the stack at. int maxPosition = findMaxPositionForStack(stack); // The min possible position we can insert the stack at. @@ -632,7 +632,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { assignStackOrdering(t); for (int i = 0; i < mChildren.size(); i++) { - final ActivityStack s = mChildren.get(i); + final Task s = mChildren.get(i); s.assignChildLayers(t); } } @@ -645,7 +645,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { mTmpHomeStacks.clear(); mTmpNormalStacks.clear(); for (int i = 0; i < mChildren.size(); ++i) { - final ActivityStack s = mChildren.get(i); + final Task s = mChildren.get(i); if (s.isAlwaysOnTop()) { mTmpAlwaysOnTopStacks.add(s); } else if (s.isActivityTypeHome()) { @@ -675,7 +675,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { t.setLayer(mBoostedAppAnimationLayer, layerForBoostedAnimationLayer); } - private int adjustNormalStackLayer(ActivityStack s, int layer) { + private int adjustNormalStackLayer(Task s, int layer) { if (s.inSplitScreenWindowingMode()) { // The split screen divider anchor is located above the split screen window. mTmpLayerForSplitScreenDividerAnchor = layer++; @@ -696,12 +696,12 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * @param normalStacks Set {@code true} if this group is neither home nor always on top. * @return The adjusted layer value. */ - private int adjustRootTaskLayer(SurfaceControl.Transaction t, ArrayList<ActivityStack> stacks, + private int adjustRootTaskLayer(SurfaceControl.Transaction t, ArrayList<Task> stacks, int startLayer, boolean normalStacks) { mTmpNeedsZBoostIndexes.clear(); final int stackSize = stacks.size(); for (int i = 0; i < stackSize; i++) { - final ActivityStack stack = stacks.get(i); + final Task stack = stacks.get(i); if (!stack.needsZBoost()) { stack.assignLayer(t, startLayer++); if (normalStacks) { @@ -714,7 +714,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { final int zBoostSize = mTmpNeedsZBoostIndexes.size(); for (int i = 0; i < zBoostSize; i++) { - final ActivityStack stack = stacks.get(mTmpNeedsZBoostIndexes.get(i)); + final Task stack = stacks.get(mTmpNeedsZBoostIndexes.get(i)); stack.assignLayer(t, startLayer++); if (normalStacks) { startLayer = adjustNormalStackLayer(stack, startLayer); @@ -781,7 +781,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { } } - void onStackRemoved(ActivityStack stack) { + void onStackRemoved(Task stack) { if (ActivityTaskManagerDebugConfig.DEBUG_STACK) { Slog.v(TAG_STACK, "removeStack: detaching " + stack + " from displayId=" + mDisplayContent.mDisplayId); @@ -800,40 +800,40 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { } } - void positionStackAt(int position, ActivityStack child, boolean includingParents) { + void positionStackAt(int position, Task child, boolean includingParents) { positionChildAt(position, child, includingParents); mDisplayContent.layoutAndAssignWindowLayersIfNeeded(); } - void positionStackAtTop(ActivityStack stack, boolean includingParents) { + void positionStackAtTop(Task stack, boolean includingParents) { positionStackAtTop(stack, includingParents, null /* updateLastFocusedStackReason */); } - void positionStackAtTop(ActivityStack stack, boolean includingParents, + void positionStackAtTop(Task stack, boolean includingParents, String updateLastFocusedStackReason) { positionStackAt(stack, getStackCount(), includingParents, updateLastFocusedStackReason); } - void positionStackAtBottom(ActivityStack stack) { + void positionStackAtBottom(Task stack) { positionStackAtBottom(stack, null /* updateLastFocusedStackReason */); } - void positionStackAtBottom(ActivityStack stack, String updateLastFocusedStackReason) { + void positionStackAtBottom(Task stack, String updateLastFocusedStackReason) { positionStackAt(stack, 0, false /* includingParents */, updateLastFocusedStackReason); } - void positionStackAt(ActivityStack stack, int position) { + void positionStackAt(Task stack, int position) { positionStackAt(stack, position, false /* includingParents */, null /* updateLastFocusedStackReason */); } - void positionStackAt(ActivityStack stack, int position, boolean includingParents, + void positionStackAt(Task stack, int position, boolean includingParents, String updateLastFocusedStackReason) { // TODO: Keep in sync with WindowContainer.positionChildAt(), once we change that to adjust // the position internally, also update the logic here - final ActivityStack prevFocusedStack = updateLastFocusedStackReason != null + final Task prevFocusedStack = updateLastFocusedStackReason != null ? getFocusedStack() : null; final boolean wasContained = mChildren.contains(stack); if (mDisplayContent.mSingleTaskInstance && getStackCount() == 1 && !wasContained) { @@ -846,7 +846,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { positionStackAt(position, stack, includingParents); if (updateLastFocusedStackReason != null) { - final ActivityStack currentFocusedStack = getFocusedStack(); + final Task currentFocusedStack = getFocusedStack(); if (currentFocusedStack != prevFocusedStack) { mLastFocusedStack = prevFocusedStack; EventLogTags.writeWmFocusedStack(mRootWindowContainer.mCurrentUser, @@ -865,8 +865,8 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * when we just want to move a task to "the back" vs. a specific place. The primary use-case * is to make sure that moved-to-back apps go into secondary split when in split-screen mode. */ - void positionTaskBehindHome(ActivityStack task) { - final ActivityStack home = getOrCreateRootHomeTask(); + void positionTaskBehindHome(Task task) { + final Task home = getOrCreateRootHomeTask(); final WindowContainer homeParent = home.getParent(); final Task homeParentTask = homeParent != null ? homeParent.asTask() : null; if (homeParentTask == null) { @@ -878,17 +878,17 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { } } else if (homeParentTask == task.getParent()) { // Apparently reparent early-outs if same stack, so we have to explicitly reorder. - ((ActivityStack) homeParentTask).positionChildAtBottom(task); + homeParentTask.positionChildAtBottom(task); } else { - task.reparent((ActivityStack) homeParentTask, false /* toTop */, + task.reparent(homeParentTask, false /* toTop */, Task.REPARENT_LEAVE_STACK_IN_PLACE, false /* animate */, false /* deferResume */, "positionTaskBehindHome"); } } - ActivityStack getStack(int rootTaskId) { + Task getStack(int rootTaskId) { for (int i = getStackCount() - 1; i >= 0; --i) { - final ActivityStack stack = getStackAt(i); + final Task stack = getStackAt(i); if (stack.getRootTaskId() == rootTaskId) { return stack; } @@ -901,7 +901,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * if a compatible stack doesn't exist. * @see #getOrCreateStack(int, int, boolean, Intent, Task) */ - ActivityStack getOrCreateStack(int windowingMode, int activityType, boolean onTop) { + Task getOrCreateStack(int windowingMode, int activityType, boolean onTop) { return getOrCreateStack(windowingMode, activityType, onTop, null /* intent */, null /* candidateTask */); } @@ -914,19 +914,19 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * @see #getStack(int, int) * @see #createStack(int, int, boolean) */ - ActivityStack getOrCreateStack(int windowingMode, int activityType, boolean onTop, + Task getOrCreateStack(int windowingMode, int activityType, boolean onTop, Intent intent, Task candidateTask) { // Need to pass in a determined windowing mode to see if a new stack should be created, // so use its parent's windowing mode if it is undefined. if (!alwaysCreateStack( windowingMode != WINDOWING_MODE_UNDEFINED ? windowingMode : getWindowingMode(), activityType)) { - ActivityStack stack = getStack(windowingMode, activityType); + Task stack = getStack(windowingMode, activityType); if (stack != null) { return stack; } } else if (candidateTask != null) { - final ActivityStack stack = (ActivityStack) candidateTask; + final Task stack = candidateTask; final int position = onTop ? POSITION_TOP : POSITION_BOTTOM; Task launchRootTask = updateLaunchRootTask(windowingMode); @@ -958,7 +958,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * if a compatible stack doesn't exist. * @see #getOrCreateStack(int, int, boolean) */ - ActivityStack getOrCreateStack(@Nullable ActivityRecord r, + Task getOrCreateStack(@Nullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable Task candidateTask, int activityType, boolean onTop) { // First preference is the windowing mode in the activity options if set. @@ -977,7 +977,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { return mAtmService.mStackSupervisor.getNextTaskIdForUser(); } - ActivityStack createStack(int windowingMode, int activityType, boolean onTop) { + Task createStack(int windowingMode, int activityType, boolean onTop) { return createStack(windowingMode, activityType, onTop, null /* info */, null /* intent */, false /* createdByOrganizer */); } @@ -997,7 +997,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * otherwise. * @return The newly created stack. */ - ActivityStack createStack(int windowingMode, int activityType, boolean onTop, ActivityInfo info, + Task createStack(int windowingMode, int activityType, boolean onTop, ActivityInfo info, Intent intent, boolean createdByOrganizer) { if (mDisplayContent.mSingleTaskInstance && getStackCount() > 0) { // Create stack on default display instead since this display can only contain 1 stack. @@ -1016,7 +1016,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { if (activityType != ACTIVITY_TYPE_STANDARD && activityType != ACTIVITY_TYPE_UNDEFINED) { // For now there can be only one stack of a particular non-standard activity type on a // display. So, get that ignoring whatever windowing mode it is currently in. - ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType); + Task stack = getStack(WINDOWING_MODE_UNDEFINED, activityType); if (stack != null) { throw new IllegalArgumentException("Stack=" + stack + " of activityType=" + activityType + " already on display=" + this + ". Can't have multiple."); @@ -1068,7 +1068,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { } @VisibleForTesting - ActivityStack createStackUnchecked(int windowingMode, int activityType, int stackId, + Task createStackUnchecked(int windowingMode, int activityType, int stackId, boolean onTop, ActivityInfo info, Intent intent, boolean createdByOrganizer) { if (windowingMode == WINDOWING_MODE_PINNED && activityType != ACTIVITY_TYPE_STANDARD) { throw new IllegalArgumentException("Stack with windowing mode cannot with non standard " @@ -1086,12 +1086,12 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { windowingMode = WINDOWING_MODE_UNDEFINED; } - final ActivityStack stack = new ActivityStack(mAtmService, stackId, activityType, + final Task stack = new Task(mAtmService, stackId, activityType, info, intent, createdByOrganizer); if (launchRootTask != null) { launchRootTask.addChild(stack, onTop ? POSITION_TOP : POSITION_BOTTOM); if (onTop) { - positionStackAtTop((ActivityStack) launchRootTask, false /* includingParents */); + positionStackAtTop(launchRootTask, false /* includingParents */); } } else { addChild(stack, onTop ? POSITION_TOP : POSITION_BOTTOM); @@ -1104,13 +1104,13 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * Get the preferred focusable stack in priority. If the preferred stack does not exist, find a * focusable and visible stack from the top of stacks in this display. */ - ActivityStack getFocusedStack() { + Task getFocusedStack() { if (mPreferredTopFocusableStack != null) { return mPreferredTopFocusableStack; } for (int i = getStackCount() - 1; i >= 0; --i) { - final ActivityStack stack = getStackAt(i); + final Task stack = getStackAt(i); if (stack.isFocusableAndVisible()) { return stack; } @@ -1119,13 +1119,13 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { return null; } - ActivityStack getNextFocusableStack(ActivityStack currentFocus, boolean ignoreCurrent) { + Task getNextFocusableStack(Task currentFocus, boolean ignoreCurrent) { final int currentWindowingMode = currentFocus != null ? currentFocus.getWindowingMode() : WINDOWING_MODE_UNDEFINED; - ActivityStack candidate = null; + Task candidate = null; for (int i = getStackCount() - 1; i >= 0; --i) { - final ActivityStack stack = getStackAt(i); + final Task stack = getStackAt(i); if (ignoreCurrent && stack == currentFocus) { continue; } @@ -1155,7 +1155,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { } ActivityRecord getFocusedActivity() { - final ActivityStack focusedStack = getFocusedStack(); + final Task focusedStack = getFocusedStack(); if (focusedStack == null) { return null; } @@ -1175,7 +1175,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { return resumedActivity; } - ActivityStack getLastFocusedStack() { + Task getLastFocusedStack() { return mLastFocusedStack; } @@ -1186,7 +1186,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { return false; } } - final ActivityStack currentFocusedStack = getFocusedStack(); + final Task currentFocusedStack = getFocusedStack(); if (ActivityTaskManagerDebugConfig.DEBUG_STACK) { Slog.d(TAG_STACK, "allResumedActivitiesComplete: mLastFocusedStack changing from=" + mLastFocusedStack + " to=" + currentFocusedStack); @@ -1208,7 +1208,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming) { boolean someActivityPaused = false; for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = getStackAt(stackNdx); + final Task stack = getStackAt(stackNdx); final ActivityRecord resumedActivity = stack.getResumedActivity(); if (resumedActivity != null && (stack.getVisibility(resuming) != STACK_VISIBILITY_VISIBLE @@ -1231,7 +1231,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { RootWindowContainer.FindTaskResult result) { mTmpFindTaskResult.clear(); for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = getStackAt(stackNdx); + final Task stack = getStackAt(stackNdx); if (!r.hasCompatibleActivityType(stack) && stack.isLeafTask()) { if (DEBUG_TASKS) { Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) " + stack); @@ -1271,11 +1271,11 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { // Collect the stacks that are necessary to be removed instead of performing the removal // by looping mStacks, so that we don't miss any stacks after the stack size changed or // stacks reordered. - final ArrayList<ActivityStack> stacks = new ArrayList<>(); + final ArrayList<Task> stacks = new ArrayList<>(); for (int j = windowingModes.length - 1; j >= 0; --j) { final int windowingMode = windowingModes[j]; for (int i = getStackCount() - 1; i >= 0; --i) { - final ActivityStack stack = getStackAt(i); + final Task stack = getStackAt(i); if (!stack.isActivityTypeStandardOrUndefined()) { continue; } @@ -1299,15 +1299,15 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { // Collect the stacks that are necessary to be removed instead of performing the removal // by looping mStacks, so that we don't miss any stacks after the stack size changed or // stacks reordered. - final ArrayList<ActivityStack> stacks = new ArrayList<>(); + final ArrayList<Task> stacks = new ArrayList<>(); for (int j = activityTypes.length - 1; j >= 0; --j) { final int activityType = activityTypes[j]; for (int i = getStackCount() - 1; i >= 0; --i) { - final ActivityStack stack = getStackAt(i); + final Task stack = getStackAt(i); // Collect the root tasks that are currently being organized. if (stack.mCreatedByOrganizer) { for (int k = stack.getChildCount() - 1; k >= 0; --k) { - final ActivityStack childStack = (ActivityStack) stack.getChildAt(k); + final Task childStack = (Task) stack.getChildAt(k); if (childStack.getActivityType() == activityType) { stacks.add(childStack); } @@ -1327,15 +1327,15 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { onSplitScreenModeDismissed(null /* toTop */); } - void onSplitScreenModeDismissed(ActivityStack toTop) { + void onSplitScreenModeDismissed(Task toTop) { mAtmService.deferWindowLayout(); try { mLaunchRootTask = null; moveSplitScreenTasksToFullScreen(); } finally { - final ActivityStack topFullscreenStack = toTop != null + final Task topFullscreenStack = toTop != null ? toTop : getTopStackInWindowingMode(WINDOWING_MODE_FULLSCREEN); - final ActivityStack homeStack = getOrCreateRootHomeTask(); + final Task homeStack = getOrCreateRootHomeTask(); if (homeStack != null && ((topFullscreenStack != null && !isTopStack(homeStack)) || toTop != null)) { // Whenever split-screen is dismissed we want the home stack directly behind the @@ -1509,13 +1509,13 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { return windowingMode; } - boolean isTopStack(ActivityStack stack) { + boolean isTopStack(Task stack) { return stack == getTopStack(); } - boolean isTopNotPinnedStack(ActivityStack stack) { + boolean isTopNotPinnedStack(Task stack) { for (int i = getStackCount() - 1; i >= 0; --i) { - final ActivityStack current = getStackAt(i); + final Task current = getStackAt(i); if (!current.inPinnedWindowingMode()) { return current == stack; } @@ -1538,7 +1538,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { */ ActivityRecord topRunningActivity(boolean considerKeyguardState) { ActivityRecord topRunning = null; - final ActivityStack focusedStack = getFocusedStack(); + final Task focusedStack = getFocusedStack(); if (focusedStack != null) { topRunning = focusedStack.topRunningActivity(); } @@ -1546,7 +1546,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { // Look in other focusable stacks. if (topRunning == null) { for (int i = getStackCount() - 1; i >= 0; --i) { - final ActivityStack stack = getStackAt(i); + final Task stack = getStackAt(i); // Only consider focusable stacks other than the current focused one. if (stack == focusedStack || !stack.isTopActivityFocusable()) { continue; @@ -1574,12 +1574,12 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { return mChildren.size(); } - protected ActivityStack getStackAt(int index) { + protected Task getStackAt(int index) { return mChildren.get(index); } @Nullable - ActivityStack getOrCreateRootHomeTask() { + Task getOrCreateRootHomeTask() { return getOrCreateRootHomeTask(false /* onTop */); } @@ -1590,8 +1590,8 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * be created at the top of the display, else at the bottom. */ @Nullable - ActivityStack getOrCreateRootHomeTask(boolean onTop) { - ActivityStack homeTask = getRootHomeTask(); + Task getOrCreateRootHomeTask(boolean onTop) { + Task homeTask = getRootHomeTask(); if (homeTask == null && mDisplayContent.supportsSystemDecorations()) { homeTask = createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, onTop); } @@ -1607,12 +1607,12 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * Returns the topmost stack on the display that is compatible with the input windowing mode. * Null is no compatible stack on the display. */ - ActivityStack getTopStackInWindowingMode(int windowingMode) { + Task getTopStackInWindowingMode(int windowingMode) { return getStack(windowingMode, ACTIVITY_TYPE_UNDEFINED); } void moveHomeStackToFront(String reason) { - final ActivityStack homeStack = getOrCreateRootHomeTask(); + final Task homeStack = getOrCreateRootHomeTask(); if (homeStack != null) { homeStack.moveToFront(reason); } @@ -1638,7 +1638,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { @Nullable ActivityRecord getHomeActivityForUser(int userId) { - final ActivityStack homeStack = getRootHomeTask(); + final Task homeStack = getRootHomeTask(); if (homeStack == null) { return null; } @@ -1660,7 +1660,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * Generally used in conjunction with {@link #moveStackBehindStack}. */ // TODO(b/151575894): Remove special stack movement methods. - void moveStackBehindBottomMostVisibleStack(ActivityStack stack) { + void moveStackBehindBottomMostVisibleStack(Task stack) { if (stack.shouldBeVisible(null)) { // Skip if the stack is already visible return; @@ -1677,8 +1677,8 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { // Find the next position where the stack should be placed final int numStacks = isRootTask ? getStackCount() : stack.getParent().getChildCount(); for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) { - final ActivityStack s = isRootTask ? getStackAt(stackNdx) - : (ActivityStack) stack.getParent().getChildAt(stackNdx); + final Task s = isRootTask ? getStackAt(stackNdx) + : (Task) stack.getParent().getChildAt(stackNdx); if (s == stack) { continue; } @@ -1703,7 +1703,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * {@param behindStack} is not currently in the display, then then the stack is moved to the * back. Generally used in conjunction with {@link #moveStackBehindBottomMostVisibleStack}. */ - void moveStackBehindStack(ActivityStack stack, ActivityStack behindStack) { + void moveStackBehindStack(Task stack, Task behindStack) { if (behindStack == null || behindStack == stack) { return; } @@ -1737,19 +1737,19 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * @return the stack currently above the {@param stack}. Can be null if the {@param stack} is * already top-most. */ - static ActivityStack getStackAbove(ActivityStack stack) { + static Task getStackAbove(Task stack) { final WindowContainer wc = stack.getParent(); final int index = wc.mChildren.indexOf(stack) + 1; - return (index < wc.mChildren.size()) ? (ActivityStack) wc.mChildren.get(index) : null; + return (index < wc.mChildren.size()) ? (Task) wc.mChildren.get(index) : null; } /** Returns true if the stack in the windowing mode is visible. */ boolean isStackVisible(int windowingMode) { - final ActivityStack stack = getTopStackInWindowingMode(windowingMode); + final Task stack = getTopStackInWindowingMode(windowingMode); return stack != null && stack.isVisible(); } - void removeStack(ActivityStack stack) { + void removeStack(Task stack) { removeChild(stack); } @@ -1783,7 +1783,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * Notifies of a stack order change * @param stack The stack which triggered the order change */ - void onStackOrderChanged(ActivityStack stack) { + void onStackOrderChanged(Task stack) { for (int i = mStackOrderChangedCallbacks.size() - 1; i >= 0; i--) { mStackOrderChangedCallbacks.get(i).onStackOrderChanged(stack); } @@ -1798,7 +1798,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * Callback for when the order of the stacks in the display changes. */ interface OnStackOrderChangedListener { - void onStackOrderChanged(ActivityStack stack); + void onStackOrderChanged(Task stack); } void ensureActivitiesVisible(ActivityRecord starting, int configChanges, @@ -1806,7 +1806,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { mAtmService.mStackSupervisor.beginActivityVisibilityUpdate(); try { for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = getStackAt(stackNdx); + final Task stack = getStackAt(stackNdx); stack.ensureActivitiesVisible(starting, configChanges, preserveWindows, notifyClients); } @@ -1817,7 +1817,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { void prepareFreezingTaskBounds() { for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = getChildAt(stackNdx); + final Task stack = getChildAt(stackNdx); stack.prepareFreezingTaskBounds(); } } @@ -1826,12 +1826,12 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { * Removes the stacks in the node applying the content removal node from the display. * @return last reparented stack, or {@code null} if the stacks had to be destroyed. */ - ActivityStack remove() { + Task remove() { mPreferredTopFocusableStack = null; // TODO(b/153090332): Allow setting content removal mode per task display area final boolean destroyContentOnRemoval = mDisplayContent.shouldDestroyContentOnRemove(); final TaskDisplayArea toDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - ActivityStack lastReparentedStack = null; + Task lastReparentedStack = null; // Stacks could be reparented from the removed display area to other display area. After // reparenting the last stack of the removed display area, the display area becomes ready to @@ -1842,10 +1842,10 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { int numStacks = getStackCount(); final boolean splitScreenActivated = toDisplayArea.isSplitScreenModeActivated(); - final ActivityStack rootStack = splitScreenActivated ? toDisplayArea + final Task rootStack = splitScreenActivated ? toDisplayArea .getTopStackInWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) : null; for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) { - final ActivityStack stack = getStackAt(stackNdx); + final Task stack = getStackAt(stackNdx); // Always finish non-standard type stacks. if (destroyContentOnRemoval || !stack.isActivityTypeStandardOrUndefined()) { stack.finishAllActivitiesImmediately(); @@ -1895,7 +1895,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { final String triplePrefix = doublePrefix + " "; pw.println(doublePrefix + "Application tokens in top down Z order:"); for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = getChildAt(stackNdx); + final Task stack = getChildAt(stackNdx); pw.println(doublePrefix + "* " + stack); stack.dump(pw, triplePrefix, dumpAll); } diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java index 00ddf82d2ba3..9a818ce80872 100644 --- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java +++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java @@ -341,8 +341,8 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { } } - ActivityStack stack = (taskDisplayArea == null && task != null) - ? task.getStack() : null; + Task stack = (taskDisplayArea == null && task != null) + ? task.getRootTask() : null; if (stack != null) { if (DEBUG) appendLog("display-from-task=" + stack.getDisplayId()); taskDisplayArea = stack.getDisplayArea(); @@ -744,13 +744,13 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { display.forAllTaskDisplayAreas(taskDisplayArea -> { int numStacks = taskDisplayArea.getStackCount(); for (int sNdx = 0; sNdx < numStacks; ++sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); - if (!stack.inFreeformWindowingMode()) { + final Task task = taskDisplayArea.getStackAt(sNdx); + if (!task.inFreeformWindowingMode()) { continue; } - for (int j = 0; j < stack.getChildCount(); ++j) { - taskBoundsToCheck.add(stack.getChildAt(j).getBounds()); + for (int j = 0; j < task.getChildCount(); ++j) { + taskBoundsToCheck.add(task.getChildAt(j).getBounds()); } } }, false /* traverseTopToBottom */); diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index f1e965ba7a14..d0785ff9a9ac 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -112,16 +112,16 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowContainer" : TAG_WM; - /** Animation layer that happens above all animating {@link ActivityStack}s. */ + /** Animation layer that happens above all animating {@link Task}s. */ static final int ANIMATION_LAYER_STANDARD = 0; - /** Animation layer that happens above all {@link ActivityStack}s. */ + /** Animation layer that happens above all {@link Task}s. */ static final int ANIMATION_LAYER_BOOSTED = 1; /** * Animation layer that is reserved for {@link WindowConfiguration#ACTIVITY_TYPE_HOME} * activities and all activities that are being controlled by the recents animation. This - * layer is generally below all {@link ActivityStack}s. + * layer is generally below all {@link Task}s. */ static final int ANIMATION_LAYER_HOME = 2; @@ -190,7 +190,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< /** * Sources which triggered a surface animation on this container. An animation target can be * promoted to higher level, for example, from a set of {@link ActivityRecord}s to - * {@link ActivityStack}. In this case, {@link ActivityRecord}s are set on this variable while + * {@link Task}. In this case, {@link ActivityRecord}s are set on this variable while * the animation is running, and reset after finishing it. */ private final ArraySet<WindowContainer> mSurfaceAnimationSources = new ArraySet<>(); diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java index 97186b4e9cda..d96b6457f9db 100644 --- a/services/core/java/com/android/server/wm/WindowFrames.java +++ b/services/core/java/com/android/server/wm/WindowFrames.java @@ -57,7 +57,7 @@ public class WindowFrames { public final Rect mParentFrame = new Rect(); /** - * The entire screen area of the {@link ActivityStack} this window is in. Usually equal to the + * The entire screen area of the {@link Task} this window is in. Usually equal to the * screen area of the device. * * TODO(b/111611553): The name is unclear and most likely should be swapped with diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 4df48dc11636..2dd25c969d0d 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1478,9 +1478,14 @@ public class WindowManagerService extends IWindowManager.Stub rootType, attrs.token, attrs.packageName)) { return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - final IBinder binder = attrs.token != null ? attrs.token : client.asBinder(); - token = new WindowToken(this, binder, type, false, displayContent, - session.mCanAddInternalSystemWindow, isRoundedCornerOverlay); + if (hasParent) { + // Use existing parent window token for child windows. + token = parentWindow.mToken; + } else { + final IBinder binder = attrs.token != null ? attrs.token : client.asBinder(); + token = new WindowToken(this, binder, type, false, displayContent, + session.mCanAddInternalSystemWindow, isRoundedCornerOverlay); + } } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) { activity = token.asActivityRecord(); @@ -1945,7 +1950,7 @@ public class WindowManagerService extends IWindowManager.Stub // re-factor. activity.firstWindowDrawn = false; activity.clearAllDrawn(); - final ActivityStack stack = activity.getStack(); + final Task stack = activity.getStack(); if (stack != null) { stack.mExitingActivities.remove(activity); } @@ -2165,6 +2170,10 @@ public class WindowManagerService extends IWindowManager.Stub throw new IllegalArgumentException( "Window type can not be changed after the window is added."); } + if (!Arrays.equals(win.mAttrs.providesInsetsTypes, attrs.providesInsetsTypes)) { + throw new IllegalArgumentException( + "Insets types can not be changed after the window is added."); + } // Odd choice but less odd than embedding in copyFrom() if ((attrs.privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY) @@ -2859,7 +2868,7 @@ public class WindowManagerService extends IWindowManager.Stub } void getStackBounds(int windowingMode, int activityType, Rect bounds) { - final ActivityStack stack = mRoot.getStack(windowingMode, activityType); + final Task stack = mRoot.getStack(windowingMode, activityType); if (stack != null) { stack.getBounds(bounds); return; @@ -4583,7 +4592,7 @@ public class WindowManagerService extends IWindowManager.Stub return mRoot.getTopFocusedDisplayContent().mCurrentFocus; } - ActivityStack getImeFocusStackLocked() { + Task getImeFocusStackLocked() { // Don't use mCurrentFocus.getStack() because it returns home stack for system windows. // Also don't use mInputMethodTarget's stack, because some window with FLAG_NOT_FOCUSABLE // and FLAG_ALT_FOCUSABLE_IM flags both set might be set to IME target so they're moved @@ -4592,7 +4601,7 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayContent topFocusedDisplay = mRoot.getTopFocusedDisplayContent(); final ActivityRecord focusedApp = topFocusedDisplay.mFocusedApp; return (focusedApp != null && focusedApp.getTask() != null) - ? focusedApp.getTask().getStack() : null; + ? focusedApp.getTask().getRootTask() : null; } public boolean detectSafeMode() { diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 24ad85356477..8912d584213e 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -317,7 +317,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub Slog.w(TAG, "Container is no longer attached: " + task); return 0; } - final ActivityStack as = (ActivityStack) task; + final Task as = task; if (hop.isReparent()) { final boolean isNonOrganizedRootableTask = @@ -337,12 +337,12 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub + " multi-window mode... newParent=" + newParent + " task=" + task); return 0; } else { - task.reparent((ActivityStack) newParent, + task.reparent((Task) newParent, hop.getToTop() ? POSITION_TOP : POSITION_BOTTOM, false /*moveParents*/, "sanitizeAndApplyHierarchyOp"); } } else { - final ActivityStack rootTask = (ActivityStack) ( + final Task rootTask = (Task) ( (newParent != null && !(newParent instanceof TaskDisplayArea)) ? newParent : task.getRootTask()); if (hop.getToTop()) { @@ -395,10 +395,10 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub private void resizePinnedStackIfNeeded(ConfigurationContainer container, int configMask, int windowMask, Configuration config) { - if ((container instanceof ActivityStack) + if ((container instanceof Task) && ((configMask & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0) && ((windowMask & WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)) { - final ActivityStack stack = (ActivityStack) container; + final Task stack = (Task) container; if (stack.inPinnedWindowingMode()) { stack.resize(config.windowConfiguration.getBounds(), PRESERVE_WINDOWS, true /* deferResume */); diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 29cf1776df9c..9a48154c7770 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -22,13 +22,6 @@ import static android.os.Build.VERSION_CODES.Q; import static android.view.Display.INVALID_DISPLAY; import static com.android.server.am.ActivityManagerService.MY_PID; -import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED; -import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSED; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSING; -import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; -import static com.android.server.wm.ActivityStack.ActivityState.STARTED; -import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE; @@ -40,6 +33,13 @@ import static com.android.server.wm.ActivityTaskManagerService.ACTIVITY_BG_START import static com.android.server.wm.ActivityTaskManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS; import static com.android.server.wm.ActivityTaskManagerService.KEY_DISPATCHING_TIMEOUT_MS; import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE; +import static com.android.server.wm.Task.ActivityState.DESTROYED; +import static com.android.server.wm.Task.ActivityState.DESTROYING; +import static com.android.server.wm.Task.ActivityState.PAUSED; +import static com.android.server.wm.Task.ActivityState.PAUSING; +import static com.android.server.wm.Task.ActivityState.RESUMED; +import static com.android.server.wm.Task.ActivityState.STARTED; +import static com.android.server.wm.Task.ActivityState.STOPPING; import android.Manifest; import android.annotation.NonNull; @@ -690,7 +690,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio if (canUpdate) { // Make sure the previous top activity in the process no longer be resumed. if (mPreQTopResumedActivity != null && mPreQTopResumedActivity.isState(RESUMED)) { - final ActivityStack stack = mPreQTopResumedActivity.getRootTask(); + final Task stack = mPreQTopResumedActivity.getRootTask(); if (stack != null) { stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */, activity); @@ -924,7 +924,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio // Since there could be more than one activities in a process record, we don't need to // compute the OomAdj with each of them, just need to find out the activity with the // "best" state, the order would be visible, pausing, stopping... - ActivityStack.ActivityState best = DESTROYED; + Task.ActivityState best = DESTROYED; boolean finishing = true; boolean visible = false; synchronized (mAtm.mGlobalLockWithoutBoost) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 27c4bf42ac1b..1cbc95090bfd 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1566,10 +1566,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return mActivityRecord != null ? mActivityRecord.getTask() : null; } - @Nullable ActivityStack getRootTask() { + @Nullable Task getRootTask() { final Task task = getTask(); if (task != null) { - return (ActivityStack) task.getRootTask(); + return task.getRootTask(); } // Some system windows (e.g. "Power off" dialog) don't have a task, but we would still // associate them with some stack to enable dimming. @@ -1611,7 +1611,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP bounds.setEmpty(); mTmpRect.setEmpty(); if (intersectWithStackBounds) { - final ActivityStack stack = task.getStack(); + final Task stack = task.getRootTask(); if (stack != null) { stack.getDimBounds(mTmpRect); } else { @@ -1622,7 +1622,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // the secondary split, it means this is "minimized" and thus must prevent // overlapping with home. // TODO(b/158242495): get rid of this when drag/drop can use surface bounds. - final ActivityStack rootSecondary = + final Task rootSecondary = task.getDisplayArea().getRootSplitScreenSecondaryTask(); if (rootSecondary.isActivityTypeHome() || rootSecondary.isActivityTypeRecents()) { final WindowContainer topTask = rootSecondary.getTopChild(); @@ -2107,7 +2107,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP boolean isObscuringDisplay() { Task task = getTask(); - if (task != null && task.getStack() != null && !task.getStack().fillsParent()) { + if (task != null && task.getRootTask() != null && !task.getRootTask().fillsParent()) { return false; } return isOpaqueDrawn() && fillsDisplay(); @@ -2191,6 +2191,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (isInputMethodTarget()) { dc.computeImeTarget(true /* updateImeTarget */); } + if (dc.mInputMethodInputTarget == this) { + dc.setInputMethodInputTarget(null); + } if (dc.mInputMethodControlTarget == this) { dc.updateImeControlTarget(); } @@ -2415,7 +2418,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return false; } - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); if (stack != null && !stack.isFocusable()) { // Ignore when the stack shouldn't receive input event. // (i.e. the minimized stack in split screen mode.) @@ -2916,7 +2919,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return false; } - return mActivityRecord.getTask().getStack().shouldIgnoreInput() + return mActivityRecord.getTask().getRootTask().shouldIgnoreInput() || !mActivityRecord.mVisibleRequested || isRecentsAnimationConsumingAppInput(); } @@ -3486,7 +3489,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return; } - final ActivityStack stack = task.getStack(); + final Task stack = task.getRootTask(); if (stack == null || inFreeformWindowingMode()) { handle.setTouchableRegionCrop(null); return; @@ -3501,7 +3504,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return; } - final ActivityStack stack = task.getStack(); + final Task stack = task.getRootTask(); if (stack == null || stack.mCreatedByOrganizer) { return; } @@ -3745,7 +3748,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } private int getRootTaskId() { - final ActivityStack stack = getRootTask(); + final Task stack = getRootTask(); if (stack == null) { return INVALID_TASK_ID; } @@ -3819,7 +3822,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return mActivityRecord.getBounds().equals(mTmpRect); } - @Override + /** + * @see Letterbox#notIntersectsOrFullyContains(Rect) + */ + boolean letterboxNotIntersectsOrFullyContains(Rect rect) { + return mActivityRecord == null + || mActivityRecord.letterboxNotIntersectsOrFullyContains(rect); + } + public boolean isLetterboxedOverlappingWith(Rect rect) { return mActivityRecord != null && mActivityRecord.isLetterboxOverlappingWith(rect); } @@ -5441,7 +5451,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP outPoint.offset(-parentBounds.left, -parentBounds.top); } - ActivityStack stack = getRootTask(); + Task stack = getRootTask(); // If we have stack outsets, that means the top-left // will be outset, and we need to inset ourselves diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 508d2d477067..77fee851889e 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -924,15 +924,15 @@ class WindowStateAnimator { int posX = 0; int posY = 0; - task.getStack().getDimBounds(mTmpStackBounds); + task.getRootTask().getDimBounds(mTmpStackBounds); boolean allowStretching = false; - task.getStack().getFinalAnimationSourceHintBounds(mTmpSourceBounds); + task.getRootTask().getFinalAnimationSourceHintBounds(mTmpSourceBounds); // If we don't have source bounds, we can attempt to use the content insets // if we have content insets. if (mTmpSourceBounds.isEmpty() && (mWin.mLastRelayoutContentInsets.width() > 0 || mWin.mLastRelayoutContentInsets.height() > 0)) { - mTmpSourceBounds.set(task.getStack().mPreAnimationBounds); + mTmpSourceBounds.set(task.getRootTask().mPreAnimationBounds); mTmpSourceBounds.inset(mWin.mLastRelayoutContentInsets); allowStretching = true; } @@ -946,7 +946,7 @@ class WindowStateAnimator { if (!mTmpSourceBounds.isEmpty()) { // Get the final target stack bounds, if we are not animating, this is just the // current stack bounds - task.getStack().getFinalAnimationBounds(mTmpAnimatingBounds); + task.getRootTask().getFinalAnimationBounds(mTmpAnimatingBounds); // Calculate the current progress and interpolate the difference between the target // and source bounds @@ -1042,7 +1042,7 @@ class WindowStateAnimator { mSurfaceController.deferTransactionUntil(mWin.getClientViewRootSurface(), mWin.getFrameNumber()); } else { - final ActivityStack stack = mWin.getRootTask(); + final Task stack = mWin.getRootTask(); mTmpPos.x = 0; mTmpPos.y = 0; if (stack != null) { @@ -1576,7 +1576,7 @@ class WindowStateAnimator { */ boolean isForceScaled() { final Task task = mWin.getTask(); - if (task != null && task.getStack().isForceScaled()) { + if (task != null && task.getRootTask().isForceScaled()) { return true; } return mForceScaleUntilResize; @@ -1592,12 +1592,6 @@ class WindowStateAnimator { if (mSurfaceController != null) { mSurfaceController.detachChildren(); } - // If the children are detached, it means the app is exiting. We don't want to tear the - // content down too early, otherwise we could end up with a flicker. By preserving the - // current surface, we ensure the content remains on screen until the window is completely - // removed. It also ensures that the old surface is cleaned up when started again since it - // forces mSurfaceController to be set to null. - preserveSurfaceLocked(); } void setOffsetPositionForStackResize(boolean offsetPositionForStackResize) { diff --git a/services/robotests/Android.bp b/services/robotests/Android.bp index 25ab5d36169e..1ae2aec90ba3 100644 --- a/services/robotests/Android.bp +++ b/services/robotests/Android.bp @@ -43,6 +43,7 @@ android_robolectric_test { // Include the testing libraries libs: [ "platform-test-annotations", + "services.backup", "testng", ], static_libs: [ diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java index 23381ffd4eaa..8db09b4f156c 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java @@ -192,6 +192,7 @@ public class ApplicationExitInfoTest { final int app1Uid = 10123; final int app1Pid1 = 12345; final int app1Pid2 = 12346; + final int app1sPid1 = 13456; final int app1DefiningUid = 23456; final int app1ConnectiongGroup = 10; final int app1UidUser2 = 1010123; @@ -202,8 +203,12 @@ public class ApplicationExitInfoTest { final long app1Rss2 = 45679; final long app1Pss3 = 34569; final long app1Rss3 = 45680; + final long app1sPss1 = 56789; + final long app1sRss1 = 67890; final String app1ProcessName = "com.android.test.stub1:process"; final String app1PackageName = "com.android.test.stub1"; + final String app1sProcessName = "com.android.test.stub_shared:process"; + final String app1sPackageName = "com.android.test.stub_shared"; final byte[] app1Cookie1 = {(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08}; final byte[] app1Cookie2 = {(byte) 0x08, (byte) 0x07, (byte) 0x06, (byte) 0x05, @@ -262,6 +267,29 @@ public class ApplicationExitInfoTest { app1Cookie1.length)); assertEquals(info.getTraceInputStream(), null); + // Now create a process record from a different package but shared UID. + sleep(1); + final long now1s = System.currentTimeMillis(); + app = makeProcessRecord( + app1sPid1, // pid + app1Uid, // uid + app1Uid, // packageUid + null, // definingUid + 0, // connectionGroup + PROCESS_STATE_BOUND_TOP, // procstate + app1sPss1, // pss + app1sRss1, // rss + app1sProcessName, // processName + app1sPackageName); // packageName + doReturn(new Pair<Long, Object>(now1s, Integer.valueOf(0))) + .when(mAppExitInfoTracker.mAppExitInfoSourceZygote) + .remove(anyInt(), anyInt()); + doReturn(null) + .when(mAppExitInfoTracker.mAppExitInfoSourceLmkd) + .remove(anyInt(), anyInt()); + noteAppKill(app, ApplicationExitInfo.REASON_USER_REQUESTED, + ApplicationExitInfo.SUBREASON_UNKNOWN, null); + // Case 2: create another app1 process record with a different pid sleep(1); final long now2 = System.currentTimeMillis(); @@ -290,8 +318,8 @@ public class ApplicationExitInfoTest { list.clear(); // Get all the records for app1Uid - mAppExitInfoTracker.getExitInfo(app1PackageName, app1Uid, 0, 0, list); - assertEquals(2, list.size()); + mAppExitInfoTracker.getExitInfo(null, app1Uid, 0, 0, list); + assertEquals(3, list.size()); info = list.get(0); @@ -315,7 +343,26 @@ public class ApplicationExitInfoTest { assertTrue(ArrayUtils.equals(info.getProcessStateSummary(), app1Cookie2, app1Cookie2.length)); + info = list.get(1); + verifyApplicationExitInfo( + info, // info + now1s, // timestamp + app1sPid1, // pid + app1Uid, // uid + app1Uid, // packageUid + null, // definingUid + app1sProcessName, // processName + 0, // connectionGroup + ApplicationExitInfo.REASON_USER_REQUESTED, // reason + null, // subReason + null, // status + app1sPss1, // pss + app1sRss1, // rss + IMPORTANCE_FOREGROUND, // importance + null); // description + + info = list.get(2); assertTrue(ArrayUtils.equals(info.getProcessStateSummary(), app1Cookie1, app1Cookie1.length)); @@ -808,7 +855,7 @@ public class ApplicationExitInfoTest { list.clear(); mAppExitInfoTracker.getExitInfo(null, app1Uid, 0, 0, list); - assertEquals(2, list.size()); + assertEquals(3, list.size()); info = list.get(0); @@ -831,6 +878,24 @@ public class ApplicationExitInfoTest { null); // description info = list.get(1); + verifyApplicationExitInfo( + info, // info + now1s, // timestamp + app1sPid1, // pid + app1Uid, // uid + app1Uid, // packageUid + null, // definingUid + app1sProcessName, // processName + 0, // connectionGroup + ApplicationExitInfo.REASON_USER_REQUESTED, // reason + null, // subReason + null, // status + app1sPss1, // pss + app1sRss1, // rss + IMPORTANCE_FOREGROUND, // importance + null); // description + + info = list.get(2); exitCode = 5; verifyApplicationExitInfo( info, // info diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java index 5d041b7c5757..3614763fecab 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java @@ -71,7 +71,6 @@ public class TimeControllerTest { private static final String SOURCE_PACKAGE = "com.android.frameworks.mockingservicestests"; private static final int SOURCE_USER_ID = 0; - private TimeController.TcConstants mConstants; private TimeController mTimeController; private MockitoSession mMockingSession; @@ -111,7 +110,6 @@ public class TimeControllerTest { // Initialize real objects. mTimeController = new TimeController(mJobSchedulerService); - mConstants = mTimeController.getTcConstants(); spyOn(mTimeController); } @@ -530,46 +528,6 @@ public class TimeControllerTest { } @Test - public void testJobDelayWakeupAlarmToggling() { - final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); - - JobStatus job = createJobStatus( - "testMaybeStartTrackingJobLocked_DeadlineReverseOrder", - createJob().setMinimumLatency(HOUR_IN_MILLIS)); - - doReturn(true).when(mTimeController) - .wouldBeReadyWithConstraintLocked(eq(job), anyInt()); - - // Starting off with using a wakeup alarm. - mConstants.USE_NON_WAKEUP_ALARM_FOR_DELAY = false; - InOrder inOrder = inOrder(mAlarmManager); - - mTimeController.maybeStartTrackingJobLocked(job, null); - inOrder.verify(mAlarmManager, times(1)) - .set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), eq(now + HOUR_IN_MILLIS), anyLong(), - anyLong(), - eq(TAG_DELAY), any(), any(), any()); - - // Use a non wakeup alarm. - mConstants.USE_NON_WAKEUP_ALARM_FOR_DELAY = true; - - mTimeController.maybeStartTrackingJobLocked(job, null); - inOrder.verify(mAlarmManager, times(1)) - .set(eq(AlarmManager.ELAPSED_REALTIME), eq(now + HOUR_IN_MILLIS), anyLong(), - anyLong(), eq(TAG_DELAY), - any(), any(), any()); - - // Back off, use a wakeup alarm. - mConstants.USE_NON_WAKEUP_ALARM_FOR_DELAY = false; - - mTimeController.maybeStartTrackingJobLocked(job, null); - inOrder.verify(mAlarmManager, times(1)) - .set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), eq(now + HOUR_IN_MILLIS), anyLong(), - anyLong(), - eq(TAG_DELAY), any(), any(), any()); - } - - @Test public void testCheckExpiredDeadlinesAndResetAlarm_AllReady() { doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt()); diff --git a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySavingStatsTest.java b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySavingStatsTest.java index 76239fcd9385..72d6caf1a5be 100644 --- a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySavingStatsTest.java +++ b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySavingStatsTest.java @@ -33,6 +33,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.server.power.batterysaver.BatterySavingStats.BatterySaverState; import com.android.server.power.batterysaver.BatterySavingStats.DozeState; import com.android.server.power.batterysaver.BatterySavingStats.InteractiveState; +import com.android.server.power.batterysaver.BatterySavingStats.PlugState; import org.junit.Test; import org.junit.runner.RunWith; @@ -118,7 +119,8 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.OFF, InteractiveState.INTERACTIVE, - DozeState.NOT_DOZING); + DozeState.NOT_DOZING, + PlugState.UNPLUGGED); target.advanceClock(4); target.drainBattery(100); @@ -126,7 +128,8 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.OFF, InteractiveState.NON_INTERACTIVE, - DozeState.NOT_DOZING); + DozeState.NOT_DOZING, + PlugState.UNPLUGGED); target.advanceClock(2); target.drainBattery(500); @@ -134,7 +137,8 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.OFF, InteractiveState.INTERACTIVE, - DozeState.NOT_DOZING); + DozeState.NOT_DOZING, + PlugState.UNPLUGGED); target.advanceClock(4); target.drainBattery(100); @@ -142,7 +146,8 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.OFF, InteractiveState.NON_INTERACTIVE, - DozeState.NOT_DOZING); + DozeState.NOT_DOZING, + PlugState.UNPLUGGED); target.advanceClock(2); target.drainBattery(500); @@ -150,7 +155,8 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.OFF, InteractiveState.INTERACTIVE, - DozeState.NOT_DOZING); + DozeState.NOT_DOZING, + PlugState.UNPLUGGED); target.advanceClock(3); target.drainBattery(100); @@ -158,7 +164,8 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.OFF, InteractiveState.NON_INTERACTIVE, - DozeState.LIGHT); + DozeState.LIGHT, + PlugState.UNPLUGGED); target.advanceClock(5); target.drainBattery(100); @@ -166,7 +173,8 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.OFF, InteractiveState.NON_INTERACTIVE, - DozeState.DEEP); + DozeState.DEEP, + PlugState.UNPLUGGED); target.advanceClock(1); target.drainBattery(200); @@ -174,7 +182,8 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.ON, InteractiveState.INTERACTIVE, - DozeState.NOT_DOZING); + DozeState.NOT_DOZING, + PlugState.UNPLUGGED); target.advanceClock(1); target.drainBattery(300); @@ -182,7 +191,8 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.OFF, InteractiveState.INTERACTIVE, - DozeState.NOT_DOZING); + DozeState.NOT_DOZING, + PlugState.UNPLUGGED); target.advanceClock(3); target.drainBattery(500); @@ -190,12 +200,17 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.ON, InteractiveState.INTERACTIVE, - DozeState.NOT_DOZING); + DozeState.NOT_DOZING, + PlugState.UNPLUGGED); target.advanceClock(3); target.drainBattery(500); - target.startCharging(); + target.transitionState( + BatterySaverState.ON, + InteractiveState.INTERACTIVE, + DozeState.NOT_DOZING, + PlugState.PLUGGED); target.advanceClock(5); target.drainBattery(1000); @@ -203,28 +218,34 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.ON, InteractiveState.INTERACTIVE, - DozeState.NOT_DOZING); + DozeState.NOT_DOZING, + PlugState.UNPLUGGED); target.advanceClock(5); target.drainBattery(100); - target.startCharging(); + target.transitionState( + BatterySaverState.ON, + InteractiveState.INTERACTIVE, + DozeState.NOT_DOZING, + PlugState.PLUGGED); target.assertDumpable(); assertEquals( - "BS=0,I=0,D=0:{4m,1000,15000.00uA/H,1500.00%}\n" + - "BS=1,I=0,D=0:{0m,0,0.00uA/H,0.00%}\n" + - "BS=0,I=1,D=0:{14m,800,3428.57uA/H,342.86%}\n" + - "BS=1,I=1,D=0:{9m,900,6000.00uA/H,600.00%}\n" + - "BS=0,I=0,D=1:{5m,100,1200.00uA/H,120.00%}\n" + - "BS=1,I=0,D=1:{0m,0,0.00uA/H,0.00%}\n" + - "BS=0,I=1,D=1:{0m,0,0.00uA/H,0.00%}\n" + - "BS=1,I=1,D=1:{0m,0,0.00uA/H,0.00%}\n" + - "BS=0,I=0,D=2:{1m,200,12000.00uA/H,1200.00%}\n" + - "BS=1,I=0,D=2:{0m,0,0.00uA/H,0.00%}\n" + - "BS=0,I=1,D=2:{0m,0,0.00uA/H,0.00%}\n" + - "BS=1,I=1,D=2:{0m,0,0.00uA/H,0.00%}", + "BS=0,I=0,D=0,P=0:{4m,1000,15000.00uA/H,1500.00%}\n" + + "BS=1,I=0,D=0,P=0:{0m,0,0.00uA/H,0.00%}\n" + + "BS=0,I=1,D=0,P=0:{14m,800,3428.57uA/H,342.86%}\n" + + "BS=1,I=1,D=0,P=0:{9m,900,6000.00uA/H,600.00%}\n" + + "BS=0,I=0,D=1,P=0:{5m,100,1200.00uA/H,120.00%}\n" + + "BS=1,I=0,D=1,P=0:{0m,0,0.00uA/H,0.00%}\n" + + "BS=0,I=1,D=1,P=0:{0m,0,0.00uA/H,0.00%}\n" + + "BS=1,I=1,D=1,P=0:{0m,0,0.00uA/H,0.00%}\n" + + "BS=0,I=0,D=2,P=0:{1m,200,12000.00uA/H,1200.00%}\n" + + "BS=1,I=0,D=2,P=0:{0m,0,0.00uA/H,0.00%}\n" + + "BS=0,I=1,D=2,P=0:{0m,0,0.00uA/H,0.00%}\n" + + "BS=1,I=1,D=2,P=0:{0m,0,0.00uA/H,0.00%}\n" + + "BS=1,I=1,D=0,P=1:{5m,1000,12000.00uA/H,1200.00%}", target.toDebugString()); } @@ -242,7 +263,8 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.OFF, InteractiveState.INTERACTIVE, - DozeState.NOT_DOZING); + DozeState.NOT_DOZING, + PlugState.UNPLUGGED); verify(mMetricsLogger, times(0)).count(anyString(), anyInt()); @@ -253,7 +275,8 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.OFF, InteractiveState.NON_INTERACTIVE, - DozeState.NOT_DOZING); + DozeState.NOT_DOZING, + PlugState.UNPLUGGED); assertLog(); @@ -264,7 +287,8 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.OFF, InteractiveState.NON_INTERACTIVE, - DozeState.DEEP); + DozeState.DEEP, + PlugState.UNPLUGGED); target.advanceClock(1); target.drainBattery(2000); @@ -274,7 +298,8 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.OFF, InteractiveState.NON_INTERACTIVE, - DozeState.LIGHT); + DozeState.LIGHT, + PlugState.UNPLUGGED); target.advanceClock(1); target.drainBattery(2000); @@ -284,7 +309,8 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.ON, InteractiveState.INTERACTIVE, - DozeState.NOT_DOZING); + DozeState.NOT_DOZING, + PlugState.UNPLUGGED); assertLog(); @@ -292,7 +318,11 @@ public class BatterySavingStatsTest { target.drainBattery(10000); reset(mMetricsLogger); - target.startCharging(); + target.transitionState( + BatterySaverState.ON, + InteractiveState.INTERACTIVE, + DozeState.NOT_DOZING, + PlugState.PLUGGED); assertLog(); @@ -303,14 +333,19 @@ public class BatterySavingStatsTest { target.transitionState( BatterySaverState.ON, InteractiveState.NON_INTERACTIVE, - DozeState.NOT_DOZING); + DozeState.NOT_DOZING, + PlugState.UNPLUGGED); verify(mMetricsLogger, times(0)).count(anyString(), anyInt()); target.advanceClock(1); target.drainBattery(2000); - target.startCharging(); + target.transitionState( + BatterySaverState.ON, + InteractiveState.NON_INTERACTIVE, + DozeState.NOT_DOZING, + PlugState.PLUGGED); assertLog(); } diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java index 1a04d2ff8c29..4dec7a1a0ab9 100644 --- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java @@ -218,6 +218,10 @@ public class AppStandbyControllerTests { } @Override + void updatePowerWhitelistCache() { + } + + @Override boolean isRestrictedBucketEnabled() { return mIsRestrictedBucketEnabled; } 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 e3bb1b6ca9f3..c60abe8d51d1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java @@ -65,9 +65,9 @@ public class ActivityDisplayTests extends ActivityTestsBase { // Create a stack at bottom. final TaskDisplayArea taskDisplayAreas = mRootWindowContainer.getDefaultDisplay().getDefaultTaskDisplayArea(); - final ActivityStack stack = + final Task stack = new StackBuilder(mRootWindowContainer).setOnTop(!ON_TOP).build(); - final ActivityStack prevFocusedStack = taskDisplayAreas.getFocusedStack(); + final Task prevFocusedStack = taskDisplayAreas.getFocusedStack(); stack.moveToFront("moveStackToFront"); // After moving the stack to front, the previous focused should be the last focused. @@ -86,7 +86,7 @@ public class ActivityDisplayTests extends ActivityTestsBase { @Test public void testFullscreenStackCanBeFocusedWhenFocusablePinnedStackExists() { // Create a pinned stack and move to front. - final ActivityStack pinnedStack = mRootWindowContainer.getDefaultTaskDisplayArea() + final Task pinnedStack = mRootWindowContainer.getDefaultTaskDisplayArea() .createStack(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, ON_TOP); final Task pinnedTask = new TaskBuilder(mService.mStackSupervisor) .setStack(pinnedStack).build(); @@ -98,7 +98,7 @@ public class ActivityDisplayTests extends ActivityTestsBase { assertTrue(pinnedStack.isFocusedStackOnDisplay()); // Create a fullscreen stack and move to front. - final ActivityStack fullscreenStack = createFullscreenStackWithSimpleActivityAt( + final Task fullscreenStack = createFullscreenStackWithSimpleActivityAt( mRootWindowContainer.getDefaultDisplay()); fullscreenStack.moveToFront("moveFullscreenStackToFront"); @@ -114,8 +114,8 @@ public class ActivityDisplayTests extends ActivityTestsBase { public void testStackShouldNotBeFocusedAfterMovingToBackOrRemoving() { // Create a display which only contains 2 stacks. final DisplayContent display = addNewDisplayContentAt(DisplayContent.POSITION_TOP); - final ActivityStack stack1 = createFullscreenStackWithSimpleActivityAt(display); - final ActivityStack stack2 = createFullscreenStackWithSimpleActivityAt(display); + final Task stack1 = createFullscreenStackWithSimpleActivityAt(display); + final Task stack2 = createFullscreenStackWithSimpleActivityAt(display); // Put stack1 and stack2 on top. stack1.moveToFront("moveStack1ToFront"); @@ -143,11 +143,11 @@ public class ActivityDisplayTests extends ActivityTestsBase { doReturn(false).when(display).shouldDestroyContentOnRemove(); // Put home stack on the display. - final ActivityStack homeStack = new StackBuilder(mRootWindowContainer) + final Task homeStack = new StackBuilder(mRootWindowContainer) .setDisplay(display).setActivityType(ACTIVITY_TYPE_HOME).build(); // Put a finishing standard activity which will be reparented. - final ActivityStack stack = createFullscreenStackWithSimpleActivityAt(display); + final Task stack = createFullscreenStackWithSimpleActivityAt(display); stack.topRunningActivity().makeFinishingLocked(); clearInvocations(homeStack); @@ -158,8 +158,8 @@ public class ActivityDisplayTests extends ActivityTestsBase { verify(homeStack, never()).resumeTopActivityUncheckedLocked(any(), any()); } - private ActivityStack createFullscreenStackWithSimpleActivityAt(DisplayContent display) { - final ActivityStack fullscreenStack = display.getDefaultTaskDisplayArea().createStack( + private Task createFullscreenStackWithSimpleActivityAt(DisplayContent display) { + final Task fullscreenStack = display.getDefaultTaskDisplayArea().createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP); final Task fullscreenTask = new TaskBuilder(mService.mStackSupervisor) .setStack(fullscreenStack).build(); @@ -174,11 +174,11 @@ public class ActivityDisplayTests extends ActivityTestsBase { public void testTopRunningActivity() { final DisplayContent display = mRootWindowContainer.getDefaultDisplay(); final KeyguardController keyguard = mSupervisor.getKeyguardController(); - final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); + final Task stack = new StackBuilder(mRootWindowContainer).build(); final ActivityRecord activity = stack.getTopNonFinishingActivity(); // Create empty stack on top. - final ActivityStack emptyStack = + final Task emptyStack = new StackBuilder(mRootWindowContainer).setCreateActivity(false).build(); // Make sure the top running activity is not affected when keyguard is not locked. @@ -223,7 +223,7 @@ public class ActivityDisplayTests extends ActivityTestsBase { @Test public void testAlwaysOnTopStackLocation() { final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - final ActivityStack alwaysOnTopStack = taskDisplayArea.createStack(WINDOWING_MODE_FREEFORM, + final Task alwaysOnTopStack = taskDisplayArea.createStack(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */); final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true) .setStack(alwaysOnTopStack).build(); @@ -234,12 +234,12 @@ public class ActivityDisplayTests extends ActivityTestsBase { assertTrue(alwaysOnTopStack.getTopNonFinishingActivity().isAlwaysOnTop()); assertEquals(alwaysOnTopStack, taskDisplayArea.getTopStack()); - final ActivityStack pinnedStack = taskDisplayArea.createStack( + final Task pinnedStack = taskDisplayArea.createStack( WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */); assertEquals(pinnedStack, taskDisplayArea.getRootPinnedTask()); assertEquals(pinnedStack, taskDisplayArea.getTopStack()); - final ActivityStack anotherAlwaysOnTopStack = taskDisplayArea.createStack( + final Task anotherAlwaysOnTopStack = taskDisplayArea.createStack( WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */); anotherAlwaysOnTopStack.setAlwaysOnTop(true); taskDisplayArea.positionStackAtTop(anotherAlwaysOnTopStack, false /* includingParents */); @@ -249,7 +249,7 @@ public class ActivityDisplayTests extends ActivityTestsBase { // existing alwaysOnTop stack. assertEquals(anotherAlwaysOnTopStack, taskDisplayArea.getStackAt(topPosition - 1)); - final ActivityStack nonAlwaysOnTopStack = taskDisplayArea.createStack( + final Task nonAlwaysOnTopStack = taskDisplayArea.createStack( WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */); assertEquals(taskDisplayArea, nonAlwaysOnTopStack.getDisplayArea()); topPosition = taskDisplayArea.getStackCount() - 1; @@ -273,7 +273,7 @@ public class ActivityDisplayTests extends ActivityTestsBase { assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop()); assertEquals(anotherAlwaysOnTopStack, taskDisplayArea.getStackAt(topPosition - 1)); - final ActivityStack dreamStack = taskDisplayArea.createStack( + final Task dreamStack = taskDisplayArea.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_DREAM, true /* onTop */); assertEquals(taskDisplayArea, dreamStack.getDisplayArea()); assertTrue(dreamStack.isAlwaysOnTop()); @@ -282,7 +282,7 @@ public class ActivityDisplayTests extends ActivityTestsBase { assertEquals(dreamStack, taskDisplayArea.getTopStack()); assertEquals(pinnedStack, taskDisplayArea.getStackAt(topPosition - 1)); - final ActivityStack assistStack = taskDisplayArea.createStack( + final Task assistStack = taskDisplayArea.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */); assertEquals(taskDisplayArea, assistStack.getDisplayArea()); assertFalse(assistStack.isAlwaysOnTop()); @@ -310,13 +310,13 @@ public class ActivityDisplayTests extends ActivityTestsBase { private void removeStackTests(Runnable runnable) { final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - final ActivityStack stack1 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + final Task stack1 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP); - final ActivityStack stack2 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + final Task stack2 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP); - final ActivityStack stack3 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + final Task stack3 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP); - final ActivityStack stack4 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + final Task stack4 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP); final Task task1 = new TaskBuilder(mService.mStackSupervisor).setStack(stack1).build(); final Task task2 = new TaskBuilder(mService.mStackSupervisor).setStack(stack2).build(); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java index e1ce431fc97c..feac6dbe1051 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java @@ -341,7 +341,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { public void testConsecutiveLaunchOnDifferentDisplay() { onActivityLaunched(mTopActivity); - final ActivityStack stack = new StackBuilder(mRootWindowContainer) + final Task stack = new StackBuilder(mRootWindowContainer) .setDisplay(addNewDisplayContentAt(DisplayContent.POSITION_BOTTOM)) .setCreateActivity(false) .build(); 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 76b1a4d69f05..e45ced64c5b6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -45,19 +45,19 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.wm.ActivityRecord.FINISH_RESULT_CANCELLED; import static com.android.server.wm.ActivityRecord.FINISH_RESULT_REMOVED; import static com.android.server.wm.ActivityRecord.FINISH_RESULT_REQUESTED; -import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED; -import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING; -import static com.android.server.wm.ActivityStack.ActivityState.FINISHING; -import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSED; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSING; -import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; -import static com.android.server.wm.ActivityStack.ActivityState.STARTED; -import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; -import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; -import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_INVISIBLE; -import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE; -import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT; +import static com.android.server.wm.Task.ActivityState.DESTROYED; +import static com.android.server.wm.Task.ActivityState.DESTROYING; +import static com.android.server.wm.Task.ActivityState.FINISHING; +import static com.android.server.wm.Task.ActivityState.INITIALIZING; +import static com.android.server.wm.Task.ActivityState.PAUSED; +import static com.android.server.wm.Task.ActivityState.PAUSING; +import static com.android.server.wm.Task.ActivityState.RESUMED; +import static com.android.server.wm.Task.ActivityState.STARTED; +import static com.android.server.wm.Task.ActivityState.STOPPED; +import static com.android.server.wm.Task.ActivityState.STOPPING; +import static com.android.server.wm.Task.STACK_VISIBILITY_INVISIBLE; +import static com.android.server.wm.Task.STACK_VISIBILITY_VISIBLE; +import static com.android.server.wm.Task.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT; import static com.google.common.truth.Truth.assertThat; @@ -106,7 +106,7 @@ import android.view.WindowManagerGlobal; import androidx.test.filters.MediumTest; import com.android.internal.R; -import com.android.server.wm.ActivityStack.ActivityState; +import com.android.server.wm.Task.ActivityState; import org.junit.Before; import org.junit.Test; @@ -123,7 +123,7 @@ import org.mockito.invocation.InvocationOnMock; @Presubmit @RunWith(WindowTestRunner.class) public class ActivityRecordTests extends ActivityTestsBase { - private ActivityStack mStack; + private Task mStack; private Task mTask; private ActivityRecord mActivity; @@ -292,7 +292,7 @@ public class ActivityRecordTests extends ActivityTestsBase { @Test public void testSetsRelaunchReason_NotDragResizing() { - mActivity.setState(ActivityStack.ActivityState.RESUMED, "Testing"); + mActivity.setState(Task.ActivityState.RESUMED, "Testing"); mTask.onRequestedOverrideConfigurationChanged(mTask.getConfiguration()); mActivity.setLastReportedConfiguration(new MergedConfiguration(new Configuration(), @@ -315,7 +315,7 @@ public class ActivityRecordTests extends ActivityTestsBase { @Test public void testSetsRelaunchReason_DragResizing() { - mActivity.setState(ActivityStack.ActivityState.RESUMED, "Testing"); + mActivity.setState(Task.ActivityState.RESUMED, "Testing"); mTask.onRequestedOverrideConfigurationChanged(mTask.getConfiguration()); mActivity.setLastReportedConfiguration(new MergedConfiguration(new Configuration(), @@ -340,7 +340,7 @@ public class ActivityRecordTests extends ActivityTestsBase { @Test public void testSetsRelaunchReason_NonResizeConfigChanges() { - mActivity.setState(ActivityStack.ActivityState.RESUMED, "Testing"); + mActivity.setState(Task.ActivityState.RESUMED, "Testing"); mTask.onRequestedOverrideConfigurationChanged(mTask.getConfiguration()); mActivity.setLastReportedConfiguration(new MergedConfiguration(new Configuration(), @@ -366,7 +366,7 @@ public class ActivityRecordTests extends ActivityTestsBase { .setTask(mTask) .setConfigChanges(CONFIG_ORIENTATION | CONFIG_SCREEN_LAYOUT) .build(); - mActivity.setState(ActivityStack.ActivityState.RESUMED, "Testing"); + mActivity.setState(Task.ActivityState.RESUMED, "Testing"); mActivity.setLastReportedConfiguration(new MergedConfiguration(new Configuration(), mActivity.getConfiguration())); @@ -489,7 +489,7 @@ public class ActivityRecordTests extends ActivityTestsBase { @Test public void testShouldMakeActive_deferredResume() { - mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing"); + mActivity.setState(Task.ActivityState.STOPPED, "Testing"); mSupervisor.beginDeferResume(); assertEquals(false, mActivity.shouldMakeActive(null /* activeActivity */)); @@ -503,14 +503,14 @@ public class ActivityRecordTests extends ActivityTestsBase { ActivityRecord finishingActivity = new ActivityBuilder(mService).setTask(mTask).build(); finishingActivity.finishing = true; ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build(); - mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing"); + mActivity.setState(Task.ActivityState.STOPPED, "Testing"); assertEquals(false, mActivity.shouldMakeActive(null /* activeActivity */)); } @Test public void testShouldResume_stackVisibility() { - mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing"); + mActivity.setState(Task.ActivityState.STOPPED, "Testing"); spyOn(mStack); doReturn(STACK_VISIBILITY_VISIBLE).when(mStack).getVisibility(null); @@ -525,7 +525,7 @@ public class ActivityRecordTests extends ActivityTestsBase { @Test public void testShouldResumeOrPauseWithResults() { - mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing"); + mActivity.setState(Task.ActivityState.STOPPED, "Testing"); spyOn(mStack); ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build(); @@ -544,9 +544,9 @@ public class ActivityRecordTests extends ActivityTestsBase { .setLaunchTaskBehind(true) .setConfigChanges(CONFIG_ORIENTATION) .build(); - mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing"); + mActivity.setState(Task.ActivityState.STOPPED, "Testing"); - final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); + final Task stack = new StackBuilder(mRootWindowContainer).build(); try { doReturn(false).when(stack).isTranslucent(any()); assertFalse(mStack.shouldBeVisible(null /* starting */)); @@ -585,7 +585,7 @@ public class ActivityRecordTests extends ActivityTestsBase { public void testShouldStartWhenMakeClientActive() { ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build(); topActivity.setOccludesParent(false); - mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing"); + mActivity.setState(Task.ActivityState.STOPPED, "Testing"); mActivity.setVisibility(true); mActivity.makeActiveIfNeeded(null /* activeActivity */); assertEquals(STARTED, mActivity.getState()); @@ -754,14 +754,14 @@ public class ActivityRecordTests extends ActivityTestsBase { @Test public void testFinishActivityIfPossible_adjustStackOrder() { // Prepare the stacks with order (top to bottom): mStack, stack1, stack2. - final ActivityStack stack1 = new StackBuilder(mRootWindowContainer).build(); + final Task stack1 = new StackBuilder(mRootWindowContainer).build(); mStack.moveToFront("test"); // The stack2 is needed here for moving back to simulate the // {@link DisplayContent#mPreferredTopFocusableStack} is cleared, so // {@link DisplayContent#getFocusedStack} will rely on the order of focusable-and-visible // stacks. Then when mActivity is finishing, its stack will be invisible (no running // activities in the stack) that is the key condition to verify. - final ActivityStack stack2 = new StackBuilder(mRootWindowContainer).build(); + final Task stack2 = new StackBuilder(mRootWindowContainer).build(); stack2.moveToBack("test", stack2.getBottomMostTask()); assertTrue(mStack.isTopStackInDisplayArea()); @@ -787,7 +787,7 @@ public class ActivityRecordTests extends ActivityTestsBase { .setCreateTask(true) .setStack(mStack) .build(); - ActivityStack topRootableTask = (ActivityStack) topActivity.getTask(); + Task topRootableTask = topActivity.getTask(); topRootableTask.moveToFront("test"); assertTrue(mStack.isTopStackInDisplayArea()); @@ -807,7 +807,7 @@ public class ActivityRecordTests extends ActivityTestsBase { public void testFinishActivityIfPossible_PreferredTopStackChanged() { final ActivityRecord topActivityOnNonTopDisplay = createActivityOnDisplay(true /* defaultDisplay */, null /* process */); - ActivityStack topRootableTask = topActivityOnNonTopDisplay.getRootTask(); + Task topRootableTask = topActivityOnNonTopDisplay.getRootTask(); topRootableTask.moveToFront("test"); assertTrue(topRootableTask.isTopStackInDisplayArea()); assertEquals(topRootableTask, topActivityOnNonTopDisplay.getDisplayArea() @@ -971,7 +971,7 @@ public class ActivityRecordTests extends ActivityTestsBase { // Simulates that {@code currentTop} starts an existing activity from background (so its // state is stopped) and the starting flow just goes to place it at top. - final ActivityStack nextStack = new StackBuilder(mRootWindowContainer).build(); + final Task nextStack = new StackBuilder(mRootWindowContainer).build(); final ActivityRecord nextTop = nextStack.getTopNonFinishingActivity(); nextTop.setState(STOPPED, "test"); @@ -1093,7 +1093,7 @@ public class ActivityRecordTests extends ActivityTestsBase { // Add another stack to become focused and make the activity there visible. This way it // simulates finishing in non-focused stack in split-screen. - final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); + final Task stack = new StackBuilder(mRootWindowContainer).build(); final ActivityRecord focusedActivity = stack.getTopMostActivity(); focusedActivity.nowVisible = true; focusedActivity.mVisibleRequested = true; @@ -1199,7 +1199,7 @@ public class ActivityRecordTests extends ActivityTestsBase { @Test public void testDestroyIfPossible_lastActivityAboveEmptyHomeStack() { // Empty the home stack. - final ActivityStack homeStack = mActivity.getDisplayArea().getRootHomeTask(); + final Task homeStack = mActivity.getDisplayArea().getRootHomeTask(); homeStack.forAllLeafTasks((t) -> { homeStack.removeChild(t, "test"); }, true /* traverseTopToBottom */); @@ -1225,7 +1225,7 @@ public class ActivityRecordTests extends ActivityTestsBase { @Test public void testCompleteFinishing_lastActivityAboveEmptyHomeStack() { // Empty the home stack. - final ActivityStack homeStack = mActivity.getDisplayArea().getRootHomeTask(); + final Task homeStack = mActivity.getDisplayArea().getRootHomeTask(); homeStack.forAllLeafTasks((t) -> { homeStack.removeChild(t, "test"); }, true /* traverseTopToBottom */); @@ -1325,7 +1325,7 @@ public class ActivityRecordTests extends ActivityTestsBase { @Test public void testRemoveFromHistory() { - final ActivityStack stack = mActivity.getRootTask(); + final Task stack = mActivity.getRootTask(); final Task task = mActivity.getTask(); mActivity.removeFromHistory("test"); @@ -1334,7 +1334,7 @@ public class ActivityRecordTests extends ActivityTestsBase { assertNull(mActivity.app); assertNull(mActivity.getTask()); assertEquals(0, task.getChildCount()); - assertEquals(task.getStack(), task); + assertEquals(task.getRootTask(), task); assertEquals(0, stack.getChildCount()); } @@ -1576,7 +1576,7 @@ public class ActivityRecordTests extends ActivityTestsBase { // Create a new task with custom config to reparent the activity to. final Task newTask = - new TaskBuilder(mSupervisor).setStack(initialTask.getStack()).build(); + new TaskBuilder(mSupervisor).setStack(initialTask.getRootTask()).build(); final Configuration newConfig = newTask.getConfiguration(); newConfig.densityDpi += 100; newTask.onRequestedOverrideConfigurationChanged(newConfig); @@ -1608,7 +1608,7 @@ public class ActivityRecordTests extends ActivityTestsBase { // Create a new task with custom config to reparent the second activity to. final Task newTask = - new TaskBuilder(mSupervisor).setStack(initialTask.getStack()).build(); + new TaskBuilder(mSupervisor).setStack(initialTask.getRootTask()).build(); final Configuration newConfig = newTask.getConfiguration(); newConfig.densityDpi += 100; newTask.onRequestedOverrideConfigurationChanged(newConfig); @@ -1696,7 +1696,7 @@ public class ActivityRecordTests extends ActivityTestsBase { display = new TestDisplayContent.Builder(mService, 2000, 1000).setDensityDpi(300) .setPosition(DisplayContent.POSITION_TOP).build(); } - final ActivityStack stack = display.getDefaultTaskDisplayArea() + final Task stack = display.getDefaultTaskDisplayArea() .createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */); final Task task = new TaskBuilder(mSupervisor).setStack(stack).build(); return new ActivityBuilder(mService).setTask(task).setUseProcess(process).build(); 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 5c6906cfa942..197c89a2d479 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java @@ -56,7 +56,7 @@ import org.junit.runner.RunWith; @Presubmit @RunWith(WindowTestRunner.class) public class ActivityStackSupervisorTests extends ActivityTestsBase { - private ActivityStack mFullscreenStack; + private Task mFullscreenStack; @Before public void setUp() throws Exception { @@ -113,7 +113,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase { public void testHandleNonResizableTaskOnSecondaryDisplay() { // Create an unresizable task on secondary display. final DisplayContent newDisplay = addNewDisplayContentAt(DisplayContent.POSITION_TOP); - final ActivityStack stack = new StackBuilder(mRootWindowContainer) + final Task stack = new StackBuilder(mRootWindowContainer) .setDisplay(newDisplay).build(); final ActivityRecord unresizableActivity = stack.getTopNonFinishingActivity(); final Task task = unresizableActivity.getTask(); 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 373eed921580..5153af2b0d6b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -34,19 +34,19 @@ 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.verify; -import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING; -import static com.android.server.wm.ActivityStack.ActivityState.FINISHING; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSING; -import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; -import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; -import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; -import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_INVISIBLE; -import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE; -import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT; import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE; import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE; +import static com.android.server.wm.Task.ActivityState.DESTROYING; +import static com.android.server.wm.Task.ActivityState.FINISHING; +import static com.android.server.wm.Task.ActivityState.PAUSING; +import static com.android.server.wm.Task.ActivityState.RESUMED; +import static com.android.server.wm.Task.ActivityState.STOPPED; +import static com.android.server.wm.Task.ActivityState.STOPPING; import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG; import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT; +import static com.android.server.wm.Task.STACK_VISIBILITY_INVISIBLE; +import static com.android.server.wm.Task.STACK_VISIBILITY_VISIBLE; +import static com.android.server.wm.Task.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT; import static com.android.server.wm.TaskDisplayArea.getStackAbove; import static com.android.server.wm.WindowContainer.POSITION_TOP; @@ -90,7 +90,7 @@ import java.util.function.Consumer; @RunWith(WindowTestRunner.class) public class ActivityStackTests extends ActivityTestsBase { private TaskDisplayArea mDefaultTaskDisplayArea; - private ActivityStack mStack; + private Task mStack; private Task mTask; @Before @@ -119,7 +119,7 @@ public class ActivityStackTests extends ActivityTestsBase { r.setState(RESUMED, "testResumedActivityFromTaskReparenting"); assertEquals(r, mStack.getResumedActivity()); - final ActivityStack destStack = mDefaultTaskDisplayArea.createStack( + final Task destStack = mDefaultTaskDisplayArea.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); mTask.reparent(destStack, true /* toTop */, Task.REPARENT_KEEP_STACK_AT_FRONT, @@ -137,7 +137,7 @@ public class ActivityStackTests extends ActivityTestsBase { r.setState(RESUMED, "testResumedActivityFromActivityReparenting"); assertEquals(r, mStack.getResumedActivity()); - final ActivityStack destStack = mDefaultTaskDisplayArea.createStack( + final Task destStack = mDefaultTaskDisplayArea.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); mTask.reparent(destStack, true /*toTop*/, REPARENT_MOVE_STACK_TO_FRONT, false, false, "testResumedActivityFromActivityReparenting"); @@ -153,7 +153,7 @@ public class ActivityStackTests extends ActivityTestsBase { organizer.setMoveToSecondaryOnEnter(false); // Create primary splitscreen stack. - final ActivityStack primarySplitScreen = mDefaultTaskDisplayArea.createStack( + final Task primarySplitScreen = mDefaultTaskDisplayArea.createStack( WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Assert windowing mode. @@ -178,10 +178,10 @@ public class ActivityStackTests extends ActivityTestsBase { public void testMoveToPrimarySplitScreenThenMoveToBack() { TestSplitOrganizer organizer = new TestSplitOrganizer(mService); // This time, start with a fullscreen activitystack - final ActivityStack primarySplitScreen = mDefaultTaskDisplayArea.createStack( + final Task primarySplitScreen = mDefaultTaskDisplayArea.createStack( WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */); - primarySplitScreen.reparent((ActivityStack) organizer.mPrimary, POSITION_TOP, + primarySplitScreen.reparent(organizer.mPrimary, POSITION_TOP, false /*moveParents*/, "test"); // Assert windowing mode. @@ -204,13 +204,13 @@ public class ActivityStackTests extends ActivityTestsBase { TestSplitOrganizer organizer = new TestSplitOrganizer(mService); // Set up split-screen with primary on top and secondary containing the home task below // another stack. - final ActivityStack primaryTask = mDefaultTaskDisplayArea.createStack( + final Task primaryTask = mDefaultTaskDisplayArea.createStack( WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack homeRoot = mDefaultTaskDisplayArea.getStack( + final Task homeRoot = mDefaultTaskDisplayArea.getStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME); - final ActivityStack secondaryTask = mDefaultTaskDisplayArea.createStack( + final Task secondaryTask = mDefaultTaskDisplayArea.createStack( WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); - mDefaultTaskDisplayArea.positionStackAtTop((ActivityStack) organizer.mPrimary, + mDefaultTaskDisplayArea.positionStackAtTop(organizer.mPrimary, false /* includingParents */); // Move primary to back. @@ -228,7 +228,7 @@ public class ActivityStackTests extends ActivityTestsBase { assertEquals(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, primaryTask.getWindowingMode()); // Move secondary to back via parent (should be equivalent) - ((ActivityStack) organizer.mSecondary).moveToBack("test", secondaryTask); + organizer.mSecondary.moveToBack("test", secondaryTask); // Assert that it is now in back but still in secondary split assertEquals(1, homeRoot.compareTo(primaryTask)); @@ -239,12 +239,12 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testRemoveOrganizedTask_UpdateStackReference() { - final ActivityStack rootHomeTask = mDefaultTaskDisplayArea.getRootHomeTask(); + final Task rootHomeTask = mDefaultTaskDisplayArea.getRootHomeTask(); final ActivityRecord homeActivity = new ActivityBuilder(mService) .setStack(rootHomeTask) .setCreateTask(true) .build(); - final ActivityStack secondaryStack = (ActivityStack) WindowContainer.fromBinder( + final Task secondaryStack = (Task) WindowContainer.fromBinder( mService.mTaskOrganizerController.createRootTask(rootHomeTask.getDisplayId(), WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token.asBinder()); @@ -258,7 +258,7 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testStackInheritsDisplayWindowingMode() { - final ActivityStack primarySplitScreen = mDefaultTaskDisplayArea.createStack( + final Task primarySplitScreen = mDefaultTaskDisplayArea.createStack( WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */); assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode()); @@ -273,7 +273,7 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testStackOverridesDisplayWindowingMode() { - final ActivityStack primarySplitScreen = mDefaultTaskDisplayArea.createStack( + final Task primarySplitScreen = mDefaultTaskDisplayArea.createStack( WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */); assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode()); @@ -354,9 +354,9 @@ public class ActivityStackTests extends ActivityTestsBase { public void testMoveStackToBackIncludingParent() { final TaskDisplayArea taskDisplayArea = addNewDisplayContentAt(DisplayContent.POSITION_TOP) .getDefaultTaskDisplayArea(); - final ActivityStack stack1 = createStackForShouldBeVisibleTest(taskDisplayArea, + final Task stack1 = createStackForShouldBeVisibleTest(taskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack stack2 = createStackForShouldBeVisibleTest(taskDisplayArea, + final Task stack2 = createStackForShouldBeVisibleTest(taskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Do not move display to back because there is still another stack. @@ -371,9 +371,9 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testShouldBeVisible_Fullscreen() { - final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); - final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Add an activity to the pinned stack so it isn't considered empty for visibility check. final ActivityRecord pinnedActivity = new ActivityBuilder(mService) @@ -384,7 +384,7 @@ public class ActivityStackTests extends ActivityTestsBase { assertTrue(homeStack.shouldBeVisible(null /* starting */)); assertTrue(pinnedStack.shouldBeVisible(null /* starting */)); - final ActivityStack fullscreenStack = createStackForShouldBeVisibleTest( + final Task fullscreenStack = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack @@ -402,14 +402,14 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testShouldBeVisible_SplitScreen() { - final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); // Home stack should always be fullscreen for this test. doReturn(false).when(homeStack).supportsSplitScreenWindowingMode(); - final ActivityStack splitScreenPrimary = + final Task splitScreenPrimary = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack splitScreenSecondary = + final Task splitScreenSecondary = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); @@ -437,7 +437,7 @@ public class ActivityStackTests extends ActivityTestsBase { assertEquals(STACK_VISIBILITY_VISIBLE, splitScreenSecondary.getVisibility(null /* starting */)); - final ActivityStack splitScreenSecondary2 = + final Task splitScreenSecondary2 = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); // First split-screen secondary shouldn't be visible behind another opaque split-split @@ -460,7 +460,7 @@ public class ActivityStackTests extends ActivityTestsBase { assertEquals(STACK_VISIBILITY_VISIBLE, splitScreenSecondary2.getVisibility(null /* starting */)); - final ActivityStack assistantStack = createStackForShouldBeVisibleTest( + final Task assistantStack = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */); @@ -531,13 +531,13 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testGetVisibility_MultiLevel() { - final ActivityStack homeStack = createStackForShouldBeVisibleTest( + final Task homeStack = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, true /* onTop */); - final ActivityStack splitPrimary = createStackForShouldBeVisibleTest( + final Task splitPrimary = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED, true /* onTop */); - final ActivityStack splitSecondary = createStackForShouldBeVisibleTest( + final Task splitSecondary = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_UNDEFINED, true /* onTop */); @@ -556,7 +556,7 @@ public class ActivityStackTests extends ActivityTestsBase { // Add fullscreen translucent task that partially occludes split tasks - final ActivityStack translucentStack = createStandardStackForVisibilityTest( + final Task translucentStack = createStandardStackForVisibilityTest( WINDOWING_MODE_FULLSCREEN, true /* translucent */); // Fullscreen translucent task should be visible assertEquals(STACK_VISIBILITY_VISIBLE, translucentStack.getVisibility(null /* starting */)); @@ -580,10 +580,10 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testGetVisibility_FullscreenBehindTranslucent() { - final ActivityStack bottomStack = + final Task bottomStack = createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, false /* translucent */); - final ActivityStack translucentStack = + final Task translucentStack = createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, true /* translucent */); @@ -595,13 +595,13 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testGetVisibility_FullscreenBehindTranslucentAndOpaque() { - final ActivityStack bottomStack = + final Task bottomStack = createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, false /* translucent */); - final ActivityStack translucentStack = + final Task translucentStack = createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, true /* translucent */); - final ActivityStack opaqueStack = + final Task opaqueStack = createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, false /* translucent */); @@ -613,13 +613,13 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testGetVisibility_FullscreenBehindOpaqueAndTranslucent() { - final ActivityStack bottomStack = + final Task bottomStack = createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, false /* translucent */); - final ActivityStack opaqueStack = + final Task opaqueStack = createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, false /* translucent */); - final ActivityStack translucentStack = + final Task translucentStack = createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, true /* translucent */); @@ -632,10 +632,10 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testGetVisibility_FullscreenTranslucentBehindTranslucent() { - final ActivityStack bottomTranslucentStack = + final Task bottomTranslucentStack = createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, true /* translucent */); - final ActivityStack translucentStack = + final Task translucentStack = createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, true /* translucent */); @@ -647,10 +647,10 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testGetVisibility_FullscreenTranslucentBehindOpaque() { - final ActivityStack bottomTranslucentStack = + final Task bottomTranslucentStack = createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, true /* translucent */); - final ActivityStack opaqueStack = + final Task opaqueStack = createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, false /* translucent */); @@ -661,13 +661,13 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testGetVisibility_FullscreenBehindTranslucentAndPip() { - final ActivityStack bottomStack = + final Task bottomStack = createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, false /* translucent */); - final ActivityStack translucentStack = + final Task translucentStack = createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, true /* translucent */); - final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */); assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT, @@ -684,7 +684,7 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testShouldBeVisible_Finishing() { - final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); ActivityRecord topRunningHomeActivity = homeStack.topRunningActivity(); if (topRunningHomeActivity == null) { @@ -694,7 +694,7 @@ public class ActivityStackTests extends ActivityTestsBase { .build(); } - final ActivityStack translucentStack = createStackForShouldBeVisibleTest( + final Task translucentStack = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); doReturn(true).when(translucentStack).isTranslucent(any()); @@ -717,7 +717,7 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testShouldBeVisible_FullscreenBehindTranslucentInHomeStack() { - final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); final ActivityRecord firstActivity = new ActivityBuilder(mService) @@ -740,9 +740,9 @@ public class ActivityStackTests extends ActivityTestsBase { public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() { mDefaultTaskDisplayArea.removeStack(mStack); - final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); - final ActivityStack fullscreenStack = createStackForShouldBeVisibleTest( + final Task fullscreenStack = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); @@ -760,9 +760,9 @@ public class ActivityStackTests extends ActivityTestsBase { public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() { mDefaultTaskDisplayArea.removeStack(mStack); - final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); - final ActivityStack fullscreenStack = createStackForShouldBeVisibleTest( + final Task fullscreenStack = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); @@ -780,10 +780,10 @@ public class ActivityStackTests extends ActivityTestsBase { public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() { mDefaultTaskDisplayArea.removeStack(mStack); - final ActivityStack fullscreenStack = createStackForShouldBeVisibleTest( + final Task fullscreenStack = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); doReturn(false).when(homeStack).isTranslucent(any()); @@ -800,15 +800,15 @@ public class ActivityStackTests extends ActivityTestsBase { public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() { mDefaultTaskDisplayArea.removeStack(mStack); - final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); - final ActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest( + final Task fullscreenStack1 = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest( + final Task fullscreenStack2 = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */); doReturn(false).when(homeStack).isTranslucent(any()); @@ -827,12 +827,12 @@ public class ActivityStackTests extends ActivityTestsBase { testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() { mDefaultTaskDisplayArea.removeStack(mStack); - final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); - final ActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest( + final Task fullscreenStack1 = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest( + final Task fullscreenStack2 = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); @@ -851,13 +851,13 @@ public class ActivityStackTests extends ActivityTestsBase { public void testMoveHomeStackBehindStack_BehindHomeStack() { mDefaultTaskDisplayArea.removeStack(mStack); - final ActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest( + final Task fullscreenStack1 = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest( + final Task fullscreenStack2 = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); doReturn(false).when(homeStack).isTranslucent(any()); @@ -874,19 +874,19 @@ public class ActivityStackTests extends ActivityTestsBase { public void testMoveHomeStackBehindStack() { mDefaultTaskDisplayArea.removeStack(mStack); - final ActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest( + final Task fullscreenStack1 = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest( + final Task fullscreenStack2 = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest( + final Task fullscreenStack3 = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest( + final Task fullscreenStack4 = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); mDefaultTaskDisplayArea.moveStackBehindStack(homeStack, fullscreenStack1); @@ -901,13 +901,13 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testSetAlwaysOnTop() { - final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); - final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */); assertEquals(pinnedStack, getStackAbove(homeStack)); - final ActivityStack alwaysOnTopStack = createStackForShouldBeVisibleTest( + final Task alwaysOnTopStack = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */); alwaysOnTopStack.setAlwaysOnTop(true); @@ -915,13 +915,13 @@ public class ActivityStackTests extends ActivityTestsBase { // Ensure (non-pinned) always on top stack is put below pinned stack. assertEquals(pinnedStack, getStackAbove(alwaysOnTopStack)); - final ActivityStack nonAlwaysOnTopStack = createStackForShouldBeVisibleTest( + final Task nonAlwaysOnTopStack = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Ensure non always on top stack is put below always on top stacks. assertEquals(alwaysOnTopStack, getStackAbove(nonAlwaysOnTopStack)); - final ActivityStack alwaysOnTopStack2 = createStackForShouldBeVisibleTest( + final Task alwaysOnTopStack2 = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */); alwaysOnTopStack2.setAlwaysOnTop(true); @@ -946,13 +946,13 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testSplitScreenMoveToFront() { - final ActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest( + final Task splitScreenPrimary = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest( + final Task splitScreenSecondary = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack assistantStack = createStackForShouldBeVisibleTest( + final Task assistantStack = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */); @@ -977,18 +977,18 @@ public class ActivityStackTests extends ActivityTestsBase { } } - private ActivityStack createStandardStackForVisibilityTest(int windowingMode, + private Task createStandardStackForVisibilityTest(int windowingMode, boolean translucent) { - final ActivityStack stack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task stack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, windowingMode, ACTIVITY_TYPE_STANDARD, true /* onTop */); doReturn(translucent).when(stack).isTranslucent(any()); return stack; } @SuppressWarnings("TypeParameterUnusedInFormals") - private ActivityStack createStackForShouldBeVisibleTest( + private Task createStackForShouldBeVisibleTest( TaskDisplayArea taskDisplayArea, int windowingMode, int activityType, boolean onTop) { - final ActivityStack stack; + final Task stack; if (activityType == ACTIVITY_TYPE_HOME) { // Home stack and activity are created in ActivityTestsBase#setupActivityManagerService stack = mDefaultTaskDisplayArea.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME); @@ -1021,7 +1021,7 @@ public class ActivityStackTests extends ActivityTestsBase { // Note the activities have non-null ActivityRecord.app, so it won't remove directly. mRootWindowContainer.mFinishDisabledPackageActivitiesHelper.process( firstActivity.packageName, null /* filterByClasses */, true /* doit */, - true /* evenPersistent */, UserHandle.USER_ALL); + true /* evenPersistent */, UserHandle.USER_ALL, false /* onlyRemoveNoProcess */); // If the activity is disabled with {@link android.content.pm.PackageManager#DONT_KILL_APP} // the activity should still follow the normal flow to finish and destroy. @@ -1050,7 +1050,7 @@ public class ActivityStackTests extends ActivityTestsBase { mRootWindowContainer.mFinishDisabledPackageActivitiesHelper.process( activity.packageName, null /* filterByClasses */, true /* doit */, - true /* evenPersistent */, UserHandle.USER_ALL); + true /* evenPersistent */, UserHandle.USER_ALL, false /* onlyRemoveNoProcess */); // Although the overlay activity is in another package, the non-overlay activities are // removed from the task. Since the overlay activity should be removed as well, the task @@ -1152,7 +1152,7 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testWontFinishHomeStackImmediately() { - final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, + final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); ActivityRecord activity = homeStack.topRunningActivity(); @@ -1172,10 +1172,10 @@ public class ActivityStackTests extends ActivityTestsBase { public void testFinishCurrentActivity() { // Create 2 activities on a new display. final DisplayContent display = addNewDisplayContentAt(DisplayContent.POSITION_TOP); - final ActivityStack stack1 = createStackForShouldBeVisibleTest( + final Task stack1 = createStackForShouldBeVisibleTest( display.getDefaultTaskDisplayArea(), WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack stack2 = createStackForShouldBeVisibleTest( + final Task stack2 = createStackForShouldBeVisibleTest( display.getDefaultTaskDisplayArea(), WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); @@ -1194,7 +1194,7 @@ public class ActivityStackTests extends ActivityTestsBase { eq(display.mDisplayId), anyBoolean(), anyBoolean()); } - private ActivityRecord finishTopActivity(ActivityStack stack) { + private ActivityRecord finishTopActivity(Task stack) { final ActivityRecord activity = stack.topRunningActivity(); assertNotNull(activity); activity.setState(STOPPED, "finishTopActivity"); @@ -1252,7 +1252,7 @@ public class ActivityStackTests extends ActivityTestsBase { public void testStackOrderChangedOnPositionStack() { StackOrderChangedListener listener = new StackOrderChangedListener(); try { - final ActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest( + final Task fullscreenStack1 = createStackForShouldBeVisibleTest( mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); mDefaultTaskDisplayArea.registerStackOrderChangedListener(listener); @@ -1382,7 +1382,7 @@ public class ActivityStackTests extends ActivityTestsBase { activities[i] = r; doReturn(null).when(mService).getProcessController( eq(r.processName), eq(r.info.applicationInfo.uid)); - r.setState(ActivityStack.ActivityState.INITIALIZING, "test"); + r.setState(Task.ActivityState.INITIALIZING, "test"); // Ensure precondition that the activity is opaque. assertTrue(r.occludesParent()); mSupervisor.startSpecificActivity(r, false /* andResume */, @@ -1443,7 +1443,7 @@ public class ActivityStackTests extends ActivityTestsBase { public boolean mChanged = false; @Override - public void onStackOrderChanged(ActivityStack stack) { + public void onStackOrderChanged(Task stack) { mChanged = true; } } 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 ca4456b7b926..c9a927901a37 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java @@ -77,7 +77,7 @@ public class ActivityStartControllerTests extends ActivityTestsBase { .setCreateTask(true) .build(); final int startFlags = random.nextInt(); - final ActivityStack stack = mService.mRootWindowContainer.getDefaultTaskDisplayArea() + final Task stack = mService.mRootWindowContainer.getDefaultTaskDisplayArea() .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); final WindowProcessController wpc = new WindowProcessController(mService, mService.mContext.getApplicationInfo(), "name", 12345, 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 e3b1d6306a81..f2f8a12b6ea9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -321,7 +321,7 @@ public class ActivityStarterTests extends ActivityTestsBase { if (mockGetLaunchStack) { // Instrument the stack and task used. - final ActivityStack stack = mRootWindowContainer.getDefaultTaskDisplayArea() + final Task stack = mRootWindowContainer.getDefaultTaskDisplayArea() .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); @@ -492,7 +492,7 @@ public class ActivityStarterTests extends ActivityTestsBase { private void assertNoTasks(DisplayContent display) { display.forAllTaskDisplayAreas(taskDisplayArea -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); assertFalse(stack.hasChild()); } }); @@ -741,7 +741,7 @@ public class ActivityStarterTests extends ActivityTestsBase { new TestDisplayContent.Builder(mService, 1000, 1500) .setPosition(POSITION_BOTTOM).build(); final TaskDisplayArea secondaryTaskContainer = secondaryDisplay.getDefaultTaskDisplayArea(); - final ActivityStack stack = secondaryTaskContainer.createStack( + final Task stack = secondaryTaskContainer.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Create an activity record on the top of secondary display. @@ -787,7 +787,7 @@ public class ActivityStarterTests extends ActivityTestsBase { ACTIVITY_TYPE_STANDARD, false /* onTop */)); // Create another activity on top of the secondary display. - final ActivityStack topStack = secondaryTaskContainer.createStack(WINDOWING_MODE_FULLSCREEN, + final Task topStack = secondaryTaskContainer.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); final Task topTask = new TaskBuilder(mSupervisor).setStack(topStack).build(); new ActivityBuilder(mService).setTask(topTask).build(); @@ -826,7 +826,7 @@ public class ActivityStarterTests extends ActivityTestsBase { Task task = topActivity.getTask(); starter.postStartActivityProcessing( - task.getTopNonFinishingActivity(), START_DELIVERED_TO_TOP, task.getStack()); + task.getTopNonFinishingActivity(), START_DELIVERED_TO_TOP, task.getRootTask()); verify(taskChangeNotifier).notifyActivityRestartAttempt( any(), anyBoolean(), anyBoolean(), anyBoolean()); @@ -835,14 +835,14 @@ public class ActivityStarterTests extends ActivityTestsBase { Task task2 = reusableActivity.getTask(); starter.postStartActivityProcessing( - task2.getTopNonFinishingActivity(), START_TASK_TO_FRONT, task.getStack()); + task2.getTopNonFinishingActivity(), START_TASK_TO_FRONT, task.getRootTask()); verify(taskChangeNotifier, times(2)).notifyActivityRestartAttempt( any(), anyBoolean(), anyBoolean(), anyBoolean()); verify(taskChangeNotifier).notifyActivityRestartAttempt( any(), anyBoolean(), anyBoolean(), eq(false)); } - private ActivityRecord createSingleTaskActivityOn(ActivityStack stack) { + private ActivityRecord createSingleTaskActivityOn(Task stack) { final ComponentName componentName = ComponentName.createRelative( DEFAULT_COMPONENT_PACKAGE_NAME, DEFAULT_COMPONENT_PACKAGE_NAME + ".SingleTaskActivity"); @@ -1046,7 +1046,7 @@ public class ActivityStarterTests extends ActivityTestsBase { targetRecord.setVisibility(false); final ActivityRecord sourceRecord = new ActivityBuilder(mService).build(); - final ActivityStack stack = spy( + final Task stack = spy( mRootWindowContainer.getDefaultTaskDisplayArea() .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, /* onTop */true)); 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 f65d6e0c82af..f8faae66c704 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java @@ -73,7 +73,7 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase { /** Verify that activity is finished correctly upon request. */ @Test public void testActivityFinish() { - final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); + final Task stack = new StackBuilder(mRootWindowContainer).build(); final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity(); assertTrue("Activity must be finished", mService.finishActivity(activity.appToken, 0 /* resultCode */, null /* resultData */, @@ -87,7 +87,7 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase { @Test public void testOnPictureInPictureRequested() throws RemoteException { - final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); + final Task stack = new StackBuilder(mRootWindowContainer).build(); final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity(); final ClientLifecycleManager mockLifecycleManager = mock(ClientLifecycleManager.class); doReturn(mockLifecycleManager).when(mService).getLifecycleManager(); @@ -106,7 +106,7 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase { @Test(expected = IllegalStateException.class) public void testOnPictureInPictureRequested_cannotEnterPip() throws RemoteException { - final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); + final Task stack = new StackBuilder(mRootWindowContainer).build(); final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity(); ClientLifecycleManager lifecycleManager = mService.getLifecycleManager(); doReturn(false).when(activity).inPinnedWindowingMode(); @@ -120,7 +120,7 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase { @Test(expected = IllegalStateException.class) public void testOnPictureInPictureRequested_alreadyInPIPMode() throws RemoteException { - final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); + final Task stack = new StackBuilder(mRootWindowContainer).build(); final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity(); ClientLifecycleManager lifecycleManager = mService.getLifecycleManager(); doReturn(true).when(activity).inPinnedWindowingMode(); 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 9d0cd26bc040..5be2f0453bf4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java @@ -112,7 +112,7 @@ class ActivityTestsBase extends SystemServiceTestsBase { private String mAffinity; private int mUid = 12345; private boolean mCreateTask; - private ActivityStack mStack; + private Task mStack; private int mActivityFlags; private int mLaunchMode; private int mResizeMode = RESIZE_MODE_RESIZEABLE; @@ -164,7 +164,7 @@ class ActivityTestsBase extends SystemServiceTestsBase { return this; } - ActivityBuilder setStack(ActivityStack stack) { + ActivityBuilder setStack(Task stack) { mStack = stack; return this; } @@ -307,7 +307,7 @@ class ActivityTestsBase extends SystemServiceTestsBase { wpc = mWpc; } else { wpc = new WindowProcessController(mService, - mService.mContext.getApplicationInfo(), mProcessName, mUid, + aInfo.applicationInfo, mProcessName, mUid, UserHandle.getUserId(12345), mock(Object.class), mock(WindowProcessListener.class)); wpc.setThread(mock(IApplicationThread.class)); @@ -338,7 +338,7 @@ class ActivityTestsBase extends SystemServiceTestsBase { private IVoiceInteractionSession mVoiceSession; private boolean mCreateStack = true; - private ActivityStack mStack; + private Task mStack; private TaskDisplayArea mTaskDisplayArea; TaskBuilder(ActivityStackSupervisor supervisor) { @@ -384,7 +384,7 @@ class ActivityTestsBase extends SystemServiceTestsBase { return this; } - TaskBuilder setStack(ActivityStack stack) { + TaskBuilder setStack(Task stack) { mStack = stack; return this; } @@ -418,7 +418,7 @@ class ActivityTestsBase extends SystemServiceTestsBase { intent.setComponent(mComponent); intent.setFlags(mFlags); - final Task task = new ActivityStack(mSupervisor.mService, mTaskId, aInfo, + final Task task = new Task(mSupervisor.mService, mTaskId, aInfo, intent /*intent*/, mVoiceSession, null /*_voiceInteractor*/, null /*taskDescription*/, mStack); spyOn(task); @@ -503,11 +503,11 @@ class ActivityTestsBase extends SystemServiceTestsBase { return this; } - ActivityStack build() { + Task build() { SystemServicesTestRule.checkHoldsLock(mRootWindowContainer.mWmService.mGlobalLock); final int stackId = mStackId >= 0 ? mStackId : mTaskDisplayArea.getNextStackId(); - final ActivityStack stack = mTaskDisplayArea.createStackUnchecked( + final Task stack = mTaskDisplayArea.createStackUnchecked( mWindowingMode, mActivityType, stackId, mOnTop, mInfo, mIntent, false /* createdByOrganizer */); final ActivityStackSupervisor supervisor = mRootWindowContainer.mStackSupervisor; @@ -593,7 +593,7 @@ class ActivityTestsBase extends SystemServiceTestsBase { DisplayContent dc = mService.mRootWindowContainer.getDisplayContent(mDisplayId); dc.forAllTaskDisplayAreas(taskDisplayArea -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + final Task stack = taskDisplayArea.getStackAt(sNdx); if (!WindowConfiguration.isSplitScreenWindowingMode(stack.getWindowingMode())) { stack.reparent(mSecondary, POSITION_BOTTOM); } 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 e8fab2b0243b..673feb260dd4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java @@ -53,14 +53,14 @@ import org.junit.runner.RunWith; @RunWith(WindowTestRunner.class) public class AppChangeTransitionTests extends WindowTestsBase { - private ActivityStack mStack; + private Task mStack; private Task mTask; private ActivityRecord mActivity; public void setUpOnDisplay(DisplayContent dc) { mActivity = createTestActivityRecord(dc, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD); mTask = mActivity.getTask(); - mStack = mTask.getStack(); + mStack = mTask.getRootTask(); // Set a remote animator with snapshot disabled. Snapshots don't work in wmtests. RemoteAnimationDefinition definition = new RemoteAnimationDefinition(); 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 6b613cad4b82..d7baf8d05bd6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java @@ -134,12 +134,12 @@ public class AppTransitionControllerTest extends WindowTestsBase { // [DisplayContent] -+- [TaskStack1] - [Task1] - [ActivityRecord1] (opening, invisible) // +- [TaskStack2] - [Task2] - [ActivityRecord2] (closing, visible) - final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent); + final Task stack1 = createTaskStackOnDisplay(mDisplayContent); final ActivityRecord activity1 = WindowTestUtils.createTestActivityRecord(stack1); activity1.setVisible(false); activity1.mVisibleRequested = true; - final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent); + final Task stack2 = createTaskStackOnDisplay(mDisplayContent); final ActivityRecord activity2 = WindowTestUtils.createTestActivityRecord(stack2); final ArraySet<ActivityRecord> opening = new ArraySet<>(); @@ -162,10 +162,10 @@ public class AppTransitionControllerTest extends WindowTestsBase { public void testGetAnimationTargets_visibilityAlreadyUpdated() { // [DisplayContent] -+- [TaskStack1] - [Task1] - [ActivityRecord1] (opening, visible) // +- [TaskStack2] - [Task2] - [ActivityRecord2] (closing, invisible) - final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent); + final Task stack1 = createTaskStackOnDisplay(mDisplayContent); final ActivityRecord activity1 = WindowTestUtils.createTestActivityRecord(stack1); - final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent); + final Task stack2 = createTaskStackOnDisplay(mDisplayContent); final ActivityRecord activity2 = WindowTestUtils.createTestActivityRecord(stack2); activity2.setVisible(false); activity2.mVisibleRequested = false; @@ -199,11 +199,45 @@ public class AppTransitionControllerTest extends WindowTestsBase { } @Test + public void testGetAnimationTargets_visibilityAlreadyUpdated_butForcedTransitionRequested() { + // [DisplayContent] -+- [TaskStack1] - [Task1] - [ActivityRecord1] (closing, invisible) + // +- [TaskStack2] - [Task2] - [ActivityRecord2] (opening, visible) + final Task stack1 = createTaskStackOnDisplay(mDisplayContent); + final ActivityRecord activity1 = WindowTestUtils.createTestActivityRecord(stack1); + activity1.setVisible(true); + activity1.mVisibleRequested = true; + activity1.mRequestForceTransition = true; + + final Task stack2 = createTaskStackOnDisplay(mDisplayContent); + final ActivityRecord activity2 = WindowTestUtils.createTestActivityRecord(stack2); + activity2.setVisible(false); + activity2.mVisibleRequested = false; + activity2.mRequestForceTransition = true; + + final ArraySet<ActivityRecord> opening = new ArraySet<>(); + opening.add(activity1); + final ArraySet<ActivityRecord> closing = new ArraySet<>(); + closing.add(activity2); + + // The visibility are already updated, but since forced transition is requested, it will + // be included. + WindowManagerService.sHierarchicalAnimations = false; + assertEquals( + new ArraySet<>(new WindowContainer[]{activity1}), + AppTransitionController.getAnimationTargets( + opening, closing, true /* visible */)); + assertEquals( + new ArraySet<>(new WindowContainer[]{activity2}), + AppTransitionController.getAnimationTargets( + opening, closing, false /* visible */)); + } + + @Test public void testGetAnimationTargets_exitingBeforeTransition() { // Create another non-empty task so the animation target won't promote to task display area. WindowTestUtils.createTestActivityRecord( mDisplayContent.getDefaultTaskDisplayArea().getOrCreateRootHomeTask()); - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final ActivityRecord activity = WindowTestUtils.createTestActivityRecord(stack); activity.setVisible(false); activity.mIsExiting = true; @@ -232,7 +266,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // +- [AppWindow1] (being-replaced) // +- [TaskStack2] - [Task2] - [ActivityRecord2] (closing, invisible) // +- [AppWindow2] (being-replaced) - final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent); + final Task stack1 = createTaskStackOnDisplay(mDisplayContent); final ActivityRecord activity1 = WindowTestUtils.createTestActivityRecord(stack1); final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams( TYPE_BASE_APPLICATION); @@ -241,7 +275,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { appWindow1.mWillReplaceWindow = true; activity1.addWindow(appWindow1); - final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent); + final Task stack2 = createTaskStackOnDisplay(mDisplayContent); final ActivityRecord activity2 = WindowTestUtils.createTestActivityRecord(stack2); activity2.setVisible(false); activity2.mVisibleRequested = false; @@ -288,7 +322,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // | // +- [TaskStack2] - [Task2] -+- [ActivityRecord3] (closing, visible) // +- [ActivityRecord4] (invisible) - final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent); + final Task stack1 = createTaskStackOnDisplay(mDisplayContent); final Task task1 = createTaskInStack(stack1, 0 /* userId */); final ActivityRecord activity1 = WindowTestUtils.createActivityRecordInTask( mDisplayContent, task1); @@ -299,7 +333,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { activity2.setVisible(false); activity2.mVisibleRequested = false; - final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent); + final Task stack2 = createTaskStackOnDisplay(mDisplayContent); final Task task2 = createTaskInStack(stack2, 0 /* userId */); final ActivityRecord activity3 = WindowTestUtils.createActivityRecordInTask( mDisplayContent, task2); @@ -331,7 +365,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // [DisplayContent] - [TaskStack] - [Task] -+- [ActivityRecord1] (opening, invisible) // +- [ActivityRecord2] (closing, visible) - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); final ActivityRecord activity1 = WindowTestUtils.createActivityRecordInTask( mDisplayContent, task); @@ -367,7 +401,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // +- [TaskStack2] - [Task2] -+- [ActivityRecord3] (closing, visible) // +- [ActivityRecord4] (visible) - final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent); + final Task stack1 = createTaskStackOnDisplay(mDisplayContent); final Task task1 = createTaskInStack(stack1, 0 /* userId */); final ActivityRecord activity1 = WindowTestUtils.createActivityRecordInTask( mDisplayContent, task1); @@ -378,7 +412,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { final ActivityRecord activity2 = WindowTestUtils.createActivityRecordInTask( mDisplayContent, task1); - final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent); + final Task stack2 = createTaskStackOnDisplay(mDisplayContent); final Task task2 = createTaskInStack(stack2, 0 /* userId */); final ActivityRecord activity3 = WindowTestUtils.createActivityRecordInTask( mDisplayContent, task2); @@ -413,7 +447,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // +- [TaskStack2] - [Task2] -+- [ActivityRecord3] (closing, visible) // +- [ActivityRecord4] (closing, visible) - final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent); + final Task stack1 = createTaskStackOnDisplay(mDisplayContent); final Task task1 = createTaskInStack(stack1, 0 /* userId */); final ActivityRecord activity1 = WindowTestUtils.createActivityRecordInTask( mDisplayContent, task1); @@ -426,7 +460,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { activity2.setVisible(false); activity2.mVisibleRequested = true; - final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent); + final Task stack2 = createTaskStackOnDisplay(mDisplayContent); final Task task2 = createTaskInStack(stack2, 0 /* userId */); final ActivityRecord activity3 = WindowTestUtils.createActivityRecordInTask( mDisplayContent, task2); @@ -459,7 +493,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // [DisplayContent] - [TaskStack] -+- [Task1] - [ActivityRecord1] (opening, invisible) // +- [Task2] - [ActivityRecord2] (closing, visible) - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final Task task1 = createTaskInStack(stack, 0 /* userId */); final ActivityRecord activity1 = WindowTestUtils.createActivityRecordInTask( mDisplayContent, task1); 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 8c8fd0516623..17914e7fb68c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java @@ -47,7 +47,6 @@ import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationTarget; import android.view.WindowManager; -import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import org.junit.Before; @@ -150,7 +149,7 @@ public class AppTransitionTests extends WindowTestsBase { final DisplayContent dc1 = createNewDisplay(Display.STATE_ON); final DisplayContent dc2 = createNewDisplay(Display.STATE_ON); - final ActivityStack stack1 = createTaskStackOnDisplay(dc1); + final Task stack1 = createTaskStackOnDisplay(dc1); final Task task1 = createTaskInStack(stack1, 0 /* userId */); final ActivityRecord activity1 = WindowTestUtils.createTestActivityRecord(dc1); 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 c8b668bac455..97a2ebe98abb 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java @@ -82,7 +82,7 @@ import java.util.ArrayList; @RunWith(WindowTestRunner.class) public class AppWindowTokenTests extends WindowTestsBase { - ActivityStack mStack; + Task mStack; Task mTask; ActivityRecord mActivity; @@ -484,7 +484,7 @@ public class AppWindowTokenTests extends WindowTestsBase { } private ActivityRecord createIsolatedTestActivityRecord() { - final ActivityStack taskStack = createTaskStackOnDisplay(mDisplayContent); + final Task taskStack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(taskStack, 0 /* userId */); return createTestActivityRecordForGivenTask(task); } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java index a8fc66da9bd0..4abb6059cc59 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java @@ -26,9 +26,11 @@ import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER; import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER; +import static android.window.DisplayAreaOrganizer.FEATURE_FULLSCREEN_MAGNIFICATION; import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED; import static android.window.DisplayAreaOrganizer.FEATURE_ROOT; import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST; +import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION; import static com.android.server.wm.DisplayArea.Type.ABOVE_TASKS; import static com.android.server.wm.DisplayAreaPolicyBuilder.Feature; @@ -178,6 +180,39 @@ public class DisplayAreaPolicyBuilderTest { } @Test + public void testBuilder_defaultPolicy_hasWindowedMagnificationFeature() { + final DisplayAreaPolicy.Provider defaultProvider = DisplayAreaPolicy.Provider.fromResources( + resourcesWithProvider("")); + final DisplayAreaPolicyBuilder.Result defaultPolicy = + (DisplayAreaPolicyBuilder.Result) defaultProvider.instantiate(mWms, mDisplayContent, + mRoot, mImeContainer); + final List<Feature> features = defaultPolicy.getFeatures(); + boolean hasWindowedMagnificationFeature = false; + for (Feature feature : features) { + hasWindowedMagnificationFeature |= feature.getId() == FEATURE_WINDOWED_MAGNIFICATION; + } + + assertThat(hasWindowedMagnificationFeature).isTrue(); + } + + @Test + public void testBuilder_defaultPolicy_hasFullscreenMagnificationFeature() { + final DisplayAreaPolicy.Provider defaultProvider = DisplayAreaPolicy.Provider.fromResources( + resourcesWithProvider("")); + final DisplayAreaPolicyBuilder.Result defaultPolicy = + (DisplayAreaPolicyBuilder.Result) defaultProvider.instantiate(mWms, mDisplayContent, + mRoot, mImeContainer); + final List<Feature> features = defaultPolicy.getFeatures(); + boolean hasFullscreenMagnificationFeature = false; + for (Feature feature : features) { + hasFullscreenMagnificationFeature |= + feature.getId() == FEATURE_FULLSCREEN_MAGNIFICATION; + } + + assertThat(hasFullscreenMagnificationFeature).isTrue(); + } + + @Test public void testBuilder_createCustomizedDisplayAreaForFeature() { final Feature dimmable; final Feature other; @@ -496,7 +531,7 @@ public class DisplayAreaPolicyBuilderTest { private Map<DisplayArea<?>, Set<Integer>> calculateZSets( DisplayAreaPolicyBuilder.Result policy, DisplayArea<WindowContainer> ime, - DisplayArea<ActivityStack> tasks) { + DisplayArea<Task> tasks) { Map<DisplayArea<?>, Set<Integer>> zSets = new HashMap<>(); int[] types = {TYPE_STATUS_BAR, TYPE_NAVIGATION_BAR, TYPE_PRESENTATION, TYPE_APPLICATION_OVERLAY}; diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java index d75b35a3db79..39bf8eb857b0 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java @@ -94,9 +94,9 @@ public class DisplayAreaPolicyTests { @Test public void testTaskDisplayArea_taskPositionChanged_updatesTaskDisplayAreaPosition() { - final ActivityStack stack1 = mTaskDisplayArea1.createStack( + final Task stack1 = mTaskDisplayArea1.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack stack2 = mTaskDisplayArea2.createStack( + final Task stack2 = mTaskDisplayArea2.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Initial order @@ -155,11 +155,11 @@ public class DisplayAreaPolicyTests { .addDisplayAreaGroupHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(group2) .setTaskDisplayAreas(Lists.newArrayList(taskDisplayArea5))) .build(wms); - final ActivityStack stack1 = taskDisplayArea1.createStack( + final Task stack1 = taskDisplayArea1.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack stack3 = taskDisplayArea3.createStack( + final Task stack3 = taskDisplayArea3.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack stack4 = taskDisplayArea4.createStack( + final Task stack4 = taskDisplayArea4.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Initial order 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 792b597d23d2..a7e0dd4e674e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -144,7 +144,7 @@ public class DisplayContentTests extends WindowTestsBase { waitUntilHandlersIdle(); exitingApp.mIsExiting = true; - exitingApp.getTask().getStack().mExitingActivities.add(exitingApp); + exitingApp.getTask().getRootTask().mExitingActivities.add(exitingApp); assertForAllWindowsOrder(Arrays.asList( mWallpaperWindow, @@ -321,7 +321,7 @@ public class DisplayContentTests extends WindowTestsBase { final DisplayContent dc = createNewDisplay(); // Add stack with activity. - final ActivityStack stack = createTaskStackOnDisplay(dc); + final Task stack = createTaskStackOnDisplay(dc); assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId()); assertEquals(dc, stack.getDisplayContent()); @@ -395,7 +395,7 @@ public class DisplayContentTests extends WindowTestsBase { final DisplayContent dc1 = createNewDisplay(); // Add stack with activity. - final ActivityStack stack0 = createTaskStackOnDisplay(dc0); + final Task stack0 = createTaskStackOnDisplay(dc0); final Task task0 = createTaskInStack(stack0, 0 /* userId */); final ActivityRecord activity = WindowTestUtils.createTestActivityRecord(dc0); @@ -403,7 +403,7 @@ public class DisplayContentTests extends WindowTestsBase { dc0.configureDisplayPolicy(); assertNotNull(dc0.mTapDetector); - final ActivityStack stack1 = createTaskStackOnDisplay(dc1); + final Task stack1 = createTaskStackOnDisplay(dc1); final Task task1 = createTaskInStack(stack1, 0 /* userId */); final ActivityRecord activity1 = WindowTestUtils.createTestActivityRecord(dc0); @@ -849,13 +849,13 @@ public class DisplayContentTests extends WindowTestsBase { dc.getDisplayRotation().setFixedToUserRotation( IWindowManager.FIXED_TO_USER_ROTATION_DISABLED); - final ActivityStack stack = + final Task stack = new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer) .setDisplay(dc) .build(); doReturn(true).when(stack).isVisible(); - final ActivityStack freeformStack = + final Task freeformStack = new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer) .setDisplay(dc) .setWindowingMode(WINDOWING_MODE_FREEFORM) @@ -881,7 +881,7 @@ public class DisplayContentTests extends WindowTestsBase { IWindowManager.FIXED_TO_USER_ROTATION_DISABLED); final int newOrientation = getRotatedOrientation(dc); - final ActivityStack stack = + final Task stack = new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer) .setDisplay(dc).build(); final ActivityRecord activity = stack.getTopMostTask().getTopNonFinishingActivity(); @@ -901,7 +901,7 @@ public class DisplayContentTests extends WindowTestsBase { IWindowManager.FIXED_TO_USER_ROTATION_ENABLED); final int newOrientation = getRotatedOrientation(dc); - final ActivityStack stack = + final Task stack = new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer) .setDisplay(dc).build(); final ActivityRecord activity = stack.getTopMostTask().getTopNonFinishingActivity(); @@ -950,6 +950,21 @@ public class DisplayContentTests extends WindowTestsBase { } @Test + public void testInputMethodInputTarget_isClearedWhenWindowStateIsRemoved() throws Exception { + final DisplayContent dc = createNewDisplay(); + + WindowState app = createWindow(null, TYPE_BASE_APPLICATION, dc, "app"); + + dc.mInputMethodInputTarget = app; + assertEquals(app, dc.computeImeControlTarget()); + + app.removeImmediately(); + + assertNull(dc.mInputMethodInputTarget); + assertNull(dc.computeImeControlTarget()); + } + + @Test public void testComputeImeControlTarget() throws Exception { final DisplayContent dc = createNewDisplay(); dc.setRemoteInsetsController(createDisplayWindowInsetsController()); @@ -1322,7 +1337,7 @@ public class DisplayContentTests extends WindowTestsBase { // Leave PiP to fullscreen. The orientation can be updated from // ActivityRecord#reportDescendantOrientationChangeIfNeeded. pinnedTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN); - homeActivity.setState(ActivityStack.ActivityState.STOPPED, "test"); + homeActivity.setState(Task.ActivityState.STOPPED, "test"); assertFalse(displayContent.hasTopFixedRotationLaunchingApp()); verify(mWm, atLeastOnce()).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt()); @@ -1430,7 +1445,7 @@ public class DisplayContentTests extends WindowTestsBase { TaskDisplayArea defaultTaskDisplayArea = mWm.mRoot.getDefaultTaskDisplayArea(); // Remove the current home stack if it exists so a new one can be created below. - ActivityStack homeTask = defaultTaskDisplayArea.getRootHomeTask(); + Task homeTask = defaultTaskDisplayArea.getRootHomeTask(); if (homeTask != null) { defaultTaskDisplayArea.removeChild(homeTask); } @@ -1446,7 +1461,7 @@ public class DisplayContentTests extends WindowTestsBase { // Remove the current home stack if it exists so a new one can be created below. TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea(); - ActivityStack homeTask = taskDisplayArea.getRootHomeTask(); + Task homeTask = taskDisplayArea.getRootHomeTask(); if (homeTask != null) { taskDisplayArea.removeChild(homeTask); } @@ -1478,7 +1493,7 @@ public class DisplayContentTests extends WindowTestsBase { @Test public void testFindScrollCaptureTargetWindow_behindWindow() { DisplayContent display = createNewDisplay(); - ActivityStack stack = createTaskStackOnDisplay(display); + Task stack = createTaskStackOnDisplay(display); Task task = createTaskInStack(stack, 0 /* userId */); WindowState activityWindow = createAppWindow(task, TYPE_APPLICATION, "App Window"); WindowState behindWindow = createWindow(null, TYPE_SCREENSHOT, display, "Screenshot"); @@ -1491,7 +1506,7 @@ public class DisplayContentTests extends WindowTestsBase { @Test public void testFindScrollCaptureTargetWindow_taskId() { DisplayContent display = createNewDisplay(); - ActivityStack stack = createTaskStackOnDisplay(display); + Task stack = createTaskStackOnDisplay(display); Task task = createTaskInStack(stack, 0 /* userId */); WindowState window = createAppWindow(task, TYPE_APPLICATION, "App Window"); WindowState behindWindow = createWindow(null, TYPE_SCREENSHOT, display, "Screenshot"); @@ -1518,7 +1533,7 @@ public class DisplayContentTests extends WindowTestsBase { @Test public void testSetWindowingModeAtomicallyUpdatesWindoingModeAndDisplayWindowingMode() { final DisplayContent dc = createNewDisplay(); - final ActivityStack stack = + final Task stack = new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer) .setDisplay(dc) .build(); 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 8fc97701bdf0..4ea5b97decf4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java @@ -40,8 +40,13 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DEC import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; +import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_BOTTOM; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_LEFT; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_RIGHT; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_TOP; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; @@ -63,6 +68,7 @@ import android.util.Pair; import android.util.SparseArray; import android.view.DisplayCutout; import android.view.DisplayInfo; +import android.view.Gravity; import android.view.InsetsState; import android.view.WindowInsets.Side; import android.view.WindowInsets.Type; @@ -167,6 +173,8 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { @Test public void addingWindow_withInsetsTypes() { + mDisplayPolicy.removeWindowLw(mStatusBarWindow); // Removes the existing one. + WindowState win = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel"); win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_TOP_GESTURES}; win.getFrameLw().set(0, 0, 500, 100); @@ -216,6 +224,47 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { } @Test + public void addingWindow_variousGravities_alternateBarPosUpdated() { + mDisplayPolicy.removeWindowLw(mNavBarWindow); // Removes the existing one. + + WindowState win1 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel1"); + win1.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR}; + win1.mAttrs.gravity = Gravity.TOP; + win1.getFrameLw().set(0, 0, 200, 500); + addWindow(win1); + + assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_TOP); + mDisplayPolicy.removeWindowLw(win1); + + WindowState win2 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel2"); + win2.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR}; + win2.mAttrs.gravity = Gravity.BOTTOM; + win2.getFrameLw().set(0, 0, 200, 500); + addWindow(win2); + + assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_BOTTOM); + mDisplayPolicy.removeWindowLw(win2); + + WindowState win3 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel3"); + win3.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR}; + win3.mAttrs.gravity = Gravity.LEFT; + win3.getFrameLw().set(0, 0, 200, 500); + addWindow(win3); + + assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_LEFT); + mDisplayPolicy.removeWindowLw(win3); + + WindowState win4 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel4"); + win4.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR}; + win4.mAttrs.gravity = Gravity.RIGHT; + win4.getFrameLw().set(0, 0, 200, 500); + addWindow(win4); + + assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_RIGHT); + mDisplayPolicy.removeWindowLw(win4); + } + + @Test public void layoutWindowLw_fitStatusBars() { mWindow.mAttrs.setFitInsetsTypes(Type.statusBars()); addWindow(mWindow); 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 0eee3ca53c7d..e18d93d82686 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java @@ -40,7 +40,6 @@ import android.view.SurfaceControl; import android.view.SurfaceSession; import android.view.View; -import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import com.android.server.LocalServices; @@ -98,7 +97,7 @@ public class DragDropControllerTests extends WindowTestsBase { private WindowState createDropTargetWindow(String name, int ownerId) { final ActivityRecord activity = WindowTestUtils.createTestActivityRecord( mDisplayContent); - final ActivityStack stack = createTaskStackOnDisplay( + final Task stack = createTaskStackOnDisplay( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent); final Task task = createTaskInStack(stack, ownerId); task.addChild(activity, 0); diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java index 61de7d83fa1a..a7a8505e336d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java @@ -309,12 +309,12 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { mController.registerModifier(positioner); - final int beforeWindowMode = task.getStack().getWindowingMode(); + final int beforeWindowMode = task.getRootTask().getWindowingMode(); assertNotEquals(windowingMode, beforeWindowMode); mController.layoutTask(task, null /* windowLayout */); - final int afterWindowMode = task.getStack().getWindowingMode(); + final int afterWindowMode = task.getRootTask().getWindowingMode(); assertEquals(windowingMode, afterWindowMode); } diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java index 9bf86d2c4704..e389a538f25d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java @@ -114,7 +114,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase { when(mRootWindowContainer.getDisplayContent(eq(mDisplayUniqueId))) .thenReturn(mTestDisplay); - ActivityStack stack = mTestDisplay.getDefaultTaskDisplayArea() + Task stack = mTestDisplay.getDefaultTaskDisplayArea() .createStack(TEST_WINDOWING_MODE, ACTIVITY_TYPE_STANDARD, /* onTop */ true); mTestTask = new TaskBuilder(mSupervisor).setComponent(TEST_COMPONENT).setStack(stack) .build(); @@ -337,7 +337,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase { public void testClearsRecordsOfTheUserOnUserCleanUp() { mTarget.saveTask(mTestTask); - ActivityStack stack = mTestDisplay.getDefaultTaskDisplayArea().createStack( + Task stack = mTestDisplay.getDefaultTaskDisplayArea().createStack( TEST_WINDOWING_MODE, ACTIVITY_TYPE_STANDARD, /* onTop */ true); final Task anotherTaskOfTheSameUser = new TaskBuilder(mSupervisor) .setComponent(ALTERNATIVE_COMPONENT) diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java index bf84aecdb6a0..2f3004bf6832 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java @@ -16,8 +16,8 @@ package com.android.server.wm; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; @@ -60,6 +60,103 @@ public class LetterboxTest { assertTrue(mLetterbox.isOverlappingWith(new Rect(0, 0, 1, 1))); } + private static final int TOP_BAR = 0x1; + private static final int BOTTOM_BAR = 0x2; + private static final int LEFT_BAR = 0x4; + private static final int RIGHT_BAR = 0x8; + @Test + public void testNotIntersectsOrFullyContains_usesGlobalCoordinates() { + final Rect outer = new Rect(0, 0, 10, 50); + final Point surfaceOrig = new Point(1000, 2000); + + final Rect topBar = new Rect(0, 0, 10, 2); + final Rect bottomBar = new Rect(0, 45, 10, 50); + final Rect leftBar = new Rect(0, 0, 2, 50); + final Rect rightBar = new Rect(8, 0, 10, 50); + + final LetterboxLayoutVerifier verifier = + new LetterboxLayoutVerifier(outer, surfaceOrig, mLetterbox); + verifier.setBarRect(topBar, bottomBar, leftBar, rightBar); + + // top + verifier.setInner(0, 2, 10, 50).verifyPositions(TOP_BAR | BOTTOM_BAR, BOTTOM_BAR); + // bottom + verifier.setInner(0, 0, 10, 45).verifyPositions(TOP_BAR | BOTTOM_BAR, TOP_BAR); + // left + verifier.setInner(2, 0, 10, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, RIGHT_BAR); + // right + verifier.setInner(0, 0, 8, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, LEFT_BAR); + // top + bottom + verifier.setInner(0, 2, 10, 45).verifyPositions(TOP_BAR | BOTTOM_BAR, 0); + // left + right + verifier.setInner(2, 0, 8, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, 0); + // top + left + verifier.setInner(2, 2, 10, 50).verifyPositions(TOP_BAR | LEFT_BAR, 0); + // top + left + right + verifier.setInner(2, 2, 8, 50).verifyPositions(TOP_BAR | LEFT_BAR | RIGHT_BAR, 0); + // left + right + bottom + verifier.setInner(2, 0, 8, 45).verifyPositions(LEFT_BAR | RIGHT_BAR | BOTTOM_BAR, 0); + // all + verifier.setInner(2, 2, 8, 45) + .verifyPositions(TOP_BAR | BOTTOM_BAR | LEFT_BAR | RIGHT_BAR, 0); + } + + private static class LetterboxLayoutVerifier { + final Rect mOuter; + final Rect mInner = new Rect(); + final Point mSurfaceOrig; + final Letterbox mLetterbox; + final Rect mTempRect = new Rect(); + + final Rect mTop = new Rect(); + final Rect mBottom = new Rect(); + final Rect mLeft = new Rect(); + final Rect mRight = new Rect(); + + LetterboxLayoutVerifier(Rect outer, Point surfaceOrig, Letterbox letterbox) { + mOuter = new Rect(outer); + mSurfaceOrig = new Point(surfaceOrig); + mLetterbox = letterbox; + } + + LetterboxLayoutVerifier setInner(int left, int top, int right, int bottom) { + mInner.set(left, top, right, bottom); + mLetterbox.layout(mOuter, mInner, mSurfaceOrig); + return this; + } + + void setBarRect(Rect top, Rect bottom, Rect left, Rect right) { + mTop.set(top); + mBottom.set(bottom); + mLeft.set(left); + mRight.set(right); + } + + void verifyPositions(int allowedPos, int noOverlapPos) { + assertEquals(mLetterbox.notIntersectsOrFullyContains(mTop), + (allowedPos & TOP_BAR) != 0); + assertEquals(mLetterbox.notIntersectsOrFullyContains(mBottom), + (allowedPos & BOTTOM_BAR) != 0); + assertEquals(mLetterbox.notIntersectsOrFullyContains(mLeft), + (allowedPos & LEFT_BAR) != 0); + assertEquals(mLetterbox.notIntersectsOrFullyContains(mRight), + (allowedPos & RIGHT_BAR) != 0); + + mTempRect.set(mTop.left, mTop.top, mTop.right, mTop.bottom + 1); + assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect), + (noOverlapPos & TOP_BAR) != 0); + mTempRect.set(mLeft.left, mLeft.top, mLeft.right + 1, mLeft.bottom); + assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect), + (noOverlapPos & LEFT_BAR) != 0); + mTempRect.set(mRight.left - 1, mRight.top, mRight.right, mRight.bottom); + assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect), + (noOverlapPos & RIGHT_BAR) != 0); + mTempRect.set(mBottom.left, mBottom.top - 1, mBottom.right, mBottom.bottom); + assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect), + (noOverlapPos & BOTTOM_BAR) != 0); + } + } + @Test public void testSurfaceOrigin_applied() { mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000)); diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java index fd169018782b..1724303633d9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -105,7 +105,7 @@ public class RecentTasksTest extends ActivityTestsBase { private static final int INVALID_STACK_ID = 999; private TaskDisplayArea mTaskContainer; - private ActivityStack mStack; + private Task mStack; private TestTaskPersister mTaskPersister; private TestRecentTasks mRecentTasks; private TestRunningTasks mRunningTasks; @@ -829,7 +829,7 @@ public class RecentTasksTest extends ActivityTestsBase { mRecentTasks.add(mTasks.get(2)); mRecentTasks.add(mTasks.get(1)); - ActivityStack stack = mTasks.get(2).getStack(); + Task stack = mTasks.get(2).getRootTask(); stack.moveToFront("", mTasks.get(2)); doReturn(stack).when(mService.mRootWindowContainer).getTopDisplayFocusedStack(); @@ -850,8 +850,8 @@ public class RecentTasksTest extends ActivityTestsBase { public void testBackStackTasks_expectNoTrim() { mRecentTasks.setParameters(-1 /* min */, 1 /* max */, -1 /* ms */); - final ActivityStack homeStack = mTaskContainer.getRootHomeTask(); - final ActivityStack aboveHomeStack = mTaskContainer.createStack( + final Task homeStack = mTaskContainer.getRootHomeTask(); + final Task aboveHomeStack = mTaskContainer.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Add a number of tasks (beyond the max) but ensure that nothing is trimmed because all @@ -868,10 +868,10 @@ public class RecentTasksTest extends ActivityTestsBase { public void testBehindHomeStackTasks_expectTaskTrimmed() { mRecentTasks.setParameters(-1 /* min */, 1 /* max */, -1 /* ms */); - final ActivityStack behindHomeStack = mTaskContainer.createStack( + final Task behindHomeStack = mTaskContainer.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityStack homeStack = mTaskContainer.getRootHomeTask(); - final ActivityStack aboveHomeStack = mTaskContainer.createStack( + final Task homeStack = mTaskContainer.getRootHomeTask(); + final Task aboveHomeStack = mTaskContainer.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Add a number of tasks (beyond the max) but ensure that only the task in the stack behind @@ -890,9 +890,9 @@ public class RecentTasksTest extends ActivityTestsBase { public void testOtherDisplayTasks_expectNoTrim() { mRecentTasks.setParameters(-1 /* min */, 1 /* max */, -1 /* ms */); - final ActivityStack homeStack = mTaskContainer.getRootHomeTask(); + final Task homeStack = mTaskContainer.getRootHomeTask(); final DisplayContent otherDisplay = addNewDisplayContentAt(DisplayContent.POSITION_TOP); - final ActivityStack otherDisplayStack = otherDisplay.getDefaultTaskDisplayArea() + final Task otherDisplayStack = otherDisplay.getDefaultTaskDisplayArea() .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Add a number of tasks (beyond the max) on each display, ensure that the tasks are not 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 4fbdd616dc93..695a0e3881ea 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -92,7 +92,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { @Mock RecentsAnimationController.RecentsAnimationCallbacks mAnimationCallbacks; @Mock TaskSnapshot mMockTaskSnapshot; private RecentsAnimationController mController; - private ActivityStack mRootHomeTask; + private Task mRootHomeTask; @Before public void setUp() throws Exception { diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java index 44ca2cdcb142..e3cfe11df99f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java @@ -31,8 +31,8 @@ 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.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSED; import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; +import static com.android.server.wm.Task.ActivityState.PAUSED; import static com.google.common.truth.Truth.assertThat; @@ -88,7 +88,7 @@ public class RecentsAnimationTest extends ActivityTestsBase { @Test public void testRecentsActivityVisiblility() { TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - ActivityStack recentsStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + Task recentsStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */); ActivityRecord recentActivity = new ActivityBuilder(mService) .setComponent(mRecentsComponent) @@ -116,7 +116,7 @@ public class RecentsAnimationTest extends ActivityTestsBase { @Test public void testPreloadRecentsActivity() { TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - final ActivityStack homeStack = + final Task homeStack = defaultTaskDisplayArea.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME); defaultTaskDisplayArea.positionStackAtTop(homeStack, false /* includingParents */); ActivityRecord topRunningHomeActivity = homeStack.topRunningActivity(); @@ -148,7 +148,7 @@ public class RecentsAnimationTest extends ActivityTestsBase { mService.startRecentsActivity(recentsIntent, null /* assistDataReceiver */, null /* recentsAnimationRunner */); - ActivityStack recentsStack = defaultTaskDisplayArea.getStack(WINDOWING_MODE_FULLSCREEN, + Task recentsStack = defaultTaskDisplayArea.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS); assertThat(recentsStack).isNotNull(); @@ -177,7 +177,7 @@ public class RecentsAnimationTest extends ActivityTestsBase { public void testRestartRecentsActivity() throws Exception { // Have a recents activity that is not attached to its process (ActivityRecord.app = null). TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - ActivityStack recentsStack = defaultTaskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + Task recentsStack = defaultTaskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */); ActivityRecord recentActivity = new ActivityBuilder(mService).setComponent( mRecentsComponent).setCreateTask(true).setStack(recentsStack).build(); @@ -206,7 +206,7 @@ public class RecentsAnimationTest extends ActivityTestsBase { @Test public void testSetLaunchTaskBehindOfTargetActivity() { TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - ActivityStack homeStack = taskDisplayArea.getRootHomeTask(); + Task homeStack = taskDisplayArea.getRootHomeTask(); // Assume the home activity support recents. ActivityRecord targetActivity = homeStack.getTopNonFinishingActivity(); if (targetActivity == null) { @@ -248,21 +248,21 @@ public class RecentsAnimationTest extends ActivityTestsBase { @Test public void testCancelAnimationOnVisibleStackOrderChange() { TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - ActivityStack fullscreenStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + Task fullscreenStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); new ActivityBuilder(mService) .setComponent(new ComponentName(mContext.getPackageName(), "App1")) .setCreateTask(true) .setStack(fullscreenStack) .build(); - ActivityStack recentsStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + Task recentsStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */); new ActivityBuilder(mService) .setComponent(mRecentsComponent) .setCreateTask(true) .setStack(recentsStack) .build(); - ActivityStack fullscreenStack2 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + Task fullscreenStack2 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); new ActivityBuilder(mService) .setComponent(new ComponentName(mContext.getPackageName(), "App2")) @@ -289,21 +289,21 @@ public class RecentsAnimationTest extends ActivityTestsBase { @Test public void testKeepAnimationOnHiddenStackOrderChange() { TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - ActivityStack fullscreenStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + Task fullscreenStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); new ActivityBuilder(mService) .setComponent(new ComponentName(mContext.getPackageName(), "App1")) .setCreateTask(true) .setStack(fullscreenStack) .build(); - ActivityStack recentsStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + Task recentsStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */); new ActivityBuilder(mService) .setComponent(mRecentsComponent) .setCreateTask(true) .setStack(recentsStack) .build(); - ActivityStack fullscreenStack2 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + Task fullscreenStack2 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); new ActivityBuilder(mService) .setComponent(new ComponentName(mContext.getPackageName(), "App2")) @@ -326,7 +326,7 @@ public class RecentsAnimationTest extends ActivityTestsBase { public void testMultipleUserHomeActivity_findUserHomeTask() { TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultDisplay() .getDefaultTaskDisplayArea(); - ActivityStack homeStack = taskDisplayArea.getStack(WINDOWING_MODE_UNDEFINED, + Task homeStack = taskDisplayArea.getStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME); ActivityRecord otherUserHomeActivity = new ActivityBuilder(mService) .setStack(homeStack) @@ -335,7 +335,7 @@ public class RecentsAnimationTest extends ActivityTestsBase { .build(); otherUserHomeActivity.getTask().mUserId = TEST_USER_ID; - ActivityStack fullscreenStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + Task fullscreenStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); new ActivityBuilder(mService) .setComponent(new ComponentName(mContext.getPackageName(), "App1")) diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java index 4aac47cf006a..3a5d33396c3a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java @@ -39,6 +39,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.wm.ActivityStackSupervisor.ON_TOP; import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE; +import static com.android.server.wm.Task.ActivityState.STOPPED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -67,7 +68,7 @@ import android.util.Pair; import androidx.test.filters.MediumTest; import com.android.internal.app.ResolverActivity; -import com.android.server.wm.ActivityStack.ActivityState; +import com.android.server.wm.Task.ActivityState; import org.junit.Before; import org.junit.Test; @@ -88,7 +89,7 @@ import java.util.function.Consumer; @Presubmit @RunWith(WindowTestRunner.class) public class RootActivityContainerTests extends ActivityTestsBase { - private ActivityStack mFullscreenStack; + private Task mFullscreenStack; @Before public void setUp() throws Exception { @@ -131,7 +132,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { mRootWindowContainer.moveActivityToPinnedStack(firstActivity, "initialMove"); final TaskDisplayArea taskDisplayArea = mFullscreenStack.getDisplayArea(); - ActivityStack pinnedStack = taskDisplayArea.getRootPinnedTask(); + Task pinnedStack = taskDisplayArea.getRootPinnedTask(); // Ensure a task has moved over. ensureStackPlacement(pinnedStack, firstActivity); ensureStackPlacement(mFullscreenStack, secondActivity); @@ -148,7 +149,30 @@ public class RootActivityContainerTests extends ActivityTestsBase { ensureStackPlacement(mFullscreenStack, firstActivity); } - private static void ensureStackPlacement(ActivityStack stack, ActivityRecord... activities) { + @Test + public void testMovingBottomMostStackActivityToPinnedStack() { + final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true) + .setStack(mFullscreenStack).build(); + final Task task = firstActivity.getTask(); + + final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(task) + .setStack(mFullscreenStack).build(); + + mFullscreenStack.moveTaskToBack(task); + + // Ensure full screen stack has both tasks. + ensureStackPlacement(mFullscreenStack, firstActivity, secondActivity); + assertEquals(task.getTopMostActivity(), secondActivity); + firstActivity.setState(STOPPED, "testMovingBottomMostStackActivityToPinnedStack"); + + + // Move first activity to pinned stack. + mRootWindowContainer.moveActivityToPinnedStack(secondActivity, "initialMove"); + + assertTrue(firstActivity.mRequestForceTransition); + } + + private static void ensureStackPlacement(Task stack, ActivityRecord... activities) { final Task task = stack.getBottomMostTask(); final ArrayList<ActivityRecord> stackActivities = new ArrayList<>(); @@ -170,7 +194,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { public void testApplySleepTokens() { final DisplayContent display = mRootWindowContainer.getDefaultDisplay(); final KeyguardController keyguard = mSupervisor.getKeyguardController(); - final ActivityStack stack = new StackBuilder(mRootWindowContainer) + final Task stack = new StackBuilder(mRootWindowContainer) .setCreateActivity(false) .setDisplay(display) .setOnTop(false) @@ -205,7 +229,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { } private void verifySleepTokenBehavior(DisplayContent display, KeyguardController keyguard, - ActivityStack stack, boolean displaySleeping, boolean displayShouldSleep, + Task stack, boolean displaySleeping, boolean displayShouldSleep, boolean isFocusedStack, boolean keyguardShowing, boolean expectWakeFromSleep, boolean expectResumeTopActivity) { reset(stack); @@ -261,7 +285,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer .getDefaultTaskDisplayArea(); final int originalStackCount = defaultTaskDisplayArea.getStackCount(); - final ActivityStack stack = defaultTaskDisplayArea.createStack( + final Task stack = defaultTaskDisplayArea.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true) .setStack(stack).build(); @@ -285,7 +309,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer .getDefaultTaskDisplayArea(); final int originalStackCount = defaultTaskDisplayArea.getStackCount(); - final ActivityStack stack = defaultTaskDisplayArea.createStack( + final Task stack = defaultTaskDisplayArea.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true) .setStack(stack).build(); @@ -294,7 +318,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { final DisplayContent dc = defaultTaskDisplayArea.getDisplayContent(); final TaskDisplayArea secondTaskDisplayArea = WindowTestsBase.createTaskDisplayArea(dc, mRootWindowContainer.mWmService, "TestTaskDisplayArea", FEATURE_VENDOR_FIRST); - final ActivityStack secondStack = secondTaskDisplayArea.createStack( + final Task secondStack = secondTaskDisplayArea.createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); new ActivityBuilder(mService).setCreateTask(true).setStack(secondStack) .setUseProcess(firstActivity.app).build(); @@ -313,7 +337,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { public void testFocusability() { final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer .getDefaultTaskDisplayArea(); - final ActivityStack stack = defaultTaskDisplayArea.createStack( + final Task stack = defaultTaskDisplayArea.createStack( WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true) .setStack(stack).build(); @@ -327,7 +351,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { assertFalse(stack.isTopActivityFocusable()); assertFalse(activity.isFocusable()); - final ActivityStack pinnedStack = defaultTaskDisplayArea.createStack( + final Task pinnedStack = defaultTaskDisplayArea.createStack( WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */); final ActivityRecord pinnedActivity = new ActivityBuilder(mService).setCreateTask(true) .setStack(pinnedStack).build(); @@ -356,7 +380,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { @Test public void testSplitScreenPrimaryChosenWhenTopActivityLaunchedToSecondary() { // Create primary split-screen stack with a task and an activity. - final ActivityStack primaryStack = mRootWindowContainer.getDefaultTaskDisplayArea() + final Task primaryStack = mRootWindowContainer.getDefaultTaskDisplayArea() .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); final Task task = new TaskBuilder(mSupervisor).setStack(primaryStack).build(); @@ -366,7 +390,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { // split-screen secondary. final ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY); - final ActivityStack result = + final Task result = mRootWindowContainer.getLaunchStack(r, options, task, true /* onTop */); // Assert that the primary stack is returned. @@ -379,13 +403,13 @@ public class RootActivityContainerTests extends ActivityTestsBase { @Test public void testFindTaskToMoveToFrontWhenRecentsOnTop() { // Create stack/task on default display. - final ActivityStack targetStack = new StackBuilder(mRootWindowContainer) + final Task targetStack = new StackBuilder(mRootWindowContainer) .setOnTop(false) .build(); final Task targetTask = targetStack.getBottomMostTask(); // Create Recents on top of the display. - final ActivityStack stack = new StackBuilder(mRootWindowContainer).setActivityType( + final Task stack = new StackBuilder(mRootWindowContainer).setActivityType( ACTIVITY_TYPE_RECENTS).build(); final String reason = "findTaskToMoveToFront"; @@ -404,14 +428,14 @@ public class RootActivityContainerTests extends ActivityTestsBase { public void testFindTaskToMoveToFrontWhenRecentsOnOtherDisplay() { // Create stack/task on default display. final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - final ActivityStack targetStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + final Task targetStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); final Task targetTask = new TaskBuilder(mSupervisor).setStack(targetStack).build(); // Create Recents on secondary display. final TestDisplayContent secondDisplay = addNewDisplayContentAt( DisplayContent.POSITION_TOP); - final ActivityStack stack = secondDisplay.getDefaultTaskDisplayArea() + final Task stack = secondDisplay.getDefaultTaskDisplayArea() .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */); final Task task = new TaskBuilder(mSupervisor).setStack(stack).build(); new ActivityBuilder(mService).setTask(task).build(); @@ -431,7 +455,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { public void testResumeActivityWhenNonTopmostStackIsTopFocused() { // Create a stack at bottom. final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - final ActivityStack targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + final Task targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */)); final Task task = new TaskBuilder(mSupervisor).setStack(targetStack).build(); final ActivityRecord activity = new ActivityBuilder(mService).setTask(task).build(); @@ -487,7 +511,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { // Create an activity on secondary display. final TestDisplayContent secondDisplay = addNewDisplayContentAt( DisplayContent.POSITION_TOP); - final ActivityStack stack = secondDisplay.getDefaultTaskDisplayArea() + final Task stack = secondDisplay.getDefaultTaskDisplayArea() .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); final Task task = new TaskBuilder(mSupervisor).setStack(stack).build(); new ActivityBuilder(mService).setTask(task).build(); @@ -511,7 +535,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { public void testResumeActivityLingeringTransition() { // Create a stack at top. final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - final ActivityStack targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + final Task targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */)); final Task task = new TaskBuilder(mSupervisor).setStack(targetStack).build(); final ActivityRecord activity = new ActivityBuilder(mService).setTask(task).build(); @@ -531,7 +555,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { public void testResumeActivityLingeringTransition_notExecuted() { // Create a stack at bottom. final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - final ActivityStack targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + final Task targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */)); final Task task = new TaskBuilder(mSupervisor).setStack(targetStack).build(); final ActivityRecord activity = new ActivityBuilder(mService).setTask(task).build(); @@ -844,7 +868,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); doReturn(true).when(mSupervisor).canPlaceEntityOnDisplay(secondaryDisplay.mDisplayId, 300 /* test realCallerPid */, 300 /* test realCallerUid */, r.info); - final ActivityStack result = mRootWindowContainer.getLaunchStack(r, options, + final Task result = mRootWindowContainer.getLaunchStack(r, options, null /* task */, true /* onTop */, null, 300 /* test realCallerPid */, 300 /* test realCallerUid */); @@ -865,7 +889,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { .setTask(task).build(); // Make sure the root task is valid and can be reused on default display. - final ActivityStack stack = mRootWindowContainer.getValidLaunchStackInTaskDisplayArea( + final Task stack = mRootWindowContainer.getValidLaunchStackInTaskDisplayArea( mRootWindowContainer.getDefaultTaskDisplayArea(), activity, task, null, null); assertEquals(task, stack); @@ -876,7 +900,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { doReturn(mFullscreenStack).when(mRootWindowContainer).getTopDisplayFocusedStack(); final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - ActivityStack homeStack = taskDisplayArea.getRootHomeTask(); + Task homeStack = taskDisplayArea.getRootHomeTask(); if (homeStack != null) { homeStack.removeImmediately(); } @@ -896,7 +920,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { // Create an activity on secondary display. final TestDisplayContent secondDisplay = addNewDisplayContentAt( DisplayContent.POSITION_TOP); - final ActivityStack stack = secondDisplay.getDefaultTaskDisplayArea() + final Task stack = secondDisplay.getDefaultTaskDisplayArea() .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); final ActivityRecord activity = new ActivityBuilder(mService).setStack(stack).build(); spyOn(activity); 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 181de8e2a1a3..2e4c9ea747c5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java @@ -25,11 +25,13 @@ import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; -import static com.android.server.wm.ActivityStack.ActivityState.FINISHING; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSED; -import static com.android.server.wm.ActivityStack.ActivityState.PAUSING; -import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; -import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; +import static com.android.server.wm.Task.ActivityState.FINISHING; +import static com.android.server.wm.Task.ActivityState.PAUSED; +import static com.android.server.wm.Task.ActivityState.PAUSING; +import static com.android.server.wm.Task.ActivityState.STOPPED; +import static com.android.server.wm.Task.ActivityState.STOPPING; import static com.google.common.truth.Truth.assertThat; @@ -149,7 +151,7 @@ public class RootWindowContainerTests extends WindowTestsBase { public void testAllPausedActivitiesComplete() { DisplayContent displayContent = mWm.mRoot.getDisplayContent(DEFAULT_DISPLAY); TaskDisplayArea taskDisplayArea = displayContent.getDefaultTaskDisplayArea(); - ActivityStack stack = taskDisplayArea.getStackAt(0); + Task stack = taskDisplayArea.getStackAt(0); ActivityRecord activity = createActivityRecord(displayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); stack.mPausingActivity = activity; @@ -169,5 +171,27 @@ public class RootWindowContainerTests extends WindowTestsBase { activity.setState(FINISHING, "test FINISHING"); assertThat(mWm.mRoot.allPausedActivitiesComplete()).isTrue(); } + + @Test + public void testForceStopPackage() { + final Task task = new ActivityTestsBase.StackBuilder(mWm.mRoot).build(); + final ActivityRecord activity1 = task.getTopMostActivity(); + final ActivityRecord activity2 = + new ActivityTestsBase.ActivityBuilder(mWm.mAtmService).setStack(task).build(); + final WindowProcessController wpc = activity1.app; + spyOn(wpc); + activity1.app = null; + activity2.setProcess(wpc); + doReturn(true).when(wpc).isRemoved(); + + mWm.mAtmService.mInternal.onForceStopPackage(wpc.mInfo.packageName, true /* doit */, + false /* evenPersistent */, wpc.mUserId); + // The activity without process should be removed. + assertEquals(1, task.getChildCount()); + + mWm.mRoot.handleAppDied(wpc); + // The activity with process should be removed because WindowProcessController#isRemoved. + assertFalse(task.hasChild()); + } } 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 3d3a0f148db5..e51a133d5cce 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java @@ -62,7 +62,7 @@ public class RunningTasksTest extends ActivityTestsBase { final int numStacks = 2; for (int stackIndex = 0; stackIndex < numStacks; stackIndex++) { - final ActivityStack stack = new StackBuilder(mRootWindowContainer) + final Task stack = new StackBuilder(mRootWindowContainer) .setCreateActivity(false) .setDisplay(display) .setOnTop(false) @@ -104,7 +104,7 @@ public class RunningTasksTest extends ActivityTestsBase { final DisplayContent display = new TestDisplayContent.Builder(mService, 1000, 2500).build(); final int numTasks = 10; for (int i = 0; i < numTasks; i++) { - final ActivityStack stack = new StackBuilder(mRootWindowContainer) + final Task stack = new StackBuilder(mRootWindowContainer) .setCreateActivity(false) .setDisplay(display) .setOnTop(true) @@ -130,7 +130,7 @@ public class RunningTasksTest extends ActivityTestsBase { /** * Create a task with a single activity in it, with the given last active time. */ - private Task createTask(ActivityStack stack, String className, int taskId, + private Task createTask(Task stack, String className, int taskId, int lastActiveTime, Bundle extras) { final Task task = new TaskBuilder(mService.mStackSupervisor) .setComponent(new ComponentName(mContext.getPackageName(), className)) diff --git a/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java b/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java index 31a102ae3bad..ef74861e9422 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java @@ -25,8 +25,8 @@ import static android.view.Gravity.BOTTOM; import static android.view.Gravity.LEFT; import static android.view.Gravity.RIGHT; import static android.view.Gravity.TOP; -import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; -import static android.view.InsetsState.ITYPE_STATUS_BAR; +import static android.view.InsetsState.ITYPE_CLIMATE_BAR; +import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; @@ -190,7 +190,7 @@ public class ScreenDecorWindowTests { @Test public void testProvidesInsetsTypes() { - int[] providesInsetsTypes = new int[]{ITYPE_STATUS_BAR}; + int[] providesInsetsTypes = new int[]{ITYPE_CLIMATE_BAR}; final View win = createWindow("StatusBarSubPanel", TOP, MATCH_PARENT, mDecorThickness, RED, FLAG_LAYOUT_IN_SCREEN, 0, providesInsetsTypes); @@ -199,7 +199,7 @@ public class ScreenDecorWindowTests { private View createDecorWindow(int gravity, int width, int height) { int[] providesInsetsTypes = - new int[]{gravity == TOP ? ITYPE_STATUS_BAR : ITYPE_NAVIGATION_BAR}; + new int[]{gravity == TOP ? ITYPE_CLIMATE_BAR : ITYPE_EXTRA_NAVIGATION_BAR}; return createWindow("decorWindow", gravity, width, height, RED, FLAG_LAYOUT_IN_SCREEN, PRIVATE_FLAG_IS_SCREEN_DECOR, providesInsetsTypes); } diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index a979c862a8e4..250cf09e8547 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -29,7 +29,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; 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.verify; -import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; +import static com.android.server.wm.Task.ActivityState.STOPPED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -65,7 +65,7 @@ import java.util.ArrayList; @Presubmit @RunWith(WindowTestRunner.class) public class SizeCompatTests extends ActivityTestsBase { - private ActivityStack mStack; + private Task mStack; private Task mTask; private ActivityRecord mActivity; @@ -86,7 +86,7 @@ public class SizeCompatTests extends ActivityTestsBase { doNothing().when(mSupervisor).scheduleRestartTimeout(mActivity); mActivity.mVisibleRequested = true; mActivity.setSavedState(null /* savedState */); - mActivity.setState(ActivityStack.ActivityState.RESUMED, "testRestart"); + mActivity.setState(Task.ActivityState.RESUMED, "testRestart"); prepareUnresizable(1.5f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED); final Rect originalOverrideBounds = new Rect(mActivity.getBounds()); @@ -94,7 +94,7 @@ public class SizeCompatTests extends ActivityTestsBase { // The visible activity should recompute configuration according to the last parent bounds. mService.restartActivityProcessIfVisible(mActivity.appToken); - assertEquals(ActivityStack.ActivityState.RESTARTING_PROCESS, mActivity.getState()); + assertEquals(Task.ActivityState.RESTARTING_PROCESS, mActivity.getState()); assertNotEquals(originalOverrideBounds, mActivity.getBounds()); } @@ -449,7 +449,7 @@ public class SizeCompatTests extends ActivityTestsBase { public void testHandleActivitySizeCompatMode() { setUpDisplaySizeWithApp(1000, 2000); ActivityRecord activity = mActivity; - activity.setState(ActivityStack.ActivityState.RESUMED, "testHandleActivitySizeCompatMode"); + activity.setState(Task.ActivityState.RESUMED, "testHandleActivitySizeCompatMode"); prepareUnresizable(-1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT); assertFitted(); @@ -476,7 +476,7 @@ public class SizeCompatTests extends ActivityTestsBase { activity.mVisibleRequested = true; activity.restartProcessIfVisible(); // The full lifecycle isn't hooked up so manually set state to resumed - activity.setState(ActivityStack.ActivityState.RESUMED, "testHandleActivitySizeCompatMode"); + activity.setState(Task.ActivityState.RESUMED, "testHandleActivitySizeCompatMode"); mStack.getDisplay().handleActivitySizeCompatModeIfNeeded(activity); // Expect null token when switching to non-size-compat mode activity. 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 50675b03ae1f..eb7d9c2d3c32 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java @@ -319,7 +319,7 @@ public class SystemServicesTestRule implements TestRule { spyOn(display); final TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea(); spyOn(taskDisplayArea); - final ActivityStack homeStack = taskDisplayArea.getStack( + final Task homeStack = taskDisplayArea.getStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME); spyOn(homeStack); } diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java index 8c3661b409f4..27a8fc3c5943 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java @@ -32,7 +32,7 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; -import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; +import static com.android.server.wm.Task.ActivityState.RESUMED; import static com.google.common.truth.Truth.assertThat; @@ -67,7 +67,7 @@ import org.junit.runner.RunWith; @RunWith(WindowTestRunner.class) public class TaskDisplayAreaTests extends WindowTestsBase { - private ActivityStack mPinnedStack; + private Task mPinnedStack; @Before public void setUp() throws Exception { @@ -89,7 +89,7 @@ public class TaskDisplayAreaTests extends WindowTestsBase { @Test public void testActivityWithZBoost_taskDisplayAreaDoesNotMoveUp() { - final ActivityStack stack = createTaskStackOnDisplay( + final Task stack = createTaskStackOnDisplay( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); final ActivityRecord activity = WindowTestUtils.createTestActivityRecord(mDisplayContent); @@ -109,8 +109,8 @@ public class TaskDisplayAreaTests extends WindowTestsBase { @Test public void testStackPositionChildAt() { // Test that always-on-top stack can't be moved to position other than top. - final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent); - final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent); + final Task stack1 = createTaskStackOnDisplay(mDisplayContent); + final Task stack2 = createTaskStackOnDisplay(mDisplayContent); final WindowContainer taskStackContainer = stack1.getParent(); @@ -134,7 +134,7 @@ public class TaskDisplayAreaTests extends WindowTestsBase { @Test public void testStackPositionBelowPinnedStack() { // Test that no stack can be above pinned stack. - final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent); + final Task stack1 = createTaskStackOnDisplay(mDisplayContent); final WindowContainer taskStackContainer = stack1.getParent(); @@ -158,7 +158,7 @@ public class TaskDisplayAreaTests extends WindowTestsBase { doReturn(true).when(mDisplayContent).isTrusted(); // The display contains pinned stack that was added in {@link #setUp}. - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); // Add another display at top. @@ -216,10 +216,10 @@ public class TaskDisplayAreaTests extends WindowTestsBase { final TaskDisplayArea defaultTaskDisplayArea = rootWindowContainer.getDefaultTaskDisplayArea(); - final ActivityStack rootHomeTask = defaultTaskDisplayArea.getRootHomeTask(); + final Task rootHomeTask = defaultTaskDisplayArea.getRootHomeTask(); rootHomeTask.mResizeMode = RESIZE_MODE_UNRESIZEABLE; - final ActivityStack primarySplitTask = + final Task primarySplitTask = new ActivityTestsBase.StackBuilder(rootWindowContainer) .setTaskDisplayArea(defaultTaskDisplayArea) .setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) @@ -247,7 +247,7 @@ public class TaskDisplayAreaTests extends WindowTestsBase { private void assertGetOrCreateStack(int windowingMode, int activityType, Task candidateTask, boolean reuseCandidate) { final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea(); - final ActivityStack stack = taskDisplayArea.getOrCreateStack(windowingMode, activityType, + final Task stack = taskDisplayArea.getOrCreateStack(windowingMode, activityType, false /* onTop */, null /* intent */, candidateTask /* candidateTask */); assertEquals(reuseCandidate, stack == candidateTask); } diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java index a69231b9e03a..a048526bb068 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java @@ -30,7 +30,6 @@ import static android.util.DisplayMetrics.DENSITY_DEFAULT; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP; @@ -1350,13 +1349,13 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { } private ActivityRecord createSourceActivity(TestDisplayContent display) { - final ActivityStack stack = display.getDefaultTaskDisplayArea() + final Task stack = display.getDefaultTaskDisplayArea() .createStack(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true); return new ActivityBuilder(mService).setStack(stack).setCreateTask(true).build(); } private void addFreeformTaskTo(TestDisplayContent display, Rect bounds) { - final ActivityStack stack = display.getDefaultTaskDisplayArea() + final Task stack = display.getDefaultTaskDisplayArea() .createStack(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true); stack.setWindowingMode(WINDOWING_MODE_FREEFORM); final Task task = new TaskBuilder(mSupervisor).setStack(stack).build(); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java index 93dcc9103640..0db3f94d1fc3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java @@ -37,7 +37,6 @@ import android.platform.test.annotations.Presubmit; import android.util.DisplayMetrics; import android.util.Log; -import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import org.junit.After; @@ -77,7 +76,7 @@ public class TaskPositionerTests extends WindowTestsBase { mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, dm); removeGlobalMinSizeRestriction(); - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final ActivityRecord activity = new ActivityTestsBase.ActivityBuilder(stack.mAtmService) .setStack(stack) // In real case, there is no additional level for freeform mode. 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 abdbd5131fd9..bf76c8ee5f0a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java @@ -173,7 +173,7 @@ public class TaskRecordTests extends ActivityTestsBase { public void testFitWithinBounds() { final Rect parentBounds = new Rect(10, 10, 200, 200); TaskDisplayArea taskDisplayArea = mService.mRootWindowContainer.getDefaultTaskDisplayArea(); - ActivityStack stack = taskDisplayArea.createStack(WINDOWING_MODE_FREEFORM, + Task stack = taskDisplayArea.createStack(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */); Task task = new TaskBuilder(mSupervisor).setStack(stack).build(); final Configuration parentConfig = stack.getConfiguration(); @@ -211,7 +211,7 @@ public class TaskRecordTests extends ActivityTestsBase { @Test public void testBoundsOnModeChangeFreeformToFullscreen() { DisplayContent display = mService.mRootWindowContainer.getDefaultDisplay(); - ActivityStack stack = new StackBuilder(mRootWindowContainer).setDisplay(display) + Task stack = new StackBuilder(mRootWindowContainer).setDisplay(display) .setWindowingMode(WINDOWING_MODE_FREEFORM).build(); Task task = stack.getBottomMostTask(); task.getRootActivity().setOrientation(SCREEN_ORIENTATION_UNSPECIFIED); @@ -252,7 +252,7 @@ public class TaskRecordTests extends ActivityTestsBase { dr.setFixedToUserRotation(FIXED_TO_USER_ROTATION_ENABLED); dr.setUserRotation(USER_ROTATION_FREE, ROTATION_0); - ActivityStack stack = new StackBuilder(mRootWindowContainer) + Task stack = new StackBuilder(mRootWindowContainer) .setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build(); Task task = stack.getBottomMostTask(); ActivityRecord root = task.getTopNonFinishingActivity(); @@ -313,7 +313,7 @@ public class TaskRecordTests extends ActivityTestsBase { Configuration.ORIENTATION_LANDSCAPE; display.onRequestedOverrideConfigurationChanged( display.getRequestedOverrideConfiguration()); - ActivityStack stack = new StackBuilder(mRootWindowContainer) + Task stack = new StackBuilder(mRootWindowContainer) .setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build(); Task task = stack.getBottomMostTask(); ActivityRecord root = task.getTopNonFinishingActivity(); @@ -324,7 +324,7 @@ public class TaskRecordTests extends ActivityTestsBase { parentWindowContainer.setBounds(fullScreenBounds); doReturn(parentWindowContainer).when(task).getParent(); doReturn(display.getDefaultTaskDisplayArea()).when(task).getDisplayArea(); - doReturn(stack).when(task).getStack(); + doReturn(stack).when(task).getRootTask(); doReturn(true).when(parentWindowContainer).handlesOrientationChangeFromDescendant(); // Setting app to fixed portrait fits within parent, but Task shouldn't adjust the @@ -409,15 +409,15 @@ public class TaskRecordTests extends ActivityTestsBase { assertTrue(task.getResolvedOverrideBounds().isEmpty()); int origScreenH = task.getConfiguration().screenHeightDp; Configuration stackConfig = new Configuration(); - stackConfig.setTo(task.getStack().getRequestedOverrideConfiguration()); + stackConfig.setTo(task.getRootTask().getRequestedOverrideConfiguration()); stackConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM); // Set bounds on stack (not task) and verify that the task resource configuration changes // despite it's override bounds being empty. - Rect bounds = new Rect(task.getStack().getBounds()); + Rect bounds = new Rect(task.getRootTask().getBounds()); bounds.bottom = (int) (bounds.bottom * 0.6f); stackConfig.windowConfiguration.setBounds(bounds); - task.getStack().onRequestedOverrideConfigurationChanged(stackConfig); + task.getRootTask().onRequestedOverrideConfigurationChanged(stackConfig); assertNotEquals(origScreenH, task.getConfiguration().screenHeightDp); } @@ -439,7 +439,7 @@ public class TaskRecordTests extends ActivityTestsBase { @Test public void testInsetDisregardedWhenFreeformOverlapsNavBar() { TaskDisplayArea taskDisplayArea = mService.mRootWindowContainer.getDefaultTaskDisplayArea(); - ActivityStack stack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, + Task stack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); DisplayInfo displayInfo = new DisplayInfo(); mService.mContext.getDisplay().getDisplayInfo(displayInfo); @@ -514,7 +514,7 @@ public class TaskRecordTests extends ActivityTestsBase { info.packageName = DEFAULT_COMPONENT_PACKAGE_NAME; info.targetActivity = targetClassName; - final Task task = new ActivityStack(mService, 1 /* taskId */, info, intent, + final Task task = new Task(mService, 1 /* taskId */, info, intent, null /* voiceSession */, null /* voiceInteractor */, null /* taskDescriptor */, null /*stack*/); assertEquals("The alias activity component should be saved in task intent.", aliasClassName, @@ -880,7 +880,7 @@ public class TaskRecordTests extends ActivityTestsBase { final Task task = getTestTask(); task.setHasBeenVisible(false); task.getDisplayContent().setDisplayWindowingMode(WINDOWING_MODE_FREEFORM); - task.getStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN); + task.getRootTask().setWindowingMode(WINDOWING_MODE_FULLSCREEN); task.setHasBeenVisible(true); task.onConfigurationChanged(task.getParent().getConfiguration()); @@ -896,7 +896,7 @@ public class TaskRecordTests extends ActivityTestsBase { final Task task = getTestTask(); task.setHasBeenVisible(false); task.getDisplayContent().setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM); - task.getStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN); + task.getRootTask().setWindowingMode(WINDOWING_MODE_FULLSCREEN); final DisplayContent oldDisplay = task.getDisplayContent(); LaunchParamsController.LaunchParams params = new LaunchParamsController.LaunchParams(); @@ -920,7 +920,7 @@ public class TaskRecordTests extends ActivityTestsBase { final Task task = getTestTask(); task.setHasBeenVisible(false); - task.getStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN); + task.getRootTask().setWindowingMode(WINDOWING_MODE_FULLSCREEN); task.setHasBeenVisible(true); task.onConfigurationChanged(task.getParent().getConfiguration()); @@ -936,7 +936,7 @@ public class TaskRecordTests extends ActivityTestsBase { final Task task = getTestTask(); task.setHasBeenVisible(false); task.getDisplayContent().setDisplayWindowingMode(WINDOWING_MODE_FREEFORM); - task.getStack().setWindowingMode(WINDOWING_MODE_PINNED); + task.getRootTask().setWindowingMode(WINDOWING_MODE_PINNED); task.setHasBeenVisible(true); task.onConfigurationChanged(task.getParent().getConfiguration()); @@ -976,7 +976,7 @@ public class TaskRecordTests extends ActivityTestsBase { } private Task getTestTask() { - final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); + final Task stack = new StackBuilder(mRootWindowContainer).build(); return stack.getBottomMostTask(); } @@ -984,7 +984,7 @@ public class TaskRecordTests extends ActivityTestsBase { Rect expectedConfigBounds) { TaskDisplayArea taskDisplayArea = mService.mRootWindowContainer.getDefaultTaskDisplayArea(); - ActivityStack stack = taskDisplayArea.createStack(windowingMode, ACTIVITY_TYPE_STANDARD, + Task stack = taskDisplayArea.createStack(windowingMode, ACTIVITY_TYPE_STANDARD, true /* onTop */); Task task = new TaskBuilder(mSupervisor).setStack(stack).build(); @@ -1024,7 +1024,7 @@ public class TaskRecordTests extends ActivityTestsBase { } private Task createTask(int taskId) { - return new ActivityStack(mService, taskId, new Intent(), null, null, null, + return new Task(mService, taskId, new Intent(), null, null, null, ActivityBuilder.getDefaultComponent(), null, false, false, false, 0, 10050, null, 0, false, null, 0, 0, 0, 0, null, null, 0, false, false, false, 0, 0, null /*ActivityInfo*/, null /*_voiceSession*/, null /*_voiceInteractor*/, 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 f1dbde066125..205b842253b7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java @@ -59,7 +59,7 @@ public class TaskStackTests extends WindowTestsBase { @Test public void testStackPositionChildAt() { - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final Task task1 = createTaskInStack(stack, 0 /* userId */); final Task task2 = createTaskInStack(stack, 1 /* userId */); @@ -74,8 +74,8 @@ public class TaskStackTests extends WindowTestsBase { assertEquals(stack.mChildren.get(1), task1); // Non-leaf task should be moved to top regardless of the user id. - createTaskInStack((ActivityStack) task2, 0 /* userId */); - createTaskInStack((ActivityStack) task2, 1 /* userId */); + createTaskInStack(task2, 0 /* userId */); + createTaskInStack(task2, 1 /* userId */); stack.positionChildAt(WindowContainer.POSITION_TOP, task2, false /* includingParents */); assertEquals(stack.mChildren.get(0), task1); assertEquals(stack.mChildren.get(1), task2); @@ -83,7 +83,7 @@ public class TaskStackTests extends WindowTestsBase { @Test public void testClosingAppDifferentStackOrientation() { - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final Task task1 = createTaskInStack(stack, 0 /* userId */); ActivityRecord activity1 = WindowTestUtils.createTestActivityRecord(mDisplayContent); @@ -103,7 +103,7 @@ public class TaskStackTests extends WindowTestsBase { @Test public void testMoveTaskToBackDifferentStackOrientation() { - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final Task task1 = createTaskInStack(stack, 0 /* userId */); ActivityRecord activity1 = WindowTestUtils.createTestActivityRecord(mDisplayContent); @@ -120,9 +120,9 @@ public class TaskStackTests extends WindowTestsBase { @Test public void testStackRemoveImmediately() { - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); - assertEquals(stack, task.getStack()); + assertEquals(stack, task.getRootTask()); // Remove stack and check if its child is also removed. stack.removeImmediately(); @@ -132,7 +132,7 @@ public class TaskStackTests extends WindowTestsBase { @Test public void testRemoveContainer() { - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); assertNotNull(stack); @@ -148,7 +148,7 @@ public class TaskStackTests extends WindowTestsBase { @Test public void testRemoveContainer_deferRemoval() { - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); // Stack removal is deferred if one of its child is animating. @@ -172,12 +172,12 @@ public class TaskStackTests extends WindowTestsBase { @Test public void testReparent() { // Create first stack on primary display. - final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent); + final Task stack1 = createTaskStackOnDisplay(mDisplayContent); final Task task1 = createTaskInStack(stack1, 0 /* userId */); // Create second display and put second stack on it. final DisplayContent dc = createNewDisplay(); - final ActivityStack stack2 = createTaskStackOnDisplay(dc); + final Task stack2 = createTaskStackOnDisplay(dc); // Reparent clearInvocations(task1); // reset the number of onDisplayChanged for task. @@ -191,7 +191,7 @@ public class TaskStackTests extends WindowTestsBase { @Test public void testStackOutset() { - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final int stackOutset = 10; spyOn(stack); doReturn(stackOutset).when(stack).getTaskOutset(); @@ -219,7 +219,7 @@ public class TaskStackTests extends WindowTestsBase { @Test public void testActivityAndTaskGetsProperType() { - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final Task task1 = createTaskInStack(stack, 0 /* userId */); ActivityRecord activity1 = WindowTestUtils.createTestActivityRecord(mDisplayContent); 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 9d88ada5a90c..039ffc464337 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java @@ -54,7 +54,7 @@ public class TaskTests extends WindowTestsBase { @Test public void testRemoveContainer() { - final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent); + final Task stackController1 = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stackController1, 0 /* userId */); final ActivityRecord activity = WindowTestUtils.createActivityRecordInTask(mDisplayContent, task); @@ -68,7 +68,7 @@ public class TaskTests extends WindowTestsBase { @Test public void testRemoveContainer_deferRemoval() { - final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent); + final Task stackController1 = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stackController1, 0 /* userId */); final ActivityRecord activity = WindowTestUtils.createActivityRecordInTask(mDisplayContent, task); @@ -90,9 +90,9 @@ public class TaskTests extends WindowTestsBase { @Test public void testReparent() { - final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent); + final Task stackController1 = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stackController1, 0 /* userId */); - final ActivityStack stackController2 = createTaskStackOnDisplay(mDisplayContent); + final Task stackController2 = createTaskStackOnDisplay(mDisplayContent); final Task task2 = createTaskInStack(stackController2, 0 /* userId */); boolean gotException = false; @@ -120,13 +120,13 @@ public class TaskTests extends WindowTestsBase { @Test public void testReparent_BetweenDisplays() { // Create first stack on primary display. - final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent); + final Task stack1 = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack1, 0 /* userId */); assertEquals(mDisplayContent, stack1.getDisplayContent()); // Create second display and put second stack on it. final DisplayContent dc = createNewDisplay(); - final ActivityStack stack2 = createTaskStackOnDisplay(dc); + final Task stack2 = createTaskStackOnDisplay(dc); final Task task2 = createTaskInStack(stack2, 0 /* userId */); // Reparent and check state clearInvocations(task); // reset the number of onDisplayChanged for task. @@ -139,7 +139,7 @@ public class TaskTests extends WindowTestsBase { @Test public void testBounds() { - final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent); + final Task stack1 = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack1, 0 /* userId */); // Check that setting bounds also updates surface position 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 efc03df877b7..3ebc28886377 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java @@ -808,7 +808,7 @@ public class WindowContainerTests extends WindowTestsBase { @Test public void testOnDisplayChanged() { - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); final ActivityRecord activity = WindowTestUtils.createActivityRecordInTask(mDisplayContent, task); @@ -852,7 +852,7 @@ public class WindowContainerTests extends WindowTestsBase { @Test public void testTaskCanApplyAnimation() { - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); final ActivityRecord activity2 = WindowTestUtils.createActivityRecordInTask(mDisplayContent, task); @@ -863,7 +863,7 @@ public class WindowContainerTests extends WindowTestsBase { @Test public void testStackCanApplyAnimation() { - final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); + final Task stack = createTaskStackOnDisplay(mDisplayContent); final ActivityRecord activity2 = WindowTestUtils.createActivityRecordInTask(mDisplayContent, createTaskInStack(stack, 0 /* userId */)); final ActivityRecord activity1 = WindowTestUtils.createActivityRecordInTask(mDisplayContent, @@ -879,7 +879,7 @@ public class WindowContainerTests extends WindowTestsBase { assertNull(windowContainer.getDisplayArea()); // ActivityStack > WindowContainer - final ActivityStack activityStack = createTaskStackOnDisplay(mDisplayContent); + final Task activityStack = createTaskStackOnDisplay(mDisplayContent); activityStack.addChild(windowContainer, 0); activityStack.setParent(null); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java index 8fa3a12f027d..f97dff3162c4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java @@ -105,13 +105,13 @@ public class WindowManagerServiceTests extends WindowTestsBase { public void testTaskFocusChange_stackNotHomeType_focusChanges() throws RemoteException { DisplayContent display = createNewDisplay(); // Current focused window - ActivityStack focusedStack = createTaskStackOnDisplay( + Task focusedStack = createTaskStackOnDisplay( WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, display); Task focusedTask = createTaskInStack(focusedStack, 0 /* userId */); WindowState focusedWindow = createAppWindow(focusedTask, TYPE_APPLICATION, "App Window"); mDisplayContent.mCurrentFocus = focusedWindow; // Tapped task - ActivityStack tappedStack = createTaskStackOnDisplay( + Task tappedStack = createTaskStackOnDisplay( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, display); Task tappedTask = createTaskInStack(tappedStack, 0 /* userId */); spyOn(mWm.mActivityTaskManager); @@ -126,13 +126,13 @@ public class WindowManagerServiceTests extends WindowTestsBase { throws RemoteException { DisplayContent display = createNewDisplay(); // Current focused window - ActivityStack focusedStack = createTaskStackOnDisplay( + Task focusedStack = createTaskStackOnDisplay( WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, display); Task focusedTask = createTaskInStack(focusedStack, 0 /* userId */); WindowState focusedWindow = createAppWindow(focusedTask, TYPE_APPLICATION, "App Window"); mDisplayContent.mCurrentFocus = focusedWindow; // Tapped home task - ActivityStack tappedStack = createTaskStackOnDisplay( + Task tappedStack = createTaskStackOnDisplay( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, display); Task tappedTask = createTaskInStack(tappedStack, 0 /* userId */); spyOn(mWm.mActivityTaskManager); @@ -149,13 +149,13 @@ public class WindowManagerServiceTests extends WindowTestsBase { final TaskDisplayArea secondTda = createTaskDisplayArea( display, mWm, "Tapped TDA", FEATURE_VENDOR_FIRST); // Current focused window - ActivityStack focusedStack = createTaskStackOnDisplay( + Task focusedStack = createTaskStackOnDisplay( WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, display); Task focusedTask = createTaskInStack(focusedStack, 0 /* userId */); WindowState focusedWindow = createAppWindow(focusedTask, TYPE_APPLICATION, "App Window"); mDisplayContent.mCurrentFocus = focusedWindow; // Tapped home task on another task display area - ActivityStack tappedStack = createTaskStackOnTaskDisplayArea( + Task tappedStack = createTaskStackOnTaskDisplayArea( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, secondTda); Task tappedTask = createTaskInStack(tappedStack, 0 /* userId */); spyOn(mWm.mActivityTaskManager); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index 7cc19ad0ddd8..bd52e9a294fc 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -103,7 +103,7 @@ public class WindowOrganizerTests extends WindowTestsBase { return registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW); } - Task createTask(ActivityStack stack, boolean fakeDraw) { + Task createTask(Task stack, boolean fakeDraw) { final Task task = createTaskInStack(stack, 0); if (fakeDraw) { @@ -112,12 +112,12 @@ public class WindowOrganizerTests extends WindowTestsBase { return task; } - Task createTask(ActivityStack stack) { + Task createTask(Task stack) { // Fake draw notifications for most of our tests. return createTask(stack, true); } - ActivityStack createStack() { + Task createStack() { return createTaskStackOnDisplay(mDisplayContent); } @@ -130,7 +130,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testAppearVanish() throws RemoteException { - final ActivityStack stack = createStack(); + final Task stack = createStack(); final Task task = createTask(stack); final ITaskOrganizer organizer = registerMockOrganizer(); @@ -144,7 +144,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testAppearWaitsForVisibility() throws RemoteException { - final ActivityStack stack = createStack(); + final Task stack = createStack(); final Task task = createTask(stack, false); final ITaskOrganizer organizer = registerMockOrganizer(); @@ -163,7 +163,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testNoVanishedIfNoAppear() throws RemoteException { - final ActivityStack stack = createStack(); + final Task stack = createStack(); final Task task = createTask(stack, false /* hasBeenVisible */); final ITaskOrganizer organizer = registerMockOrganizer(); @@ -179,7 +179,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testSwapOrganizer() throws RemoteException { - final ActivityStack stack = createStack(); + final Task stack = createStack(); final Task task = createTask(stack); final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW); final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED); @@ -193,7 +193,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testSwapWindowingModes() throws RemoteException { - final ActivityStack stack = createStack(); + final Task stack = createStack(); final Task task = createTask(stack); final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW); final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED); @@ -207,7 +207,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testTaskNoDraw() throws RemoteException { - final ActivityStack stack = createStack(); + final Task stack = createStack(); final Task task = createTask(stack, false /* fakeDraw */); final ITaskOrganizer organizer = registerMockOrganizer(); @@ -223,7 +223,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testClearOrganizer() throws RemoteException { - final ActivityStack stack = createStack(); + final Task stack = createStack(); final Task task = createTask(stack); final ITaskOrganizer organizer = registerMockOrganizer(); @@ -238,7 +238,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testUnregisterOrganizer() throws RemoteException { - final ActivityStack stack = createStack(); + final Task stack = createStack(); final Task task = createTask(stack); final ITaskOrganizer organizer = registerMockOrganizer(); @@ -253,11 +253,11 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testUnregisterOrganizerReturnsRegistrationToPrevious() throws RemoteException { - final ActivityStack stack = createStack(); + final Task stack = createStack(); final Task task = createTask(stack); - final ActivityStack stack2 = createStack(); + final Task stack2 = createStack(); final Task task2 = createTask(stack2); - final ActivityStack stack3 = createStack(); + final Task stack3 = createStack(); final Task task3 = createTask(stack3); final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW); @@ -297,7 +297,7 @@ public class WindowOrganizerTests extends WindowTestsBase { public void testRegisterTaskOrganizerStackWindowingModeChanges() throws RemoteException { final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_PINNED); - final ActivityStack stack = createStack(); + final Task stack = createStack(); final Task task = createTask(stack); final Task task2 = createTask(stack); stack.setWindowingMode(WINDOWING_MODE_PINNED); @@ -310,7 +310,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testRegisterTaskOrganizerWithExistingTasks() throws RemoteException { - final ActivityStack stack = createStack(); + final Task stack = createStack(); final Task task = createTask(stack); stack.setWindowingMode(WINDOWING_MODE_PINNED); @@ -322,7 +322,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testTaskTransaction() { removeGlobalMinSizeRestriction(); - final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot) + final Task stack = new ActivityTestsBase.StackBuilder(mWm.mRoot) .setWindowingMode(WINDOWING_MODE_FREEFORM).build(); final Task task = stack.getTopMostTask(); testTransaction(task); @@ -331,7 +331,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testStackTransaction() { removeGlobalMinSizeRestriction(); - final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot) + final Task stack = new ActivityTestsBase.StackBuilder(mWm.mRoot) .setWindowingMode(WINDOWING_MODE_FREEFORM).build(); StackInfo info = mWm.mAtmService.getStackInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD); @@ -356,7 +356,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testSetWindowingMode() { - final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot) + final Task stack = new ActivityTestsBase.StackBuilder(mWm.mRoot) .setWindowingMode(WINDOWING_MODE_FREEFORM).build(); testSetWindowingMode(stack); @@ -375,7 +375,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testSetActivityWindowingMode() { final ActivityRecord record = makePipableActivity(); - final ActivityStack stack = record.getStack(); + final Task stack = record.getStack(); final WindowContainerTransaction t = new WindowContainerTransaction(); t.setWindowingMode(stack.mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_PINNED); @@ -390,7 +390,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testContainerFocusableChanges() { removeGlobalMinSizeRestriction(); - final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot) + final Task stack = new ActivityTestsBase.StackBuilder(mWm.mRoot) .setWindowingMode(WINDOWING_MODE_FREEFORM).build(); final Task task = stack.getTopMostTask(); WindowContainerTransaction t = new WindowContainerTransaction(); @@ -406,7 +406,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testContainerHiddenChanges() { removeGlobalMinSizeRestriction(); - final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot) + final Task stack = new ActivityTestsBase.StackBuilder(mWm.mRoot) .setWindowingMode(WINDOWING_MODE_FREEFORM).build(); WindowContainerTransaction t = new WindowContainerTransaction(); assertTrue(stack.shouldBeVisible(null)); @@ -421,7 +421,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testOverrideConfigSize() { removeGlobalMinSizeRestriction(); - final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot) + final Task stack = new ActivityTestsBase.StackBuilder(mWm.mRoot) .setWindowingMode(WINDOWING_MODE_FREEFORM).build(); final Task task = stack.getTopMostTask(); WindowContainerTransaction t = new WindowContainerTransaction(); @@ -489,7 +489,7 @@ public class WindowOrganizerTests extends WindowTestsBase { RunningTaskInfo info1 = mWm.mAtmService.mTaskOrganizerController.createRootTask( mDisplayContent.mDisplayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); - final ActivityStack stack = createTaskStackOnDisplay( + final Task stack = createTaskStackOnDisplay( WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent); assertEquals(mDisplayContent.getWindowingMode(), stack.getWindowingMode()); WindowContainerTransaction wct = new WindowContainerTransaction(); @@ -550,7 +550,7 @@ public class WindowOrganizerTests extends WindowTestsBase { lastReportedTiles.clear(); called[0] = false; - final ActivityStack stack = createTaskStackOnDisplay( + final Task stack = createTaskStackOnDisplay( WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent); Task task1 = WindowContainer.fromBinder(info1.token.asBinder()).asTask(); WindowContainerTransaction wct = new WindowContainerTransaction(); @@ -561,7 +561,7 @@ public class WindowOrganizerTests extends WindowTestsBase { lastReportedTiles.clear(); called[0] = false; - final ActivityStack stack2 = createTaskStackOnDisplay( + final Task stack2 = createTaskStackOnDisplay( WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, mDisplayContent); wct = new WindowContainerTransaction(); wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), info1.token, true /* onTop */); @@ -617,9 +617,9 @@ public class WindowOrganizerTests extends WindowTestsBase { final int initialRootTaskCount = mWm.mAtmService.mTaskOrganizerController.getRootTasks( mDisplayContent.mDisplayId, null /* activityTypes */).size(); - final ActivityStack stack = createTaskStackOnDisplay( + final Task stack = createTaskStackOnDisplay( WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent); - final ActivityStack stack2 = createTaskStackOnDisplay( + final Task stack2 = createTaskStackOnDisplay( WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, mDisplayContent); // Check getRootTasks works @@ -694,7 +694,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testTrivialBLASTCallback() throws RemoteException { - final ActivityStack stackController1 = createStack(); + final Task stackController1 = createStack(); final Task task = createTask(stackController1); final ITaskOrganizer organizer = registerMockOrganizer(); @@ -716,7 +716,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testOverlappingBLASTCallback() throws RemoteException { - final ActivityStack stackController1 = createStack(); + final Task stackController1 = createStack(); final Task task = createTask(stackController1); final ITaskOrganizer organizer = registerMockOrganizer(); @@ -745,7 +745,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testBLASTCallbackWithWindow() { - final ActivityStack stackController1 = createStack(); + final Task stackController1 = createStack(); final Task task = createTask(stackController1); final ITaskOrganizer organizer = registerMockOrganizer(); final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window"); @@ -769,7 +769,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testBLASTCallbackNoDoubleAdd() { - final ActivityStack stackController1 = createStack(); + final Task stackController1 = createStack(); final Task task = createTask(stackController1); final ITaskOrganizer organizer = registerMockOrganizer(); final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window"); @@ -791,7 +791,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testBLASTCallbackWithInvisibleWindow() { - final ActivityStack stackController1 = createStack(); + final Task stackController1 = createStack(); final Task task = createTask(stackController1); final ITaskOrganizer organizer = registerMockOrganizer(); final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window"); @@ -813,7 +813,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testBLASTCallbackWithChildWindow() { - final ActivityStack stackController1 = createStack(); + final Task stackController1 = createStack(); final Task task = createTask(stackController1); final ITaskOrganizer organizer = registerMockOrganizer(); final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window"); @@ -930,7 +930,7 @@ public class WindowOrganizerTests extends WindowTestsBase { mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(o, WINDOWING_MODE_MULTI_WINDOW); - final ActivityStack stack = createStack(); + final Task stack = createStack(); final Task task = createTask(stack); final ActivityRecord record = WindowTestUtils.createActivityRecordInTask( stack.mDisplayContent, task); @@ -943,7 +943,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testPreventDuplicateAppear() throws RemoteException { - final ActivityStack stack = createStack(); + final Task stack = createStack(); final Task task = createTask(stack); final ITaskOrganizer organizer = registerMockOrganizer(); @@ -965,7 +965,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testInterceptBackPressedOnTaskRoot() throws RemoteException { - final ActivityStack stack = createStack(); + final Task stack = createStack(); final Task task = createTask(stack); final ActivityRecord activity = WindowTestUtils.createActivityRecordInTask( stack.mDisplayContent, task); @@ -992,7 +992,7 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testBLASTCallbackWithMultipleWindows() throws Exception { - final ActivityStack stackController = createStack(); + final Task stackController = createStack(); final Task task = createTask(stackController); final ITaskOrganizer organizer = registerMockOrganizer(); final WindowState w1 = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window 1"); 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 ce9dd685293a..3894a2eaa461 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -250,7 +250,7 @@ public class WindowStateTests extends WindowTestsBase { // minimized and home stack is resizable, so that we should ignore input for the stack. final DockedStackDividerController controller = mDisplayContent.getDockedDividerController(); - final ActivityStack stack = createTaskStackOnDisplay(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, + final Task stack = createTaskStackOnDisplay(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, mDisplayContent); spyOn(appWindow); spyOn(controller); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java index 49993610bbed..2502932c5421 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java @@ -32,8 +32,8 @@ import com.android.server.wm.ActivityTestsBase.ActivityBuilder; */ class WindowTestUtils { - /** Creates a {@link Task} and adds it to the specified {@link ActivityStack}. */ - static Task createTaskInStack(WindowManagerService service, ActivityStack stack, int userId) { + /** Creates a {@link Task} and adds it to the specified {@link Task}. */ + static Task createTaskInStack(WindowManagerService service, Task stack, int userId) { final Task task = new ActivityTestsBase.TaskBuilder(stack.mStackSupervisor) .setUserId(userId) .setStack(stack) @@ -48,7 +48,7 @@ class WindowTestUtils { return activity; } - static ActivityRecord createTestActivityRecord(ActivityStack stack) { + static ActivityRecord createTestActivityRecord(Task stack) { final ActivityRecord activity = new ActivityTestsBase.ActivityBuilder(stack.mAtmService) .setStack(stack) .setCreateTask(true) 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 0bbe0a04f618..dc388833f338 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -211,7 +211,7 @@ class WindowTestsBase extends SystemServiceTestsBase { ActivityRecord createTestActivityRecord(DisplayContent dc, int windowingMode, int activityType) { - final ActivityStack stack = createTaskStackOnDisplay(windowingMode, activityType, dc); + final Task stack = createTaskStackOnDisplay(windowingMode, activityType, dc); return WindowTestUtils.createTestActivityRecord(stack); } @@ -322,12 +322,12 @@ class WindowTestsBase extends SystemServiceTestsBase { return newTaskDisplayArea; } - /** Creates a {@link ActivityStack} and adds it to the specified {@link DisplayContent}. */ - ActivityStack createTaskStackOnDisplay(DisplayContent dc) { + /** Creates a {@link Task} and adds it to the specified {@link DisplayContent}. */ + Task createTaskStackOnDisplay(DisplayContent dc) { return createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, dc); } - ActivityStack createTaskStackOnDisplay(int windowingMode, int activityType, DisplayContent dc) { + Task createTaskStackOnDisplay(int windowingMode, int activityType, DisplayContent dc) { return new ActivityTestsBase.StackBuilder(dc.mWmService.mRoot) .setDisplay(dc) .setWindowingMode(windowingMode) @@ -337,7 +337,7 @@ class WindowTestsBase extends SystemServiceTestsBase { .build(); } - ActivityStack createTaskStackOnTaskDisplayArea(int windowingMode, int activityType, + Task createTaskStackOnTaskDisplayArea(int windowingMode, int activityType, TaskDisplayArea tda) { return new ActivityTestsBase.StackBuilder(tda.mWmService.mRoot) .setTaskDisplayArea(tda) @@ -348,8 +348,8 @@ class WindowTestsBase extends SystemServiceTestsBase { .build(); } - /** Creates a {@link Task} and adds it to the specified {@link ActivityStack}. */ - Task createTaskInStack(ActivityStack stack, int userId) { + /** Creates a {@link Task} and adds it to the specified {@link Task}. */ + Task createTaskInStack(Task stack, int userId) { return WindowTestUtils.createTaskInStack(mWm, stack, userId); } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java index cef202cdc5d5..f185da395754 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java @@ -84,6 +84,10 @@ public class WindowTokenTests extends WindowTestsBase { assertFalse(token.hasWindow(window12)); assertTrue(token.hasWindow(window2)); assertTrue(token.hasWindow(window3)); + + // The child windows should have the same window token as their parents. + assertEquals(window1.mToken, window11.mToken); + assertEquals(window1.mToken, window12.mToken); } @Test diff --git a/tests/FlickerTests/README.md b/tests/FlickerTests/README.md index a7c9e20e0a07..6b28fdf8a8ef 100644 --- a/tests/FlickerTests/README.md +++ b/tests/FlickerTests/README.md @@ -1,146 +1,88 @@ # Flicker Test Library ## Motivation -Detect *flicker* — any discontinuous, or unpredictable behavior seen during UI transitions that is not due to performance. This is often the result of a logic error in the code and difficult to identify because the issue is transient and at times difficult to reproduce. This library helps create integration tests between `SurfaceFlinger`, `WindowManager` and `SystemUI` to identify flicker. +This set of tests use the flickerlib from `platform_testing/libraries/flicker` to execute a set of common UI transitions to detect discontinuous or unpredictable behavior. -## Adding a Test -The library builds and runs UI transitions, captures Winscope traces and exposes common assertions that can be tested against each trace. - -### Building Transitions -Start by defining common or error prone transitions using `TransitionRunner`. -```java -// Example: Build a transition that cold launches an app from launcher -TransitionRunner transition = TransitionRunner.newBuilder() - // Specify a tag to identify the transition (optional) - .withTag("OpenAppCold_" + testApp.getLauncherName()) - - // Specify preconditions to setup the device - // Wake up device and go to home screen - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - - // Setup transition under test - // Press the home button and close the app to test a cold start - .runBefore(device::pressHome) - .runBefore(testApp::exit) - - // Run the transition under test - // Open the app and wait for UI to be idle - // This is the part of the transition that will be tested. - .run(testApp::open) - .run(device::waitForIdle) - - // Perform any tear downs - // Close the app - .runAfterAll(testApp::exit) - - // Number of times to repeat the transition to catch any flaky issues - .repeat(5); -``` - - -Run the transition to get a list of `TransitionResult` for each time the transition is repeated. -```java - List<TransitionResult> results = transition.run(); -``` -`TransitionResult` contains paths to test artifacts such as Winscope traces and screen recordings. - - -### Checking Assertions -Each `TransitionResult` can be tested using an extension of the Google Truth library, `LayersTraceSubject` and `WmTraceSubject`. They try to balance test principles set out by Google Truth (not supporting nested assertions, keeping assertions simple) with providing support for common assertion use cases. - -Each trace can be represented as a ordered collection of trace entries, with an associated timestamp. Each trace entry has common assertion checks. The trace subjects expose methods to filter the range of entries and test for changing assertions. - -```java - TransitionResult result = results.get(0); - Rect displayBounds = getDisplayBounds(); +The tests are organized in packages according to the transitions they test (e.g., `rotation`, `splitscreen`). - // check all trace entries - assertThat(result).coversRegion(displayBounds).forAllEntries(); - - // check a range of entries - assertThat(result).coversRegion(displayBounds).forRange(startTime, endTime); - - // check first entry - assertThat(result).coversRegion(displayBounds).inTheBeginning(); +## Adding a Test - // check last entry - assertThat(result).coversRegion(displayBounds).atTheEnd(); +By default tests should inherit from `RotationTestBase` or `NonRotationTestBase` and must override the variable `transitionToRun` (Kotlin) or the function `getTransitionToRun()` (Java). +Only tests that are not supported by these classes should inherit directly from the `FlickerTestBase` class. - // check a change in assertions, e.g. wallpaper window is visible, - // then wallpaper window becomes and stays invisible - assertThat(result) - .showsBelowAppWindow("wallpaper") - .then() - .hidesBelowAppWindow("wallpaper") - .forAllEntries(); -``` +### Rotation animations and transitions -All assertions return `Result` which contains a `success` flag, `assertionName` string identifier, and `reason` string to provide actionable details to the user. The `reason` string is build along the way with all the details as to why the assertions failed and any hints which might help the user determine the root cause. Failed assertion message will also contain a path to the trace that was tested. Example of a failed test: +Tests that rotate the device should inherit from `RotationTestBase`. +Tests that inherit from the class automatically receive start and end rotation values. +Moreover, these tests inherit the following checks: +* all regions on the screen are covered +* status bar is always visible +* status bar rotates +* nav bar is always visible +* nav bar is rotates -``` - java.lang.AssertionError: Not true that <com.android.server.wm.flicker.LayersTrace@65da4cc> - Layers Trace can be found in: /layers_trace_emptyregion.pb - Timestamp: 2308008331271 - Assertion: coversRegion - Reason: Region to test: Rect(0, 0 - 1440, 2880) - first empty point: 0, 99 - visible regions: - StatusBar#0Rect(0, 0 - 1440, 98) - NavigationBar#0Rect(0, 2712 - 1440, 2880) - ScreenDecorOverlay#0Rect(0, 0 - 1440, 91) - ... - at com.google.common.truth.FailureStrategy.fail(FailureStrategy.java:24) - ... -``` +The default tests can be disabled by overriding the respective methods and including an `@Ignore` annotation. ---- +### Non-Rotation animations and transitions -## Running Tests +`NonRotationTestBase` was created to make it easier to write tests that do not involve rotation (e.g., `Pip`, `split screen` or `IME`). +Tests that inherit from the class are automatically executed twice: once in portrait and once in landscape mode and the assertions are checked independently. +Moreover, these tests inherit the following checks: +* all regions on the screen are covered +* status bar is always visible +* nav bar is always visible -The tests can be run as any other Android JUnit tests. `platform_testing/tests/flicker` uses the library to test common UI transitions. Run `atest FlickerTest` to execute these tests. +The default tests can be disabled by overriding the respective methods and including an `@Ignore` annotation. ---- +### Exceptional cases -## Other Topics -### Monitors -Monitors capture test artifacts for each transition run. They are started before each iteration of the test transition (after the `runBefore` calls) and stopped after the transition is completed. Each iteration will produce a new test artifact. The following monitors are available: +Tests that rotate the device should inherit from `RotationTestBase`. +This class allows the test to be freely configured and does not provide any assertions. -#### LayersTraceMonitor -Captures Layers trace. This monitor is started by default. Build a transition with `skipLayersTrace()` to disable this monitor. -#### WindowManagerTraceMonitor -Captures Window Manager trace. This monitor is started by default. Build a transition with `skipWindowManagerTrace()` to disable this monitor. -#### WindowAnimationFrameStatsMonitor -Captures WindowAnimationFrameStats for the transition. This monitor is started by default and is used to eliminate *janky* runs. If an iteration has skipped frames, as determined by WindowAnimationFrameStats, the results for the iteration is skipped. If the list of results is empty after all iterations are completed, then the test should fail. Build a transition with `includeJankyRuns()` to disable this monitor. -#### ScreenRecorder -Captures screen to a video file. This monitor is disabled by default. Build a transition with `recordEachRun()` to capture each transition or build with `recordAllRuns()` to capture every transition including setup and teardown. ---- +### Example -### Extending Assertions - -To add a new assertion, add a function to one of the trace entry classes, `LayersTrace.Entry` or `WindowManagerTrace.Entry`. +Start by defining common or error prone transitions using `TransitionRunner`. +```kotlin +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class MyTest( + beginRotationName: String, + beginRotation: Int +) : NonRotationTestBase(beginRotationName, beginRotation) { + init { + mTestApp = MyAppHelper(InstrumentationRegistry.getInstrumentation()) + } -```java - // Example adds an assertion to the check if layer is hidden by parent. - Result isHiddenByParent(String layerName) { - // Result should contain a details if assertion fails for any reason - // such as if layer is not found or layer is not hidden by parent - // or layer has no parent. - // ... + override val transitionToRun: TransitionRunner + get() = TransitionRunner.newBuilder() + .withTag("myTest") + .recordAllRuns() + .runBefore { device.pressHome() } + .runBefore { device.waitForIdle() } + .run { testApp.open() } + .runAfter{ testApp.exit() } + .repeat(2) + .includeJankyRuns() + .build() + + @Test + fun myWMTest() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAppWindow(MyTestApp) + .forAllEntries() + } } -``` -Then add a function to the trace subject `LayersTraceSubject` or `WmTraceSubject` which will add the assertion for testing. When the assertion is evaluated, the trace will first be filtered then the assertion will be applied to the remaining entries. -```java - public LayersTraceSubject isHiddenByParent(String layerName) { - mChecker.add(entry -> entry.isHiddenByParent(layerName), - "isHiddenByParent(" + layerName + ")"); - return this; + @Test + fun mySFTest() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer(MyTestApp) + .forAllEntries() + } } +} ``` - -To use the new assertion: -```java - // Check if "Chrome" layer is hidden by parent in the first trace entry. - assertThat(result).isHiddenByParent("Chrome").inTheBeginning(); -```
\ No newline at end of file diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp index 43387fc054b5..e3b6db08c503 100644 --- a/tools/stats_log_api_gen/Android.bp +++ b/tools/stats_log_api_gen/Android.bp @@ -121,26 +121,10 @@ cc_library { ], target: { android: { - shared_libs: [ - "libstatssocket", - "libstatspull", - ], - export_shared_lib_headers: [ - "libstatssocket", - "libstatspull", - ], + shared_libs: ["libstatssocket"], }, host: { - static_libs: [ - "libstatssocket", - "libstatspull", - "statsd-aidl-ndk_platform", - ], - shared_libs: ["libbinder_ndk"], - export_static_lib_headers: [ - "libstatssocket", - "libstatspull", - ], + static_libs: ["libstatssocket"], }, }, } diff --git a/tools/stats_log_api_gen/native_writer.cpp b/tools/stats_log_api_gen/native_writer.cpp index 21e88b360dcd..0c6c0099e459 100644 --- a/tools/stats_log_api_gen/native_writer.cpp +++ b/tools/stats_log_api_gen/native_writer.cpp @@ -82,77 +82,21 @@ static void write_annotations(FILE* out, int argIndex, } } -static int write_native_method_body(FILE* out, vector<java_type_t>& signature, - const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet, - const AtomDecl& attributionDecl) { - int argIndex = 1; - fprintf(out, " AStatsEvent_setAtomId(event, code);\n"); - write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet, "AStatsEvent_", - "event, "); - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - switch (*arg) { - case JAVA_TYPE_ATTRIBUTION_CHAIN: { - const char* uidName = attributionDecl.fields.front().name.c_str(); - const char* tagName = attributionDecl.fields.back().name.c_str(); - fprintf(out, - " AStatsEvent_writeAttributionChain(event, " - "reinterpret_cast<const uint32_t*>(%s), %s.data(), " - "static_cast<uint8_t>(%s_length));\n", - uidName, tagName, uidName); - break; - } - case JAVA_TYPE_BYTE_ARRAY: - fprintf(out, - " AStatsEvent_writeByteArray(event, " - "reinterpret_cast<const uint8_t*>(arg%d.arg), " - "arg%d.arg_length);\n", - argIndex, argIndex); - break; - case JAVA_TYPE_BOOLEAN: - fprintf(out, " AStatsEvent_writeBool(event, arg%d);\n", argIndex); - break; - case JAVA_TYPE_INT: // Fall through. - case JAVA_TYPE_ENUM: - fprintf(out, " AStatsEvent_writeInt32(event, arg%d);\n", argIndex); - break; - case JAVA_TYPE_FLOAT: - fprintf(out, " AStatsEvent_writeFloat(event, arg%d);\n", argIndex); - break; - case JAVA_TYPE_LONG: - fprintf(out, " AStatsEvent_writeInt64(event, arg%d);\n", argIndex); - break; - case JAVA_TYPE_STRING: - fprintf(out, " AStatsEvent_writeString(event, arg%d);\n", argIndex); - break; - default: - // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIRS - fprintf(stderr, "Encountered unsupported type."); - return 1; - } - write_annotations(out, argIndex, fieldNumberToAtomDeclSet, "AStatsEvent_", - "event, "); - argIndex++; - } - return 0; -} - -static int write_native_stats_write_methods(FILE* out, const SignatureInfoMap& signatureInfoMap, +static int write_native_stats_write_methods(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl, const bool supportQ) { fprintf(out, "\n"); - for (auto signatureInfoMapIt = signatureInfoMap.begin(); - signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) { + for (auto signatureInfoMapIt = atoms.signatureInfoMap.begin(); + signatureInfoMapIt != atoms.signatureInfoMap.end(); signatureInfoMapIt++) { vector<java_type_t> signature = signatureInfoMapIt->first; const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second; // Key value pairs not supported in native. if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) { continue; } - write_native_method_signature(out, "int stats_write(", signature, attributionDecl, " {"); + write_native_method_signature(out, "int stats_write", signature, attributionDecl, " {"); - // Write method body. + int argIndex = 1; if (supportQ) { - int argIndex = 1; fprintf(out, " StatsEventCompat event;\n"); fprintf(out, " event.setAtomId(code);\n"); write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet, "event.", ""); @@ -194,36 +138,78 @@ static int write_native_stats_write_methods(FILE* out, const SignatureInfoMap& s write_annotations(out, argIndex, fieldNumberToAtomDeclSet, "event.", ""); argIndex++; } - fprintf(out, " return event.writeToSocket();\n"); // end method body. + fprintf(out, " return event.writeToSocket();\n"); } else { fprintf(out, " AStatsEvent* event = AStatsEvent_obtain();\n"); - int ret = write_native_method_body(out, signature, fieldNumberToAtomDeclSet, - attributionDecl); - if (ret != 0) { - return ret; + fprintf(out, " AStatsEvent_setAtomId(event, code);\n"); + write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet, "AStatsEvent_", + "event, "); + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + switch (*arg) { + case JAVA_TYPE_ATTRIBUTION_CHAIN: { + const char* uidName = attributionDecl.fields.front().name.c_str(); + const char* tagName = attributionDecl.fields.back().name.c_str(); + fprintf(out, + " AStatsEvent_writeAttributionChain(event, " + "reinterpret_cast<const uint32_t*>(%s), %s.data(), " + "static_cast<uint8_t>(%s_length));\n", + uidName, tagName, uidName); + break; + } + case JAVA_TYPE_BYTE_ARRAY: + fprintf(out, + " AStatsEvent_writeByteArray(event, " + "reinterpret_cast<const uint8_t*>(arg%d.arg), " + "arg%d.arg_length);\n", + argIndex, argIndex); + break; + case JAVA_TYPE_BOOLEAN: + fprintf(out, " AStatsEvent_writeBool(event, arg%d);\n", argIndex); + break; + case JAVA_TYPE_INT: // Fall through. + case JAVA_TYPE_ENUM: + fprintf(out, " AStatsEvent_writeInt32(event, arg%d);\n", argIndex); + break; + case JAVA_TYPE_FLOAT: + fprintf(out, " AStatsEvent_writeFloat(event, arg%d);\n", argIndex); + break; + case JAVA_TYPE_LONG: + fprintf(out, " AStatsEvent_writeInt64(event, arg%d);\n", argIndex); + break; + case JAVA_TYPE_STRING: + fprintf(out, " AStatsEvent_writeString(event, arg%d);\n", argIndex); + break; + default: + // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIRS + fprintf(stderr, "Encountered unsupported type."); + return 1; + } + write_annotations(out, argIndex, fieldNumberToAtomDeclSet, "AStatsEvent_", + "event, "); + argIndex++; } fprintf(out, " const int ret = AStatsEvent_write(event);\n"); fprintf(out, " AStatsEvent_release(event);\n"); - fprintf(out, " return ret;\n"); // end method body. + fprintf(out, " return ret;\n"); } - fprintf(out, "}\n\n"); // end method. + fprintf(out, "}\n\n"); } return 0; } -static void write_native_stats_write_non_chained_methods(FILE* out, - const SignatureInfoMap& signatureInfoMap, +static void write_native_stats_write_non_chained_methods(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl) { fprintf(out, "\n"); - for (auto signature_it = signatureInfoMap.begin(); - signature_it != signatureInfoMap.end(); signature_it++) { + for (auto signature_it = atoms.nonChainedSignatureInfoMap.begin(); + signature_it != atoms.nonChainedSignatureInfoMap.end(); signature_it++) { vector<java_type_t> signature = signature_it->first; // Key value pairs not supported in native. if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) { continue; } - write_native_method_signature(out, "int stats_write_non_chained(", signature, + write_native_method_signature(out, "int stats_write_non_chained", signature, attributionDecl, " {"); vector<java_type_t> newSignature; @@ -249,34 +235,6 @@ static void write_native_stats_write_non_chained_methods(FILE* out, } } -static int write_native_build_stats_event_methods(FILE* out, - const SignatureInfoMap& signatureInfoMap, - const AtomDecl& attributionDecl) { - fprintf(out, "\n"); - for (auto signatureInfoMapIt = signatureInfoMap.begin(); - signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) { - vector<java_type_t> signature = signatureInfoMapIt->first; - const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second; - // Key value pairs not supported in native. - if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) { - continue; - } - write_native_method_signature(out, "void addAStatsEvent(AStatsEventList* pulled_data, ", - signature, attributionDecl, " {"); - - fprintf(out, " AStatsEvent* event = AStatsEventList_addStatsEvent(pulled_data);\n"); - int ret = write_native_method_body(out, signature, fieldNumberToAtomDeclSet, - attributionDecl); - if (ret != 0) { - return ret; - } - fprintf(out, " AStatsEvent_build(event);\n"); // end method body. - - fprintf(out, "}\n\n"); // end method. - } - return 0; -} - static void write_native_method_header(FILE* out, const string& methodName, const SignatureInfoMap& signatureInfoMap, const AtomDecl& attributionDecl) { @@ -304,22 +262,13 @@ int write_stats_log_cpp(FILE* out, const Atoms& atoms, const AtomDecl& attributi fprintf(out, "#include <StatsEventCompat.h>\n"); } else { fprintf(out, "#include <stats_event.h>\n"); - - if (!atoms.pulledAtomsSignatureInfoMap.empty()) { - fprintf(out, "#include <stats_pull_atom_callback.h>\n"); - } } - - fprintf(out, "\n"); write_namespace(out, cppNamespace); - write_native_stats_write_methods(out, atoms.signatureInfoMap, attributionDecl, supportQ); - write_native_stats_write_non_chained_methods(out, atoms.nonChainedSignatureInfoMap, - attributionDecl); - write_native_build_stats_event_methods(out, atoms.pulledAtomsSignatureInfoMap, - attributionDecl); + write_native_stats_write_methods(out, atoms, attributionDecl, supportQ); + write_native_stats_write_non_chained_methods(out, atoms, attributionDecl); // Print footer fprintf(out, "\n"); @@ -339,9 +288,6 @@ int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl& attrib fprintf(out, "#include <vector>\n"); fprintf(out, "#include <map>\n"); fprintf(out, "#include <set>\n"); - if (!atoms.pulledAtomsSignatureInfoMap.empty()) { - fprintf(out, "#include <stats_pull_atom_callback.h>\n"); - } fprintf(out, "\n"); write_namespace(out, cppNamespace); @@ -391,22 +337,12 @@ int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl& attrib fprintf(out, "//\n"); fprintf(out, "// Write methods\n"); fprintf(out, "//\n"); - write_native_method_header(out, "int stats_write(", atoms.signatureInfoMap, attributionDecl); - fprintf(out, "\n"); + write_native_method_header(out, "int stats_write", atoms.signatureInfoMap, attributionDecl); fprintf(out, "//\n"); fprintf(out, "// Write flattened methods\n"); fprintf(out, "//\n"); - write_native_method_header(out, "int stats_write_non_chained(", atoms.nonChainedSignatureInfoMap, - attributionDecl); - fprintf(out, "\n"); - - // Print pulled atoms methods. - fprintf(out, "//\n"); - fprintf(out, "// Add AStatsEvent methods\n"); - fprintf(out, "//\n"); - write_native_method_header(out, "void addAStatsEvent(AStatsEventList* pulled_data, ", - atoms.pulledAtomsSignatureInfoMap, + write_native_method_header(out, "int stats_write_non_chained", atoms.nonChainedSignatureInfoMap, attributionDecl); fprintf(out, "\n"); diff --git a/tools/stats_log_api_gen/utils.cpp b/tools/stats_log_api_gen/utils.cpp index 4b3734053421..abb89133e58e 100644 --- a/tools/stats_log_api_gen/utils.cpp +++ b/tools/stats_log_api_gen/utils.cpp @@ -182,10 +182,10 @@ void write_native_atom_constants(FILE* out, const Atoms& atoms, const AtomDecl& fprintf(out, "\n"); } -void write_native_method_signature(FILE* out, const string& signaturePrefix, +void write_native_method_signature(FILE* out, const string& methodName, const vector<java_type_t>& signature, const AtomDecl& attributionDecl, const string& closer) { - fprintf(out, "%sint32_t code", signaturePrefix.c_str()); + fprintf(out, "%s(int32_t code", methodName.c_str()); int argIndex = 1; for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end(); arg++) { diff --git a/tools/stats_log_api_gen/utils.h b/tools/stats_log_api_gen/utils.h index 42dc90eb79dc..73e0cb838227 100644 --- a/tools/stats_log_api_gen/utils.h +++ b/tools/stats_log_api_gen/utils.h @@ -59,7 +59,7 @@ void write_closing_namespace(FILE* out, const string& cppNamespaces); void write_native_atom_constants(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl); -void write_native_method_signature(FILE* out, const string& signaturePrefix, +void write_native_method_signature(FILE* out, const string& methodName, const vector<java_type_t>& signature, const AtomDecl& attributionDecl, const string& closer); |