Build an Android system app from the AOSP source tree - android

Is there a way to build an Android system app from AOSP without having to clone the entire code tree and having to build the entire OS?
Just being able to build the unmodified app from a Linux shell is sufficient, with any toolchain that will do the job. Being able to make modifications in an IDE (Eclipse or Android Studio) is not a requirement (a text editor will do for making changes).
The app in question is CarrierConfig. Most of the app is just assets, the code consists of just one single Java class (~400 lines of code), but with four internal dependencies not exposed through the SDK API:
android.annotation.Nullable
android.os.PersistableBundle.restoreFromXml(XmlPullParser)
android.telephony.TelephonyManager.from(Context)
android.telephony.TelephonyManager#getCarrierIdFromMccMnc(String)
These are what prevents me from simple adding a generic build.gradle and running it through the gradle toolchain. The build artifact is a simple APK file, with which I would then patch the system image.
So how would I build this app without needing the entire AOSP source code (just the actual dependencies, and dependencies of dependencies etc.)?

Not a complete answer (yet), but some snippets I was able to find out so far:
Downloading just individual projects from the source tree
This is what I have been able to piece together from various instructions—untested so far:
mkdir <dir>
cd <dir>
repo init -u <url> -b <branch>
repo sync <project-list>
Where
<dir> is a dir on your system where you are going to keep the source
<url> is the URL for your build, e.g.:
AOSP: https://android.googlesource.com/platform/manifest
LineageOS: https://github.com/LineageOS/android.git
<branch> is the branch to check out (omit -b to check out the master branch)
AOSP branches are found at https://source.android.com/setup/start/build-numbers#source-code-tags-and-builds
LineageOS branches are found at https://github.com/LineageOS/android/branches
<project-list> is a list of projects to fetch (if omitted, repo sync will fetch the entire source tree). Projects can be indicated either by their name or by their path within the source tree, separated with spaces.
(source 1, source 2, source 3, source 4)
Figuring out which repos you need can get tricky, and if your dependencies have further dependencies, this can become a time-comsuming process.
Also I haven’t figured out if the next step actually works with a source tree stripped down in this manner.
Building individual projects
If you just need to build a single project, you can use mmm for that:
. build/envsetup.sh
lunch
mmm path/to/the/project/
(source)

Related

How to build AOSP app without building all of Android?

I've synced the entire Android repo, and set up a build environment per the instructions here:
https://source.android.com/source/building
The build instructions seem to be assuming that you want to build the entire Android platform. I'm really interested in building a specific AOSP app, like contacts, SMS, camera, etc. I've seen mirrors of the stock app's code on GitHub, but there doesn't seem to be any build instructions within those, for example:
https://github.com/android/platform_packages_apps_contacts
https://github.com/android/platform_packages_apps_calendar
Is there a build guide for doing this? Am I stuck downloading, modifying, building this huge (100+GB) code set?
Just as you have 'mm' to build a certain target, you can also use 'mma' to build that target with its dependencies. For example:
$ mma Settings -j16
This will scan the project for the dependencies of the Settings app, and will afterward build the dependencies first before commencing the build of the Settings app.
here are compile and module-based compilation commands:
lunch: lunch <product_name>-<build_variant>
tapas: tapas [<App1> <App2> ...] [arm|x86|mips|armv5] [eng|userdebug|user]
croot: Changes directory to the top of the tree.
m: Makes from the top of the tree.
mm: Builds all of the modules in the current directory, but not their dependencies.
mmm: Builds all of the modules in the supplied directories, but not their dependencies.
To limit the modules being built use the syntax: mmm dir/:target1,target2
mma: Builds all of the modules in the current directory, and their dependencies.
mmma: Builds all of the modules in the supplied directories, and their dependencies.
cgrep: Greps on all local C/C++ files.
jgrep: Greps on all local Java files.
resgrep: Greps on all local res/*.xml files.
godir: Go to the directory containing a file.
you can look here for other and more build commands : https://source.android.com/setup/build/building
and here :https://elinux.org/Android_Build_System
And check "build/envsetup.sh" file's comments to see full list.

How do I add media codecs support to Crosswalk while using the Cordova plug-in?

I'm building a PhoneGap app which needs to play AAC audio. It works well using the native WebView, but I would like to use Crosswalk on a build targeting APIs 16-20 because some CSS features in my app do not work at all on Android 4.x.
When I make a copy of the project to add Crosswalk Lite, I can see that the app works except for the <audio> element pointing to a AAC file. This is because Crosswalk does not ship with proprietary codecs by default.
The linked page says:
To build Crosswalk with these codecs, a developer must run the build
with the “must accept a EULA” switch turned on:
$ xwalk/gyp_xwalk -Dmediacodecs_EULA=1
Then build Crosswalk. The ffmpegsumo.dll or libffmpegsumo.so in
the build output directory will contain the proprietary codecs.
Refer to Crosswalk Build Instruction for more details.
However, I am adding Crosswalk using the suggested plug-in, thus I get pre-built libraries without proprietary codecs:
phonegap plugin add cordova-plugin-crosswalk-webview --variable XWALK_MODE="lite" --save
How can I integrate proprietary codecs in the Cordova Crosswalk plug-in?
I managed to understand the (convoluted) process of building everything. This answer deals with the process of compiling a custom build of the full Crosswalk (not the lite version).
Actually, I decided to finally use the standard build and replace AAC audio with MP3s, but I thought this answer could be useful for future reference.
Environment
I compiled Crosswalk in a Ubuntu 16.04 Docker container to avoid "polluting" my system and to ensure I had the right Linux version. The standard image is pretty barebones so I installed some dependencies. I also set up a shared folder to access the compiled files:
docker run -it -v /home/andrea/shared:/shared ubuntu:16.04 /bin/bash
apt update
apt install -y python git nano lsb-release sudo wget curl software-properties-common
export EDITOR=nano # life it too short to learn vi
Finally, it is necessary to add the multiverse repositories:
apt-add-repository multiverse
Note: this procedure needs a lot of space. Make sure to have at least 25GB of free space before continuing.
Requirements
Install the depot_tools as outlined in the documentation:
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=$PATH:/path/to/depot_tools
Initialize a working directory with:
mkdir crosswalk-checkout
cd crosswalk-checkout
export XWALK_OS_ANDROID=1
gclient config --name src/xwalk https://github.com/crosswalk-project/crosswalk.git
Then edit the config file with nano .gclient and add the following line:
target_os = ['android']
Save the file.
Fetching the source
Attempt a first sync with:
gclient sync
This command will fail but it's OK. The instructions say:
Do not worry if gyp_xwalk fails due to missing dependencies; installing them is covered in a later section, after which you can run gyp_xwalk manually again.
Adjust the install-build-deps.sh file and then run it:
sed -si "s/msttcorefonts/ttf-mscorefonts-installer/g" src/build/install-build-deps.sh
sudo ./src/build/install-build-deps-android.sh
Run gclient sync again and wait until it finishes correctly.
Building
By inspecting the files src/xwalk/build/common.gypi and src/tools/mb/mb_config.pyl, we can see that we need to add ffmpeg_branding="Chrome" in the build arguments.
To prevent an error later on, install the development package related to libnotify:
sudo apt install libnotify-dev
Move to the src directory and open the configuration:
cd src/
gn args out/Default
Ensure the content is as follows:
import("//xwalk/build/android.gni")
target_os = "android"
is_debug = false
ffmpeg_branding = "Chrome"
use_sysroot = false
The parameters use_sysroot = false prevents yet another error. When saving the file, you should see something like this:
Waiting for editor on "/home/utente/crosswalk-checkout/src/out/Default/args.gn"...
Generating files...
Done. Wrote 6060 targets from 1003 files in 2416ms
Issue cd .. and run gclient sync again.
Finally, to build the core library do:
cd src/
ninja -C out/Default xwalk_core_library
This will build the library for ARM, producing an AAR file located at:
src/out/Default/xwalk_core_library.aar
Copy this file in a safe place.
Building for x86
Get back to the args with:
gn args out/Default
Add the following line:
target_cpu = "x86"
Save the file, run gclient sync again and then repeat the ninja command. Make a copy of the new AAR file which now contains the x86 libraries.
Using the AAR files
The standard Cordova Crosswalk plug-in uses a single AAR file with libraries for both platforms. This message by Raphael Kubo da Costa suggests how to produce this single archive:
AAR files are just zip files; given the only difference between the ARM
and x86 AAR files are the different shared libraries, you can use
something like zipmerge or anything that merges zip files (or even
extract everything into some directory and then create one new zip file)
to build one final, multi-architecture AAR archive.
Finally, to use the custom built AAR file in the Cordova plug-in, see How to change the Crosswalk version used by the Cordova Crosswalk Webview plugin.

Building just one tool from Android source (AOSP)

Currently I'm using the the AOSP ROM Builder image on Amazon AWS to build Android.
The point is, I'm only interested in the external tool grxmlcompile that is built for the host (linux) in the path: aosp/out/host/linux-x86/bin
where the source is at aosp/external/srec/tools/grxmlcompile
I'm not very familiar with Linux and make files, hence my difficulty to get this going.
I would like to copy the source (if needed the whole tree) and build just this tool on another linux machine.
I can't find the make file I need to run to build just this part.
UPDATE:
Looks like make out/host/linux-x86/bin/grxmlcompile would do the job. I would still like to be able to port only the needed parts of the source tree to the build machine
cd to the top of your Android build source.
source build/envsetup.sh
cd external/srec/tools/grxmlcompile
mma
...or any directory, or sub-directory a makefile. From AOSP build/envsetup.sh
m: Makes from the top of the tree.
mm: Builds all of the modules in the current directory, but not their dependencies.
mmm: Builds all of the modules in the supplied directories, but not their dependencies.
To limit the modules being built use the syntax: mmm dir/:target1,target2.
mma: Builds all of the modules in the current directory, and their dependencies.
mmma: Builds all of the modules in the supplied directories, and their dependencies.
external/srec was removed from the platform/manifest after android-5.1.1_r4 tag. So later, if you are using a manifest such as revision 5, 6 or later, you may need to do git clone https://android.googlesource/platform/external/srec external/srec to include that directory.

Building a particular module in the android source code

I am working on an android source code which I have downloaded from source.android.com.
After a full build I went through this site http://elinux.org/Android_Build_System which explains the android build system.
When I make changes in external/webkit code and build it with
make -j4 libwebcore it compiles the corresponding file and updates the libwebcore.so, and it save me a lot of time.
The same thing is applied to applications and also for building apks.
The problem arises when I make changes in the framework and give the command as
make -j4 framework its not compiling the corresponding files.
Can any one help me!
The folder frameworks contains many things, you have to be more specific about telling make what to build.
For example I made a change in:
frameworks/base/cmds/input/src/com/android/commands/input/Input.java.
Now the corresponding Android.mk file is located in:
frameworks/base/cmds/input/Android.mk, which contains a line saying: LOCAL_MODULE := input.
Thus the module being build from the source is called input, so I call:
$ make input
Which rebuilds that specific module.
As a bonus info, you can use the mmm helper and you can specify the path of the module to build like this:
$ mmm frameworks/base/cmds/input
or using mm which just builds the module in you current working directory:
$ cd frameworks/base/cmds/input
$ mm
I normally use mmm as my preferred tool.
Update
Oh, I see you might be talking specifically about the module called framework
I just tried to modify: frameworks/base/core/java/android/app/Dialog.java, and do a: make framework.
This seems to recompile the framework just fine. Which file exactly are you making changes in before running make framework ?
In response to your comment
I just tried to modify frameworks/base/core/java/android/webkit/WebView.java. mmm frameworks/base as well as make framework works perfectly fine for me.
If it does not work for you, can you update your question with additional information about which android version you are building, which commands you are typing exactly, and the output your are seeing?
Here are fuller descriptions of mm, mmm, and other convenient functions provided by sourcing the build/envsetup.sh file:
Invoke . build/envsetup.sh from your shell to add the following functions to your environment:
lunch: lunch <product_name>-<build_variant>
tapas: tapas [<App1> <App2> ...] [arm|x86|mips|armv5] [eng|userdebug|user]
croot: Changes directory to the top of the tree.
m: Makes from the top of the tree.
mm: Builds all of the modules in the current directory, but not their dependencies.
mmm: Builds all of the modules in the supplied directories, but not their dependencies.
To limit the modules being built use the syntax: mmm dir/:target1,target2.
mma: Builds all of the modules in the current directory, and their dependencies.
mmma: Builds all of the modules in the supplied directories, and their dependencies.
cgrep: Greps on all local C/C++ files.
jgrep: Greps on all local Java files.
resgrep: Greps on all local res/*.xml files.
godir: Go to the directory containing a file.
Plese check build/envsetup.sh file's comments to see full list of functions.

What goes into Source Control?

Given: http://developer.android.com/resources/faq/commontasks.html#filelist
What are the best practices for getting your projects into source control? I ask because if you simply right click on your project, choose team, etc. you end up with the /bin & /gen folders, .classpath as well as all the Eclipse related items.
If I'm inheriting a project with .../workspace/projectName et al. included how can I clean that up to include only the items relevant to the aforementioned URL?
I summarized all my findings in a blog post that can be found here: http://www.aydabtudev.com/2011/05/what-goes-into-source-control-android.html
I executed the following commands from within my project folder to get them out of source control:
svn rm --keep-local .classpath
svn rm --keep-local .project
svn rm --keep-local default.properties
svn rm --keep-local proguard.cfg
svn rm --keep-local bin/
svn rm --keep-local gen/
Then I executed the following command to add them to an ignore list:
svn pe svn:ignore .
Add each item above without the associated command like so:
.classpath
.project
bin/
...
I followed that up with a commit and an update to solidify my changes.
svn commit -q -m "Removing files" .
svn update
It would seem the smarter way to do this would be to configure the Ignored Resources under the Eclipse Team preferences.
If you're using SVN, you should selectively add files/directories to your repository.
For example with the following directory structure (quick example from my disk):
res/
src/
build/
.idea/
You do not want the build directory, nor the personal preferences for your IDE (.idea folder) adding, so you would only issue the command: svn add res src
To (I think) answer your second point, I'd manage everything to do with version control from command line initially, and then let your IDE do it.
My apologies if I'm missing the point of the question.
Here are some basic points:
Don't store stuff in version control that your source code produces. For example, if you build a jarfile, don't store that jarfile under source control.
Source control is for source. If you have releases, use a release repository like Artifactory. Don't let the Maven stuff scare you away. Maybe you don't use Maven (now), but a Maven repository tool is in standard format, and makes it easy to find your releases. Artifactory can work with Ant/Ivy, and with a little elbow grease, you can get it to work with C and C++ projects too.
Which brings me to the next statement: Don't store your jarfiles (if you're a Java project) in your source repository. It's convenient, but you'll end up hating yourself for it in the long run. Binary files take a long time to process in many source control systems and they can take up lots of room. What's even worse is that you lose information about them. For example what version of common-utils.jar is checked into Subversion that my project now depends upon. Again, use Artifactory and Ant/Ivy or Maven. If you're non-Java, you can use wget or curl to fetch your dependent libraries out of Artifactory. Again, don't let the whole Maven thing scare you.
If you have a Java project, and you don't use Maven, insist that code is stored in the repository using Maven's standard layout. That is, Java code is stored under src/main/java and non Java files are under src/main/resources. The advantage is that it makes it easy to move from project to project, and new developers can quickly find where things are. Plus, it makes your build.xml files much cleaner. You can use any standard repository layout you want, but by insisting on Maven's standard, you can squelch all complaints. "Hey, I agree with you, but Maven says you put your code under this directory. Sorry, I wish I could help, but my hands are tied"
If you're using Subversion, stick with the standard, trunk, branches, tags style and don't be too fancy. I'm not 100% crazy about the layout myself. (I'd rather have a main under the branches directory and no trunk), but you'll simply confuse developers and make support more difficult, and all for very little gain.
Make sure all projects (if you're using Ant) have standard target names. Again, I borrow Maven's naming convention. Make sure all build.xml use the description parameter in target names, and that internal only targets don't use description. That way, ant -p works. Also make sure that all built artifacts are under the target directory (again, Maven's way). It makes it easy to do a clean if you only have to delete the target directory. The idea of clean is to restore your layout to pristine checkout condition. Makes it much easier to use a tool like Jenkins. Which reminds me...
Use a continuous build tool like Jenkins. It helps you enforce your policy and standards. Unlike many tools, developers actually like Jenkins. And, you can add stuff like automatic testing, checkstyle, etc.
1.
It depends on your workflow. If you expect everybody who will ever work on your project to use eclipse having the .classpath folder in there is good because it keeps all your settings(library paths, external dependencies..)
To the best of my knowledge subclipse doesn't put the /bin folder under version control(it probably happened because of the weird way the repository shaped as you describe in 2.) because eclipse can generate that one on the fly as soon as it has the /src folder.
usually moving everything under /workspace/projectName to / and deleting /workspace is sufficient.

Categories

Resources