User:VladVukicevic/Android Notes: Difference between revisions
Jump to navigation
Jump to search
mNo edit summary |
No edit summary |
||
| Line 1: | Line 1: | ||
=== 16 Nov 2009 === | |||
* Android apps/activies are all separate processes | |||
** Therefore, they communicate with system services using IPC (binder) | |||
** Therefore, we should be able to duplicate that communication | |||
* Apps are all launched from a forked Zygote process, which is basically a pre-initialized dalvik instance | |||
** the zygote process is executed at system boot; it does initialization, and then runs a select() loop listening to requests | |||
** the zygote process is sent a message, which includes the start args, which will include the class name for main launch | |||
** the zygote process reads connection args in ZygoteConnection.runOnce | |||
** the zygote process forks in ZygoteConnection.runOnce (Zygote.forkAndSpecialize, native) | |||
** ZygoteConnection.handleChildProc is called, which does some cleanup and eventually throws a MethodAndArgsCaller (via ZygoteInit.invokeStaticMain) | |||
** ... which takes us all the way back to ZygoteInit.main, which catches that trampoline exception, and calls run() | |||
* Stack on onCreate, generally the initial entry point for a normal Android activity: | |||
<pre> | |||
TestApp.onCreate(Bundle) line: 10 | |||
Instrumentation.callActivityOnCreate(Activity, Bundle) line: 1123 | |||
ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2364 | |||
ActivityThread.handleLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2417 | |||
ActivityThread.access$2100(ActivityThread, ActivityThread$ActivityRecord, Intent) line: 116 | |||
ActivityThread$H.handleMessage(Message) line: 1794 | |||
ActivityThread$H(Handler).dispatchMessage(Message) line: 99 | |||
Looper.loop() line: 123 | |||
ActivityThread.main(String[]) line: 4203 | |||
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method] | |||
Method.invoke(Object, Object...) line: 521 | |||
ZygoteInit$MethodAndArgsCaller.run() line: 791 | |||
This is the run() that was called after the fork, in our new process | |||
ZygoteInit.main(String[]) line: 549 | |||
NativeStart.main(String[]) line: not available [native method] | |||
</pre> | |||
* ActivityThread.main() is effectively the "main" for an app; an app launch involves: | |||
** telling the ActivityManagerService that an app launch is desired, with info about which app | |||
** spinning up a new process via zygote that executes ActivityThread.main() | |||
** ActivityThread.main() calls Looper.prepareMainLooper, to initialize the main event loop for the new process | |||
** ActivityThread.main() connects to the ActivityManagerService and asks it for the next app that's waiting in the launch queue | |||
** Looper.loop() is called, which reads and dispatches messages | |||
=== 1 Sep 2009 === | |||
;Rendering is easy | ;Rendering is easy | ||
:frameworks/base/cmds/bootanimation has a simple native command that shows how to connect to SurfaceComposer, create a Surface (which has move/etc. functions on ISurface), and draw to it. | :frameworks/base/cmds/bootanimation has a simple native command that shows how to connect to SurfaceComposer, create a Surface (which has move/etc. functions on ISurface), and draw to it. | ||
Revision as of 22:38, 16 November 2009
16 Nov 2009
- Android apps/activies are all separate processes
- Therefore, they communicate with system services using IPC (binder)
- Therefore, we should be able to duplicate that communication
- Apps are all launched from a forked Zygote process, which is basically a pre-initialized dalvik instance
- the zygote process is executed at system boot; it does initialization, and then runs a select() loop listening to requests
- the zygote process is sent a message, which includes the start args, which will include the class name for main launch
- the zygote process reads connection args in ZygoteConnection.runOnce
- the zygote process forks in ZygoteConnection.runOnce (Zygote.forkAndSpecialize, native)
- ZygoteConnection.handleChildProc is called, which does some cleanup and eventually throws a MethodAndArgsCaller (via ZygoteInit.invokeStaticMain)
- ... which takes us all the way back to ZygoteInit.main, which catches that trampoline exception, and calls run()
- Stack on onCreate, generally the initial entry point for a normal Android activity:
TestApp.onCreate(Bundle) line: 10 Instrumentation.callActivityOnCreate(Activity, Bundle) line: 1123 ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2364 ActivityThread.handleLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2417 ActivityThread.access$2100(ActivityThread, ActivityThread$ActivityRecord, Intent) line: 116 ActivityThread$H.handleMessage(Message) line: 1794 ActivityThread$H(Handler).dispatchMessage(Message) line: 99 Looper.loop() line: 123 ActivityThread.main(String[]) line: 4203 Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method] Method.invoke(Object, Object...) line: 521 ZygoteInit$MethodAndArgsCaller.run() line: 791 This is the run() that was called after the fork, in our new process ZygoteInit.main(String[]) line: 549 NativeStart.main(String[]) line: not available [native method]
- ActivityThread.main() is effectively the "main" for an app; an app launch involves:
- telling the ActivityManagerService that an app launch is desired, with info about which app
- spinning up a new process via zygote that executes ActivityThread.main()
- ActivityThread.main() calls Looper.prepareMainLooper, to initialize the main event loop for the new process
- ActivityThread.main() connects to the ActivityManagerService and asks it for the next app that's waiting in the launch queue
- Looper.loop() is called, which reads and dispatches messages
1 Sep 2009
- Rendering is easy
- frameworks/base/cmds/bootanimation has a simple native command that shows how to connect to SurfaceComposer, create a Surface (which has move/etc. functions on ISurface), and draw to it.
- Events are all java side
- the core pieces are IWindowManager and IWindow. See IWindowManager.aidl, IWindow.aidl, IWindowSession.aidl in frameworks/base/core/java/android/view. Also core is WindowManagerService in frameworks/base/services/java/com/android/server/WindowManagerService.java . The service seems to be the piece that we need to interact with; we need to have an IWindow and call addWindow on the service. It dispatches events to windows that it knows about, as best I can tell, using the IWindow interface.
- For exploration
- create a java shim that would basically bridge all the java pieces back to native code; essentially, in the end, part of widget/src/android would be implemented in java (and a simple java launcher). We should create that shim and some native rendering/event handling code first (ignoring gecko entirely) to see what that would look like.