Android JNI: Disallow automatic conversion from long to jint
Start using JniIntWrapper from Chromium instead of bypassing it in jni_generator_helper.h. Bug: webrtc:8278 Change-Id: I20313e1e610b05f79c210e823ab50cfb2073674e Reviewed-on: https://webrtc-review.googlesource.com/74841 Reviewed-by: Sami Kalliomäki <sakal@webrtc.org> Commit-Queue: Magnus Jedvert <magjed@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23230}
This commit is contained in:
committed by
Commit Bot
parent
fdf1f88f62
commit
8a483be137
@ -1142,12 +1142,8 @@ rtc_static_library("native_api_jni") {
|
||||
visibility = [ "*" ]
|
||||
sources = [
|
||||
"native_api/jni/class_loader.cc",
|
||||
"native_api/jni/class_loader.h",
|
||||
"native_api/jni/java_types.cc",
|
||||
"native_api/jni/java_types.h",
|
||||
"native_api/jni/jvm.cc",
|
||||
"native_api/jni/jvm.h",
|
||||
"native_api/jni/scoped_java_ref.h",
|
||||
"src/jni/jni_generator_helper.cc",
|
||||
"src/jni/jni_generator_helper.h",
|
||||
]
|
||||
@ -1155,6 +1151,7 @@ rtc_static_library("native_api_jni") {
|
||||
public = [
|
||||
"native_api/jni/class_loader.h",
|
||||
"native_api/jni/java_types.h",
|
||||
"native_api/jni/jni_int_wrapper.h",
|
||||
"native_api/jni/jvm.h",
|
||||
"native_api/jni/scoped_java_ref.h",
|
||||
]
|
||||
|
||||
59
sdk/android/native_api/jni/jni_int_wrapper.h
Normal file
59
sdk/android/native_api/jni/jni_int_wrapper.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
// Originally this class is from Chromium.
|
||||
// https://cs.chromium.org/chromium/src/base/android/jni_int_wrapper.h.
|
||||
|
||||
#ifndef SDK_ANDROID_NATIVE_API_JNI_JNI_INT_WRAPPER_H_
|
||||
#define SDK_ANDROID_NATIVE_API_JNI_JNI_INT_WRAPPER_H_
|
||||
|
||||
// Wrapper used to receive int when calling Java from native. The wrapper
|
||||
// disallows automatic conversion of anything besides int32_t to a jint.
|
||||
// Checking is only done in debugging builds.
|
||||
|
||||
#ifdef NDEBUG
|
||||
|
||||
typedef jint JniIntWrapper;
|
||||
|
||||
// This inline is sufficiently trivial that it does not change the
|
||||
// final code generated by g++.
|
||||
inline jint as_jint(JniIntWrapper wrapper) {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
class JniIntWrapper {
|
||||
public:
|
||||
JniIntWrapper() : i_(0) {}
|
||||
JniIntWrapper(int32_t i) : i_(i) {} // NOLINT(runtime/explicit)
|
||||
explicit JniIntWrapper(const JniIntWrapper& ji) : i_(ji.i_) {}
|
||||
|
||||
jint as_jint() const { return i_; }
|
||||
|
||||
// If you get an "invokes a deleted function" error at the lines below it is
|
||||
// because you used an implicit conversion to convert e.g. a long to an
|
||||
// int32_t when calling Java. We disallow this. If you want a lossy
|
||||
// conversion, please use an explicit conversion in your C++ code.
|
||||
JniIntWrapper(uint32_t) = delete; // NOLINT(runtime/explicit)
|
||||
JniIntWrapper(uint64_t) = delete; // NOLINT(runtime/explicit)
|
||||
JniIntWrapper(int64_t) = delete; // NOLINT(runtime/explicit)
|
||||
|
||||
private:
|
||||
const jint i_;
|
||||
};
|
||||
|
||||
inline jint as_jint(const JniIntWrapper& wrapper) {
|
||||
return wrapper.as_jint();
|
||||
}
|
||||
|
||||
#endif // NDEBUG
|
||||
|
||||
#endif // SDK_ANDROID_NATIVE_API_JNI_JNI_INT_WRAPPER_H_
|
||||
@ -522,7 +522,7 @@ int32_t MediaCodecVideoDecoder::DecodeOnCodecThread(
|
||||
// Feed input to decoder.
|
||||
bool success = Java_MediaCodecVideoDecoder_queueInputBuffer(
|
||||
jni, j_media_codec_video_decoder_, j_input_buffer_index,
|
||||
inputImage._length, presentation_timestamp_us,
|
||||
static_cast<int>(inputImage._length), presentation_timestamp_us,
|
||||
static_cast<int64_t>(inputImage._timeStamp), inputImage.ntp_time_ms_);
|
||||
if (CheckException(jni) || !success) {
|
||||
ALOGE << "queueInputBuffer error";
|
||||
|
||||
@ -605,8 +605,8 @@ void GetAudioParameters(JNIEnv* env,
|
||||
bool use_stereo_output,
|
||||
AudioParameters* input_parameters,
|
||||
AudioParameters* output_parameters) {
|
||||
const size_t output_channels = use_stereo_output ? 2 : 1;
|
||||
const size_t input_channels = use_stereo_input ? 2 : 1;
|
||||
const int output_channels = use_stereo_output ? 2 : 1;
|
||||
const int input_channels = use_stereo_input ? 2 : 1;
|
||||
const size_t output_buffer_size = Java_WebRtcAudioManager_getOutputBufferSize(
|
||||
env, j_context, j_audio_manager, sample_rate, output_channels);
|
||||
const size_t input_buffer_size = Java_WebRtcAudioManager_getInputBufferSize(
|
||||
|
||||
@ -107,7 +107,7 @@ int32_t AudioRecordJni::InitRecording() {
|
||||
|
||||
int frames_per_buffer = Java_WebRtcAudioRecord_initRecording(
|
||||
env_, j_audio_record_, audio_parameters_.sample_rate(),
|
||||
audio_parameters_.channels());
|
||||
static_cast<int>(audio_parameters_.channels()));
|
||||
if (frames_per_buffer < 0) {
|
||||
direct_buffer_address_ = nullptr;
|
||||
RTC_LOG(LS_ERROR) << "InitRecording failed";
|
||||
|
||||
@ -77,9 +77,9 @@ int32_t AudioTrackJni::InitPlayout() {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
RTC_DCHECK(!initialized_);
|
||||
RTC_DCHECK(!playing_);
|
||||
if (!Java_WebRtcAudioTrack_initPlayout(env_, j_audio_track_,
|
||||
audio_parameters_.sample_rate(),
|
||||
audio_parameters_.channels())) {
|
||||
if (!Java_WebRtcAudioTrack_initPlayout(
|
||||
env_, j_audio_track_, audio_parameters_.sample_rate(),
|
||||
static_cast<int>(audio_parameters_.channels()))) {
|
||||
RTC_LOG(LS_ERROR) << "InitPlayout failed";
|
||||
return -1;
|
||||
}
|
||||
@ -138,7 +138,8 @@ bool AudioTrackJni::SpeakerVolumeIsAvailable() {
|
||||
int AudioTrackJni::SetSpeakerVolume(uint32_t volume) {
|
||||
RTC_LOG(INFO) << "SetSpeakerVolume(" << volume << ")";
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
return Java_WebRtcAudioTrack_setStreamVolume(env_, j_audio_track_, volume)
|
||||
return Java_WebRtcAudioTrack_setStreamVolume(env_, j_audio_track_,
|
||||
static_cast<int>(volume))
|
||||
? 0
|
||||
: -1;
|
||||
}
|
||||
|
||||
@ -35,7 +35,8 @@ ScopedJavaLocalRef<jobject> NativeToJavaEncodedImage(
|
||||
if (image.qp_ != -1)
|
||||
qp = NativeToJavaInteger(jni, image.qp_);
|
||||
return Java_EncodedImage_Constructor(
|
||||
jni, buffer, image._encodedWidth, image._encodedHeight,
|
||||
jni, buffer, static_cast<int>(image._encodedWidth),
|
||||
static_cast<int>(image._encodedHeight),
|
||||
image.capture_time_ms_ * rtc::kNumNanosecsPerMillisec, frame_type,
|
||||
static_cast<jint>(image.rotation_), image._completeFrame, qp);
|
||||
}
|
||||
|
||||
@ -9,9 +9,7 @@
|
||||
*/
|
||||
// Do not include this file directly. It's intended to be used only by the JNI
|
||||
// generation script. We are exporting types in strange namespaces in order to
|
||||
// be compatible with the generated code targeted for Chromium. We are bypassing
|
||||
// the wrapping done by Chromium's JniIntWrapper, JavaRef, and
|
||||
// ScopedJavaLocalRef, and use raw jobjects instead.
|
||||
// be compatible with the generated code targeted for Chromium.
|
||||
|
||||
#ifndef SDK_ANDROID_SRC_JNI_JNI_GENERATOR_HELPER_H_
|
||||
#define SDK_ANDROID_SRC_JNI_JNI_GENERATOR_HELPER_H_
|
||||
@ -19,6 +17,7 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
#include "sdk/android/native_api/jni/jni_int_wrapper.h"
|
||||
#include "sdk/android/native_api/jni/scoped_java_ref.h"
|
||||
|
||||
#define CHECK_CLAZZ(env, jcaller, clazz, ...) RTC_DCHECK(clazz);
|
||||
@ -39,15 +38,6 @@ inline void CheckException(JNIEnv* env) {
|
||||
}
|
||||
} // namespace jni_generator
|
||||
|
||||
namespace { // NOLINT(build/namespaces)
|
||||
// Bypass JniIntWrapper.
|
||||
// TODO(magjed): Start using Chromium's JniIntWrapper.
|
||||
typedef jint JniIntWrapper;
|
||||
inline jint as_jint(JniIntWrapper wrapper) {
|
||||
return wrapper;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace base {
|
||||
|
||||
namespace subtle {
|
||||
|
||||
@ -75,8 +75,8 @@ int32_t VideoEncoderWrapper::InitEncodeInternal(JNIEnv* jni) {
|
||||
|
||||
ScopedJavaLocalRef<jobject> settings = Java_Settings_Constructor(
|
||||
jni, number_of_cores_, codec_settings_.width, codec_settings_.height,
|
||||
codec_settings_.startBitrate, codec_settings_.maxFramerate,
|
||||
automatic_resize_on);
|
||||
static_cast<int>(codec_settings_.startBitrate),
|
||||
static_cast<int>(codec_settings_.maxFramerate), automatic_resize_on);
|
||||
|
||||
ScopedJavaLocalRef<jobject> callback =
|
||||
Java_VideoEncoderWrapper_createEncoderCallback(jni,
|
||||
|
||||
Reference in New Issue
Block a user