1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/android/jni_bytebuffer.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <algorithm>
11 #include <limits>
12
13 #include "base/android/jni_android.h"
14 #include "base/android/jni_string.h"
15 #include "base/android/scoped_java_ref.h"
16 #include "base/containers/span.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace base::android {
22
TEST(JniByteBuffer,ConversionDoesNotCopy)23 TEST(JniByteBuffer, ConversionDoesNotCopy) {
24 uint8_t bytes[] = {0, 1, 2, 3};
25 JNIEnv* env = AttachCurrentThread();
26
27 ScopedJavaLocalRef<jobject> jbuffer(
28 env, env->NewDirectByteBuffer(bytes, sizeof(bytes)));
29 ASSERT_TRUE(jbuffer);
30
31 base::span<const uint8_t> span = JavaByteBufferToSpan(env, jbuffer.obj());
32 EXPECT_EQ(span.data(), bytes);
33 EXPECT_EQ(span.size(), sizeof(bytes));
34 }
35
36 // Disabled pending diagnosis: https://crbug.com/1521406
37 // Specifically, under test, env->GetDirectBufferAddress() is returning non-null
38 // and env->GetDirectBufferCapacity() is returning >= 0, both of which they are
39 // not supposed to do in this situation.
TEST(JniByteBuffer,DISABLED_ConversionFromNonBuffer)40 TEST(JniByteBuffer, DISABLED_ConversionFromNonBuffer) {
41 JNIEnv* env = AttachCurrentThread();
42 jclass cls = env->FindClass("java/util/ArrayList");
43 ASSERT_TRUE(cls);
44
45 jmethodID init =
46 base::android::MethodID::Get<base::android::MethodID::TYPE_INSTANCE>(
47 env, cls, "<init>", "()V");
48
49 ScopedJavaLocalRef<jobject> jnonbuffer(env, env->NewObject(cls, init));
50
51 std::optional<base::span<const uint8_t>> maybe_span =
52 MaybeJavaByteBufferToSpan(env, jnonbuffer.obj());
53 EXPECT_FALSE(maybe_span.has_value());
54 }
55
TEST(JniByteBuffer,ZeroByteConversionSucceeds)56 TEST(JniByteBuffer, ZeroByteConversionSucceeds) {
57 JNIEnv* env = AttachCurrentThread();
58 ScopedJavaLocalRef<jobject> jbuffer(env,
59 env->NewDirectByteBuffer(nullptr, 0));
60 ASSERT_TRUE(jbuffer);
61
62 base::span<const uint8_t> span = JavaByteBufferToSpan(env, jbuffer.obj());
63 EXPECT_EQ(span.data(), nullptr);
64 EXPECT_EQ(span.size(), 0u);
65 }
66
67 } // namespace base::android
68