OSDN Git Service

Add support for Split APK dependcies
authorAdam Lesinski <adamlesinski@google.com>
Tue, 22 Nov 2016 00:02:24 +0000 (16:02 -0800)
committerAdam Lesinski <adamlesinski@google.com>
Wed, 25 Jan 2017 02:34:08 +0000 (18:34 -0800)
commit4e8628157ad0c8c52e74b720eb0328086272ffda
treebdd92850181581f952cffe42fcd8d208ac22b96c
parent896c7f8937618a419777df5372b71753f397ff9c
Add support for Split APK dependcies

Apps can now declare in their base APK AndroidManifest.xml
that they want to have their split APKs loaded in isolated
Contexts. This means code and resources from the split
get loaded into their own ClassLoader and AssetManager.

<manifest xmlns:android="..."
          ...
          android:isolatedSplits="true"
          ...

In order to make this more useful, splits can declare dependencies
on other splits, which will all get pulled in to the Context
and run as expected at runtime.

A split declares its dependency on another split by using the
tag <uses-split> in its AndroidManifest.xml:

<manifest xmlns:android="...">
    ...
    <uses-split android:name="feature_split_1" />
    ...

A split can have a single parent on which it depends on. This is
due to the limitation of having a single ClassLoader parent.
All splits depend on the base APK implicitly.

PackageManager verifies that no cycles exist and that each dependency
is present before allowing an installation to succeed.

The runtime will then load splits based on the dependencies.

Given the following APKs:

base <-- split A <-- split C
  ^----- split B

If an Activity defined in split C is launched, then the base,
split A, and split C will be loaded into the ClassLoader defined
for the Activity's Context. The AssetManager will similarly be loaded
with the resources of the splits.

A split can be manually loaded by creating a Context for that split, defined
by its name:

Context.createContextForSplit("my_feature_split_1");

All installed Activities, Services, Receivers, and Providers are accessible
to other apps via Intent resolution. When they are instantiated, they are
given the appropriate Context that satisfies any dependencies the split they
were defined in stipulated.

Test: WIP (CTS tests to come)
Change-Id: I8989712b241b7bc84381f2919d88455fcad62161
25 files changed:
api/current.txt
api/system-current.txt
api/test-current.txt
cmds/pm/src/com/android/commands/pm/Pm.java
core/java/android/app/ActivityThread.java
core/java/android/app/ContextImpl.java
core/java/android/app/LoadedApk.java
core/java/android/content/Context.java
core/java/android/content/ContextWrapper.java
core/java/android/content/pm/ApplicationInfo.java
core/java/android/content/pm/ComponentInfo.java
core/java/android/content/pm/InstrumentationInfo.java
core/java/android/content/pm/PackageParser.java
core/java/android/content/pm/split/DefaultSplitAssetLoader.java [new file with mode: 0644]
core/java/android/content/pm/split/SplitAssetDependencyLoader.java [new file with mode: 0644]
core/java/android/content/pm/split/SplitAssetLoader.java [new file with mode: 0644]
core/java/android/content/pm/split/SplitDependencyLoaderHelper.java [new file with mode: 0644]
core/java/android/os/Parcel.java
core/res/res/values/attrs_manifest.xml
core/res/res/values/public.xml
services/core/java/com/android/server/pm/PackageInstallerSession.java
services/core/java/com/android/server/pm/PackageManagerService.java
services/core/java/com/android/server/pm/PackageManagerShellCommand.java
test-runner/src/android/test/mock/MockContext.java
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java