Implement InstanceIDAndroid using InstanceIDWithSubtype.java
Replaces the previous stub implementation with a fully functional
implementation backed by InstanceIDWithSubtype.java.
Part of a series of patches:
1. https://codereview.chromium.org/1832833002 adds InstanceIDWithSubtype
2. this patch
3. https://codereview.chromium.org/1829023002 adds fake and test
4. https://codereview.chromium.org/1854093002 enables InstanceID by default
5. https://codereview.chromium.org/1851423003 switches Push to InstanceIDs
BUG=589461
Review URL: https://codereview.chromium.org/1830983002
Cr-Commit-Position: refs/heads/master@{#387646}
diff --git a/components/gcm_driver/instance_id/android/BUILD.gn b/components/gcm_driver/instance_id/android/BUILD.gn
new file mode 100644
index 0000000..6168aff
--- /dev/null
+++ b/components/gcm_driver/instance_id/android/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2016 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.
+
+import("//build/config/android/rules.gni")
+
+# GYP version: components/gcm_driver.gypi:instance_id_driver_jni_headers
+generate_jni("jni_headers") {
+ sources = [
+ "java/src/org/chromium/components/gcm_driver/instance_id/InstanceIDBridge.java",
+ ]
+ jni_package = "components/gcm_driver/instance_id"
+}
+
+# GYP version: components/gcm_driver.gypi:instance_id_driver_java
+android_library("instance_id_driver_java") {
+ deps = [
+ "//base:base_java",
+ google_play_services_library,
+ ]
+
+ java_files = [
+ "java/src/org/chromium/components/gcm_driver/instance_id/InstanceIDBridge.java",
+ "java/src/org/chromium/components/gcm_driver/instance_id/InstanceIDWithSubtype.java",
+ ]
+}
diff --git a/components/gcm_driver/instance_id/android/component_jni_registrar.cc b/components/gcm_driver/instance_id/android/component_jni_registrar.cc
new file mode 100644
index 0000000..de6705b
--- /dev/null
+++ b/components/gcm_driver/instance_id/android/component_jni_registrar.cc
@@ -0,0 +1,26 @@
+// Copyright 2016 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 "components/gcm_driver/instance_id/android/component_jni_registrar.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_registrar.h"
+#include "base/macros.h"
+#include "components/gcm_driver/instance_id/instance_id_android.h"
+
+namespace instance_id {
+namespace android {
+
+static base::android::RegistrationMethod kInstanceIDRegisteredMethods[] = {
+ {"InstanceID", instance_id::InstanceIDAndroid::RegisterJni},
+};
+
+bool RegisterInstanceIDJni(JNIEnv* env) {
+ return base::android::RegisterNativeMethods(
+ env, kInstanceIDRegisteredMethods,
+ arraysize(kInstanceIDRegisteredMethods));
+}
+
+} // namespace android
+} // namespace instance_id
diff --git a/components/gcm_driver/instance_id/android/component_jni_registrar.h b/components/gcm_driver/instance_id/android/component_jni_registrar.h
new file mode 100644
index 0000000..dc40f9bc
--- /dev/null
+++ b/components/gcm_driver/instance_id/android/component_jni_registrar.h
@@ -0,0 +1,19 @@
+// Copyright 2016 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.
+
+#ifndef COMPONENTS_GCM_DRIVER_INSTANCE_ID_ANDROID_COMPONENT_JNI_REGISTRAR_H_
+#define COMPONENTS_GCM_DRIVER_INSTANCE_ID_ANDROID_COMPONENT_JNI_REGISTRAR_H_
+
+#include <jni.h>
+
+namespace instance_id {
+namespace android {
+
+// Register all JNI bindings necessary for the gcm_driver/instance_id component.
+bool RegisterInstanceIDJni(JNIEnv* env);
+
+} // namespace android
+} // namespace instance_id
+
+#endif // COMPONENTS_GCM_DRIVER_INSTANCE_ID_ANDROID_COMPONENT_JNI_REGISTRAR_H_
diff --git a/components/gcm_driver/instance_id/android/java/src/org/chromium/components/gcm_driver/instance_id/InstanceIDBridge.java b/components/gcm_driver/instance_id/android/java/src/org/chromium/components/gcm_driver/instance_id/InstanceIDBridge.java
new file mode 100644
index 0000000..a984a24
--- /dev/null
+++ b/components/gcm_driver/instance_id/android/java/src/org/chromium/components/gcm_driver/instance_id/InstanceIDBridge.java
@@ -0,0 +1,146 @@
+// Copyright 2016 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.
+
+package org.chromium.components.gcm_driver.instance_id;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.os.Bundle;
+
+import com.google.android.gms.iid.InstanceID;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+
+import java.io.IOException;
+
+/**
+ * Wraps InstanceID and InstanceIDWithSubtype so they can be used over JNI.
+ * Performs disk/network operations on a background thread and replies asynchronously.
+ */
+@JNINamespace("instance_id")
+public class InstanceIDBridge {
+ /** Underlying InstanceID. May be shared by multiple InstanceIDBridges. */
+ private final InstanceID mInstanceID;
+ private long mNativeInstanceIDAndroid;
+
+ private InstanceIDBridge(
+ long nativeInstanceIDAndroid, Context context, String subtype) {
+ mInstanceID = InstanceIDWithSubtype.getInstance(context, subtype);
+ mNativeInstanceIDAndroid = nativeInstanceIDAndroid;
+ }
+
+ /**
+ * Returns a wrapped {@link InstanceIDWithSubtype}. Multiple InstanceIDBridge instances may
+ * share an underlying InstanceIDWithSubtype.
+ */
+ @CalledByNative
+ public static InstanceIDBridge create(
+ long nativeInstanceIDAndroid, Context context, String subtype) {
+ // TODO(johnme): This should also be async.
+ return new InstanceIDBridge(nativeInstanceIDAndroid, context, subtype);
+ }
+
+ /**
+ * Called when our C++ counterpart is destroyed. Clears the handle to our native C++ object,
+ * ensuring it's not called by pending async tasks.
+ */
+ @CalledByNative
+ private void destroy() {
+ mNativeInstanceIDAndroid = 0;
+ }
+
+ /** Wrapper for {@link InstanceID#getId}. */
+ @CalledByNative
+ public String getId() {
+ // TODO(johnme): This should also be async.
+ return mInstanceID.getId();
+ }
+
+ /** Wrapper for {@link InstanceID#getCreationTime}. */
+ @CalledByNative
+ public long getCreationTime() {
+ // TODO(johnme): This should also be async.
+ return mInstanceID.getCreationTime();
+ }
+
+ /** Async wrapper for {@link InstanceID#getToken(String, String, Bundle)}. */
+ @CalledByNative
+ private void getToken(final int requestId, final String authorizedEntity, final String scope,
+ String[] extrasStrings) {
+ final Bundle extras = new Bundle();
+ assert extrasStrings.length % 2 == 0;
+ for (int i = 0; i < extrasStrings.length; i += 2) {
+ extras.putString(extrasStrings[i], extrasStrings[i + 1]);
+ }
+ new AsyncTask<Void, Void, String>() {
+ @Override
+ protected String doInBackground(Void... params) {
+ try {
+ return mInstanceID.getToken(authorizedEntity, scope, extras);
+ } catch (IOException ex) {
+ return "";
+ }
+ }
+ @Override
+ protected void onPostExecute(String token) {
+ if (mNativeInstanceIDAndroid != 0) {
+ nativeDidGetToken(mNativeInstanceIDAndroid, requestId, token);
+ }
+ }
+ }.execute();
+ }
+
+ /** Async wrapper for {@link InstanceID#deleteToken(String, String)}. */
+ @CalledByNative
+ private void deleteToken(
+ final int requestId, final String authorizedEntity, final String scope) {
+ new AsyncTask<Void, Void, Boolean>() {
+ @Override
+ protected Boolean doInBackground(Void... params) {
+ try {
+ mInstanceID.deleteToken(authorizedEntity, scope);
+ return true;
+ } catch (IOException ex) {
+ return false;
+ }
+ }
+ @Override
+ protected void onPostExecute(Boolean success) {
+ if (mNativeInstanceIDAndroid != 0) {
+ nativeDidDeleteToken(mNativeInstanceIDAndroid, requestId, success);
+ }
+ }
+ }.execute();
+ }
+
+ /** Async wrapper for {@link InstanceID#deleteInstanceID}. */
+ @CalledByNative
+ private void deleteInstanceID(final int requestId) {
+ new AsyncTask<Void, Void, Boolean>() {
+ @Override
+ protected Boolean doInBackground(Void... params) {
+ try {
+ mInstanceID.deleteInstanceID();
+ return true;
+ } catch (IOException ex) {
+ return false;
+ }
+ }
+ @Override
+ protected void onPostExecute(Boolean success) {
+ if (mNativeInstanceIDAndroid != 0) {
+ nativeDidDeleteID(mNativeInstanceIDAndroid, requestId, success);
+ }
+ }
+ }.execute();
+ }
+
+ private native void nativeDidGetToken(
+ long nativeInstanceIDAndroid, int requestId, String token);
+ private native void nativeDidDeleteToken(
+ long nativeInstanceIDAndroid, int requestId, boolean success);
+ private native void nativeDidDeleteID(
+ long nativeInstanceIDAndroid, int requestId, boolean success);
+}
\ No newline at end of file