/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.fenix.components.searchengine import android.graphics.Bitmap import android.util.Base64 import android.util.Log import org.w3c.dom.Document import java.io.ByteArrayOutputStream import java.io.StringWriter import javax.xml.parsers.DocumentBuilderFactory import javax.xml.parsers.ParserConfigurationException import javax.xml.transform.OutputKeys import javax.xml.transform.TransformerConfigurationException import javax.xml.transform.TransformerException import javax.xml.transform.TransformerFactory import javax.xml.transform.dom.DOMSource import javax.xml.transform.stream.StreamResult private const val BITMAP_COMPRESS_QUALITY = 100 private fun Bitmap.toBase64(): String { val stream = ByteArrayOutputStream() compress(Bitmap.CompressFormat.PNG, BITMAP_COMPRESS_QUALITY, stream) val encodedImage = Base64.encodeToString(stream.toByteArray(), Base64.DEFAULT) return "data:image/png;base64,$encodedImage" } class SearchEngineWriter { companion object { private const val LOG_TAG = "SearchEngineWriter" fun buildSearchEngineXML(engineName: String, searchQuery: String, iconBitmap: Bitmap): String? { try { val document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument() val rootElement = document!!.createElement("OpenSearchDescription") rootElement.setAttribute("xmlns", "http://a9.com/-/spec/opensearch/1.1/") document.appendChild(rootElement) val shortNameElement = document.createElement("ShortName") shortNameElement.textContent = engineName rootElement.appendChild(shortNameElement) val imageElement = document.createElement("Image") imageElement.setAttribute("width", "16") imageElement.setAttribute("height", "16") imageElement.textContent = iconBitmap.toBase64() rootElement.appendChild(imageElement) val descriptionElement = document.createElement("Description") descriptionElement.textContent = engineName rootElement.appendChild(descriptionElement) val urlElement = document.createElement("Url") urlElement.setAttribute("type", "text/html") val templateSearchString = searchQuery.replace("%s", "{searchTerms}") urlElement.setAttribute("template", templateSearchString) rootElement.appendChild(urlElement) return xmlToString(document) } catch (e: ParserConfigurationException) { Log.e(LOG_TAG, "Couldn't create new Document for building search engine XML", e) return null } } private fun xmlToString(doc: Document): String? { val writer = StringWriter() try { val tf = TransformerFactory.newInstance().newTransformer() tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8") tf.transform(DOMSource(doc), StreamResult(writer)) } catch (e: TransformerConfigurationException) { return null } catch (e: TransformerException) { return null } return writer.toString() } } }