User:Clouserw/APKFactory: Difference between revisions

(Added user stories)
 
(54 intermediate revisions by 5 users not shown)
Line 2: Line 2:
= C&C APK Factory =
= C&C APK Factory =


We're building an APK Factory!  In short, this is a black box which will accept a manifest URL as input and return a URL to where an APK of the app at the manifest URL can be downloaded.  This project includes some UI changes on the Marketplace but the vast majority of the project is backend and APIs.
We're building an APK Factory!  In short, this is a black box which will accept a manifest URL as input and return a .apk file.  This project includes some UI changes on the Marketplace but the vast majority of the project is backend APIs.


The primary use case is:
The primary use case is:
* Developer uploads new app to the Marketplace
* An end user, using Fennec, clicks an ''Install'' button on any web page
* Marketplace validates the app
* Fennec retrieves the manifest linked to from the ''Install'' button and sends it to the APK Factory
* Marketplace puts app in queue for reviewers
* The APK Factory processes it and turns it into an APK (~seconds)
* Marketplace dispatches information to the APK Factory and requests a '''reviewer copy''' of the APK (that means signed with a debug key)
* The APK Factory returns the APK in response
* APK Factory returns a URL which will hold an APK when ready (maybe return 202 until it's there?)
* Fennec installs the APK as a normal android app
* Marketplace retrieves APK from URL and caches locally
* When app is approved, Marketplace dispatches a second request to APK factory asking for a '''production copy''' of the APK (signed with a real per-app key)
* APK Factory returns a URL which will hold an APK when ready
* Marketplace retrieves APK from URL, caches locally, and gives to end users when requested
 
Secondary use case (public factory):
* Developer sends URL directly to the APK Factory
* APK Factory returns a '''reviewer copy''' of the APK (signed with a debug key) and a '''production copy''' of the APK (signed with a real per-app key)
** (this is a secondary function.  Some product decisions need to happen around whether this is a requirement)
 
= Changes needed =
 
      +------------------+      +---------------------+        +------------------+
      |                  |      |                    |        |                  |
      |  Marketplace    |+----->|    APK Factory     |+------> |    APK Signer    |
      |    (modify)      |<-----+|      (create)      |<------+ |    (create)    |
      |                  |      |                    |        |                  |
      |                  |      |                    |        |                  |
      +------------------+      +---------------------+        +------------------+
 
== Marketplace ==
* [''uiwanted''] Adjust developer flow to opt-out of automatic APK generation
* Adjust developer flow to send manifest (or mini-manifest) URL to APK Factory
* Adjust developer tools to add APK download link to versions page of the app page
* [''uiwanted''] Adjust developer tools to accept a user specified signing key (associated with app)
* Adjust reviewer tools to add APK download link to review detail page
* Adjust mini-manifests to include APK download URL (should automatically make all install buttons work)
 
== APK Factory ==
* '''Requires Java Development Kit (JDK) not just an environment (JRE).  Requires new hardware?'''
* API to accept manifest as input
** Differentiate between hosted & packaged apps
** (...) the actual packaging here.  Need to duplicate/enhance [https://github.com/jhugman/synth-apks prototype] for functionality and scale
* API to accept signing key if specified
* Ability to sign using [https://developer.android.com/tools/publishing/app-signing.html#debugmode an android debug key] for all non-reviewed manifests.
* Ability to sign using production app keys if signing for final packages
* API to send and receive keys from the APK Signer
* GC to clean up old packages on disk
 
== APK Signer ==
* '''Requires new hardware'''
* Based heavily on [https://github.com/mozilla/solitude solitude]
* A secure storage area for production signing keys
* No outside network traffic (see above diagram)




* What are we doing with existing developers?  Are we opting them in to doing this conversion?
** We are opting them in.  We'll notify them first.  -- David Almstrom
* Question from David Bialer - How do we handle people who have apps already installed?
** It's possible we have something in Fx29 for this already which will do a one time check. There is a bug already filed.  -- David Almstrom
** It's unclear how many there actually are; we may be willing to have people with existing implementations reinstall their apps.  We have no ADIs to check what percentage of installs are in active use.  -- myk
** This is not a blocker.
** Bill Walker / Vishy is investigating our options: http://bugzil.la/938667 (wrong bug?)


= User Stories =
= User Stories =
== Use case: install ==
=== Use case: install ===
 
'''As a user, I can tap ''Install'' on a web page and an APK is downloaded to my device so that my phone's native package installer can install the app.'''
'''As a user, I can tap install on a marketplace page and an APK is downloaded to my device so that my phone's native package installer can install the app.'''
 
We will be modifying the implementation of the mozApps.install() and
mozApps.installPackage() APIs on Android. On webapp install, Fennec
will  download an APK which is generated from the manifest URL which
is  passed to the apk-builder.
 
In this manner, we are able to avoid changing any marketplace code,
and support third-party webapp marketplaces.[at the very least, with
this method we avoid the marketplace trying to detect whether the
phone is android or not -BillW]
 
 
=== Implementation of the apk-builder ===
 
It is intended that apk-builder use Android's standard toolchain.
 
The apk-builder accepts a URL to a JSON document, that could be a
webapp  manifest or mini-manifest. It should detect the difference
between a  packaged app and hosted app and act accordingly.
 
The apk-builder constructs an Android project from a template and
data  in the webapp manifest, including icons, string translations,
permissions, and web activities.
 
Both webapps and Android have very similar concepts. There is some
impedance mismatch, though this is not particularly relevant for the
scope of this project.
 
The exception to this is around [https://developer.android.com/tools/publishing/app-signing.html APK signing].
Android apps are expected to be signed by the developer, regardless of whether they
seek any special permissions. The same signature is used to  sign
successive versions of the same APK, otherwise the update will not
be allowed to continue.
 
For packaged webapps, the package.zip and mini-manifest files will be included in the APK.
 
Once the apk-builder has created an Android project, it can build it
with ant, javac and the rest of the Android toolchain.
 
By design, the Android project's template contains no Java code. All code
is contained in a [https://developer.android.com/tools/projects/index.html#LibraryProjects library-project].
Both, especially the library project, are being actively developed
in  parallel to the apk-builder.
 
It is desirable that the project template and library code be taken
live from a code repository so that changes are easy to incorporate
in to the workflow.
 
== Use case: update ==


=== Use case: manual update ===
'''As a user, I can have my phone check for updates and have my phone download them so that I may keep my webapps safely up-to-date.'''
'''As a user, I can have my phone check for updates and have my phone download them so that I may keep my webapps safely up-to-date.'''


The synthesized APK is relatively lightweight. For hosted apps,
''Implementation Note:'' Fennec will poll the APK factory (or, perhaps a different domain?) with a JSON blob to see if there are updatesPush notifications are not available across all our platforms so we're back to polling here.
Gecko  can manage updating appcache and resources generated at
runtimeUpdating anything used to build the APK should trigger a
rebuild of the APK itself. In practice, this means the APK should be
rebuilt anytime  the webapp manifest changes. From a computation
point of view, the  detection of change in the manifest and the
rebuilding of the APK would  be sensibly done on the server.


For packaged apps, any change of the app should trigger a rebuild,
=== Use case: update ===
however, we are working with the assumption that a release of the
'''As a user, I can trust that my phone will automatically keep my webapps up to date.'''
app is  needed, and a change in the mini-manifest will be triggered.


Android apps have a hard requirement that the versionCode, a non
=== <span style="font-size:1.2em; color: #f33">Not v1</span> Use case: developer's own keys ===
user facing integer representation of the version string, be
'''As a developer, I can use my own key to sign my Android APK, so I can use the key elsewhere.''' 
positively increasing.


The same android signing key should be used to sign the updated APK
''Implementation Notes:'' 
as was used to sign the previous version of the APK.
* Changing keys for an already published APK is impossible
* For a large proportion of developers, a randomly generated APK signing key will be sufficient.
* We'll need this early enough in the submission process that the first copy of their app will have the right key
* [''uiwanted'']: We need to make sure developers with keys actually see this as otherwise their userbase is forked.


=== <span style="font-size:1.2em; color: #f33">Not v1</span> Use case: developer opt-out ===
'''As a Developer, I can chose not to have my app auto-generated as an Android APK''': This story is obsolete since anyone could have their own marketplace and hit the APK builder and generate a package.


== Use case: developer's own keys ==
''Implementation Note:''
* [''uiwanted''] We need to make sure the developer realizes what is happening so their user base isn't forked.  Original concern:
** ''dvd: Issue: what if the developer doesn't know that his app is going to be auto-generated and installed as an APK on Android. If the OWA has not been submitted through the marketplace, the developer is not aware of this. The developer may already have the same app developed as an Android native app or an Android Webapp. If Fennec displays any webapp with an install button as the webapp thinks it will be deployed within the browser, there is no way for the developer to opt out. I am not arguing against the openness as an argument but rather for the developer to be in control.''


'''As a developer, I can use my own key to sign my Android APK, so I can use the key elsewhere.'''
=== Use case: pre-submission development ===
'''As a developer I would like to be able to test my APK without submitting it to the marketplace.'''


Changing keys for an already published APK is impossible.
IDEAL: This should be possible without requiring a network on each edit-compile-run cycle.


For a large proportion of developers, a randomly generated APK
''Implementation Notes:''
signing key will be sufficient.
* NO use of APK factory service. Two implementation paths:
** BEST: I register my app with the App Manager and connect my device. The manager sees the device and offers to install the app on it. I install the app on it and can launch it and use it. The manager sees that the app is running and offers to enable debugging. I enable debugging and can use the Developer Tools to debug the app.
** ACCEPTABLE: I install the Android SDK and the APK Factory CLI. I use the Factory CLI to build an APK for the app and the Android SDK to install the APK on my device. I can then launch and use the app. And the app is configured to enable Firefox remote debugging via a known host and port, so I click Web Developer > Connect… in Firefox and connect to the app at that host/port. I can then use the Developer Tools to debug the app.
*** This is currently the solution we're aiming for, but Austin would like to have the Factory CLI be a wrapper which would communicate with the APK Factory online.  Myk sounds concerned.
**** '''We're going to move forward with both a separate CLI Factory tool and a CLI Factory wrapper and see which is better. -- Austin'''


However, a few will want to be able to use their own. During app
=== Use case: post-submission review ===
submission, if the app is to be on Android, they should have the
* '''As a reviewer, I would like to follow the same review process as I do for the normal app. '''
opportunity to upload their own key.
* '''As a reviewer I can run the APK on my Android phone. '''
* '''As a developer I can run the same APK as the reviewer.'''


== Use case: pre-submission development ==


'''As a developer I would like to be able to test my APK without submitting it to the marketplace.'''
''Implementation Notes:'' The APK should not be publishable on an APK app-store, e.g. signed with a [https://developer.android.com/tools/publishing/app-signing.html#debugmode debug key]
* The reviewer (or developer) will set a path on their phone to sign apps with the debug cert server, similar to how reviewers today install a reviewer cert


It is assumed that the Android toolchain is rather cumbersome and
=== Use case: post-review acceptance ===
not  interesting enough for the webapp developer to actually set it
'''As a developer, I can download the APK that will be installed on user's devices, so I can distribute it myself.'''
up  successfully.


The apk-builder should accept a POST of the webapp manifest and
''Implementation Notes:''
resources needed for the webapp, and return an APK. A command line
* This is a download link in the Developer control panel
or  option in the app manager will be used to send the POST.


The APK should not be publishable on an APK app-store, e.g. signed
= Implementation =
with a [https://developer.android.com/tools/publishing/app-signing.html#debugmode debug key],
  +------------+    +-------------+    +------------+                        +-------------+
icon marked with "IN TEST".
  | User Agent +--->| APK Factory +--->| APK Signer |                        |    Debug    |
  |  (Fennec)  |<---+            |<---+            |                        |    APK    |
  |            |    |            |    |            |                        |  Factory  |
  +------------+    +-------+-----+    +------------+                        +-------+-----+
                          ^ |                                                        ^ |
                          | |                                                        | |
  +-------------+        | |                  +----------------------------+        | |
  | Marketplace +---------+ |                  | Developers' and Reviewers' +---------+ |
  |            |<----------+                  |    User Agents (Fennec)    |<----------+
  |            |                              |                            |
  +-------------+                              +----------------------------+


This use of the apk-builder should be invoked by the developer from
=== User Agent / Fennec Modifications ===
the command line or App Manager.
* mozApps.install() and mozApps.installPackage() to send the manifest to the APK Factory
* Manual updating UI and [https://github.com/mozilla/apk-factory-service/issues/4 JSON request]
* Periodic updating check


In coming releases, we would like the developer to be able to
=== <span style="font-size:1.2em; color: #f33">Not v1</span> Marketplace Modifications ===
construct an APK without calling out to a server, either from the
None of these are v1 and, once we actually get it implemented, may not be something we need to do at all.
command line or App Manager.
* [''uiwanted''] Adjust developer flow to opt-out of automatic APK generation
* Adjust developer tools to add APK download link to versions page of the app page
* [''uiwanted''] Adjust developer tools to accept a user specified signing key (associated with app)
* Adjust reviewer tools to ask for Reviewer APKs (make sure the reviewer is using the debug server somehow)


== Use case: post-submission review ==
=== APK Factory Modifications (this is a new service) ===
 
* '''Requires Java Development Kit (JDK) not just an environment (JRE).  Requires new hardware?'''
* '''As a reviewer I can run the APK on my Android phone. '''
* API to accept manifest as input
* '''As a developer I can run the same APK as the reviewer.'''
** Differentiate between hosted & packaged apps
** Do the actual packaging
*** duplicate/enhance [https://github.com/jhugman/synth-apks the prototype]
*** APK Factory builds the android project from a template and data in the manifest including icons, L10n, permissions, and web activities
*** For packaged webapps, the package.zip and mini-manifest files will be included in the .apk
* API to accept signing key from the Marketplace if specified
* Ability to sign using [https://developer.android.com/tools/publishing/app-signing.html#debugmode an android debug key]
* Ability to sign using production app keys if signing for final packages
* API to send and receive keys from the APK Signer
* GC to clean up old packages on disk
* API to accept a JSON list of manifests and return which have updates
** App freshness is a function of:
*** the manifest
*** changes to the android library code
*** If it's a packaged app, the package.zip (we can hash this)
** Android Apps have a hard requirement that the versionCode, a non user facing integer representation of the version string, be positively increasing.
* Have the ability to regenerate all apps (including bumping versionCode) (useful for fixing a security hole in apk-factory-library)


The APK should not be publishable on an APK app-store, e.g. signed
* An assumption is that developers will only specify their own key if they are uploading via the Marketplace.  Perhaps that isn't true?  ozten brings up a good point that we'd need auth for this somewhere, marketplace makes sense...
with a [https://developer.android.com/tools/publishing/app-signing.html#debugmode debug key],
** dvd: wouldn't the APK Factory need to store manifest URL, version code, keys (or link to key). Would also need to check if the manifest fits the app, no? Like what we do in the marketplace if the app has significantly changed from the manifest, then it will not run.
icon marked with "IN REVIEW".
** Not a v1 concern


== Use case: post-review acceptance ==
'''(todo:dbialer)''' What kind of scalability are we building this for?  thousands per day?  millions per day?


'''As a developer, I can download the APK that will be installed on user's devices, so I can distribute it myself.'''
=== APK Signer Modifications (this is a new service) ===
 
* '''Requires new hardware'''
Once the webapp is ready for publishing, the developer should
* Based heavily on [https://github.com/mozilla/solitude solitude]
receive (as part of an existing email?), a link to the APK.
* A secure storage area for production signing keys
* No outside network traffic (see above diagram)

Latest revision as of 23:34, 9 January 2014

C&C APK Factory

We're building an APK Factory! In short, this is a black box which will accept a manifest URL as input and return a .apk file. This project includes some UI changes on the Marketplace but the vast majority of the project is backend APIs.

The primary use case is:

  • An end user, using Fennec, clicks an Install button on any web page
  • Fennec retrieves the manifest linked to from the Install button and sends it to the APK Factory
  • The APK Factory processes it and turns it into an APK (~seconds)
  • The APK Factory returns the APK in response
  • Fennec installs the APK as a normal android app


  • What are we doing with existing developers? Are we opting them in to doing this conversion?
    • We are opting them in. We'll notify them first. -- David Almstrom
  • Question from David Bialer - How do we handle people who have apps already installed?
    • It's possible we have something in Fx29 for this already which will do a one time check. There is a bug already filed. -- David Almstrom
    • It's unclear how many there actually are; we may be willing to have people with existing implementations reinstall their apps. We have no ADIs to check what percentage of installs are in active use. -- myk
    • This is not a blocker.
    • Bill Walker / Vishy is investigating our options: http://bugzil.la/938667 (wrong bug?)

User Stories

Use case: install

As a user, I can tap Install on a web page and an APK is downloaded to my device so that my phone's native package installer can install the app.

Use case: manual update

As a user, I can have my phone check for updates and have my phone download them so that I may keep my webapps safely up-to-date.

Implementation Note: Fennec will poll the APK factory (or, perhaps a different domain?) with a JSON blob to see if there are updates. Push notifications are not available across all our platforms so we're back to polling here.

Use case: update

As a user, I can trust that my phone will automatically keep my webapps up to date.

Not v1 Use case: developer's own keys

As a developer, I can use my own key to sign my Android APK, so I can use the key elsewhere.

Implementation Notes:

  • Changing keys for an already published APK is impossible
  • For a large proportion of developers, a randomly generated APK signing key will be sufficient.
  • We'll need this early enough in the submission process that the first copy of their app will have the right key
  • [uiwanted]: We need to make sure developers with keys actually see this as otherwise their userbase is forked.

Not v1 Use case: developer opt-out

As a Developer, I can chose not to have my app auto-generated as an Android APK: This story is obsolete since anyone could have their own marketplace and hit the APK builder and generate a package.

Implementation Note:

  • [uiwanted] We need to make sure the developer realizes what is happening so their user base isn't forked. Original concern:
    • dvd: Issue: what if the developer doesn't know that his app is going to be auto-generated and installed as an APK on Android. If the OWA has not been submitted through the marketplace, the developer is not aware of this. The developer may already have the same app developed as an Android native app or an Android Webapp. If Fennec displays any webapp with an install button as the webapp thinks it will be deployed within the browser, there is no way for the developer to opt out. I am not arguing against the openness as an argument but rather for the developer to be in control.

Use case: pre-submission development

As a developer I would like to be able to test my APK without submitting it to the marketplace.

IDEAL: This should be possible without requiring a network on each edit-compile-run cycle.

Implementation Notes:

  • NO use of APK factory service. Two implementation paths:
    • BEST: I register my app with the App Manager and connect my device. The manager sees the device and offers to install the app on it. I install the app on it and can launch it and use it. The manager sees that the app is running and offers to enable debugging. I enable debugging and can use the Developer Tools to debug the app.
    • ACCEPTABLE: I install the Android SDK and the APK Factory CLI. I use the Factory CLI to build an APK for the app and the Android SDK to install the APK on my device. I can then launch and use the app. And the app is configured to enable Firefox remote debugging via a known host and port, so I click Web Developer > Connect… in Firefox and connect to the app at that host/port. I can then use the Developer Tools to debug the app.
      • This is currently the solution we're aiming for, but Austin would like to have the Factory CLI be a wrapper which would communicate with the APK Factory online. Myk sounds concerned.
        • We're going to move forward with both a separate CLI Factory tool and a CLI Factory wrapper and see which is better. -- Austin

Use case: post-submission review

  • As a reviewer, I would like to follow the same review process as I do for the normal app.
  • As a reviewer I can run the APK on my Android phone.
  • As a developer I can run the same APK as the reviewer.


Implementation Notes: The APK should not be publishable on an APK app-store, e.g. signed with a debug key

  • The reviewer (or developer) will set a path on their phone to sign apps with the debug cert server, similar to how reviewers today install a reviewer cert

Use case: post-review acceptance

As a developer, I can download the APK that will be installed on user's devices, so I can distribute it myself.

Implementation Notes:

  • This is a download link in the Developer control panel

Implementation

  +------------+    +-------------+    +------------+                         +-------------+
  | User Agent +--->| APK Factory +--->| APK Signer |                         |    Debug    |
  |  (Fennec)  |<---+             |<---+            |                         |     APK     |
  |            |    |             |    |            |                         |   Factory   |
  +------------+    +-------+-----+    +------------+                         +-------+-----+
                          ^ |                                                         ^ |
                          | |                                                         | |
  +-------------+         | |                  +----------------------------+         | |
  | Marketplace +---------+ |                  | Developers' and Reviewers' +---------+ |
  |             |<----------+                  |    User Agents (Fennec)    |<----------+
  |             |                              |                            |
  +-------------+                              +----------------------------+

User Agent / Fennec Modifications

  • mozApps.install() and mozApps.installPackage() to send the manifest to the APK Factory
  • Manual updating UI and JSON request
  • Periodic updating check

Not v1 Marketplace Modifications

None of these are v1 and, once we actually get it implemented, may not be something we need to do at all.

  • [uiwanted] Adjust developer flow to opt-out of automatic APK generation
  • Adjust developer tools to add APK download link to versions page of the app page
  • [uiwanted] Adjust developer tools to accept a user specified signing key (associated with app)
  • Adjust reviewer tools to ask for Reviewer APKs (make sure the reviewer is using the debug server somehow)

APK Factory Modifications (this is a new service)

  • Requires Java Development Kit (JDK) not just an environment (JRE). Requires new hardware?
  • API to accept manifest as input
    • Differentiate between hosted & packaged apps
    • Do the actual packaging
      • duplicate/enhance the prototype
      • APK Factory builds the android project from a template and data in the manifest including icons, L10n, permissions, and web activities
      • For packaged webapps, the package.zip and mini-manifest files will be included in the .apk
  • API to accept signing key from the Marketplace if specified
  • Ability to sign using an android debug key
  • Ability to sign using production app keys if signing for final packages
  • API to send and receive keys from the APK Signer
  • GC to clean up old packages on disk
  • API to accept a JSON list of manifests and return which have updates
    • App freshness is a function of:
      • the manifest
      • changes to the android library code
      • If it's a packaged app, the package.zip (we can hash this)
    • Android Apps have a hard requirement that the versionCode, a non user facing integer representation of the version string, be positively increasing.
  • Have the ability to regenerate all apps (including bumping versionCode) (useful for fixing a security hole in apk-factory-library)
  • An assumption is that developers will only specify their own key if they are uploading via the Marketplace. Perhaps that isn't true? ozten brings up a good point that we'd need auth for this somewhere, marketplace makes sense...
    • dvd: wouldn't the APK Factory need to store manifest URL, version code, keys (or link to key). Would also need to check if the manifest fits the app, no? Like what we do in the marketplace if the app has significantly changed from the manifest, then it will not run.
    • Not a v1 concern

(todo:dbialer) What kind of scalability are we building this for? thousands per day? millions per day?

APK Signer Modifications (this is a new service)

  • Requires new hardware
  • Based heavily on solitude
  • A secure storage area for production signing keys
  • No outside network traffic (see above diagram)