1 /* 2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. 3 */ 4 #include "config.h" 5 6 #include "Frame.h" 7 #include "FrameLoader.h" 8 #include "BackForwardList.h" 9 #include "BackForwardController.h" 10 #include "HistoryItem.h" 11 #include "Image.h" 12 #include "JavaEnv.h" 13 #include "Page.h" 14 #include "WebPage.h" 15 16 using namespace WebCore; 17 18 #ifdef __cplusplus 19 extern "C" { 20 #endif 21 22 static Page* getPage(jlong jpage) 23 { 24 return WebPage::pageFromJLong(jpage); 25 } 26 27 static BackForwardList* getBfl(jlong jpage) 28 { 29 return static_cast<WebCore::BackForwardList*>(getPage(jpage)->backForward().client()); 30 } 31 32 static HistoryItem* getItem(jlong jitem) 33 { 34 return static_cast<HistoryItem*>(jlong_to_ptr(jitem)); 35 } 36 37 static jmethodID initMethod(JNIEnv* env, jclass cls, const char* name, const char* signature) 38 { 39 jmethodID mid = env->GetMethodID(cls, name, signature); 40 ASSERT(mid); 41 return mid; 42 } 43 44 static jmethodID initCtor(JNIEnv* env, jclass cls, const char* signature) 45 { 46 return initMethod(env, cls, "<init>", signature); 47 } 48 49 // ENTRY-RELATED METHODS 50 51 static jclass getJEntryClass() 52 { 53 JNIEnv* env = WebCore_GetJavaEnv(); 54 55 static JGClass jEntryClass(env->FindClass("com/sun/webkit/BackForwardList$Entry")); 56 ASSERT(jEntryClass); 57 58 return jEntryClass; 59 } 60 61 static jclass getJBFLClass() 62 { 63 JNIEnv* env = WebCore_GetJavaEnv(); 64 65 static JGClass jBFLClass(env->FindClass("com/sun/webkit/BackForwardList")); 66 ASSERT(jBFLClass); 67 68 return jBFLClass; 69 } 70 71 static JLObject createEntry(HistoryItem* item, jlong jpage) 72 { 73 74 JNIEnv* env = WebCore_GetJavaEnv(); 75 static jmethodID entryCtorMID = initCtor(env, getJEntryClass(), "(JJ)V"); 76 77 JLObject jEntry(env->NewObject(getJEntryClass(), entryCtorMID, ptr_to_jlong(item), jpage)); 78 CheckAndClearException(env); 79 80 item->setHostObject(jEntry); 81 82 return jEntry; 83 } 84 85 static void notifyHistoryItemChangedImpl(HistoryItem* item) { 86 JNIEnv* env = WebCore_GetJavaEnv(); 87 static jmethodID notifyItemChangedMID = initMethod(env, getJEntryClass(), "notifyItemChanged", "()V"); 88 if (item->hostObject()) { 89 env->CallVoidMethod(item->hostObject(), notifyItemChangedMID); 90 CheckAndClearException(env); 91 } 92 } 93 94 void notifyHistoryItemDestroyed(const JLObject &host) 95 { 96 WC_GETJAVAENV_CHKRET(env); 97 static jmethodID notifyItemDestroyedMID = 98 initMethod(env, getJEntryClass(), "notifyItemDestroyed", "()V"); 99 if (host) { 100 env->CallVoidMethod(host, notifyItemDestroyedMID); 101 CheckAndClearException(env); 102 } 103 } 104 105 // entry.getURL() 106 JNIEXPORT jstring JNICALL Java_com_sun_webkit_BackForwardList_bflItemGetURL(JNIEnv* env, jclass z, jlong jitem) 107 { 108 HistoryItem* item = getItem(jitem); 109 String urlString = item->urlString(); 110 return urlString.toJavaString(env).releaseLocal(); 111 } 112 113 // entry.getTitle() 114 JNIEXPORT jstring JNICALL Java_com_sun_webkit_BackForwardList_bflItemGetTitle(JNIEnv* env, jclass z, jlong jitem) 115 { 116 HistoryItem* item = getItem(jitem); 117 String title = item->title(); 118 return title.toJavaString(env).releaseLocal(); 119 } 120 121 // entry.getIcon() 122 JNIEXPORT jobject JNICALL Java_com_sun_webkit_BackForwardList_bflItemGetIcon(JNIEnv* env, jclass z, jlong jitem) 123 { 124 HistoryItem* item = getItem(jitem); 125 /* 126 if (item != NULL) { 127 // TODO: crashes with DRT 128 return *WebCore::iconDatabase().synchronousIconForPageURL(item->url(), WebCore::IntSize(16, 16))->nativeImageForCurrentFrame(); 129 Image* icon = item->icon(); 130 if (icon != NULL) { 131 return *icon->javaImage(); 132 } 133 } 134 */ 135 return NULL; 136 } 137 138 // entry.getLastVisited() 139 JNIEXPORT jlong JNICALL Java_com_sun_webkit_BackForwardList_bflItemGetLastVisitedDate(JNIEnv* env, jclass z, jlong jitem) 140 { 141 // HistoryItem* item = getItem(jitem); 142 // double lastVisitedDate = item->lastVisitedTime(); 143 // return (jlong) (lastVisitedDate * 1000); 144 return 0; // todo tav where is lastVisitedDate field? 145 } 146 147 // entry.isTargetItem() 148 JNIEXPORT jboolean JNICALL Java_com_sun_webkit_BackForwardList_bflItemIsTargetItem(JNIEnv* env, jclass z, jlong jitem) 149 { 150 HistoryItem* item = getItem(jitem); 151 return (jboolean)item->isTargetItem(); 152 } 153 154 // entry.getTarget() 155 JNIEXPORT jstring JNICALL Java_com_sun_webkit_BackForwardList_bflItemGetTarget(JNIEnv* env, jclass z, jlong jitem) 156 { 157 HistoryItem* item = getItem(jitem); 158 String target = item->target(); 159 if (!target.isEmpty()) { 160 return target.toJavaString(env).releaseLocal(); 161 } else { 162 return NULL; 163 } 164 } 165 166 // entry.getChildren() 167 JNIEXPORT jobjectArray JNICALL Java_com_sun_webkit_BackForwardList_bflItemGetChildren(JNIEnv* env, jclass z, jlong jitem, jlong jpage) 168 { 169 HistoryItem* item = getItem(jitem); 170 if (!item->hasChildren()) { 171 return NULL; 172 } 173 jobjectArray children = env->NewObjectArray(item->children().size(), getJEntryClass(), NULL); 174 int i = 0; 175 for (HistoryItemVector::const_iterator it = item->children().begin(); 176 it != item->children().end(); 177 ++it) 178 { 179 env->SetObjectArrayElement(children, i++, (jobject)createEntry(&**it, jpage)); 180 } 181 return children; 182 } 183 184 // BACKFORWARDLIST METHODS 185 186 static int getSize(BackForwardList* bfl) 187 { 188 int size = 0; 189 if (bfl->currentItem()) 190 size = bfl->forwardListCount() + bfl->backListCount() + 1; 191 return size; 192 } 193 194 // BackForwardList.size() 195 JNIEXPORT jint JNICALL Java_com_sun_webkit_BackForwardList_bflSize(JNIEnv* env, jclass z, jlong jpage) 196 { 197 return getSize(getBfl(jpage)); 198 } 199 200 // BackForwardList.getMaximumSize() 201 JNIEXPORT jint JNICALL Java_com_sun_webkit_BackForwardList_bflGetMaximumSize(JNIEnv* env, jclass z, jlong jpage) 202 { 203 BackForwardList* bfl = static_cast<BackForwardList *>(getBfl(jpage)); 204 return bfl->capacity(); 205 } 206 207 // BackForwardList.setMaximumSize() 208 JNIEXPORT void JNICALL Java_com_sun_webkit_BackForwardList_bflSetMaximumSize(JNIEnv* env, jclass z, jlong jpage, jint size) 209 { 210 BackForwardList* bfl = static_cast<BackForwardList *>(getBfl(jpage)); 211 bfl->setCapacity(size); 212 } 213 214 // BackForwardList.getCurrentIndex() 215 JNIEXPORT jint JNICALL Java_com_sun_webkit_BackForwardList_bflGetCurrentIndex(JNIEnv* env, jclass z, jlong jpage) 216 { 217 BackForwardList* bfl = getBfl(jpage); 218 return bfl->currentItem() ? bfl->backListCount() : -1; 219 } 220 221 // BackForwardList.setEnabled() 222 JNIEXPORT void JNICALL Java_com_sun_webkit_BackForwardList_bflSetEnabled(JNIEnv* env, jclass z, jlong jpage, jboolean flag) 223 { 224 BackForwardList* bfl = static_cast<BackForwardList *>(getBfl(jpage)); 225 bfl->setEnabled(flag); 226 } 227 228 // BackForwardList.isEnabled() 229 JNIEXPORT jboolean JNICALL Java_com_sun_webkit_BackForwardList_bflIsEnabled(JNIEnv* env, jclass z, jlong jpage) 230 { 231 BackForwardList* bfl = static_cast<BackForwardList *>(getBfl(jpage)); 232 return bfl->enabled(); 233 } 234 235 static HistoryItem* itemAtIndex(BackForwardList* bfl, int index) 236 { 237 // Note: WebKit counts from the *current* position 238 return bfl->itemAtIndex(index - bfl->backListCount()); 239 } 240 241 // BackForwardList.get() 242 JNIEXPORT jobject JNICALL Java_com_sun_webkit_BackForwardList_bflGet(JNIEnv* env, jclass z, jlong jpage, jint index) 243 { 244 BackForwardList* bfl = getBfl(jpage); 245 HistoryItem* item = itemAtIndex(bfl, index); 246 if (!item) 247 return 0; 248 JLObject host(item->hostObject()); 249 if (!host) { 250 host = createEntry(item, jpage); 251 } 252 return host.releaseLocal(); 253 } 254 255 // BackForwardList.setCurrentIndex() 256 JNIEXPORT jint JNICALL Java_com_sun_webkit_BackForwardList_bflSetCurrentIndex(JNIEnv* env, jclass z, jlong jpage, jint index) 257 { 258 Page* page = getPage(jpage); 259 BackForwardList* bfl = static_cast<BackForwardList*>(page->backForward().client()); 260 if (index < 0 || index >= getSize(bfl)) 261 return -1; 262 int distance = index - bfl->backListCount(); 263 page->backForward().goBackOrForward(distance); 264 return index; 265 } 266 267 // BackForwardList.get[Last]IndexOf() 268 JNIEXPORT jint JNICALL Java_com_sun_webkit_BackForwardList_bflIndexOf(JNIEnv* env, jclass z, jlong jpage, jlong jitem, jboolean reverse) 269 { 270 if (!jitem) 271 return -1; 272 BackForwardList* bfl = getBfl(jpage); 273 int size = getSize(bfl); 274 int start = reverse ? size - 1 : 0; 275 int end = reverse ? -1 : size; 276 int inc = reverse ? -1 : 1; 277 HistoryItem* item = static_cast<HistoryItem*>(jlong_to_ptr(jitem)); 278 for (int i = start; i != end; i += inc) 279 if (item == itemAtIndex(bfl, i)) 280 return i; 281 return -1; 282 } 283 284 JNIEXPORT void JNICALL Java_com_sun_webkit_BackForwardList_bflSetHostObject(JNIEnv* env, jclass z, jlong jpage, jobject host) 285 { 286 BackForwardList* bfl = getBfl(jpage); 287 bfl->setHostObject(JLObject(host, true)); 288 289 notifyHistoryItemChanged = notifyHistoryItemChangedImpl; 290 } 291 292 #ifdef __cplusplus 293 } 294 #endif 295 296 namespace WebCore { 297 298 // ChangeListener support 299 void notifyBackForwardListChanged(const JLObject &host) 300 { 301 JNIEnv* env = WebCore_GetJavaEnv(); 302 303 if (!host) { 304 return; 305 } 306 307 static jmethodID notifyChangedMID = initMethod( 308 env, 309 getJBFLClass(), 310 "notifyChanged", 311 "()V"); 312 ASSERT(notifyChangedMID); 313 314 env->CallVoidMethod(host, notifyChangedMID); 315 CheckAndClearException(env); 316 } 317 318 } // namespace WebCore