1// Copyright 2014 The Chromium Authors. All rights reserved.
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_weak_ref.h"
6
7#include <utility>
8
9#include "base/android/jni_android.h"
10#include "base/logging.h"
11
12using base::android::AttachCurrentThread;
13
14JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef() : obj_(nullptr) {}
15
16JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef(
17    const JavaObjectWeakGlobalRef& orig)
18    : obj_(nullptr) {
19  Assign(orig);
20}
21
22JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef(JavaObjectWeakGlobalRef&& orig)
23    : obj_(orig.obj_) {
24  orig.obj_ = nullptr;
25}
26
27JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef(JNIEnv* env, jobject obj)
28    : obj_(env->NewWeakGlobalRef(obj)) {
29}
30
31JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef(
32    JNIEnv* env,
33    const base::android::JavaRef<jobject>& obj)
34    : obj_(env->NewWeakGlobalRef(obj.obj())) {
35}
36
37JavaObjectWeakGlobalRef::~JavaObjectWeakGlobalRef() {
38  reset();
39}
40
41void JavaObjectWeakGlobalRef::operator=(const JavaObjectWeakGlobalRef& rhs) {
42  Assign(rhs);
43}
44
45void JavaObjectWeakGlobalRef::operator=(JavaObjectWeakGlobalRef&& rhs) {
46  std::swap(obj_, rhs.obj_);
47}
48
49void JavaObjectWeakGlobalRef::reset() {
50  if (obj_) {
51    AttachCurrentThread()->DeleteWeakGlobalRef(obj_);
52    obj_ = nullptr;
53  }
54}
55
56base::android::ScopedJavaLocalRef<jobject>
57    JavaObjectWeakGlobalRef::get(JNIEnv* env) const {
58  return GetRealObject(env, obj_);
59}
60
61base::android::ScopedJavaLocalRef<jobject> GetRealObject(
62    JNIEnv* env, jweak obj) {
63  jobject real = nullptr;
64  if (obj)
65    real = env->NewLocalRef(obj);
66  return base::android::ScopedJavaLocalRef<jobject>(env, real);
67}
68
69void JavaObjectWeakGlobalRef::Assign(const JavaObjectWeakGlobalRef& other) {
70  if (&other == this)
71    return;
72
73  JNIEnv* env = AttachCurrentThread();
74  if (obj_)
75    env->DeleteWeakGlobalRef(obj_);
76
77  obj_ = other.obj_ ? env->NewWeakGlobalRef(other.obj_) : nullptr;
78}
79