Just An Application

December 16, 2009

What’s New In MIDP 3.0: Redux – LCDUI – Notification

Filed under: JME, Java, MIDP, MIDP3, MIDP3Issues, MIDP3LCDUI, Mobile Java — Tags: , , , , , , — Simon Lewis @ 10:28 pm

Original Post

Changes Since Proposed Final Draft

Removing the NotificationListener via the Notification.setListener(NotificationListener) method no longer removes the Notification as well.

This eliminates the inconsistency between its behaviour and the documentation describing the Notification life-cycle which I noted in the original post.

Issues

The other minor issues noted in my original post still exist.


Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

December 15, 2009

What’s New In MIDP 3.0: Redux – LCDUI – Menus

Filed under: JME, Java, MIDP, MIDP3, MIDP3Issues, MIDP3LCDUI, Mobile Java — Tags: , , , , , — Simon Lewis @ 9:30 pm

Original Post

Changes Since Proposed Final Draft

The semantics of the depth returned by the method Menu.getMenuDepth() have been changed.

The method now

Returns this menu’s depth within its menu tree. The top menu is of depth 0, the menus attached to it are of depth 1, 2, etc. The top menu is the menu in the menu tree that has no parent menu . If a menu is attached to both a Displayable and another menu, its depth is calculated based on the menu to which it is attached. For instance, a menu A is a sub-menu of menu B and is also attached to a Displayable. If menu B is of depth 3, then menu A will return a depth of 4.

Previously, as I observed in my original post, the specification was both contradictory, and seemed to imply, amongst other things, that a Menu could effectively have two depths.

Issues

Although it is not a particularly serious issue, despite the changes, it is not exactly clear what having the ability to obtain the depth of a given Menu is actually for.

The depth of a Menu is only significant in the context of the maximum limit on Menu depth.

If you know that a Menu is at the maximum permitted depth then it is true that you know that you definitely cannot add a sub-Menu to it.

If you know that a Menu is not at the maximum permitted depth however, you do not know that you can add a given Menu as a sub-Menu with out knowing whether the Menu you wish to attach itself has any sub-Menus, and if so what the maximum depth of the sub-Menu tree, and you are going to have to compute that.

As I say it is not serious but some use-cases might have helped.

This is also true of the eternally enigmatic Menu.onParentEnabled(true). What is it for ?


Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

September 11, 2009

“MIDlet not constructed by createMIDlet.” ?

Filed under: JME, Java, MIDP, MIDP Implementation, MIDlets, Mobile Java — Tags: , , , , — Simon Lewis @ 11:23 am

This is a bit of a meta or recursive post in a way because it is prompted by my curiousity as to why the phrase

MIDlet not constructed by createMIDlet.

keeps turning up in the list of search terms used by people who have ended up here.

It is not really a generic term like some of the others which bring people here. For example

MIDP3

or

MIDlets on Android

or variations thereof.

It is pretty specific, and it is the same phrase everytime, but It is not one I’ve ever used here. So what does it match here and what is everyone looking for ?

Finding out what the search engines are matching here is easy enough. Type it in and see what they reference. The answer is this post

      What’s New In MIDP 3.0 ? Part 10: The MIDlet Lifecycle

which contains the terms “constructed”. “create”, and “MIDlet()”. Hence the match, but obviously not very useful given the actual search term.

Where does the search term itself originate ? Judging from some of the other search results it is an error message associated with a SecurityException thrown by Sun’s MIDP implementatation, so I’m guessing that people are seeing this exception and want to know what causes it.

The answer I suspect is that they are trying to create a MIDlet programatically and you are not allowed to do that as it says in the Throws clause of the documentation for the javax.microedition.midlet.MIDlet constructor

java.lang.SecurityException – unless the application management software is creating the MIDlet.

There are a good reasons for not allowing this. It would be very hard if not impossible to implement MIDP and ensure the correct lifecycle behaviour if MIDlets could be constructed programmatically.

Ironically it is actually pretty tricky to prevent it happening as well. As an implementor the only hook you have is the javax.microedition.midlet.MIDlet constructor which is in what is effectively a sealed package, but it can be done.

If you want to see exactly how Sun did it you can download their MIDP implementation as part of Phoneme Feature or Phoneme Advanced.

If you want to see how we (Symbian) did it, well unfortunately currently you can’t, which is a shame, because it was quite clever. Well at least I thought so, but then I would.

August 22, 2009

A Standalone Android Runtime: UI And Graphics

Filed under: Android, Java, Mobile Java, Standalone Android Runtime — Tags: , , , — Simon Lewis @ 7:59 pm

,

The basis of the Android runtime graphics and UI functionality is the Skia graphics library and the SurfaceFlinger client/server architecture which are implemented in C/C++. In the case of the graphics functionality a large proportion of the classes in the android.graphics package are effectively Java wrappers around the equivalent C++ classes in Skia.

There is no direct equivalent to either Skia or the SurfaceFlinger in standard Java but there is sufficient graphics functionality available to substitute for enough of the functionality of Skia and the SurfaceFinger to produce at least basic UIs.

screenlocked

This is the standard locked screen showing the StatusBar and the KeyGuard. The resources, that is, the colours, drawables, and layouts used to produce them are unchanged, as are the fonts, and all the UI code involved. The battery charging animation works, as does the updating of the dates in the StatusBar and the KeyGuard. The only difference is that the rendering is being done in Java, as is the the composition. The top-level window is a java.awt.Frame

helloworld

This is HelloWorld, Comparison with the emulator shows that is not quite right. Some of the padding in the title bar seems to have gone astray. This is probably down to the replacement resource handling code not doing the right thing.

One of the things that there is no support for in standard Java, not suprisingly, is the NinePatchDrawable. This is a specialized form of PNG. As both the StatusBar and the Activity title bar use them they have to be supported. The 9-patch specific information is contained a specialized chunk within the PNG the format. To make life interesting the exact format of this chunk is not documented, but it is possible to work out what it is with the aid of the source code.


Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

A Standalone Android Runtime: Running HelloWorld The Hard Way

Whichever way HelloWorld gets launched there is a point at which the runtime will start to execute the code in the HelloWorld package HelloWorld.apk. Which is a problem. HelloWorld.apk is a standard Android package built using the Android development tools so what is in it, as you might expect, is a classes.dex file, which is nice if you are the Dalvik VM but not so great if you are another kind of JVM that does not talk Dalvik bytecode, and ours does not.

So why not put the class files in the package when its being built and use them ? Where’s the fun in that ? The contents of classes.dex started out as some class files, so lets turn it back into the class files on demand !

To do this we need a specialized ClassLoader which is pretty simple, in this case at least, a Dex loader, likewise, and a DVM to JVM bytecode compiler, which is a bit trickier. Fortunately the HelloWorld application is doing nothing much at all so there are not a large number or variety of instructions to compile.

Loading the Dex file and compiling the code back into JVM bytecode on-the-fly is not necessarily how you would solve this problem for real but it will work in this case.

Compiling is not the most visual of activities so instead here is the trace from the compiler which is invoked by the ClassLoader when the first class in the HelloWorld application is accessed by the runtime. To make life simpler at this point we load the entire Dex file and compile everything in sight, which is not a lot as you can see. The compiler is printing each DVM instruction as it compiles it.

Process[25001]:
Process[25001]: Class standalone/helloworld/HelloWorldActivity
Process[25001]:
Process[25001]: compiling <init>
Process[25001]:
Process[25001]: invoke-direct Landroid/app/Activity; <init> ()V
Process[25001]: return-void
Process[25001]:
Process[25001]: compiling onCreate
Process[25001]:
Process[25001]: invoke-super Landroid/app/Activity; onCreate (Landroid/os/Bundle;)V
Process[25001]: const #+2130903040
Process[25001]: invoke-virtual Lstandalone/helloworld/HelloWorldActivity; setContentView (I)V
Process[25001]: return-void
Process[25001]:
Process[25001]:
Process[25001]:
Process[25001]: Class standalone/helloworld/R$attr
Process[25001]:
Process[25001]: compiling <init>
Process[25001]:
Process[25001]: invoke-direct Ljava/lang/Object; <init> ()V
Process[25001]: return-void
Process[25001]:
Process[25001]:
Process[25001]:
Process[25001]: Class standalone/helloworld/R$drawable
Process[25001]:
Process[25001]: compiling <init>
Process[25001]:
Process[25001]: invoke-direct Ljava/lang/Object; <init> ()V
Process[25001]: return-void
Process[25001]:
Process[25001]:
Process[25001]:
Process[25001]: Class standalone/helloworld/R$layout
Process[25001]:
Process[25001]: compiling <init>
Process[25001]:
Process[25001]: invoke-direct Ljava/lang/Object; <init> ()V
Process[25001]: return-void
Process[25001]:
Process[25001]:
Process[25001]:
Process[25001]: Class standalone/helloworld/R$string
Process[25001]:
Process[25001]: compiling <init>
Process[25001]:
Process[25001]: invoke-direct Ljava/lang/Object; <init> ()V
Process[25001]: return-void
Process[25001]:
Process[25001]:
Process[25001]:
Process[25001]: Class standalone/helloworld/R
Process[25001]:
Process[25001]: compiling <init>
Process[25001]:
Process[25001]: invoke-direct Ljava/lang/Object; <init> ()V
Process[25001]: return-void

Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

A Standalone Android Runtime: Launching HelloWorld The Easy Way

Filed under: Android, Java, Mobile Java, Standalone Android Runtime — Tags: , , , — Simon Lewis @ 9:03 am

There is a considerably easier way of getting an application launched and that is to make it the home application. This can be done by modifying the application manifest, which is rather simpler than modifying the internals of the ActivityManagerService.

The standard home application is the Launcher which you can find here

    $(ANDROID_SRC)/packages/apps/Launcher

If you look at the application manifest (the file AndroidManifest.xml) you will see two category elements in the intent-filter of the activity, one named

    android.intent.category.HOME

and the other

    android.intent.category.DEFAULT

It is the presence of those two category elements which make the Launcher the home application.

Adding these to the HelloWorld application manifest gives us the following

    <?xml version="1.0" encoding="utf-8"?>
    <manifest
          xmlns:android="http://schemas.android.com/apk/res/android"
          package="standalone.helloworld"
          android:versionCode="1"
          android:versionName="1.0">
        <application android:icon="@drawable/icon" android:label="@string/app_name">
            <activity android:name=".HelloWorldActivity"
                  android:label="@string/app_name">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.HOME"/>
                    <category android:name="android.intent.category.DEFAULT"/>
               </intent-filter>
            </activity>
        </application>
        <uses-sdk android:minSdkVersion="3" />
    </manifest>

If we put the new version of the HelloWorld package in the data app directory and and start the SystemServer then HelloWorld gets launched automatically by the ActivityManager.

Here’s part of the Main log.

...

21-08-09 17:07:58: 22001: DEBUG: PowerManagerService system ready!
21-08-09 17:07:58: 22001: DEBUG: ActivityManager Start running!
21-08-09 17:07:58: 22001: INFO: ActivityManager Starting activity: Intent { ... }

Having started the ActivityManager begins launching HelloWorld as the home application . The Intent is

    {
        action=android.intent.action.MAIN
        categories={android.intent.category.HOME}
        flags=0x10000000
        comp={standalone.helloworld/standalone.helloworld.HelloWorldActivity}
    }

The flag is Intent.FLAG_ACTIVITY_NEW_TASK as before.

21-08-09 17:07:59: 22001: INFO: ActivityManager Start proc standalone.helloworld for activity standalone.helloworld/.HelloWorldActivity: pid=25001 uid=10000 gids={}
21-08-09 17:07:59: 22001: WARN: ActivityManager Unable to start service Intent { ... } }: not found
21-08-09 17:07:59: 22001: ERROR: LockPatternKeyguardView Failed to bind to GLS while checking for account
21-08-09 17:07:59: 22001: WARN: StatusBar Icon not found in : 0
21-08-09 17:07:59: 22001: DEBUG: LocationManagerService PowerStateBroadcastReceiver: Battery changed
21-08-09 17:08:00: 22001: DEBUG: StatusBar updateResources
21-08-09 17:08:00: 22001: DEBUG: LocationManagerService PowerStateBroadcastReceiver: Screen on
21-08-09 17:08:00: 22001: DEBUG: LocationManagerService updateWakelockStatus(): true
21-08-09 17:08:00: 22001: DEBUG: LocationManagerService Cancelling existing alarm
21-08-09 17:08:00: 22001: DEBUG: LocationManagerService No need for alarm
21-08-09 17:08:00: 22001: DEBUG: LocationManagerService Can't release wakelock again!
21-08-09 17:08:02: 22001: INFO: ActivityManager Displayed activity standalone.helloworld/.HelloWorldActivity: 3152 ms

The rest of the log is as before at this point in the start up and then the application is running.

A section of the Event log.

21-08-09 17:07:58: 22001 11664372 boot_progress_ams_ready[3040]	time 7085 milliseconds
21-08-09 17:07:59: 22001 11664372 am_create_task[30004]         Task ID 2
21-08-09 17:07:59: 22001 11664372 am_create_activity[30005]     Token 2412794 Task ID 2 Component Name standalone.helloworld/.HelloWorldActivity Action android.intent.action.MAIN MIME Type  URI  Flags 268435456
21-08-09 17:07:59: 22001 11664372 am_proc_start[30014]          PID 25001 UID 10001 Process Name standalone.helloworld Type activity Component standalone.helloworld/.HelloWorldActivity
21-08-09 17:07:59: 22001 15182069 am_proc_bound[30010]          PID 25001 Process Name standalone.helloworld
21-08-09 17:07:59: 22001 15182069 am_restart_activity[30006]	Token 2412794 Task ID 2 Component Name standalone.helloworld/.HelloWorldActivity
...
21-08-09 17:08:01: 25001 15069394 am_on_resume_called[30022]	Component Name standalone.helloworld.HelloWorldActivity
21-08-09 17:08:02: 22001 8778710 activity_launch_time[30009]	Token 2412794 Component Name standalone.helloworld/.HelloWorldActivity time 3152 milliseconds

Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

A Standalone Android Runtime: Launching HelloWorld The Hard Way

Filed under: Android, Java, Mobile Java, Standalone Android Runtime — Tags: , , — Simon Lewis @ 8:11 am

So how do we launch our newly installed HelloWorld application ? Easy, we just invoke startActivity() on the ActivityManager with the appropriate Intent.

If we were doing it from an Android application the code would look something like this.

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;

...

    void launch(Context theContext, String thePackage, String theClassName)
    {
        theContext.
            startActivity(
                new Intent(
                    Intent.ACTION_MAIN).
                setComponent(
                    new ComponentName(
                        thePackage,
                        theClassName)).
                addFlags(
                    Intent.FLAG_ACTIVITY_NEW_TASK));
    }

...

But of course we can’t do that because to run it we would have to launch the application containing the code to do the launching which is what we are trying to do in the first place.

Still we have a functioning IPC mechanism which we can use to get a Binder for the ActivityManager and which we can subsequently use to do the invocation so we can launch the application from outside so to speak. Except that we can’t. The ActivityManager, as you might expect, does not take kindly to applications being launched by things Android knows nothing about. Here is part of the code from the ActivityManagerService method startActivityLocked(). Its the variant with rather too many parameters for comfort starting at line 3003.


...

        ProcessRecord callerApp = null;
        if (err == START_SUCCESS && caller != null) {
            callerApp = getRecordForAppLocked(caller);
            if (callerApp != null) {
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } else {
                Log.w(TAG, "Unable to find app for caller " + caller
                      + " (pid=" + callingPid + ") when starting: "
                      + intent.toString());
                err = START_PERMISSION_DENIED;
            }
        }

...

This is of course exactly the right thing to do but we have an application to launch so we will simply elide that check for now,

Following this sleight of hand the application duly lauches and the main log shows the following

21-08-09 15:55:56: 22001: INFO: ActivityManager Starting activity: Intent { ... }

The Intent is

     {
         action = android.intent.action.MAIN
         type   =
         flags  = 0x10000000
         comp   = {standalone.helloworld/standalone.helloworld.HelloWorldActivity}
     }

The value of flags is actually Intent.FLAG_ACTIVITY_NEW_TASK

21-08-09 15:56:01: 22001: INFO: ActivityManager Start proc standalone.helloworld for activity standalone.helloworld/.HelloWorldActivity: pid=25001 uid=10000 gids={}
21-08-09 15:56:04: 22001: INFO: ActivityManager Displayed activity standalone.helloworld/.HelloWorldActivity: 2583 ms

And the Event log shows this

21-08-09 15:56:01: 22001 2668988 am_create_task[30004]	      Task ID 2
21-08-09 15:56:01: 22001 2668988 am_create_activity[30005]    Token 5975831 Task ID 2 Component Name standalone.helloworld/.HelloWorldActivity Action android.intent.action.MAIN MIME Type  URI  Flags 268435456
21-08-09 15:56:01: 22001 2668988 am_proc_start[30014]	      PID 25001 UID 10001 Process Name standalone.helloworld Type activity Component standalone.helloworld/.HelloWorldActivity
21-08-09 15:56:02: 22001 16490550 am_proc_bound[30010]        PID 25001 Process Name standalone.helloworld
21-08-09 15:56:02: 22001 16490550 am_restart_activity[30006]  Token 5975831 Task ID 2 Component Name standalone.helloworld/.HelloWorldActivity
21-08-09 15:56:04: 25001 7161559 am_on_resume_called[30022]   Component Name standalone.helloworld.HelloWorldActivity
21-08-09 15:56:04: 22001 10621833 activity_launch_time[30009] Token 5975831 Component Name standalone.helloworld/.HelloWorldActivity time 2583 milliseconds

Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

A Standalone Android Runtime: Application Installation

Filed under: Android, Java, Mobile Java, Standalone Android Runtime — Tags: , , , — Simon Lewis @ 7:25 am

It turns out that an application can be installed, such that it can subsequently be run, simply by placing the package containing it in the data app directory. On a device this would usually be the directory

    /data/app

When it is started by the SystemServer the PackageManagerService will scan this directory and find the package containing the application. It will then ask the Installer to install the application.

The Installer in the SystemServer is simply a proxy for the installd process which can be found here

    $(ANDROID_SRC)/frameworks/base/cmds/installd

It is responsible for creating the directories for the application being installed and for changing their ownership to that of the application. This requires root privilege or something like it which is why it is being done by a standlone process rather than in the context of the SystemServer process.

The proxy in the SystemServer communicates with installd using local sockets. Neither local sockets nor some of the functionality required by installd are available in standard Java but we can mimic enough that the installation of the application succeeds.


Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

August 21, 2009

A Standalone Android Runtime: SystemServer Startup

Filed under: Android, Java, Mobile Java, Standalone Android Runtime — Tags: , , , — Simon Lewis @ 11:44 am

There isn’t a great deal to show for a successful startup of the SystemServer except the contents of the logs so here they are.

The Main Log

The date at the start of each line is elided, and in some cases the time too, as it enables some long lines to just about fit.

... 09:50:31: 22001: INFO: SystemServer Entered the Android system server!
... 09:50:32: 22001: INFO: SystemServer Starting Power Manager.
... 09:50:32: 22001: INFO: SystemServer Starting Activity Manager.
... 09:50:33: 22001: INFO: SystemServer Starting telephony registry
... 09:50:33: 22001: INFO: SystemServer Starting Package Manager.

Nothing very interesting so far

... 09:50:33: 22001: WARN: PackageManager **** ro.build.version.sdk not set!

That’s because its not, but its only a warning so we won’t worry about it

... 22001: INFO: PackageManager Got library android.awt in /system/framework/android.awt.jar
... 22001: INFO: PackageManager Got library android.test.runner in /system/framework/android.test.runner.jar
... 22001: INFO: PackageManager Got library com.android.im.plugin in /system/framework/com.android.im.plugin.jar
... 09:50:33: 22001: WARN: PackageManager No BOOTCLASSPATH found!

That’s also true, but again its only a warning

... 09:50:33: 22001: DEBUG: PackageManager Scanning app dir /Users/simon/Scratch/standalone/system/framework
... 09:50:33: 22001: DEBUG: PackageManager Scanning app dir /Users/simon/Scratch/standalone/system/app
... 09:50:33: 22001: DEBUG: PackageManager Scanning app dir /Users/simon/Scratch/standalone/data/app
... 22001: WARN: PackageParser Skipping non-package file: /Users/simon/Scratch/standalone/data/app/.DS_Store

That’s MacOS X for you.

... 09:50:34: 22001: DEBUG: PackageManager Scanning app dir /Users/simon/Scratch/standalone/data/app-private
... 09:50:34: 22001: INFO: PackageManager Time to scan packages: 0.763 seconds
... 22001: WARN: PackageManager Removing dangling permission: android.permission.ACCESS_CACHE_FILESYSTEM from package null
... 09:50:34: 22001: INFO: SystemServer Starting Content Manager.
... 09:50:34: 22001: WARN: ActivityManager Unable to start service Intent { ... } }: not found
... 09:50:34: 22001: WARN: AccountMonitor Couldn't connect to Intent {  ... } } (Missing service?)

These two lines are very long indeed so they’ve been elided. The Intent being complained about is

    {
       action = android.accounts.IAccountsService
       comp   = { com.google.android.googleapps/com.google.android.googleapps.GoogleLoginService }
    }

and its true its not there. On the other hand its not there in the Emulator either.

... 09:50:34: 22001: INFO: SystemServer Starting System Content Providers.
... 09:50:34: 22001: INFO: ActivityThread Publishing provider sync: android.content.SyncProvider
... 09:50:34: 22001: INFO: ActivityThread Publishing provider settings: standalone.content.SettingsProvider

This is our substitute ContentProvider for the

    content://settings/...

URIs being started.

... 09:50:34: 22001: INFO: SystemServer Starting Battery Service.
... 09:50:34: 22001: INFO: SystemServer Starting Hardware Service.
... 09:50:34: 22001: INFO: SystemServer Starting Alarm Manager.
... 09:50:34: 22001: INFO: SystemServer Starting Sensor Service.
... 09:50:34: 22001: INFO: SystemServer Starting Window Manager.
... 09:50:35: 22001: INFO: SystemServer Starting Bluetooth Service.
... 09:50:35: 22001: INFO: SystemServer Starting Status Bar Service.
... 09:50:37: 22001: INFO: SystemServer Starting Clipboard Service.
... 09:50:37: 22001: INFO: SystemServer Starting Input Method Service.
... 09:50:37: 22001: INFO: InputManagerService Enabled input methods: null
... 09:50:37: 22001: INFO: InputManagerService Enabled input methods has not been set, enabling all
... 09:50:37: 22001: INFO: SystemServer Starting NetStat Service.
... 09:50:37: 22001: INFO: SystemServer Starting Connectivity Service.
... 09:50:37: 22001: INFO: WifiService WifiService starting up with Wi-Fi disabled
... 09:50:37: 22001: INFO: SystemServer Starting Notification Manager.
... 09:50:37: 22001: INFO: SystemServer Starting Mount Service.
... 09:50:37: 22001: INFO: SystemServer Starting DeviceStorageMonitor service
... 09:50:37: 22001: INFO: SystemServer Starting Location Manager.
... 09:50:37: 22001: INFO: SystemServer Starting Search Service.
... 09:50:37: 22001: INFO: SystemServer Starting Checkin Service.
... 09:50:37: 22001: WARN: ActivityManager Unable to start service Intent { ... }: not found

Another long line. This time the Intent is

    {
        comp = { com.google.android.server.checkin/com.google.android.server.checkin.CheckinService }
    }

Again its true its not there, and again its not there in the SDK emulator either.

... 09:50:37: 22001: WARN: SystemServer Using fallback Checkin Service.
... 09:50:37: 22001: INFO: SystemServer Starting Wallpaper Service
... 09:50:37: 22001: DEBUG: WallpaperService WallpaperService startup
... 09:50:37: 22001: INFO: SystemServer Starting Audio Service
... 22001: WARN: AudioService Soundpool could not load file: /Users/simon/Scratch/standalone/system/media/audio/ui/Effect_Tick.ogg
... 22001: WARN: AudioService Soundpool could not load file: /Users/simon/Scratch/standalone/system/media/audio/ui/KeypressStandard.ogg
... 22001: WARN: AudioService Soundpool could not load file: /Users/simon/Scratch/standalone/system/media/audio/ui/KeypressSpacebar.ogg
... 22001: WARN: AudioService Soundpool could not load file: /Users/simon/Scratch/standalone/system/media/audio/ui/KeypressDelete.ogg
... 22001: WARN: AudioService Soundpool could not load file: /Users/simon/Scratch/standalone/system/media/audio/ui/KeypressReturn.ogg

Haven’t got any of those, and neither does the Emulator.

... 09:50:37: 22001: INFO: SystemServer Starting HeadsetObserver
... 09:50:37: 22001: WARN: HeadsetObserver This kernel does not have wired headset support
... 09:50:37: 22001: INFO: SystemServer Starting AppWidget Service
... 09:50:37: 22001: INFO: WindowManager Menu key state: 0 safeMode=false
... 09:50:38: 22001: INFO: WindowManager Config changed: { scale=1.0 imsi=0/0 locale=en_US touch=1 key=1/2/2 nav=1 orien=1 }
... 09:50:38: 22001: DEBUG: PowerManagerService system ready!

We’re done.

... 09:50:38: 22001: DEBUG: ActivityManager Start running!
... 09:50:38: 22001: WARN: ActivityManager Unable to start service Intent { ... }: not found

Another missing service. The Intent is

     {
         action = android.accounts.IAccountsService
         comp   = { com.google.android.googleapps/com.google.android.googleapps.GoogleLoginService }
     }

No we don’t have it. Neither does the Emulator.

... 09:50:38: 22001: ERROR: LockPatternKeyguardView Failed to bind to GLS while checking for account

A consequence of the previous problem. Also present in the Emulator.

... 09:50:38: 22001: WARN: StatusBar Icon not found in : 0

This looks as though it is a bug except that it happens in the Emulator as well.

... 09:50:38: 22001: DEBUG: LocationManagerService PowerStateBroadcastReceiver: Battery changed
... 09:50:38: 22001: DEBUG: StatusBar updateResources
... 09:50:38: 22001: DEBUG: LocationManagerService PowerStateBroadcastReceiver: Screen on
... 09:50:38: 22001: DEBUG: LocationManagerService updateWakelockStatus(): true
... 09:50:38: 22001: DEBUG: LocationManagerService Cancelling existing alarm
... 09:50:38: 22001: DEBUG: LocationManagerService No need for alarm
... 09:50:38: 22001: DEBUG: LocationManagerService Can't release wakelock again!

The Event Log

A very rough-and-ready formatted version of the contents of the Event log.

... 09:50:31: 22001 902782 boot_progress_system_run[3010]	time 0 milliseconds
... 09:50:33: 22001 902782 boot_progress_pms_start[3060]	time 1315 milliseconds
... 09:50:33: 22001 902782 boot_progress_pms_system_scan_start[3070]	time 1414 milliseconds
... 09:50:33: 22001 902782 boot_progress_pms_data_scan_start[3080]	time 1867 milliseconds
... 09:50:34: 22001 902782 boot_progress_pms_scan_end[3090]	time 2177 milliseconds
... 09:50:34: 22001 902782 boot_progress_pms_ready[3100]	time 2209 milliseconds
... 09:50:34: 22001 902782 battery_status[2723]	status 0 health 0 present 0 plugged 1 technology
... 09:50:34: 22001 902782 battery_level[2722]	level 74 percent voltage 0 temperature 0
... 09:50:34: 22001 1259814 power_screen_state[2728]	offOrOn 1 becauseOfUser 0 totalTouchDownTime 0 milliseconds touchCycles 0
... 09:50:34: 22001 1259814 power_screen_broadcast_send[2725]	wakelockCount 1
... 09:50:38: 22001 902782 configuration_changed[2719]	config mask 248
... 09:50:38: 22001 902782 boot_progress_ams_ready[3040]	time 6205 milliseconds
... 09:50:38: 22001 1259814 screen_toggled[70000]	screen_state 1
... 09:50:38: 22001 1259814 power_screen_broadcast_done[2726]	on 1 broadcastDuration 762 milliseconds wakelockCount 1 

The records were accessed using the classes in the com.android.ddmlib.log package.


Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

August 20, 2009

A Standalone Android Runtime: Settings

Filed under: Android, Java, Mobile Java, Standalone Android Runtime — Tags: , , , — Simon Lewis @ 8:32 pm

One piece of functionality which elements of the SystemServer require but which is not present is the ContentProvider responsible for content with the following URIs

  • content://settings/bookmark
  • content://settings/gservices
  • content://settings/secure
  • content://settings/system

This is because we are running without any of the system supplied applications or content providers, and all of these content URIs are handled by the SettingsProvider application which can be found in

    $(ANDROID_SRC)/frameworks/base/packages/SettingsProvider

Since various things fall-over more or less badly if some of these settings are not available we provide a dummy ContentProvider, which when queried returns a Cursor capable of returning some appropriate hardwired values. We install this ContentProvider by hand in the method

    public static final void installSystemProviders()

of the com.android.server.am.ActivityManagerService class.


Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

Older Posts »

Blog at WordPress.com.