CloudServices/NativeSync

From MozillaWiki
Jump to navigation Jump to search

Native Sync

Setup

Setting up an Android dev environment

  • note: installing *all* the platform tools (all Android from 1 to 3.3) takes a while, if you only need a specific SDK version, just install from the GUI tool:
$SDK/tools/android

Emulators

  • create emulator with $SDK/tools/android, menubar>Tools>Manage AVDs...
  • Target (probably) needs to match build specified in .mozconfig (see Building Fennec Native below)
  • to launch:
$SDK/tools/emulator -wipe-data -avd <AVD> -partition-size 2047

(so you don't run into insufficient storage error)

After installation, fennec would crash on installation (unable to locate mozutils library, although it's in the apk). Possibly related to emulator failing to run NDK applications?

Running everything

You'll be wanting to run test-android-sync:

This depends on the android-sync project, as described in the Android testing docs:

android-sync dependencies

android-sync has the following dependencies:

  • sync-crypto, described below.
  • httpclientandroidlib, which provides a working modern version of the Apache HTTPClient under a different Java package.
  • json-simple 1.1 and commons-codec 1.2, which ship with Android.
  • Android 2.3.3.

For testing it requires:

sync-crypto dependencies

sync-crypto relies on Apache commons-codec 1.5, which includes Base32. The Android system libraries include the 8-year-old version 1.2. As a result, sync-crypto is packaged as an assembly jar (aka über jar). Simply run build.sh to instruct Maven to do the right thing.

An up-to-date version is checked in to the external directory in android-sync, with the mvnify script in that directory taking care of installing it in your local repository.

What you need to do

git clone https://github.com/rnewman/base64-unstub
git clone https://github.com/rnewman/log-unstub
git clone https://github.com/mozilla-services/android-sync
git clone https://github.com/mozilla-services/test-android-sync
pushd base64-unstub; mvn install; popd
pushd log-unstub;    mvn install; popd
pushd android-sync/external; ./mvnify; popd
pushd android-sync
./deps.sh
mvn test

To do real Android development and testing, you need to import both android-sync and test-android-sync as projects in Eclipse with the ADT installed.

Note that both android-sync and sync-crypto have JUnit 4 tests that run in both Eclipse and Maven. android-sync also provides functionality to test-android-sync, which includes Android JUnit 3 tests for activity and store testing. This is to avoid the mammoth annoyance of testing in a VM without introducing robolectric.

Running Fennec

EDIT: Fennec Native has been moved to mozilla-central.

hg clone http://hg.mozilla.org/mozilla-central/

The rest of the directions on Building Fennec Native should be correct (look at the How to Build section).

After building Fennec, make the apk.

make -sj8 -C objdir-droid/ package

The apk will be something like $objdir/dist/fennec-11.apk

  • Android device: (WFM)
    • enable USB debugging: Settings > Applications > Development > USB debugging
$SDK/platform-tools/adb install -r <path-to-apk>
  • Emulator:
$SDK/tools/emulator
(as another process:)
$SDK/platform-tools/adb install -r <path-to-apk>

You may need to run adb kill-server, adb start-server if adb doesn't recognize the emulator.

  • Logcat debug statements
adb logcat

Setting up Eclipse

If you want to use Eclipse:

  • Install it and the SDK plugin, as described in the Android SDK page.
  • Run these in your repo:
mvn -Declipse.workspace=<path-to-eclipse-workspace> eclipse:add-maven-repo
mvn -DdownloadJavadocs=true -DdownloadSources=true eclipse:eclipse
  • Open Eclipse, choose File > Import… Existing Project, pick your repo dir.
  • Correct formatting: Preferences > Java:Code style:Formatter, Edit…, change name to "Mozilla", change both indentation values to 2, tab policy = Spaces only, check "Align fields in columns".

Copy the example.project -> .project and example.classpath to .classpath, making sure to update the path values.

Development

Let's stick to some fairly sane Java conventions: 2-space indenting (Java is wide enough as it is), Maven2 for dependencies and build, JUnit4 for unit tests. We can wire in Hudson later if we have time. "Simple" for HTTP test server.

Let's figure out bleeding edge stuff ("how do I get a SyncAdapter to work?") in throwaway projects. There will be a lot of these :)

We don't quite follow the Fennec/NativeUI/CodingStyle. See also the Android coding style.

Security

Goals: no less secure than currently, at most Fennec, Service, UI have access to credentials.

Android Docs on security

Sandboxing by using UIDs, specifically the section on "User IDs and File Access".

See also manifest entries:

android:sharedUserId The name of a Linux user ID that will be shared with other applications. By default, Android assigns each application its own unique user ID. However, if this attribute is set to the same value for two or more applications, they will all share the same ID — provided that they are also signed by the same certificate. Application with the same user ID can access each other's data and, if desired, run in the same process

Permissions

   <uses-permission android:name="android.permission.GET_ACCOUNTS" />
   <uses-permission android:name="android.permission.MANAGE_CREDENTIALS" />
   <uses-permission android:name="android.permission.USE_CREDENTIALS" />
   <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
   <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
   <uses-permission android:name="android.permission.WRITE_SETTINGS" />
   <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
   <uses-permission android:name="android.permission.READ_SYNC_STATS" />
   <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
   <uses-permission android:name="android.permission.INTERNET"/>
   <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
   <uses-permission android:name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"/>

Adjusting sync frequency

If API > 8, use ContentResolver.addPeriodicSync()

If API = 7, create a service with a periodic timer callback, and call ContentResolver.requestSync().

API < 6 does not support syncAdapter, so no worries.

Triggering a sync:

 android:supportsUploading defaults to true and if true an upload-only sync will be requested for all syncadapters associated with an   
 authority whenever that authority's content provider does a notifyChange(android.net.Uri, android.database.ContentObserver, boolean) with 
 syncToNetwork set to true. 

Altering Sync settings

 android:syncAdapterSettingsAction defaults to null and if supplied it specifies an Intent action of an activity that can be used to adjust the sync adapter's sync settings. The activity must live in the same package as the sync adapter. 

Localization

http://developer.android.com/guide/topics/resources/localization.html

Schemas

TODO

Gotchas

Android's sqlite cursors are limited. Oh, and the heap is limited. We have to be very careful about how much data we store and process at one time.

“You are out of heap space. With a 16MB non-compacting heap, and the fact that a Cursor holds the entire result set in the heap, that is not out of the question. CursorWindow only supports 1MB of data, which is what the error message suggests more directly.

If there is a logical way to divide your queries into discrete chunks, you could do incremental queries and use CursorJoiner to stitch them together, and see if that helps.”

jvoll's notes

Having trouble with the emulator when loading Fennec and Sync onto it? Use: emulator -avd android-14 -partition-size 2047

Lines to remove from mobile/android/base/AndroidManifest.xml.in if you don't feel like working around the permissions stuff: -android:permission="org.mozilla.gecko.permissions.BROWSER_PROVIDER"/> from both providers -<permission android:name="org.mozilla.gecko.permissions.BROWSER_PROVIDER"

                android:protectionLevel="signature"/>

Tests failing and seeing a ProfileDatabaseException logged in logcat? This usually happens when you did a fresh install of fennec and haven't opened it yet. So, just open Fennec. If that fails (and this works for other weird stuff too), go to apps and stop Fennec, clear app data and/or in extreme cases uninstall and reinstall it. This stuff *should* all be fixed shortly, but for now these are good work arounds.