File: device_info.cc

package info (click to toggle)
chromium 145.0.7632.116-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,974,048 kB
  • sloc: cpp: 36,197,932; ansic: 7,602,761; javascript: 3,563,590; python: 1,649,324; xml: 838,470; asm: 717,087; pascal: 185,708; sh: 88,786; perl: 88,718; objc: 79,984; sql: 59,811; cs: 42,452; fortran: 24,101; makefile: 21,016; tcl: 15,277; php: 14,022; yacc: 9,066; ruby: 7,553; awk: 3,720; lisp: 3,233; lex: 1,328; ada: 727; jsp: 228; sed: 36
file content (153 lines) | stat: -rw-r--r-- 4,683 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/android/device_info.h"

#include <string>

#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/compiler_specific.h"
#include "base/no_destructor.h"
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/lock.h"

// Must come after all headers that specialize FromJniType() / ToJniType().
#include "base/build_info_jni/DeviceInfo_jni.h"

#if __ANDROID_API__ >= 29
// .aidl based NDK generation is only available when our min SDK level is 29 or
// higher.
#include "aidl/org/chromium/base/IDeviceInfo.h"
using aidl::org::chromium::base::IDeviceInfo;
#endif

namespace base::android::device_info {
namespace {
#if __ANDROID_API__ < 29
struct IDeviceInfo {
  std::string gmsVersionCode;
  bool isAutomotive;
  bool isDesktop;
  bool isFoldable;
  bool isTv;
  // Available only on Android T+.
  int32_t vulkanDeqpLevel;
  bool isXr;
  bool wasLaunchedOnLargeDisplay;
};
#endif

static std::optional<IDeviceInfo>& get_holder() {
  static base::NoDestructor<std::optional<IDeviceInfo>> holder;
  return *holder;
}

IDeviceInfo& get_device_info() {
  std::optional<IDeviceInfo>& holder = get_holder();
  if (!holder.has_value()) {
    Java_DeviceInfo_nativeReadyForFields(AttachCurrentThread());
  }
  return *holder;
}

}  // namespace

void Set(const IDeviceInfo& info) {
  static base::NoDestructor<base::Lock> lock;
  base::AutoLock l(*lock);

  std::optional<IDeviceInfo>& holder = get_holder();
  holder.emplace(info);
}

static void JNI_DeviceInfo_FillFields(JNIEnv* env,
                                      std::string& gmsVersionCode,
                                      bool isTV,
                                      bool isAutomotive,
                                      bool isFoldable,
                                      bool isDesktop,
                                      jint vulkanDeqpLevel,
                                      bool isXr,
                                      bool wasLaunchedOnLargeDisplay) {
  Set(IDeviceInfo{.gmsVersionCode = gmsVersionCode,
                  .isAutomotive = isAutomotive,
                  .isDesktop = isDesktop,
                  .isFoldable = isFoldable,
                  .isTv = isTV,
                  .vulkanDeqpLevel = vulkanDeqpLevel,
                  .isXr = isXr,
                  .wasLaunchedOnLargeDisplay = wasLaunchedOnLargeDisplay});
}

const std::string& gms_version_code() {
  return get_device_info().gmsVersionCode;
}

void set_gms_version_code_for_test(const std::string& gms_version_code) {
  get_device_info().gmsVersionCode = gms_version_code;
  Java_DeviceInfo_setGmsVersionCodeForTest(AttachCurrentThread(),
                                           gms_version_code);
}

bool is_tv() {
  return get_device_info().isTv;
}
bool is_automotive() {
  return get_device_info().isAutomotive;
}
bool is_foldable() {
  return get_device_info().isFoldable;
}

bool is_desktop() {
  return get_device_info().isDesktop;
}

// Available only on Android T+.
int32_t vulkan_deqp_level() {
  return get_device_info().vulkanDeqpLevel;
}

bool is_xr() {
  return get_device_info().isXr;
}

// Roughly matches the check logic in device_form_factor.h to see if the device
// is a tablet (based on mostly elimination of other possible form-factors and
// screen-width). Where possible, prefer using device_form_factor.h (runtime
// check) as a first choice, but fall back to this if not feasible.
bool is_tablet() {
  return was_launched_on_large_display() && !is_tv() && !is_automotive() &&
         !is_desktop() && !is_xr();
}

// This returns the cached value during initial startup. If you need this
// evaluated at runtime, then use device_form_factor Additionally, this differs
// from device_form_factor in that it does not guarantee that the Android
// resource (-sw600) is respected.
bool was_launched_on_large_display() {
  return get_device_info().wasLaunchedOnLargeDisplay;
}

std::string device_name() {
  JNIEnv* env = base::android::AttachCurrentThread();
  return base::android::ConvertJavaStringToUTF8(
      env, Java_DeviceInfo_getDeviceName(env));
}

void set_is_xr_for_testing() {
  Java_DeviceInfo_setIsXrForTesting(AttachCurrentThread(), true);  // IN-TEST
  get_holder().reset();
}

void reset_is_xr_for_testing() {
  Java_DeviceInfo_resetIsXrForTesting(AttachCurrentThread());  // IN-TEST
  get_holder().reset();
}
}  // namespace base::android::device_info

DEFINE_JNI(DeviceInfo)