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 package org.chromium.chrome.browser.dom_distiller; 6 7 import android.app.Activity; 8 9 import org.chromium.base.CalledByNative; 10 import org.chromium.base.JNINamespace; 11 import org.chromium.chrome.browser.EmptyTabObserver; 12 import org.chromium.chrome.browser.Tab; 13 import org.chromium.chrome.browser.TabObserver; 14 import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; 15 import org.chromium.content.browser.ContentViewCore; 16 import org.chromium.content_public.browser.WebContents; 17 18 /** 19 * Java implementation of dom_distiller::android::FeedbackReporterAndroid. 20 */ 21 @JNINamespace("dom_distiller::android") 22 public final class DomDistillerFeedbackReporter implements 23 DomDistillerFeedbackReportingView.FeedbackObserver { 24 25 private static ExternalFeedbackReporter sExternalFeedbackReporter = 26 new NoOpExternalFeedbackReporter(); 27 28 public static void setExternalFeedbackReporter(ExternalFeedbackReporter reporter) { 29 sExternalFeedbackReporter = reporter; 30 } 31 32 private static class NoOpExternalFeedbackReporter implements ExternalFeedbackReporter { 33 @Override 34 public void reportFeedback(Activity activity, String url, boolean good) { 35 } 36 } 37 38 private final long mNativePointer; 39 private final Tab mTab; 40 41 private ContentViewCore mContentViewCore; 42 private DomDistillerFeedbackReportingView mReportingView; 43 44 /** 45 * @return whether the DOM Distiller feature is enabled. 46 */ 47 public static boolean isEnabled() { 48 return false; 49 } 50 51 /** 52 * Creates the FeedbackReporter, adds itself as a TabObserver, and ensures 53 * references to ContentView and WebContents are up to date. 54 * 55 * @param tab the tab where the overlay should be displayed. 56 */ 57 public DomDistillerFeedbackReporter(Tab tab) { 58 mNativePointer = nativeInit(); 59 mTab = tab; 60 mTab.addObserver(createTabObserver()); 61 updatePointers(); 62 } 63 64 @Override 65 public void onYesPressed(DomDistillerFeedbackReportingView view) { 66 if (view != mReportingView) return; 67 recordQuality(true); 68 dismissOverlay(); 69 } 70 71 @Override 72 public void onNoPressed(DomDistillerFeedbackReportingView view) { 73 if (view != mReportingView) return; 74 recordQuality(false); 75 dismissOverlay(); 76 } 77 78 /** 79 * Records feedback for the distilled content. 80 * 81 * @param good whether the perceived quality of the distillation of a web page was good. 82 */ 83 private void recordQuality(boolean good) { 84 nativeReportQuality(good); 85 if (!good) { 86 Activity activity = mTab.getWindowAndroid().getActivity().get(); 87 String url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl( 88 mContentViewCore.getWebContents().getUrl()); 89 sExternalFeedbackReporter.reportFeedback(activity, url, good); 90 } 91 } 92 93 /** 94 * Start showing the overlay. 95 */ 96 @CalledByNative 97 private void showOverlay() { 98 mReportingView = DomDistillerFeedbackReportingView.create(mContentViewCore, this); 99 } 100 101 /** 102 * Dismiss the overlay which is currently being displayed. 103 */ 104 @CalledByNative 105 private void dismissOverlay() { 106 if (mReportingView != null) { 107 mReportingView.dismiss(true); 108 mReportingView = null; 109 } 110 } 111 112 /** 113 * Updates which ContentViewCore and WebContents the FeedbackReporter is monitoring. 114 */ 115 private void updatePointers() { 116 mContentViewCore = mTab.getContentViewCore(); 117 nativeReplaceWebContents(mNativePointer, mTab.getWebContents()); 118 } 119 120 /** 121 * Creates a TabObserver for monitoring a Tab, used to react to changes in the ContentViewCore 122 * or to trigger its own destruction. 123 * 124 * @return TabObserver that can be used to monitor a Tab. 125 */ 126 private TabObserver createTabObserver() { 127 return new EmptyTabObserver() { 128 @Override 129 public void onWebContentsSwapped(Tab tab, boolean didStartLoad, 130 boolean didFinishLoad) { 131 updatePointers(); 132 } 133 134 @Override 135 public void onContentChanged(Tab tab) { 136 updatePointers(); 137 } 138 139 @Override 140 public void onDestroyed(Tab tab) { 141 nativeDestroy(mNativePointer); 142 mContentViewCore = null; 143 } 144 }; 145 } 146 147 private static native boolean nativeIsEnabled(); 148 149 private static native void nativeReportQuality(boolean good); 150 151 private native long nativeInit(); 152 153 private native void nativeDestroy(long nativeFeedbackReporterAndroid); 154 155 private native void nativeReplaceWebContents( 156 long nativeFeedbackReporterAndroid, WebContents webContents); 157 } 158