Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions README-places.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
This branch is a WIP for hooking up the "places" component in the reference
browser. It will only work with
[this android-components branch](https://github.com/mhammond/android-components/tree/autocomplete-places),
and in particular, after following
[these instructions](https://github.com/mhammond/android-components/blob/autocomplete-places/components/service/sync-places/README.md)

There's a new `BrowserAutocompleteProvider.kt` which wraps both the
`DomainAutocompleteProvider` and the places component. It first tries to
find matches using places, then using the `DomainAutocompleteProvider`.

Note that because we don't yet have geckoview hooked up to collect visit
information and write them to the places database. the places database will
be empty - meaning only
suggestions from `DomainAutocompleteProvider` will be shown. However, there's
a trick you can use to import your desktop places database and have it use
that.

* You will need to check out the application-services repo, and from the
`places` directory (soon to be `components/places`), execute:

`cargo run --release --example autocomplete -- --import-places auto`

(alternatively, in the place of `auto`, specify the full path to a desktop
`places.sqlite`)

This will also start a demo-app where you can perform auto-complete queries.
Press ESC to exit the app, and note that in the same directory you will have
a file `new-places.db` - rename this file to `places.sqlite`

* Kill the app in the emulator.

* Use the "Device File Explorer" in Android Studio, and navigate to the
`sdcard/Android/data/org.mozilla.reference.browser/files` directory - if
you've run the app before, you should already find a `places.sqlite` there.
Upload the file created above here and restart the app.

Note that if you have many many visits (eg, mine has ~170k places with ~230k
visits with a db size of ~75MB) a search for a full domain may take a couple
of seconds, but we know how to fix this. Even with a database this size,
searches of small substrings (eg, a few letters) are fast. We never expect a
"real" mobile device database to be this large, but it's a nice stress-test.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ dependencies {

implementation Deps.mozilla_ui_autocomplete

implementation Deps.mozilla_service_sync_places
implementation Deps.mozilla_service_firefox_accounts

implementation Deps.mozilla_support_utils
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* 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/. */

// This is, roughly, an "auto-complete aggregator" - it first tries to find a match via "places",
// and if that fails, falls back to the "domain" provider.
package org.mozilla.reference.browser.browser

import android.app.Activity
import android.content.Context
import kotlinx.coroutines.experimental.launch
import mozilla.components.browser.domains.DomainAutoCompleteProvider
import mozilla.components.browser.toolbar.BrowserToolbar
import mozilla.components.ui.autocomplete.InlineAutocompleteEditText
import mozilla.components.service.sync.places.PlacesAwesomeBarProvider

// NOTE: this should be updated or replaced once mozilla.components.concept.awesomebar is in-place
// and has an implementation. Consider this a proof-of-concept only.
class BrowserAutocompleteProvider (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this type should ultimately live in the components repo. Likely, part of this component:
mozilla-mobile/android-components#1109

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PlacesConnection could live in the services/sync-places component using the mozilla.components package.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PlacesConnection has an unsafe implementation so it should live in a-s. (Although maybe there will be a very similar type in mozilla.components, as with the recent fxa work)

context: Context,
toolbar: BrowserToolbar,
sessionId: String? = null) {

private val domainAutoCompleteProvider = DomainAutoCompleteProvider().apply {
initialize(context)
}

// XXX - this should be in the "profile" dir, but I'm not sure how to fetch that.
private val placesProvider = PlacesAwesomeBarProvider(context)

init {
toolbar.setAutocompleteFilter { value, view ->
view?.let { _ ->
// use a coroutine to do this off the main thread.
launch {
// First try places.
// XXX - given the inlineautocomplete functionality, we eventually want to perform
// an OriginOrUrl search - however, for now, we just perform a "normal" search,
// then iterate the results until we find one that matches at the start.
var finalResult: String? = null
var finalSource: String? = null
var finalSize: Int? = 0;

val placesResult = placesProvider.getSuggestion(value)
if (placesResult != null) {
finalResult = placesResult
finalSource = "places"
finalSize = 1
} else {
val result = domainAutoCompleteProvider.autocomplete(value)
finalResult = result.text
finalSource = result.source
finalSize = result.size
}
// domainAutoCompleteProvider always provides a result, even if it is empty strings.
val activity = view.context as Activity
activity.runOnUiThread {
view.applyAutocompleteResult(
InlineAutocompleteEditText.AutocompleteResult(finalResult, finalSource!!, finalSize!!)
)
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

package org.mozilla.reference.browser.browser

import android.app.Activity
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.os.Bundle
import android.support.v4.app.Fragment
Expand Down Expand Up @@ -47,6 +48,8 @@ class BrowserFragment : Fragment(), BackHandler, DownloadDialogListener {

tabsToolbarFeature = TabsToolbarFeature(context!!, toolbar, ::showTabs)

BrowserAutocompleteProvider(context!!, toolbar)

downloadsFeature = DownloadsFeature(
requireContext(),
sessionManager = requireComponents.sessionManager,
Expand Down
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ plugins {

allprojects {
repositories {
mavenLocal()

google()

maven {
Expand Down
4 changes: 3 additions & 1 deletion buildSrc/src/main/java/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ private object Versions {

const val android_gradle_plugin = "3.1.4"

const val mozilla_android_components = "0.28.0"
const val mozilla_android_components = "0.28.0-SNAPSHOT"
}

// Synchronized dependencies used by (some) modules
Expand Down Expand Up @@ -50,6 +50,8 @@ object Deps {
const val mozilla_support_utils = "org.mozilla.components:support-utils:${Versions.mozilla_android_components}"
const val mozilla_support_ktx= "org.mozilla.components:support-ktx:${Versions.mozilla_android_components}"

const val mozilla_service_sync_places = "org.mozilla.components:service-sync-places:0.28.0-SNAPSHOT" // TODO: use a released version.

const val testing_junit = "junit:junit:${Versions.junit}"
const val testing_robolectric = "org.robolectric:robolectric:${Versions.robolectric}"
const val testing_mockito = "org.mockito:mockito-core:${Versions.mockito}"
Expand Down