User:Anaaktgeboren/SearchEngineSync
Goals
- Sync search engine prefs on Desktop
- addition of an engine
- removal of an engine
- reordering of engines
- keywords/aliases for a particular engine
- restore defaults (potentially not a special case for implementation, but could be considered a feature by users)
- Format to be interoperable with firefox os, mobile firefox, or other future clients
- Nongoals:
- implementation on firefox os
- implementation on mobile firefox
Design
Requirements Gathering (deadline for input: july 26)
- Stakeholders
- Desktop: Gavin
- Desktop UX: madhava, boriss, ibarlow on mobile, poked twice
- Mobile: bnicholson, mfinkle
- B@G: N/A, Ben Francis, b2g has no plugins and few preferences at this time
- Privacy: Tom, Sid
- Security: David Chan
- Product: Asa
- Services Integration: Gps
- Community: dev-planning, dev-apps-firefox lists
- Legal: bug 778823,
- Current Requirements
- does not sync hijacked queries
- origin: Asa, browser cannot currently detect this, requires a new browser feature
- syncs code & not a server call, mitigate risk
- origin sstamm, reducing the addon sync threat
- search order preserved
- 3rd party plugins appear
- does not sync hijacked queries
Current Suggestions/Notes
- input
- want to avoid syncing app-shipped search plugins, origin: gavin
- dont sync XML files, sync the JSON cache that's the result of parse origin: gavin
- mobile uses same nsISearchService as desktop -mfinkle
- should it be applicationID based, the way addons?
- should we limit to a blessed type of plugin to address hijacking?
- impact of Australis?
Design Reviews if needed
- privacy security?
- UI changes?
Implementation
- not started
Release
- targeted to land on Nightly during Q3 (not a promise, subject to scope change)
Reference
- this implementation bug: 444284
- addon sync implemetnation bug: 534956
- https://developer.mozilla.org/en/Adding_search_engines_from_web_pages
- http://www.opensearch.org/Specifications/OpenSearch/1.1#OpenSearch_description_document
- https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox
- http://docs.services.mozilla.com/sync/index.html
Draft Plan
- currently full of holes
Spec
- proposed data model for a plugin record
{
id // string id
name // similiar but different from the description
alias // optional, if user has set keywords
order // optional if user has reordered engines
hidden // optional, if user has 'deleted' a default engine, or an extensions had hidden a custom one.
description // short description string
searchForm // exists
iconurl // the icon. found on defaults as well.
urls //a nice fat object for included ones, less so for custom probably
url // optional, not found on default
installLocation // optional. if not present, this plugin is default [app]
type //optional
queryCharset //optional
readOnly // optional in the event that we sync readonly plugins in the future
locale // currently all records should have the same value, but it is reasonable for in the future
// for plugins to have different settings for this
}
- Not Syncing
- directory - machine specific
- lastModifiedTime - machine & directory specific. used to invalidate cache
- filepath - path to the xml, which wont exist since we arent syncing the xml and would be specific to a machine (where fx is installed, where profile is installed, etc)
- The OpenSearch plugins, ordering of search engines, keywords for search engines (both custom & default), and hidden flags (default engines only afaik) will be sync'ed across platforms (though the mobile client(s) will be written later)
- parts of default engines will be synced (such as ordering & keywords)
- the currently selected engine will not be synced, as that is a local setting and probably does not make sense to sync
- read-only engines cannot be serialized, and therefore probably should not be sync'ed (I believe this is just the default ones)
- When a user changes or removes a keyword or custom engine, the removal will be synced
- When a user removes a default engine, the removal will be synced (but note that the browser does not actually remove those, it just hides it)
- The results of "Restore Defaults" will be synced (restores all deleted defaults, wipes db to default single entry (ketwords, ordering). This will not be treated as a special operation by sync
- Until the browser implements detecting hijacked searches, this engine will be preffed off by default for existing and new users
- Reconciliation: Merge by Default
- When users choose model from settings, overrides this default?
- what if the default ordering is different on two clients?
Implementation schedule
- largely made up, as the repositories re-write is a huge wild card
- feedback due by 26-jul
- spec finalized by 3-Aug
- Implement store, record for json + tests by 10-aug
- Implement store, record for db(ordering, keywords) + tests by 15-aug
- Implement tracker + xpc tracker tests by 24-aug
- Implement engine + xpc tests by 7-sep
- most likely to get snagged here
- Implement tps tests (if possible, see dependencies) and any remaining xpc tests by sep-14
- Debugging (unknown)
- 'cause there's going to a landmine somewhere
Dependencies
- TPS supporting desktop to mobile operations (jgriffin's team)
- TPS new data tupe addition (jgriffin's team)
- Desktop client supporting hijacked search detection (gavin?)
- so engine can be enabled by default for new or existing users
- Someone implementing the corresponding mobile engine (?)
- repositories rewrite (gps)
Test Plan
TPS Tests
- Important Notes
- tps does not support the native mobile at this time. timeframe unknown for support
- dependency - adding a new engine will require work on tps. timeframe unknown, but likely to be reasonable
- tests cannot really be written ahead of those changes to tps
- Tests
- only reordering syncs between profile 1 & profile 2
- only keyword addition, change, and removal sync between profile 1 & 2
- adding and removing a search engine plugin syncs between profile 1 & 2
- add plugin, add keyword, reorder, sync between two desktops, remove & sync again
- add plugin, add keyword, reorder, sync between mobile (if mobile client exists) & desktop, remove & sync again
XPC Shell Tests
- make sure there is heavy testing about reordering with hidden & default engines, as some of the calls may have unexpected side effects (and some functions consider hidden in counts and others do not, same deal with what counts as default)
- impacted by repositories re-write?
Scratch and Notes
- Insights
- user created keywords are called 'alias'es in code, stored in search-metadata.json
- search-metadata.json
- may not exist if nothigns been changed
- contains per plugin: order placement, hidden, and keywords
- /profile/search.json
- "directories" will have two entries, the default one ("/Applications/Firefox.app/Contents/MacOS/searchplugins") & "/Users/mozilla/Documents/inbox-desktop/test_profiles/searchplugins" in my case) The first has no usefully syncable data, though it does have a lastModifiedTime (this is the lastModifiedTime of the directory, used for cache invalidation --Gavin)
- /profile/search.sqlite(DO NOT SYNC) (this is no longer used after bug 699856, replaced by search-metadata.json --Gavin)
- pref browser.search.selectedEngine represents the currently selected entry, status "user set" is useful
- pref browser.search.useDBForOrder i bet that represents ordering (this gets set to true once the user has customized the search engine order, to indicate that we should use the positioning information in search-metadata.json rather than the one in default prefs (browser.search.order.*) --Gavin)
- pref browser.search.order.1-3 are hard coded defaults. do not sync
- JAR loading code is for mobile, for their default plugin handling
- Australis is not making the search engines or their data go away
- "Search service changes will be required for this, almost certainly. Exposing the engine description as JSON and adding the ability to distinguish app-shipped plugins via the nsIBrowserSearchService API seem like good first steps to me" - gavin
- Poking Pointers
- changes frequently dont show up immediate (but get written on close)
- ordering in data store includes hidden engines. the number may not match the observed number
- note in the example below all engines are off by 1 because google is order:1 and hidden, so youtube appears first in the list but has order:2
- getting a 3rd party search thingy
- right click on a website search bar (ie youtube) and /profile/searchplugins will be created with an OpenSearch .xml
- searchplugins doesn't exist until you create a non-default one
- SQLite table: install addon, go to tools -> SQLiteManager -> select db, go
- default engines have a hidden value, which afaic, is never applied to custom engines?
- current problems
- what should happen when default lists dont match?
- defaults should be synced because they may not be present on other systems and users can expect to see them (though the mobile client may grey them out)
- should be clients problem
- mobile has state that desktop does not (enable/disable)
- mobile will want more state about usage than desktop does
- how do i gracefully slurp the json content?
- can i dump the json content back into the data store *without* the xml?
- design pondering
- Should this be like tabs and a one-record /client
- or breakdown the table's multiple entry, grab the json and make it one record per 3rd party (but what about ordering of defaults?)
- treat the table & the json as entirely separate things, essentially two record types? tis not really the sync way and I do not even know if it is feasible
- do i extract the values of the json blob and rebuild it on the client, or send the thing over the wire wholesale?
- what should happen when default lists dont match?
- What do these data formats look like anyway?
- search-metadata.json. reordering + keywords. Note this file can be empty
{
"[app]/google.xml":
{
"hidden":true,
"alias":null,
"order":1
},
"[profile]/youtube-video-search.xml":
{
"order":2,
"alias":"anaaktge_test_keyword"
},
"[app]/bing.xml":
{
"order":3
},
"[app]/amazondotcom.xml":
{
"order":4,
"alias":"anaaktge_test_keyword_default"
},
"[app]/eBay.xml":
{
"order":5
},
"[app]/twitter.xml":
{
"order":6
},
"[app]/wikipedia.xml":
{
"order":7
},
"[app]/yahoo.xml":
{
"order":8
}
}
- search.json, one default plugin, one custom (youtube) plugin
{
"version":7,
"buildID":"20120730133507",
"locale":"en-US",
"directories":
{
"/Users/mozilla/moz/hg/services-central/./obj-x86_64-apple-darwin11.4.0/dist/NightlyDebug.app/Contents/MacOS/searchplugins":
{
"lastModifiedTime":1343683762000,
"engines":
[
{
"_id":"[app]/amazondotcom.xml",
"_name":"Amazon.com",
"_hidden":false,
"description":"Amazon.com Search",
"__searchForm":"http://www.amazon.com/",
"_iconURL":"data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHgSURBVHjalFM9TNtQEP4cB7PwM1RITUXIgsRaYEEVEyKZwhiyZAQyd0BhpFOlIjoBqhjSqVQMoVMLLAjEwECCQJkSkBqJYDOAFOMKFSf28d7DTUxiUDnp/Pzeu/vuu7t3ICKF6SLTMv2/lB0fRWKfjwDm4JJisYh0Oo3fpZLYT0SjSCQS8JAFMADNDZ3NZsnf1taiqVTKi4nGASruk5lkkmTmMB6JUKFQqO+DfX1eABWeQoVR6f7HSdM0obqu48Yw8G1tDT82NsRd1TSbU9BbGPCog8PDj+jLzurFoAVgMh4XxoNDQ6SqKi0tL9eBvAB8zZwymYxYY7EYAoEA8vm82BNTg6XUIs0MeGTZoR1mhXSnwNl4pmAbjU7mcjkKhkL1ynMnntZ4OEw3VyrV8utk7s5TdW++0QXz+1i3P7IK36t+PCfVn1OQOoOA0gXr5DPak+cPXbBK+/T3S69AtY3LJ98vZ1or/iLr+pTuvr59/A6s003UdqZFJF/PCKQ3o5CUznoBST2AfbEF/9iqYEDaIfwj73VJPEfgNTe0tWNYR0uwy9uOW0OkrgHI7z5ADo2C7v48nLV3XHKAT+x/1m1sX58xsBxg8rZJrDYD8DHHp4aJj/MK09sXjPOt46PcCzAACXY8/u34wN0AAAAASUVORK5CYII=",
"_urls":
[
{
"template":"http://www.amazon.com/exec/obidos/external-search/",
"rels":[],
"params":
[
{
"name":"field-keywords",
"value":"{searchTerms}"
},
{
"name":"mode",
"value":"blended"
},
{
"name":"tag",
"value":"mozilla-20"
},
{
"name":"sourceid",
"value":"Mozilla-search"
}
]
}
],
"filePath":"/Users/mozilla/moz/hg/services-central/./obj-x86_64-apple-darwin11.4.0/dist/NightlyDebug.app/Contents/MacOS/searchplugins/amazondotcom.xml"
}
]
}
"/Users/mozilla/Documents/inbox-desktop/test_profiles/search_engine_sync_0/searchplugins":
{
"lastModifiedTime":1343685412000,
"engines":
[
{
"_id":"[profile]/youtube-video-search.xml",
"_name":"YouTube Video Search",
"_hidden":false,
"description":"Search for videos on YouTube",
"__searchForm":"http://www.youtube.com",
"_iconURL":"data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgNkQkIDZGiCA2RzAgNkcwIDZH/CA2R/wgNkf8IDZH/CA2R/wgNkf8IDZH/CA2R2AgNkcwIDZHMCA2RhAgNkQYIDpWHCA6V/wgOlf8IDpX/CA6V/wgOlf8IDpX/CA6V/wgOlf8IDpX/CA6V/wgOlf8IDpX/CA6V/wgOlf8IDpWHCQ6ZzAkOmf8JDpn/CQ6Z/wkOmf8JDpb/BQhc/wgMgf8JDpn/CQ6Z/wkOmf8JDpn/CQ6Z/wkOmf8JDpn/CQ6ZzAkOnuoJDp7/CQ6e/wkOnv8JDp7/Exed/8jIy/9RU4j/Bwp0/wkOm/8JDp7/CQ6e/wkOnv8JDp7/CQ6e/wkOnuoJD6T8CQ+k/wkPpP8JD6T/CQ+k/xUbo//V1dX/1dXV/4yNrP8QFG//CA6Y/wkPpP8JD6T/CQ+k/wkPpP8JD6T8CQ+q/wkPqv8JD6r/CQ+q/wkPqv8WG6n/3d3d/93d3f/d3d3/v7/M/y0wjv8JD6r/CQ+q/wkPqv8JD6r/CQ+q/woQr/8KEK//ChCv/woQr/8KEK//Fx2v/+fn5//n5+f/5+fn/+jo6P+YmtP/ChCv/woQr/8KEK//ChCv/woQr/8KELX8ChC1/woQtf8KELX/ChC1/xgdtf/x8fH/8fHx//Ly8v+bndv/Ehi3/woQtf8KELX/ChC1/woQtf8KELX8ChG76goRu/8KEbv/ChG7/woRu/8YH77/+fn5/+/v9/9fY9H/ChG7/woRu/8KEbv/ChG7/woRu/8KEbv/ChG76goRwMwKEcD/ChHA/woRwP8KEcD/EBfB/6Ol5/8tM8n/ChHA/woRwP8KEcD/ChHA/woRwP8KEcD/ChHA/woRwMwLEcSHCxHE/wsRxP8LEcT/CxHE/wsRxP8LEcT/CxHE/wsRxP8LEcT/CxHE/wsRxP8LEcT/CxHE/wsRxP8LEcSHCxLICQsSyKULEsjMCxLI+QsSyP8LEsj/CxLI/wsSyP8LEsj/CxLI/wsSyP8LEsj/CxLI0gsSyMwLEsiiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAD//wAA//8AAA==",
"_urls":
[
{
"template":"http://www.youtube.com/results?search_query={searchTerms}&page={startPage?}&utm_source=opensearch",
"rels":[],
"params":[]
}
],
"filePath":"/Users/mozilla/Documents/inbox-desktop/test_profiles/search_engine_sync_0/searchplugins/youtube-video-search.xml",
"_url":"http://www.youtube.com/opensearch?locale=en_US",
"_installLocation":2,
"type":3,
"queryCharset":"UTF-8",
"_readOnly":false
}
]
}
}
}