Commit 119a9230 authored by sunangel@chromium.org's avatar sunangel@chromium.org

Observer Support for DistilledPagePrefs

These changes provide support for observers for DistilledPagePrefs
to listen to changes in DistilledPagePrefs.

BUG=383630

Review URL: https://codereview.chromium.org/403323005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285109 0039d316-1c4b-4281-b951-d872f2087c98
parent 87389c9d
// Copyright 2014 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.base;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @NativeCall is used by the JNI generator to create the necessary JNI bindings
* so a native function can be bound to a Java inner class. The native class for
* which the JNI method will be generated is specified by the first parameter.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface NativeCall {
/*
* Value determines which native class the method should map to.
*/
public String value() default "";
}
...@@ -7,36 +7,110 @@ package org.chromium.chrome.browser.dom_distiller; ...@@ -7,36 +7,110 @@ package org.chromium.chrome.browser.dom_distiller;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
import android.test.UiThreadTest; import android.test.UiThreadTest;
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Feature;
import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.shell.ChromeShellTestBase; import org.chromium.chrome.shell.ChromeShellTestBase;
import org.chromium.components.dom_distiller.core.DistilledPagePrefs; import org.chromium.components.dom_distiller.core.DistilledPagePrefs;
import org.chromium.components.dom_distiller.core.DomDistillerService; import org.chromium.components.dom_distiller.core.DomDistillerService;
import org.chromium.components.dom_distiller.core.Theme; import org.chromium.components.dom_distiller.core.Theme;
import org.chromium.content.browser.test.util.UiUtils;
/** /**
* Test class for {@link DistilledPagePrefs}. * Test class for {@link DistilledPagePrefs}.
*/ */
public class DistilledPagePrefsTest extends ChromeShellTestBase { public class DistilledPagePrefsTest extends ChromeShellTestBase {
private DistilledPagePrefs mDistilledPagePrefs;
@Override
public void setUp() throws Exception {
super.setUp();
startChromeBrowserProcessSync(getInstrumentation().getTargetContext());
getDistilledPagePrefs();
}
private void getDistilledPagePrefs() {
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
public void run() {
DomDistillerService domDistillerService = DomDistillerServiceFactory.
getForProfile(Profile.getLastUsedProfile());
mDistilledPagePrefs = domDistillerService.getDistilledPagePrefs();
}
});
}
@SmallTest @SmallTest
@UiThreadTest @UiThreadTest
@Feature({"DomDistiller"}) @Feature({"DomDistiller"})
public void testGetAndSetPrefs() throws InterruptedException { public void testGetAndSetPrefs() throws InterruptedException {
startChromeBrowserProcessSync(getInstrumentation().getTargetContext()); // Check the default theme.
DomDistillerService service = DomDistillerServiceFactory. assertEquals(mDistilledPagePrefs.getTheme(), Theme.LIGHT);
getForProfile(Profile.getLastUsedProfile());
assertNotNull(service);
DistilledPagePrefs distilledPagePrefs = service.getDistilledPagePrefs();
assertNotNull(distilledPagePrefs);
// Check default theme.
assertEquals(distilledPagePrefs.getTheme(), Theme.LIGHT);
// Check that theme can be correctly set. // Check that theme can be correctly set.
distilledPagePrefs.setTheme(Theme.DARK); mDistilledPagePrefs.setTheme(Theme.DARK);
assertEquals(Theme.DARK, distilledPagePrefs.getTheme()); assertEquals(Theme.DARK, mDistilledPagePrefs.getTheme());
distilledPagePrefs.setTheme(Theme.LIGHT); mDistilledPagePrefs.setTheme(Theme.LIGHT);
assertEquals(Theme.LIGHT, distilledPagePrefs.getTheme()); assertEquals(Theme.LIGHT, mDistilledPagePrefs.getTheme());
distilledPagePrefs.setTheme(Theme.SEPIA); mDistilledPagePrefs.setTheme(Theme.SEPIA);
assertEquals(Theme.SEPIA, distilledPagePrefs.getTheme()); assertEquals(Theme.SEPIA, mDistilledPagePrefs.getTheme());
}
@SmallTest
@Feature({"DomDistiller"})
public void testSingleObserver() throws InterruptedException {
TestingObserver testObserver = new TestingObserver();
mDistilledPagePrefs.addObserver(testObserver);
setTheme(Theme.DARK);
// Assumes that callback does not occur immediately.
assertNull(testObserver.getTheme());
UiUtils.settleDownUI(getInstrumentation());
// Check that testObserver's theme has been updated,
assertEquals(Theme.DARK, testObserver.getTheme());
mDistilledPagePrefs.removeObserver(testObserver);
}
@SmallTest
@Feature({"DomDistiller"})
public void testMultipleObservers() throws InterruptedException {
TestingObserver testObserverOne = new TestingObserver();
mDistilledPagePrefs.addObserver(testObserverOne);
TestingObserver testObserverTwo = new TestingObserver();
mDistilledPagePrefs.addObserver(testObserverTwo);
setTheme(Theme.SEPIA);
UiUtils.settleDownUI(getInstrumentation());
assertEquals(Theme.SEPIA, testObserverOne.getTheme());
assertEquals(Theme.SEPIA, testObserverTwo.getTheme());
mDistilledPagePrefs.removeObserver(testObserverOne);
setTheme(Theme.DARK);
UiUtils.settleDownUI(getInstrumentation());
// Check that testObserverOne's theme is not changed but testObserverTwo's is.
assertEquals(Theme.SEPIA, testObserverOne.getTheme());
assertEquals(Theme.DARK, testObserverTwo.getTheme());
mDistilledPagePrefs.removeObserver(testObserverTwo);
}
private static class TestingObserver implements DistilledPagePrefs.Observer {
private Theme mTheme;
public TestingObserver() {}
public Theme getTheme() {
return mTheme;
}
public void onChangeTheme(Theme theme) {
mTheme = theme;
}
}
private void setTheme(final Theme theme) {
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
public void run() {
mDistilledPagePrefs.setTheme(theme);
}
});
} }
} }
...@@ -4,7 +4,12 @@ ...@@ -4,7 +4,12 @@
package org.chromium.components.dom_distiller.core; package org.chromium.components.dom_distiller.core;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace; import org.chromium.base.JNINamespace;
import org.chromium.base.NativeCall;
import java.util.HashMap;
import java.util.Map;
/** /**
* Wrapper for the dom_distiller::DistilledPagePrefs. * Wrapper for the dom_distiller::DistilledPagePrefs.
...@@ -13,25 +18,85 @@ import org.chromium.base.JNINamespace; ...@@ -13,25 +18,85 @@ import org.chromium.base.JNINamespace;
public final class DistilledPagePrefs { public final class DistilledPagePrefs {
private final long mDistilledPagePrefsAndroid; private final long mDistilledPagePrefsAndroid;
private Map<Observer, DistilledPagePrefsObserverWrapper> mObserverMap;
/**
* Observer interface for observing DistilledPagePrefs changes.
*/
public interface Observer {
void onChangeTheme(Theme theme);
}
/**
* Wrapper for dom_distiller::android::DistilledPagePrefsObserverAndroid.
*/
private static class DistilledPagePrefsObserverWrapper {
private final Observer mDistilledPagePrefsObserver;
private final long mNativeDistilledPagePrefsObserverAndroidPtr;
public DistilledPagePrefsObserverWrapper(Observer observer) {
mNativeDistilledPagePrefsObserverAndroidPtr = nativeInitObserverAndroid();
mDistilledPagePrefsObserver = observer;
}
@CalledByNative("DistilledPagePrefsObserverWrapper")
private void onChangeTheme(int theme) {
mDistilledPagePrefsObserver.onChangeTheme(Theme.getThemeForValue(theme));
}
public void destroy() {
nativeDestroyObserverAndroid(mNativeDistilledPagePrefsObserverAndroidPtr);
}
public long getNativePtr() {
return mNativeDistilledPagePrefsObserverAndroidPtr;
}
@NativeCall("DistilledPagePrefsObserverWrapper")
private native long nativeInitObserverAndroid();
@NativeCall("DistilledPagePrefsObserverWrapper")
private native void nativeDestroyObserverAndroid(
long nativeDistilledPagePrefsObserverAndroid);
}
DistilledPagePrefs(long distilledPagePrefsPtr) { DistilledPagePrefs(long distilledPagePrefsPtr) {
mDistilledPagePrefsAndroid = nativeInit(distilledPagePrefsPtr); mDistilledPagePrefsAndroid = nativeInit(distilledPagePrefsPtr);
mObserverMap = new HashMap<Observer, DistilledPagePrefsObserverWrapper>();
}
public void addObserver(Observer obs) {
DistilledPagePrefsObserverWrapper wrappedObserver =
new DistilledPagePrefsObserverWrapper(obs);
nativeAddObserver(mDistilledPagePrefsAndroid, wrappedObserver.getNativePtr());
mObserverMap.put(obs, wrappedObserver);
}
public void removeObserver(Observer obs) {
DistilledPagePrefsObserverWrapper wrappedObserver = mObserverMap.remove(obs);
if (wrappedObserver != null) {
nativeRemoveObserver(mDistilledPagePrefsAndroid, wrappedObserver.getNativePtr());
wrappedObserver.destroy();
}
} }
// TODO(sunangel): Add observer support from this Java class to native
// counterpart so UI can be updated across tabs.
public void setTheme(Theme theme) { public void setTheme(Theme theme) {
nativeSetTheme(mDistilledPagePrefsAndroid, theme.asNativeEnum()); nativeSetTheme(mDistilledPagePrefsAndroid, theme.asNativeEnum());
} }
public Theme getTheme() { public Theme getTheme() {
return Theme.getThemeForValue( return Theme.getThemeForValue(nativeGetTheme(mDistilledPagePrefsAndroid));
nativeGetTheme(mDistilledPagePrefsAndroid));
} }
private native long nativeInit(long distilledPagePrefPtr); private native long nativeInit(long distilledPagePrefPtr);
private native void nativeSetTheme(long nativeDistilledPagePrefsAndroid,
int theme); private native void nativeSetTheme(long nativeDistilledPagePrefsAndroid, int theme);
private native int nativeGetTheme(
long nativeDistilledPagePrefsAndroid); private native int nativeGetTheme(long nativeDistilledPagePrefsAndroid);
private native void nativeAddObserver(long nativeDistilledPagePrefsAndroid,
long nativeObserverPtr);
private native void nativeRemoveObserver(long nativeDistilledPagePrefsAndroid,
long nativeObserverPtr);
} }
...@@ -17,6 +17,10 @@ static_library("core") { ...@@ -17,6 +17,10 @@ static_library("core") {
"distiller.h", "distiller.h",
"distiller_page.cc", "distiller_page.cc",
"distiller_page.h", "distiller_page.h",
"distilled_page_prefs.cc",
"distilled_page_prefs.h",
"distilled_page_prefs_android.cc",
"distilled_page_prefs_android.h",
"distiller_url_fetcher.cc", "distiller_url_fetcher.cc",
"distiller_url_fetcher.h", "distiller_url_fetcher.h",
"dom_distiller_constants.cc", "dom_distiller_constants.cc",
......
...@@ -9,13 +9,14 @@ ...@@ -9,13 +9,14 @@
#include "jni/DistilledPagePrefs_jni.h" #include "jni/DistilledPagePrefs_jni.h"
namespace dom_distiller { namespace dom_distiller {
namespace android { namespace android {
DistilledPagePrefsAndroid::DistilledPagePrefsAndroid( DistilledPagePrefsAndroid::DistilledPagePrefsAndroid(
JNIEnv* env, JNIEnv* env,
jobject obj, jobject obj,
DistilledPagePrefs* distillerPagePrefsPtr) DistilledPagePrefs* distilled_page_prefs_ptr)
: distilled_page_prefs_(distillerPagePrefsPtr) { : distilled_page_prefs_(distilled_page_prefs_ptr) {
} }
DistilledPagePrefsAndroid::~DistilledPagePrefsAndroid() { DistilledPagePrefsAndroid::~DistilledPagePrefsAndroid() {
...@@ -29,11 +30,11 @@ jint DistilledPagePrefsAndroid::GetTheme(JNIEnv* env, jobject obj) { ...@@ -29,11 +30,11 @@ jint DistilledPagePrefsAndroid::GetTheme(JNIEnv* env, jobject obj) {
return (int)distilled_page_prefs_->GetTheme(); return (int)distilled_page_prefs_->GetTheme();
} }
jlong Init(JNIEnv* env, jobject obj, jlong distilledPagePrefsPtr) { jlong Init(JNIEnv* env, jobject obj, jlong distilled_page_prefs_ptr) {
DistilledPagePrefs* distilledPagePrefs = DistilledPagePrefs* distilled_page_prefs =
reinterpret_cast<DistilledPagePrefs*>(distilledPagePrefsPtr); reinterpret_cast<DistilledPagePrefs*>(distilled_page_prefs_ptr);
DistilledPagePrefsAndroid* distilled_page_prefs_android = DistilledPagePrefsAndroid* distilled_page_prefs_android =
new DistilledPagePrefsAndroid(env, obj, distilledPagePrefs); new DistilledPagePrefsAndroid(env, obj, distilled_page_prefs);
return reinterpret_cast<intptr_t>(distilled_page_prefs_android); return reinterpret_cast<intptr_t>(distilled_page_prefs_android);
} }
...@@ -41,5 +42,48 @@ bool DistilledPagePrefsAndroid::Register(JNIEnv* env) { ...@@ -41,5 +42,48 @@ bool DistilledPagePrefsAndroid::Register(JNIEnv* env) {
return RegisterNativesImpl(env); return RegisterNativesImpl(env);
} }
void DistilledPagePrefsAndroid::AddObserver(JNIEnv* env,
jobject obj,
jlong observer_ptr) {
DistilledPagePrefsObserverAndroid* distilled_page_prefs_observer_wrapper =
reinterpret_cast<DistilledPagePrefsObserverAndroid*>(observer_ptr);
distilled_page_prefs_->AddObserver(distilled_page_prefs_observer_wrapper);
}
void DistilledPagePrefsAndroid::RemoveObserver(JNIEnv* env,
jobject obj,
jlong observer_ptr) {
DistilledPagePrefsObserverAndroid* distilled_page_prefs_observer_wrapper =
reinterpret_cast<DistilledPagePrefsObserverAndroid*>(observer_ptr);
distilled_page_prefs_->RemoveObserver(distilled_page_prefs_observer_wrapper);
}
DistilledPagePrefsObserverAndroid::DistilledPagePrefsObserverAndroid(
JNIEnv* env,
jobject obj) {
java_ref_.Reset(env, obj);
}
DistilledPagePrefsObserverAndroid::~DistilledPagePrefsObserverAndroid() {}
void DistilledPagePrefsObserverAndroid::DestroyObserverAndroid(JNIEnv* env,
jobject obj) {
delete this;
}
void DistilledPagePrefsObserverAndroid::OnChangeTheme(
DistilledPagePrefs::Theme new_theme) {
JNIEnv* env = base::android::AttachCurrentThread();
Java_DistilledPagePrefsObserverWrapper_onChangeTheme(
env, java_ref_.obj(), (int)new_theme);
}
jlong InitObserverAndroid(JNIEnv* env, jobject obj) {
DistilledPagePrefsObserverAndroid* observer_android =
new DistilledPagePrefsObserverAndroid(env, obj);
return reinterpret_cast<intptr_t>(observer_android);
}
} // namespace android } // namespace android
} // namespace dom_distiller } // namespace dom_distiller
...@@ -17,11 +17,13 @@ class DistilledPagePrefsAndroid { ...@@ -17,11 +17,13 @@ class DistilledPagePrefsAndroid {
public: public:
DistilledPagePrefsAndroid(JNIEnv* env, DistilledPagePrefsAndroid(JNIEnv* env,
jobject obj, jobject obj,
DistilledPagePrefs* distillerPagePrefsPtr); DistilledPagePrefs* distilled_page_prefs_ptr);
virtual ~DistilledPagePrefsAndroid(); virtual ~DistilledPagePrefsAndroid();
static bool Register(JNIEnv* env); static bool Register(JNIEnv* env);
void SetTheme(JNIEnv* env, jobject obj, jint theme); void SetTheme(JNIEnv* env, jobject obj, jint theme);
jint GetTheme(JNIEnv* env, jobject obj); jint GetTheme(JNIEnv* env, jobject obj);
void AddObserver(JNIEnv* env, jobject obj, jlong obs);
void RemoveObserver(JNIEnv* env, jobject obj, jlong obs);
private: private:
DistilledPagePrefs* distilled_page_prefs_; DistilledPagePrefs* distilled_page_prefs_;
...@@ -29,6 +31,20 @@ class DistilledPagePrefsAndroid { ...@@ -29,6 +31,20 @@ class DistilledPagePrefsAndroid {
DISALLOW_COPY_AND_ASSIGN(DistilledPagePrefsAndroid); DISALLOW_COPY_AND_ASSIGN(DistilledPagePrefsAndroid);
}; };
class DistilledPagePrefsObserverAndroid : public DistilledPagePrefs::Observer {
public:
DistilledPagePrefsObserverAndroid(JNIEnv* env, jobject obj);
virtual ~DistilledPagePrefsObserverAndroid();
// DistilledPagePrefs::Observer implementation.
virtual void OnChangeTheme(DistilledPagePrefs::Theme new_theme) OVERRIDE;
virtual void DestroyObserverAndroid(JNIEnv* env, jobject obj);
private:
base::android::ScopedJavaGlobalRef<jobject> java_ref_;
};
} // namespace android } // namespace android
} // namespace dom_distiller } // namespace dom_distiller
......
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