10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/android/jni_weak_ref.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_android.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::AttachCurrentThread;
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef()
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  : obj_(NULL) {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef(
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const JavaObjectWeakGlobalRef& orig)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : obj_(NULL) {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Assign(orig);
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef(JNIEnv* env, jobject obj)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : obj_(env->NewWeakGlobalRef(obj)) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(obj_);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JavaObjectWeakGlobalRef::~JavaObjectWeakGlobalRef() {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reset();
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JavaObjectWeakGlobalRef::operator=(const JavaObjectWeakGlobalRef& rhs) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Assign(rhs);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JavaObjectWeakGlobalRef::reset() {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (obj_) {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AttachCurrentThread()->DeleteWeakGlobalRef(obj_);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    obj_ = NULL;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::android::ScopedJavaLocalRef<jobject>
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JavaObjectWeakGlobalRef::get(JNIEnv* env) const {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetRealObject(env, obj_);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::android::ScopedJavaLocalRef<jobject> GetRealObject(
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env, jweak obj) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jobject real = NULL;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (obj) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    real = env->NewLocalRef(obj);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!real)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(ERROR) << "The real object has been deleted!";
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::android::ScopedJavaLocalRef<jobject>(env, real);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JavaObjectWeakGlobalRef::Assign(const JavaObjectWeakGlobalRef& other) {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (&other == this)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (obj_)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    env->DeleteWeakGlobalRef(obj_);
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  obj_ = other.obj_ ? env->NewWeakGlobalRef(other.obj_) : NULL;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68