diff options
author | chrome-bot <chrome-bot@chromium.org> | 2024-05-07 05:16:56 -0700 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2024-05-10 00:47:08 +0000 |
commit | 2fa54e63cbb6acbb67e162d831fa97bace5e01a9 (patch) | |
tree | d4dbcbcc2953ef25112356c039543ca15b34340f | |
parent | f93c8c501293b12089e5afbdf87589857e9541a2 (diff) | |
parent | db41af4bab810cbaa4e6ab2a64aaaa9ccf2ac16b (diff) | |
download | libchrome-upstream-main.tar.gz |
Automated commit: libchrome r1297392 uprevupstream-main
Merge with upstream commit db41af4bab810cbaa4e6ab2a64aaaa9ccf2ac16b
BUG=None
TEST=sudo emerge libchrome
Cq-Depend: chromium:5528177
Change-Id: Ieae5a8e1ce89d8a1e2b3c060e5ebd1bafc8d08c1
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/libchrome/+/5521313
Commit-Queue: Grace Cham <hscham@chromium.org>
Reviewed-by: Grace Cham <hscham@chromium.org>
Tested-by: Jae Hoon Kim <kimjae@chromium.org>
Reviewed-by: Jae Hoon Kim <kimjae@chromium.org>
20 files changed, 422 insertions, 179 deletions
@@ -1 +1 @@ -1296734 +1297392 diff --git a/base/android/java/src/org/chromium/base/cached_flags/CachedFlagUtils.java b/base/android/java/src/org/chromium/base/cached_flags/CachedFlagUtils.java index 7ee79a5d83..453dbd4c68 100644 --- a/base/android/java/src/org/chromium/base/cached_flags/CachedFlagUtils.java +++ b/base/android/java/src/org/chromium/base/cached_flags/CachedFlagUtils.java @@ -15,25 +15,30 @@ import java.util.List; */ public class CachedFlagUtils { /** Caches flags that must take effect on startup but are set via native code. */ - public static void cacheNativeFlags(List<CachedFlag> featuresToCache) { + public static void cacheNativeFlags(List<CachedFlag>... listsOfFeaturesToCache) { // Batch the updates into a single apply() call to avoid calling the expensive // SharedPreferencesImpl$EditorImpl.commitToMemory() method many times unnecessarily. final SharedPreferences.Editor editor = CachedFlagsSharedPreferences.getInstance().getEditor(); - for (CachedFlag feature : featuresToCache) { - feature.writeCacheValueToEditor(editor); + for (final List<CachedFlag> featuresToCache : listsOfFeaturesToCache) { + for (CachedFlag feature : featuresToCache) { + feature.writeCacheValueToEditor(editor); + } } editor.apply(); } /** Caches flags that must take effect on startup but are set via native code. */ - public static void cacheFieldTrialParameters(List<CachedFieldTrialParameter> parameters) { + public static void cacheFieldTrialParameters( + List<CachedFieldTrialParameter>... listsOfParameters) { // Batch the updates into a single apply() call to avoid calling the expensive // SharedPreferencesImpl$EditorImpl.commitToMemory() method many times unnecessarily. final SharedPreferences.Editor editor = CachedFlagsSharedPreferences.getInstance().getEditor(); - for (final CachedFieldTrialParameter parameter : parameters) { - parameter.writeCacheValueToEditor(editor); + for (final List<CachedFieldTrialParameter> parameters : listsOfParameters) { + for (final CachedFieldTrialParameter parameter : parameters) { + parameter.writeCacheValueToEditor(editor); + } } editor.apply(); } diff --git a/base/memory/discardable_shared_memory.cc b/base/memory/discardable_shared_memory.cc index 42617c8176..f5d96a5204 100644 --- a/base/memory/discardable_shared_memory.cc +++ b/base/memory/discardable_shared_memory.cc @@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40284755): Remove this and spanify to fix the errors. -#pragma allow_unsafe_buffers -#endif - #include "base/memory/discardable_shared_memory.h" #include <stdint.h> @@ -145,15 +140,11 @@ bool UseAshmemUnpinningForDiscardableMemory() { } // namespace -DiscardableSharedMemory::DiscardableSharedMemory() - : mapped_size_(0), locked_page_count_(0) { -} +DiscardableSharedMemory::DiscardableSharedMemory() = default; DiscardableSharedMemory::DiscardableSharedMemory( UnsafeSharedMemoryRegion shared_memory_region) - : shared_memory_region_(std::move(shared_memory_region)), - mapped_size_(0), - locked_page_count_(0) {} + : shared_memory_region_(std::move(shared_memory_region)) {} DiscardableSharedMemory::~DiscardableSharedMemory() = default; @@ -173,10 +164,8 @@ bool DiscardableSharedMemory::CreateAndMap(size_t size) { if (!shared_memory_mapping_.IsValid()) return false; - mapped_size_ = shared_memory_mapping_.mapped_size() - - AlignToPageSize(sizeof(SharedState)); - - locked_page_count_ = AlignToPageSize(mapped_size_) / base::GetPageSize(); + locked_page_count_ = + AlignToPageSize(mapped_memory().size()) / base::GetPageSize(); #if DCHECK_IS_ON() for (size_t page = 0; page < locked_page_count_; ++page) locked_pages_.insert(page); @@ -200,10 +189,8 @@ bool DiscardableSharedMemory::Map(size_t size) { if (!shared_memory_mapping_.IsValid()) return false; - mapped_size_ = shared_memory_mapping_.mapped_size() - - AlignToPageSize(sizeof(SharedState)); - - locked_page_count_ = AlignToPageSize(mapped_size_) / base::GetPageSize(); + locked_page_count_ = + AlignToPageSize(mapped_memory().size()) / base::GetPageSize(); #if DCHECK_IS_ON() for (size_t page = 0; page < locked_page_count_; ++page) locked_pages_.insert(page); @@ -221,7 +208,6 @@ bool DiscardableSharedMemory::Unmap() { #if DCHECK_IS_ON() locked_pages_.clear(); #endif - mapped_size_ = 0; return true; } @@ -258,12 +244,12 @@ DiscardableSharedMemory::LockResult DiscardableSharedMemory::Lock( // Zero for length means "everything onward". if (!length) - length = AlignToPageSize(mapped_size_) - offset; + length = AlignToPageSize(mapped_memory().size()) - offset; size_t start = offset / base::GetPageSize(); size_t end = start + length / base::GetPageSize(); DCHECK_LE(start, end); - DCHECK_LE(end, AlignToPageSize(mapped_size_) / base::GetPageSize()); + DCHECK_LE(end, AlignToPageSize(mapped_memory().size()) / base::GetPageSize()); // Add pages to |locked_page_count_|. // Note: Locking a page that is already locked is an error. @@ -299,9 +285,8 @@ DiscardableSharedMemory::LockResult DiscardableSharedMemory::Lock( // // For more information, see // https://bugs.chromium.org/p/chromium/issues/detail?id=823915. - madvise(static_cast<char*>(shared_memory_mapping_.memory()) + - AlignToPageSize(sizeof(SharedState)), - AlignToPageSize(mapped_size_), MADV_FREE_REUSE); + base::span<uint8_t> mapped = mapped_memory(); + madvise(mapped.data(), AlignToPageSize(mapped.size()), MADV_FREE_REUSE); return DiscardableSharedMemory::SUCCESS; #else return DiscardableSharedMemory::SUCCESS; @@ -316,9 +301,9 @@ void DiscardableSharedMemory::Unlock(size_t offset, size_t length) { DFAKE_SCOPED_LOCK(thread_collision_warner_); // Passing zero for |length| means "everything onward". Note that |length| may - // still be zero after this calculation, e.g. if |mapped_size_| is zero. + // still be zero after this calculation, e.g. if the mapped size is zero. if (!length) - length = AlignToPageSize(mapped_size_) - offset; + length = AlignToPageSize(mapped_memory().size()) - offset; DCHECK(shared_memory_mapping_.IsValid()); @@ -329,7 +314,7 @@ void DiscardableSharedMemory::Unlock(size_t offset, size_t length) { size_t start = offset / base::GetPageSize(); size_t end = start + length / base::GetPageSize(); DCHECK_LE(start, end); - DCHECK_LE(end, AlignToPageSize(mapped_size_) / base::GetPageSize()); + DCHECK_LE(end, AlignToPageSize(mapped_memory().size()) / base::GetPageSize()); // Remove pages from |locked_page_count_|. // Note: Unlocking a page that is not locked is an error. @@ -369,9 +354,14 @@ void DiscardableSharedMemory::Unlock(size_t offset, size_t length) { last_known_usage_ = current_time; } -void* DiscardableSharedMemory::memory() const { - return static_cast<uint8_t*>(shared_memory_mapping_.memory()) + - AlignToPageSize(sizeof(SharedState)); +span<uint8_t> DiscardableSharedMemory::memory() const { + return shared_memory_mapping_.GetMemoryAsSpan<uint8_t>().subspan( + AlignToPageSize(sizeof(SharedState))); +} + +span<uint8_t> DiscardableSharedMemory::mapped_memory() const { + return shared_memory_mapping_.mapped_memory().subspan( + AlignToPageSize(sizeof(SharedState))); } bool DiscardableSharedMemory::Purge(Time current_time) { @@ -420,17 +410,16 @@ bool DiscardableSharedMemory::Purge(Time current_time) { // Advise the kernel to remove resources associated with purged pages. // Subsequent accesses of memory pages will succeed, but might result in // zero-fill-on-demand pages. - if (madvise(static_cast<char*>(shared_memory_mapping_.memory()) + - AlignToPageSize(sizeof(SharedState)), - AlignToPageSize(mapped_size_), MADV_PURGE_ARGUMENT)) { + base::span<uint8_t> map = mapped_memory(); + if (madvise(map.data(), AlignToPageSize(map.size()), MADV_PURGE_ARGUMENT)) { DPLOG(ERROR) << "madvise() failed"; } #elif BUILDFLAG(IS_WIN) // On Windows, discarded pages are not returned to the system immediately and // not guaranteed to be zeroed when returned to the application. - char* address = static_cast<char*>(shared_memory_mapping_.memory()) + - AlignToPageSize(sizeof(SharedState)); - size_t length = AlignToPageSize(mapped_size_); + base::span<uint8_t> mapped = mapped_memory(); + uint8_t* address = mapped.data(); + size_t length = AlignToPageSize(mapped.size()); DWORD ret = DiscardVirtualMemory(address, length); // DiscardVirtualMemory is buggy in Win10 SP0, so fall back to MEM_RESET on @@ -442,11 +431,10 @@ bool DiscardableSharedMemory::Purge(Time current_time) { #elif BUILDFLAG(IS_FUCHSIA) // De-commit via our VMAR, rather than relying on the VMO handle, since the // handle may have been closed after the memory was mapped into this process. - uint64_t address_int = reinterpret_cast<uint64_t>( - static_cast<char*>(shared_memory_mapping_.memory()) + - AlignToPageSize(sizeof(SharedState))); + base::span<uint8_t> mapped = mapped_memory(); + uint64_t address_int = reinterpret_cast<uint64_t>(mapped.data()); zx_status_t status = zx::vmar::root_self()->op_range( - ZX_VMO_OP_DECOMMIT, address_int, AlignToPageSize(mapped_size_), nullptr, + ZX_VMO_OP_DECOMMIT, address_int, AlignToPageSize(mapped.size()), nullptr, 0); ZX_DCHECK(status == ZX_OK, status) << "zx_vmo_op_range(ZX_VMO_OP_DECOMMIT)"; #endif // BUILDFLAG(IS_FUCHSIA) @@ -455,36 +443,6 @@ bool DiscardableSharedMemory::Purge(Time current_time) { return true; } -void DiscardableSharedMemory::ReleaseMemoryIfPossible(size_t offset, - size_t length) { -#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL) -// Linux and Android provide MADV_REMOVE which is preferred as it has a -// behavior that can be verified in tests. Other POSIX flavors (MacOSX, BSDs), -// provide MADV_FREE which has the same result but memory is purged lazily. -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) -#define MADV_PURGE_ARGUMENT MADV_REMOVE -#elif BUILDFLAG(IS_APPLE) -// MADV_FREE_REUSABLE is similar to MADV_FREE, but also marks the pages with the -// reusable bit, which allows both Activity Monitor and memory-infra to -// correctly track the pages. -#define MADV_PURGE_ARGUMENT MADV_FREE_REUSABLE -#else // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) -#define MADV_PURGE_ARGUMENT MADV_FREE -#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || - // BUILDFLAG(IS_ANDROID) - // Advise the kernel to remove resources associated with purged pages. - // Subsequent accesses of memory pages will succeed, but might result in - // zero-fill-on-demand pages. - if (madvise(static_cast<char*>(shared_memory_mapping_.memory()) + offset, - length, MADV_PURGE_ARGUMENT)) { - DPLOG(ERROR) << "madvise() failed"; - } -#else // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL) - partition_alloc::DiscardSystemPages( - static_cast<char*>(shared_memory_mapping_.memory()) + offset, length); -#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL) -} - bool DiscardableSharedMemory::IsMemoryResident() const { DCHECK(shared_memory_mapping_.IsValid()); diff --git a/base/memory/discardable_shared_memory.h b/base/memory/discardable_shared_memory.h index 73ae10b311..8006deb78a 100644 --- a/base/memory/discardable_shared_memory.h +++ b/base/memory/discardable_shared_memory.h @@ -8,6 +8,7 @@ #include <stddef.h> #include "base/base_export.h" +#include "base/containers/span.h" #include "base/dcheck_is_on.h" #include "base/memory/shared_memory_mapping.h" #include "base/memory/unsafe_shared_memory_region.h" @@ -71,8 +72,15 @@ class BASE_EXPORT DiscardableSharedMemory { // not mapped. bool Unmap(); - // The actual size of the mapped memory (may be larger than requested). - size_t mapped_size() const { return mapped_size_; } + // The actual size of the mapped memory (may be larger than requested). It is + // 0 when the memory has not been mapped via `Map()`. + size_t mapped_size() const { + if (shared_memory_mapping_.IsValid()) { + return mapped_memory().size(); + } else { + return 0u; + } + } // Returns a duplicated shared memory region for this DiscardableSharedMemory // object. @@ -109,22 +117,20 @@ class BASE_EXPORT DiscardableSharedMemory { // Passing 0 for |length| means "everything onward". void Unlock(size_t offset, size_t length); - // Gets a pointer to the opened discardable memory space. Discardable memory + // Gets a span over the opened discardable memory space. Discardable memory // must have been mapped via Map(). - void* memory() const; + // + // This gives the logical memory region, matching the size of what was + // requested. The actual mapped memory may be larger due to system alignment + // requirements. See `SharedMemoryMapping::size()` vs + // `SharedMemoryMapping::mapped_size()`. + span<uint8_t> memory() const; // Returns the last known usage time for DiscardableSharedMemory object. This // may be earlier than the "true" usage time when memory has been used by a // different process. Returns NULL time if purged. Time last_known_usage() const { return last_known_usage_; } - // Releases any allocated pages in the specified range, if supported by the - // platform. Address space in the specified range continues to be reserved. - // The memory is not guaranteed to be released immediately. - // |offset| and |length| are both in bytes. |offset| and |length| must both be - // page aligned. - void ReleaseMemoryIfPossible(size_t offset, size_t length); - // This returns true and sets |last_known_usage_| to 0 if // DiscardableSharedMemory object was successfully purged. Purging can fail // for two reasons; object might be locked or our last known usage timestamp @@ -166,6 +172,12 @@ class BASE_EXPORT DiscardableSharedMemory { #endif private: + // Returns the full mapped memory region after the internal bookkeeping + // header. This may be larger than the region exposed through `memory()` due + // to platform alignment requirements. Discardable memory must have been + // mapped via Map(). + span<uint8_t> mapped_memory() const; + // LockPages/UnlockPages are platform-native discardable page management // helper functions. Both expect |offset| to be specified relative to the // base address at which |memory| is mapped, and that |offset| and |length| @@ -184,8 +196,7 @@ class BASE_EXPORT DiscardableSharedMemory { UnsafeSharedMemoryRegion shared_memory_region_; WritableSharedMemoryMapping shared_memory_mapping_; - size_t mapped_size_; - size_t locked_page_count_; + size_t locked_page_count_ = 0u; #if DCHECK_IS_ON() std::set<size_t> locked_pages_; #endif diff --git a/base/memory/discardable_shared_memory_unittest.cc b/base/memory/discardable_shared_memory_unittest.cc index 9c7d495799..0853cf8ac0 100644 --- a/base/memory/discardable_shared_memory_unittest.cc +++ b/base/memory/discardable_shared_memory_unittest.cc @@ -2,11 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/memory/discardable_shared_memory.h" + #include <fcntl.h> #include <stdint.h> +#include <algorithm> + #include "base/files/scoped_file.h" -#include "base/memory/discardable_shared_memory.h" #include "base/memory/page_size.h" #include "base/memory/shared_memory_tracker.h" #include "base/tracing_buildflags.h" @@ -434,7 +437,7 @@ TEST(DiscardableSharedMemoryTest, ZeroFilledPagesAfterPurge) { ASSERT_TRUE(rv); // Initialize all memory to '0xaa'. - memset(memory2.memory(), 0xaa, kDataSize); + std::ranges::fill(memory2.memory(), 0xaa); // Unlock memory. memory2.SetNow(Time::FromSecondsSinceUnixEpoch(1)); @@ -450,7 +453,7 @@ TEST(DiscardableSharedMemoryTest, ZeroFilledPagesAfterPurge) { // Check that reading memory after it has been purged is returning // zero-filled pages. uint8_t expected_data[kDataSize] = {}; - EXPECT_EQ(memcmp(memory2.memory(), expected_data, kDataSize), 0); + EXPECT_EQ(base::span(expected_data), memory2.memory()); } #endif diff --git a/base/memory/shared_memory_mapping.h b/base/memory/shared_memory_mapping.h index d546deb538..42d53a14f3 100644 --- a/base/memory/shared_memory_mapping.h +++ b/base/memory/shared_memory_mapping.h @@ -242,6 +242,18 @@ class BASE_EXPORT WritableSharedMemoryMapping : public SharedMemoryMapping { size_t size, const UnguessableToken& guid, SharedMemoryMapper* mapper); + + friend class DiscardableSharedMemory; + // Returns a span over the entire mapped memory, which may be more than the + // logical requested memory. Bytes outside of the logical size should not be + // used. + span<uint8_t> mapped_memory() const { + if (!IsValid()) { + return span<uint8_t>(); + } + return UNSAFE_BUFFERS( + span(static_cast<uint8_t*>(raw_memory_ptr()), mapped_size())); + } }; } // namespace base diff --git a/base/os_compat_android.cc b/base/os_compat_android.cc index d0f920be4a..8bdd84a558 100644 --- a/base/os_compat_android.cc +++ b/base/os_compat_android.cc @@ -35,7 +35,8 @@ int futimes(int fd, const struct timeval tv_ptr[2]) { ts[0].tv_nsec = tv[0].tv_usec * 1000; ts[1].tv_sec = tv[1].tv_sec; ts[1].tv_nsec = tv[1].tv_usec * 1000; - return base::checked_cast<int>(syscall(__NR_utimensat, fd, NULL, ts, 0)); + return base::checked_cast<int>( + syscall(__NR_utimensat, fd, NULL, ts.data(), 0)); } #endif diff --git a/base/task/sequence_manager/thread_controller.cc b/base/task/sequence_manager/thread_controller.cc index 5bf8ce736d..dd2cc559ed 100644 --- a/base/task/sequence_manager/thread_controller.cc +++ b/base/task/sequence_manager/thread_controller.cc @@ -331,8 +331,8 @@ ThreadController::RunLevelTracker::RunLevel::RunLevel(RunLevel&& other) = void ThreadController::RunLevelTracker::RunLevel::LogPercentageMetric( const char* name, int percentage) { - UmaHistogramPercentage( - base::StrCat({name, base::StrCat({".", GetThreadName()})}), percentage); + UmaHistogramPercentage(base::StrCat({name, ".", GetThreadName()}), + percentage); } void ThreadController::RunLevelTracker::RunLevel::LogPercentageMetric( diff --git a/base/task/sequence_manager/thread_controller.h b/base/task/sequence_manager/thread_controller.h index 6ee818e299..47bb7b92c3 100644 --- a/base/task/sequence_manager/thread_controller.h +++ b/base/task/sequence_manager/thread_controller.h @@ -279,7 +279,7 @@ class BASE_EXPORT ThreadController { void EnableTimeKeeperMetrics( const char* thread_name, - bool wall_time_based_metrics_for_testing_enabled); + bool wall_time_based_metrics_enabled_for_testing); // Observes changes of state sent as trace-events so they can be tested. class TraceObserverForTesting { diff --git a/base/test/android/javatests/src/org/chromium/base/test/transit/ActivityElement.java b/base/test/android/javatests/src/org/chromium/base/test/transit/ActivityElement.java new file mode 100644 index 0000000000..f21f33e4d1 --- /dev/null +++ b/base/test/android/javatests/src/org/chromium/base/test/transit/ActivityElement.java @@ -0,0 +1,113 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.base.test.transit; + +import android.app.Activity; + +import androidx.annotation.Nullable; + +import org.chromium.base.ActivityState; +import org.chromium.base.ApplicationStatus; +import org.chromium.base.supplier.Supplier; + +import java.util.List; +import java.util.Set; + +/** + * Represents an {@link Activity} that needs to exist to consider the Station active. + * + * <p>Subclasses are treated as a different type. + * + * @param <ActivityT> exact type of Activity expected + */ +public class ActivityElement<ActivityT extends Activity> + implements ElementInState, Supplier<ActivityT> { + private final Class<ActivityT> mActivityClass; + private final String mId; + private final ActivityExistsCondition mEnterCondition; + + ActivityElement(Class<ActivityT> activityClass) { + mActivityClass = activityClass; + mId = "AE/" + activityClass.getCanonicalName(); + mEnterCondition = new ActivityExistsCondition(); + } + + @Override + public String getId() { + return mId; + } + + @Override + public Condition getEnterCondition() { + return mEnterCondition; + } + + @Override + public @Nullable Condition getExitCondition(Set<String> destinationElementIds) { + return null; + } + + @Override + public String toString() { + return mId; + } + + @Override + public ActivityT get() { + return mEnterCondition.mMatchedActivity; + } + + @Override + public boolean hasValue() { + return mEnterCondition.mMatchedActivity != null; + } + + private class ActivityExistsCondition extends InstrumentationThreadCondition { + private ActivityT mMatchedActivity; + + @Override + public ConditionStatus check() { + ActivityT candidate = null; + List<Activity> allActivities = ApplicationStatus.getRunningActivities(); + for (Activity activity : allActivities) { + if (mActivityClass.equals(activity.getClass())) { + ActivityT matched = mActivityClass.cast(activity); + if (candidate != null) { + return error("%s matched two Activities: %s, %s", this, candidate, matched); + } + candidate = matched; + } + } + mMatchedActivity = candidate; + if (mMatchedActivity == null) { + return notFulfilled("No Activity with expected class"); + } + + @ActivityState int state = ApplicationStatus.getStateForActivity(mMatchedActivity); + return whether( + state == ActivityState.RESUMED, + "matched: %s (state=%s)", + mMatchedActivity, + activityStateDescription(state)); + } + + @Override + public String buildDescription() { + return "Activity exists and is RESUMED: " + mActivityClass.getSimpleName(); + } + } + + private static String activityStateDescription(@ActivityState int state) { + return switch (state) { + case ActivityState.CREATED -> "CREATED"; + case ActivityState.STARTED -> "STARTED"; + case ActivityState.RESUMED -> "RESUMED"; + case ActivityState.PAUSED -> "PAUSED"; + case ActivityState.STOPPED -> "STOPPED"; + case ActivityState.DESTROYED -> "DESTROYED"; + default -> throw new IllegalStateException("Unexpected value: " + state); + }; + } +} diff --git a/base/test/android/javatests/src/org/chromium/base/test/transit/Elements.java b/base/test/android/javatests/src/org/chromium/base/test/transit/Elements.java index d5436ce004..1a590a44de 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/transit/Elements.java +++ b/base/test/android/javatests/src/org/chromium/base/test/transit/Elements.java @@ -4,6 +4,7 @@ package org.chromium.base.test.transit; +import android.app.Activity; import android.view.View; import org.hamcrest.Matcher; @@ -64,6 +65,13 @@ public class Elements { mElements = elements; } + /** Declare as an element an Android Activity of type |activityClass|. */ + public <T extends Activity> ActivityElement<T> declareActivity(Class<T> activityClass) { + ActivityElement<T> element = new ActivityElement<>(activityClass); + mElements.mElementsInState.add(element); + return element; + } + /** Declare as an element a View that matches |viewMatcher|. */ public ViewElementInState declareView(ViewElement viewElement) { ViewElementInState inState = new ViewElementInState(viewElement, /* gate= */ null); diff --git a/base/test/android/javatests/src/org/chromium/base/test/transit/LogicalElement.java b/base/test/android/javatests/src/org/chromium/base/test/transit/LogicalElement.java index b71b48d79c..652cb07e0f 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/transit/LogicalElement.java +++ b/base/test/android/javatests/src/org/chromium/base/test/transit/LogicalElement.java @@ -14,7 +14,7 @@ import java.util.concurrent.Callable; * * <p>LogicalElements should be declared by calling {@link * Elements.Builder#declareLogicalElement(LogicalElement)} passing in an instance created by one of - * the factory methods here such as {@link #sharedUiThreadLogicalElement(String, Callable)}. + * the factory methods here such as {@link #uiThreadLogicalElement(String, Callable)}. * * <p>Generates ENTER and EXIT Conditions for the ConditionalState to ensure the LogicalElement is * in the right state. @@ -29,9 +29,27 @@ public class LogicalElement implements ElementInState { @Nullable private Condition mExitCondition; /** + * Alias for {@link #unscopedUiThreadLogicalElement(String, Callable)} as the default way to + * declare LogicalElements. + */ + public static LogicalElement uiThreadLogicalElement( + String description, Callable<Boolean> checkFunction) { + return unscopedUiThreadLogicalElement(description, checkFunction); + } + + /** + * Alias for {@link #unscopedInstrumentationThreadLogicalElement(String, Callable)} as the + * default way to declare LogicalElements. + */ + public static LogicalElement instrumentationThreadLogicalElement( + String description, Callable<Boolean> checkFunction) { + return unscopedInstrumentationThreadLogicalElement(description, checkFunction); + } + + /** * Create a shared-scope LogicalElement that runs the check on the UI Thread. * - * <p>Unscoped LogicalElements wait for the function to be true as an ENTER Condition. It also + * <p>Shared LogicalElements wait for the function to be true as an ENTER Condition. It also * waits for the function to be false as an EXIT Condition when transitioning to a * ConditionalState that does not declare the LogicalElement too. */ diff --git a/base/trace_event/memory_infra_background_allowlist.cc b/base/trace_event/memory_infra_background_allowlist.cc index 84088f243b..524bc705ff 100644 --- a/base/trace_event/memory_infra_background_allowlist.cc +++ b/base/trace_event/memory_infra_background_allowlist.cc @@ -268,6 +268,8 @@ constexpr auto kAllocatorDumpNameAllowlist = "v8/main/heap/read_only_space", "v8/main/heap/shared_large_object_space", "v8/main/heap/shared_space", + "v8/main/heap/shared_trusted_large_object_space", + "v8/main/heap/shared_trusted_space", "v8/main/heap/trusted_space", "v8/main/heap/trusted_large_object_space", "v8/main/malloc", @@ -286,6 +288,8 @@ constexpr auto kAllocatorDumpNameAllowlist = "v8/utility/heap/read_only_space", "v8/utility/heap/shared_large_object_space", "v8/utility/heap/shared_space", + "v8/utility/heap/shared_trusted_large_object_space", + "v8/utility/heap/shared_trusted_space", "v8/utility/heap/trusted_space", "v8/utility/heap/trusted_large_object_space", "v8/utility/malloc", @@ -304,6 +308,8 @@ constexpr auto kAllocatorDumpNameAllowlist = "v8/workers/heap/read_only_space/isolate_0x?", "v8/workers/heap/shared_large_object_space/isolate_0x?", "v8/workers/heap/shared_space/isolate_0x?", + "v8/workers/heap/shared_trusted_large_object_space/isolate_0x?", + "v8/workers/heap/shared_trusted_space/isolate_0x?", "v8/workers/heap/trusted_space/isolate_0x?", "v8/workers/heap/trusted_large_object_space/isolate_0x?", "v8/workers/malloc/isolate_0x?", diff --git a/base/values.cc b/base/values.cc index d66a2e1adc..2ac910b6af 100644 --- a/base/values.cc +++ b/base/values.cc @@ -217,8 +217,9 @@ Value::Value(DoubleStorage storage) : data_(std::move(storage)) {} Value::DoubleStorage::DoubleStorage(double v) : v_(bit_cast<decltype(v_)>(v)) { if (!std::isfinite(v)) { - NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) " - << "values cannot be represented in JSON"; + DUMP_WILL_BE_NOTREACHED_NORETURN() + << "Non-finite (i.e. NaN or positive/negative infinity) " + << "values cannot be represented in JSON"; v_ = bit_cast<decltype(v_)>(0.0); } } diff --git a/build/install-build-deps.py b/build/install-build-deps.py index b321fffec0..3f0c4ef716 100755 --- a/build/install-build-deps.py +++ b/build/install-build-deps.py @@ -233,7 +233,6 @@ def dev_list(): "libsctp-dev", "libspeechd-dev", "libsqlite3-dev", - "libssl-dev", "libsystemd-dev", "libudev-dev", "libva-dev", @@ -326,6 +325,17 @@ def dev_list(): elif package_exists("lib32gcc1"): packages.append("lib32gcc1") + # TODO(b/339091434): Remove this workaround once this bug is fixed. This + # workaround ensures the newer libssl-dev is used to prevent package conficts. + apt_cache_cmd = ["apt-cache", "show", "libssl-dev"] + output = subprocess.check_output(apt_cache_cmd).decode() + pattern = re.compile(r'^Version: (.+?)$', re.M) + versions = re.findall(pattern, output) + if set(versions) == {"3.2.1-3", "3.0.10-1"}: + packages.append("libssl-dev=3.2.1-3") + else: + packages.append("libssl-dev") + return packages diff --git a/components/policy/core/common/default_chrome_apps_migrator.cc b/components/policy/core/common/default_chrome_apps_migrator.cc index 199636a2b6..7d95058dae 100644 --- a/components/policy/core/common/default_chrome_apps_migrator.cc +++ b/components/policy/core/common/default_chrome_apps_migrator.cc @@ -120,7 +120,8 @@ void DefaultChromeAppsMigrator::EnsurePolicyValueIsList( policies->Get(key::kExtensionInstallForcelist); PolicyMap::Entry policy_entry( forcelist_entry->level, forcelist_entry->scope, forcelist_entry->source, - base::Value(base::Value::Type::LIST), nullptr); + base::Value(base::Value::Type::LIST), /*external_data_fetcher=*/nullptr, + policies->GetPolicyDetails(policy_name)); // If `policy_value` has wrong type, add message before overriding value. if (policy_value) { policy_entry.AddMessage(PolicyMap::MessageType::kError, diff --git a/components/policy/core/common/policy_map.cc b/components/policy/core/common/policy_map.cc index b7d37e054c..5a1962a903 100644 --- a/components/policy/core/common/policy_map.cc +++ b/components/policy/core/common/policy_map.cc @@ -68,7 +68,8 @@ PolicyPriorityBrowser GetPriority( PolicyScope scope, bool cloud_policy_overrides_platform_policy, bool cloud_user_policy_overrides_cloud_machine_policy, - bool is_user_affiliated) { + bool is_user_affiliated, + const PolicyDetails* details) { switch (source) { case POLICY_SOURCE_ENTERPRISE_DEFAULT: return POLICY_PRIORITY_BROWSER_ENTERPRISE_DEFAULT; @@ -82,6 +83,11 @@ PolicyPriorityBrowser GetPriority( ? POLICY_PRIORITY_BROWSER_CLOUD_MACHINE_RAISED : POLICY_PRIORITY_BROWSER_CLOUD_MACHINE; } + // For policies that can only be set with managed account, raise the + // priority of correct source to highest. + if (details && details->scope == kSingleProfile) { + return POLICY_PRIORITY_BROWSER_CLOUD_USER_DOUBLE_RAISED; + } if (cloud_user_policy_overrides_cloud_machine_policy && is_user_affiliated) { // Raise the priority of cloud user policies only when the metapolicy @@ -120,11 +126,13 @@ PolicyMap::Entry::Entry( PolicyScope scope, PolicySource source, std::optional<base::Value> value, - std::unique_ptr<ExternalDataFetcher> external_data_fetcher) + std::unique_ptr<ExternalDataFetcher> external_data_fetcher, + const PolicyDetails* details) : level(level), scope(scope), source(source), external_data_fetcher(std::move(external_data_fetcher)), + details(details), value_(std::move(value)) {} PolicyMap::Entry::~Entry() = default; @@ -138,7 +146,8 @@ PolicyMap::Entry PolicyMap::Entry::DeepCopy() const { value_ ? std::make_optional<base::Value>(value_->Clone()) : std::nullopt, external_data_fetcher ? std::make_unique<ExternalDataFetcher>(*external_data_fetcher) - : nullptr); + : nullptr, + details); copy.ignored_ = ignored_; copy.message_ids_ = message_ids_; copy.is_default_value_ = is_default_value_; @@ -378,7 +387,7 @@ void PolicyMap::Set( std::optional<base::Value> value, std::unique_ptr<ExternalDataFetcher> external_data_fetcher) { Entry entry(level, scope, source, std::move(value), - std::move(external_data_fetcher)); + std::move(external_data_fetcher), GetPolicyDetails(policy)); Set(policy, std::move(entry)); } @@ -541,12 +550,17 @@ void PolicyMap::set_chrome_policy_details_callback_for_test( } bool PolicyMap::IsPolicyExternal(const std::string& policy) { - const PolicyDetails* policy_details = details_callback_.Run(policy); + const PolicyDetails* policy_details = GetPolicyDetails(policy); if (policy_details && policy_details->max_external_data_size > 0) return true; return false; } +const PolicyDetails* PolicyMap::GetPolicyDetails( + const std::string& policy) const { + return details_callback_.Run(policy); +} + void PolicyMap::LoadFrom(const base::Value::Dict& policies, PolicyLevel level, PolicyScope scope, @@ -611,20 +625,21 @@ bool PolicyMap::EntryHasHigherPriority(const PolicyMap::Entry& lhs, return std::tie(lhs.level, lhs.scope, lhs.source) > std::tie(rhs.level, rhs.scope, rhs.source); #else // BUILDFLAG(IS_CHROMEOS) + const PolicyDetails* details = lhs.details ? lhs.details : rhs.details; PolicyPriorityBrowser lhs_priority = using_default_precedence - ? GetPriority(lhs.source, lhs.scope, false, false, false) + ? GetPriority(lhs.source, lhs.scope, false, false, false, details) : GetPriority(lhs.source, lhs.scope, cloud_policy_overrides_platform_policy_, cloud_user_policy_overrides_cloud_machine_policy_, - IsUserAffiliated()); + IsUserAffiliated(), details); PolicyPriorityBrowser rhs_priority = using_default_precedence - ? GetPriority(rhs.source, rhs.scope, false, false, false) + ? GetPriority(rhs.source, rhs.scope, false, false, false, details) : GetPriority(rhs.source, rhs.scope, cloud_policy_overrides_platform_policy_, cloud_user_policy_overrides_cloud_machine_policy_, - IsUserAffiliated()); + IsUserAffiliated(), details); return std::tie(lhs.level, lhs_priority) > std::tie(rhs.level, rhs_priority); #endif // BUILDFLAG(IS_CHROMEOS) } diff --git a/components/policy/core/common/policy_map.h b/components/policy/core/common/policy_map.h index 683ab5b429..22d6fbbb77 100644 --- a/components/policy/core/common/policy_map.h +++ b/components/policy/core/common/policy_map.h @@ -16,6 +16,7 @@ #include "base/containers/flat_set.h" #include "base/functional/callback.h" #include "base/gtest_prod_util.h" +#include "base/memory/raw_ptr.h" #include "base/values.h" #include "components/policy/core/common/external_data_fetcher.h" #include "components/policy/core/common/policy_details.h" @@ -55,13 +56,18 @@ class POLICY_EXPORT PolicyMap { PolicySource source = POLICY_SOURCE_ENTERPRISE_DEFAULT; std::unique_ptr<ExternalDataFetcher> external_data_fetcher; std::vector<EntryConflict> conflicts; + // Unsupported raw_ptr: Pointer fields in classes/structs that are used as + // global. + // PolicyDetails is defined in gen/components/policy/policy_constants.cc + RAW_PTR_EXCLUSION const PolicyDetails* details = nullptr; Entry(); Entry(PolicyLevel level, PolicyScope scope, PolicySource source, std::optional<base::Value> value, - std::unique_ptr<ExternalDataFetcher> external_data_fetcher); + std::unique_ptr<ExternalDataFetcher> external_data_fetcher, + const PolicyDetails* details = nullptr); ~Entry(); Entry(Entry&&) noexcept; @@ -323,8 +329,12 @@ class POLICY_EXPORT PolicyMap { // Returns the set containing device affiliation ID strings. const base::flat_set<std::string>& GetDeviceAffiliationIds() const; - // Sets the ChromePolicyDetailsCallback, which is used in IsPolicyExternal(), - // in test environments + // Returns the PolicyDetails which is generated with the yaml definition of + // the `policy`. + const PolicyDetails* GetPolicyDetails(const std::string& policy) const; + + // Sets the ChromePolicyDetailsCallback, which is used in + // IsPolicyExternal(), in test environments void set_chrome_policy_details_callback_for_test( const GetChromePolicyDetailsCallback& details_callback); diff --git a/components/policy/core/common/policy_map_unittest.cc b/components/policy/core/common/policy_map_unittest.cc index 6f771964e3..d40c3f5cb0 100644 --- a/components/policy/core/common/policy_map_unittest.cc +++ b/components/policy/core/common/policy_map_unittest.cc @@ -42,6 +42,13 @@ const char kTestPolicyName8[] = "policy.test.8"; // Dummy error message. const char16_t kTestError[] = u"Test error message"; +const PolicyDetails kExternalDetails_ = {false, false, kProfile, 0, 10, {}}; +const PolicyDetails kNonExternalDetails_ = {false, false, kProfile, 0, 0, {}}; +#if !BUILDFLAG(IS_CHROMEOS) +const PolicyDetails kUserCloudDetails = {false, false, kSingleProfile, + 0, 0, {}}; +#endif + // Utility functions for the tests. void SetPolicy(PolicyMap* map, const char* name, base::Value value) { map->Set(name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, @@ -81,16 +88,13 @@ class PolicyMapTest : public PolicyMapTestBase, public testing::Test { public: const PolicyDetails* GetPolicyDetailsExternalCallback( const std::string& policy_name) { - return &externalDetails_; + return &kExternalDetails_; } const PolicyDetails* GetPolicyDetailsNonExternalCallback( const std::string& policy_name) { - return &nonExternalDetails_; + return &kNonExternalDetails_; } - - PolicyDetails externalDetails_ = {false, false, kProfile, 0, 10, {}}; - PolicyDetails nonExternalDetails_ = {false, false, kProfile, 0, 0, {}}; }; TEST_F(PolicyMapTest, SetAndGet) { @@ -1719,7 +1723,29 @@ class PolicyMapPriorityTest bool IsUserAffiliated() { return std::get<2>(GetParam()); } - void CheckPriorityConditions(PolicyMap& policy_map) { + void SetUp() override { + // Update the metapolicy values. + policy_map_.Set(key::kCloudPolicyOverridesPlatformPolicy, + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_PLATFORM, + base::Value(CloudPolicyOverridesPlatformPolicy()), nullptr); + policy_map_.Set( + key::kCloudUserPolicyOverridesCloudMachinePolicy, + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM, + base::Value(CloudUserPolicyOverridesCloudMachinePolicy()), nullptr); + // Causes the stored metapolicy values to be updated. + PolicyMap policy_map_empty; + policy_map_.MergeFrom(policy_map_empty); + + if (IsUserAffiliated()) { + base::flat_set<std::string> affiliation_ids; + affiliation_ids.insert("a"); + policy_map_.SetUserAffiliationIds(affiliation_ids); + policy_map_.SetDeviceAffiliationIds(affiliation_ids); + } + } + + void CheckPriorityConditions() { PolicyMap::Entry platform_machine( POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM, base::Value(), nullptr); @@ -1742,101 +1768,119 @@ class PolicyMapPriorityTest if (CloudPolicyOverridesPlatformPolicy() && CloudUserPolicyOverridesCloudMachinePolicy() && IsUserAffiliated()) { EXPECT_TRUE( - policy_map.EntryHasHigherPriority(platform_machine, platform_user)); + policy_map_.EntryHasHigherPriority(platform_machine, platform_user)); EXPECT_FALSE( - policy_map.EntryHasHigherPriority(platform_machine, cloud_machine)); + policy_map_.EntryHasHigherPriority(platform_machine, cloud_machine)); EXPECT_FALSE( - policy_map.EntryHasHigherPriority(platform_machine, cloud_user)); + policy_map_.EntryHasHigherPriority(platform_machine, cloud_user)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(cloud_machine, platform_user)); + policy_map_.EntryHasHigherPriority(cloud_machine, platform_user)); EXPECT_FALSE( - policy_map.EntryHasHigherPriority(cloud_machine, cloud_user)); + policy_map_.EntryHasHigherPriority(cloud_machine, cloud_user)); EXPECT_FALSE( - policy_map.EntryHasHigherPriority(platform_user, cloud_user)); - EXPECT_TRUE(policy_map.EntryHasHigherPriority(cloud_user, command_line)); + policy_map_.EntryHasHigherPriority(platform_user, cloud_user)); + EXPECT_TRUE(policy_map_.EntryHasHigherPriority(cloud_user, command_line)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(cloud_user, enterprise_default)); + policy_map_.EntryHasHigherPriority(cloud_user, enterprise_default)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(command_line, enterprise_default)); + policy_map_.EntryHasHigherPriority(command_line, enterprise_default)); } else if (CloudUserPolicyOverridesCloudMachinePolicy() && IsUserAffiliated()) { EXPECT_TRUE( - policy_map.EntryHasHigherPriority(platform_machine, platform_user)); + policy_map_.EntryHasHigherPriority(platform_machine, platform_user)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(platform_machine, cloud_machine)); + policy_map_.EntryHasHigherPriority(platform_machine, cloud_machine)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(platform_machine, cloud_user)); + policy_map_.EntryHasHigherPriority(platform_machine, cloud_user)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(cloud_machine, platform_user)); + policy_map_.EntryHasHigherPriority(cloud_machine, platform_user)); EXPECT_FALSE( - policy_map.EntryHasHigherPriority(cloud_machine, cloud_user)); + policy_map_.EntryHasHigherPriority(cloud_machine, cloud_user)); EXPECT_FALSE( - policy_map.EntryHasHigherPriority(platform_user, cloud_user)); - EXPECT_TRUE(policy_map.EntryHasHigherPriority(cloud_user, command_line)); + policy_map_.EntryHasHigherPriority(platform_user, cloud_user)); + EXPECT_TRUE(policy_map_.EntryHasHigherPriority(cloud_user, command_line)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(cloud_user, enterprise_default)); + policy_map_.EntryHasHigherPriority(cloud_user, enterprise_default)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(command_line, enterprise_default)); + policy_map_.EntryHasHigherPriority(command_line, enterprise_default)); } else if (CloudPolicyOverridesPlatformPolicy()) { EXPECT_TRUE( - policy_map.EntryHasHigherPriority(platform_machine, platform_user)); + policy_map_.EntryHasHigherPriority(platform_machine, platform_user)); EXPECT_FALSE( - policy_map.EntryHasHigherPriority(platform_machine, cloud_machine)); + policy_map_.EntryHasHigherPriority(platform_machine, cloud_machine)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(platform_machine, cloud_user)); + policy_map_.EntryHasHigherPriority(platform_machine, cloud_user)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(cloud_machine, platform_user)); - EXPECT_TRUE(policy_map.EntryHasHigherPriority(cloud_machine, cloud_user)); - EXPECT_TRUE(policy_map.EntryHasHigherPriority(platform_user, cloud_user)); - EXPECT_TRUE(policy_map.EntryHasHigherPriority(cloud_user, command_line)); + policy_map_.EntryHasHigherPriority(cloud_machine, platform_user)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(cloud_user, enterprise_default)); + policy_map_.EntryHasHigherPriority(cloud_machine, cloud_user)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(command_line, enterprise_default)); + policy_map_.EntryHasHigherPriority(platform_user, cloud_user)); + EXPECT_TRUE(policy_map_.EntryHasHigherPriority(cloud_user, command_line)); + EXPECT_TRUE( + policy_map_.EntryHasHigherPriority(cloud_user, enterprise_default)); + EXPECT_TRUE( + policy_map_.EntryHasHigherPriority(command_line, enterprise_default)); } else { EXPECT_TRUE( - policy_map.EntryHasHigherPriority(platform_machine, platform_user)); + policy_map_.EntryHasHigherPriority(platform_machine, platform_user)); + EXPECT_TRUE( + policy_map_.EntryHasHigherPriority(platform_machine, cloud_machine)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(platform_machine, cloud_machine)); + policy_map_.EntryHasHigherPriority(platform_machine, cloud_user)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(platform_machine, cloud_user)); + policy_map_.EntryHasHigherPriority(cloud_machine, platform_user)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(cloud_machine, platform_user)); - EXPECT_TRUE(policy_map.EntryHasHigherPriority(cloud_machine, cloud_user)); - EXPECT_TRUE(policy_map.EntryHasHigherPriority(platform_user, cloud_user)); - EXPECT_TRUE(policy_map.EntryHasHigherPriority(cloud_user, command_line)); + policy_map_.EntryHasHigherPriority(cloud_machine, cloud_user)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(cloud_user, enterprise_default)); + policy_map_.EntryHasHigherPriority(platform_user, cloud_user)); + EXPECT_TRUE(policy_map_.EntryHasHigherPriority(cloud_user, command_line)); EXPECT_TRUE( - policy_map.EntryHasHigherPriority(command_line, enterprise_default)); + policy_map_.EntryHasHigherPriority(cloud_user, enterprise_default)); + EXPECT_TRUE( + policy_map_.EntryHasHigherPriority(command_line, enterprise_default)); } } + + PolicyMap policy_map_; }; TEST_P(PolicyMapPriorityTest, PriorityCheck) { - PolicyMap policy_map; - - // Update the metapolicy values. - policy_map.Set(key::kCloudPolicyOverridesPlatformPolicy, - POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, - POLICY_SOURCE_PLATFORM, - base::Value(CloudPolicyOverridesPlatformPolicy()), nullptr); - policy_map.Set( - key::kCloudUserPolicyOverridesCloudMachinePolicy, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM, - base::Value(CloudUserPolicyOverridesCloudMachinePolicy()), nullptr); - // Causes the stored metapolicy values to be updated. - PolicyMap policy_map_empty; - policy_map.MergeFrom(policy_map_empty); + CheckPriorityConditions(); +} - if (IsUserAffiliated()) { - base::flat_set<std::string> affiliation_ids; - affiliation_ids.insert("a"); - policy_map.SetUserAffiliationIds(affiliation_ids); - policy_map.SetDeviceAffiliationIds(affiliation_ids); - } +TEST_P(PolicyMapPriorityTest, SingleProfilePolicy) { + PolicyMap::Entry platform_machine( + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM, + base::Value(), nullptr, &kUserCloudDetails); + PolicyMap::Entry platform_user(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_PLATFORM, base::Value(), nullptr, + &kUserCloudDetails); + PolicyMap::Entry cloud_machine(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_CLOUD, base::Value(), nullptr, + &kUserCloudDetails); + PolicyMap::Entry cloud_user(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_CLOUD, base::Value(), nullptr, + &kUserCloudDetails); + PolicyMap::Entry command_line(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_COMMAND_LINE, base::Value(), + nullptr, &kUserCloudDetails); + + EXPECT_TRUE(policy_map_.EntryHasHigherPriority(cloud_user, cloud_machine)); + EXPECT_TRUE(policy_map_.EntryHasHigherPriority(cloud_user, platform_user)); + EXPECT_TRUE(policy_map_.EntryHasHigherPriority(cloud_user, platform_machine)); + EXPECT_TRUE(policy_map_.EntryHasHigherPriority(cloud_user, platform_machine)); +} - CheckPriorityConditions(policy_map); +TEST_P(PolicyMapPriorityTest, SingleProfilePolicyWithMissingDetails) { + PolicyMap::Entry cloud_machine(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_CLOUD, base::Value(), nullptr, + &kUserCloudDetails); + PolicyMap::Entry cloud_user(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_CLOUD, base::Value(), nullptr, + nullptr); + EXPECT_TRUE(policy_map_.EntryHasHigherPriority(cloud_user, cloud_machine)); + EXPECT_FALSE(policy_map_.EntryHasHigherPriority(cloud_machine, cloud_user)); } INSTANTIATE_TEST_SUITE_P(PolicyMapPriorityTestInstance, diff --git a/mojo/public/interfaces/bindings/tests/data/README.md b/mojo/public/interfaces/bindings/tests/data/README.md new file mode 100644 index 0000000000..13d964b963 --- /dev/null +++ b/mojo/public/interfaces/bindings/tests/data/README.md @@ -0,0 +1,27 @@ +# Mojo conformance test data +The files in [validations](validations) are test data for mojo conformance +tests, which validate the memory layout of mojo messages. + +Run validation tests using the following command: + +``` +autoninja -C out/Default mojo_unittests +out/Default/bin/run_mojo_unittests --gtest_filter=ValidationTest.* +``` + +Note that you do not need to rebuild after changing the test data. + +## Adding test data + +1. Add a test method if necessary in + [validation test interfaces](../validation_test_interfaces.mojom). +1. Add a .data and .expected file in [validations](validations). + * The syntax for the .data file can be found in the + [validation test input parser](/mojo/public/cpp/bindings/tests/validation_test_input_parser.h). +1. Run `ValidationTest.*` to ensure that tests work as expected. +1. Update [validation_data_files.gni](../validation_data_files.gni) with your + test files. +1. Use [python script](/build/ios/update_bundle_filelist.py) to update + [validation_unittest_bundle_data.filelist](../validation_unittest_bundle_data.filelist). + * The presubmit will give you a copy pastable command, so there is no need to + to figure out how to invoke the script. |