Commit ac2b767c authored by Yafei Duan's avatar Yafei Duan Committed by Commit Bot

[Explore Sites] Implementing ExploreSitesBridge::GetIcon.

Implements ExploreSitesBridge::GetIcon using ImageFetcher, which takes
url and return fetched image via callback.

Bug: 852075
Change-Id: I8d3acd770cb2510639cd7896a79a81499874d50d
Reviewed-on: https://chromium-review.googlesource.com/1099771
Commit-Queue: Yafei Duan <romax@chromium.org>
Reviewed-by: default avatarTommy Nyquist <nyquist@chromium.org>
Reviewed-by: default avatarCathy Li <chili@chromium.org>
Cr-Commit-Position: refs/heads/master@{#568608}
parent f27f8934
...@@ -31,11 +31,17 @@ public class ExploreSitesBridge { ...@@ -31,11 +31,17 @@ public class ExploreSitesBridge {
} }
/** /**
* Fetches an icon from a url and returns in a Bitmap image. * Fetches an icon from a url and returns in a Bitmap image. The callback argument will be null
* if the operation fails.
*/ */
public static void getIcon(final String iconUrl, final Callback<Bitmap> callback) {} public static void getIcon(
Profile profile, final String iconUrl, final Callback<Bitmap> callback) {
nativeGetIcon(profile, iconUrl, callback);
}
private static native void nativeGetNtpCategories(Profile profile, private static native void nativeGetNtpCategories(Profile profile,
List<ExploreSitesCategoryTile> result, List<ExploreSitesCategoryTile> result,
Callback<List<ExploreSitesCategoryTile>> callback); Callback<List<ExploreSitesCategoryTile>> callback);
private static native void nativeGetIcon(
Profile profile, String iconUrl, Callback<Bitmap> callback);
} }
...@@ -61,7 +61,7 @@ public class ExploreSitesSection { ...@@ -61,7 +61,7 @@ public class ExploreSitesSection {
-> mNavigationDelegate.navigateToSuggestionUrl( -> mNavigationDelegate.navigateToSuggestionUrl(
WindowOpenDisposition.CURRENT_TAB, tile.getNavigationUrl())); WindowOpenDisposition.CURRENT_TAB, tile.getNavigationUrl()));
ExploreSitesBridge.getIcon( ExploreSitesBridge.getIcon(
tile.getIconUrl(), (Bitmap icon) -> onIconRetrieved(tileView, icon)); mProfile, tile.getIconUrl(), (Bitmap icon) -> onIconRetrieved(tileView, icon));
} }
} }
......
...@@ -1713,6 +1713,7 @@ chrome_test_java_sources = [ ...@@ -1713,6 +1713,7 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapterTest.java", "javatests/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapterTest.java",
"javatests/src/org/chromium/chrome/browser/download/ui/StubbedProvider.java", "javatests/src/org/chromium/chrome/browser/download/ui/StubbedProvider.java",
"javatests/src/org/chromium/chrome/browser/engagement/SiteEngagementServiceTest.java", "javatests/src/org/chromium/chrome/browser/engagement/SiteEngagementServiceTest.java",
"javatests/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridgeTest.java",
"javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImplTest.java", "javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImplTest.java",
"javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java", "javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java",
"javatests/src/org/chromium/chrome/browser/externalnav/IntentWithGesturesHandlerTest.java", "javatests/src/org/chromium/chrome/browser/externalnav/IntentWithGesturesHandlerTest.java",
......
// Copyright 2018 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.chrome.browser.explore_sites;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.Callback;
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.UrlUtils;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.test.ChromeBrowserTestRule;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.net.test.EmbeddedTestServer;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/** Tests for {@link ExploreSitesBridge}. */
@RunWith(ChromeJUnit4ClassRunner.class)
public final class ExploreSitesBridgeTest {
@Rule
public final ChromeBrowserTestRule mRule = new ChromeBrowserTestRule();
private static final String TEST_IMAGE = "/chrome/test/data/android/google.png";
private static final int TIMEOUT_MS = 5000;
private EmbeddedTestServer mTestServer;
private Profile mProfile;
@Before
public void setUp() throws Exception {
ThreadUtils.runOnUiThreadBlocking(() -> { mProfile = Profile.getLastUsedProfile(); });
mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
}
@After
public void tearDown() throws Exception {
mTestServer.stopAndDestroyServer();
mTestServer = null;
}
@Test
@SmallTest
public void testGetIcon() throws Exception {
Bitmap expectedIcon =
BitmapFactory.decodeFile(UrlUtils.getIsolatedTestFilePath(TEST_IMAGE));
String testImageUrl = mTestServer.getURL(TEST_IMAGE);
final Semaphore semaphore = new Semaphore(0);
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
ExploreSitesBridge.getIcon(mProfile, testImageUrl, new Callback<Bitmap>() {
@Override
public void onResult(Bitmap icon) {
Assert.assertNotNull(icon);
Assert.assertTrue(expectedIcon.sameAs(icon));
semaphore.release();
}
});
}
});
Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
}
}
file://chrome/browser/android/explore_sites/OWNERS
# TEAM: offline-dev@chromium.org
...@@ -9,21 +9,47 @@ ...@@ -9,21 +9,47 @@
#include "base/android/jni_string.h" #include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h" #include "base/android/scoped_java_ref.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_android.h" #include "chrome/browser/profiles/profile_android.h"
#include "chrome/browser/search/suggestions/image_decoder_impl.h"
#include "components/image_fetcher/core/image_fetcher.h"
#include "components/image_fetcher/core/image_fetcher_impl.h"
#include "jni/ExploreSitesBridge_jni.h" #include "jni/ExploreSitesBridge_jni.h"
#include "jni/ExploreSitesCategoryTile_jni.h" #include "jni/ExploreSitesCategoryTile_jni.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request_context_getter.h"
#include "services/network/public/cpp/simple_url_loader.h" #include "services/network/public/cpp/simple_url_loader.h"
#include "ui/gfx/android/java_bitmap.h"
#include "ui/gfx/image/image.h"
namespace explore_sites { namespace explore_sites {
using base::android::JavaParamRef; using base::android::JavaParamRef;
using base::android::JavaRef; using base::android::JavaRef;
using base::android::ScopedJavaLocalRef;
using base::android::ScopedJavaGlobalRef; using base::android::ScopedJavaGlobalRef;
using base::android::ScopedJavaLocalRef;
namespace { namespace {
constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("explore_sites_image_fetcher", R"(
semantics {
sender: "Explore Sites image fetcher"
description:
"Downloads images for explore sites usage."
trigger:
"When Explore Sites feature requires images from url."
data: "Requested image at url."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: YES
setting: "user"
policy_exception_justification:
"This feature is only enabled explicitly by flag."
})");
void GotNTPCategoriesFromJson( void GotNTPCategoriesFromJson(
const ScopedJavaGlobalRef<jobject>& j_callback_ref, const ScopedJavaGlobalRef<jobject>& j_callback_ref,
const ScopedJavaGlobalRef<jobject>& j_result_ref, const ScopedJavaGlobalRef<jobject>& j_result_ref,
...@@ -43,6 +69,22 @@ void GotNTPCategoriesFromJson( ...@@ -43,6 +69,22 @@ void GotNTPCategoriesFromJson(
base::android::RunCallbackAndroid(j_callback_ref, j_result_ref); base::android::RunCallbackAndroid(j_callback_ref, j_result_ref);
} }
void OnGetIconDone(std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher,
const ScopedJavaGlobalRef<jobject>& j_callback_obj,
const std::string& id,
const gfx::Image& image,
const image_fetcher::RequestMetadata& metadata) {
ScopedJavaLocalRef<jobject> j_bitmap;
if (!image.IsEmpty()) {
j_bitmap = gfx::ConvertToJavaBitmap(image.ToSkBitmap());
}
base::android::RunCallbackAndroid(j_callback_obj, j_bitmap);
// Delete |image_fetcher| when appropriate.
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
std::move(image_fetcher));
}
} // namespace } // namespace
// static // static
...@@ -61,4 +103,27 @@ void JNI_ExploreSitesBridge_GetNtpCategories( ...@@ -61,4 +103,27 @@ void JNI_ExploreSitesBridge_GetNtpCategories(
base::WrapUnique(ntp_fetcher))); base::WrapUnique(ntp_fetcher)));
} }
// static
static void JNI_ExploreSitesBridge_GetIcon(
JNIEnv* env,
const JavaParamRef<jclass>& j_caller,
const JavaParamRef<jobject>& j_profile,
const JavaParamRef<jstring>& j_url,
const JavaParamRef<jobject>& j_callback_obj) {
Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
GURL icon_url(ConvertJavaStringToUTF8(env, j_url));
scoped_refptr<net::URLRequestContextGetter> request_context =
profile->GetRequestContext();
auto image_fetcher = std::make_unique<image_fetcher::ImageFetcherImpl>(
std::make_unique<suggestions::ImageDecoderImpl>(), request_context.get());
// |image_fetcher| will be owned by the callback and gets destroyed at the end
// of the callback.
image_fetcher::ImageFetcher* image_fetcher_ptr = image_fetcher.get();
image_fetcher_ptr->FetchImage(
icon_url.spec(), icon_url,
base::BindOnce(&OnGetIconDone, std::move(image_fetcher),
ScopedJavaGlobalRef<jobject>(j_callback_obj)),
kTrafficAnnotation);
}
} // namespace explore_sites } // namespace explore_sites
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_ANDROID_EXPLORE_SITES_EXPLORE_SITES_BRIDGE_H_ #ifndef CHROME_BROWSER_ANDROID_EXPLORE_SITES_EXPLORE_SITES_BRIDGE_H_
#define CHROME_BROWSER_ANDROID_EXPLORE_SITES_EXPLORE_SITES_BRIDGE_H_ #define CHROME_BROWSER_ANDROID_EXPLORE_SITES_EXPLORE_SITES_BRIDGE_H_
#include <memory>
#include "base/android/jni_android.h" #include "base/android/jni_android.h"
#include "base/android/jni_weak_ref.h" #include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h" #include "base/android/scoped_java_ref.h"
...@@ -24,6 +26,13 @@ static void JNI_ExploreSitesBridge_GetNtpCategories( ...@@ -24,6 +26,13 @@ static void JNI_ExploreSitesBridge_GetNtpCategories(
const base::android::JavaParamRef<jobject>& j_result_obj, const base::android::JavaParamRef<jobject>& j_result_obj,
const base::android::JavaParamRef<jobject>& j_callback_obj); const base::android::JavaParamRef<jobject>& j_callback_obj);
static void JNI_ExploreSitesBridge_GetIcon(
JNIEnv* env,
const base::android::JavaParamRef<jclass>& j_caller,
const base::android::JavaParamRef<jobject>& j_profile,
const base::android::JavaParamRef<jstring>& j_url,
const base::android::JavaParamRef<jobject>& j_callback_obj);
} // namespace explore_sites } // namespace explore_sites
#endif // CHROME_BROWSER_ANDROID_EXPLORE_SITES_EXPLORE_SITES_BRIDGE_H_ #endif // CHROME_BROWSER_ANDROID_EXPLORE_SITES_EXPLORE_SITES_BRIDGE_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment