// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/midi/midi_input_port_android.h"

#include "base/android/jni_array.h"
#include "base/time/time.h"
#include "jni/MidiInputPortAndroid_jni.h"

using base::android::JavaParamRef;

namespace midi {

MidiInputPortAndroid::MidiInputPortAndroid(JNIEnv* env,
                                           jobject raw,
                                           Delegate* delegate)
    : raw_port_(env, raw), delegate_(delegate) {}

MidiInputPortAndroid::~MidiInputPortAndroid() {
  Close();
}

bool MidiInputPortAndroid::Open() {
  JNIEnv* env = base::android::AttachCurrentThread();
  return Java_MidiInputPortAndroid_open(env, raw_port_,
                                        reinterpret_cast<jlong>(this));
}

void MidiInputPortAndroid::Close() {
  JNIEnv* env = base::android::AttachCurrentThread();
  Java_MidiInputPortAndroid_close(env, raw_port_);
}

void MidiInputPortAndroid::OnData(JNIEnv* env,
                                  const JavaParamRef<jobject>& caller,
                                  const JavaParamRef<jbyteArray>& data,
                                  jint offset,
                                  jint size,
                                  jlong timestamp) {
  std::vector<uint8_t> bytes;
  base::android::JavaByteArrayToByteVector(env, data, &bytes);

  if (size == 0) {
    return;
  }

  // TimeTick's internal value is in microseconds, |timestamp| is in
  // nanoseconds. Both are monotonic.
  base::TimeTicks timestamp_to_pass = base::TimeTicks::FromInternalValue(
      timestamp / base::TimeTicks::kNanosecondsPerMicrosecond);
  delegate_->OnReceivedData(this, &bytes[offset], size, timestamp_to_pass);
}

bool MidiInputPortAndroid::Register(JNIEnv* env) {
  return RegisterNativesImpl(env);
}

}  // namespace midi
