Android implements sleep wake-up based on standard Linux (3)

Source: Internet
Author: User

Iv. Android-layer source code parsing

On Linux, Android software stacks are encapsulated and used in the upper-layer Java applications. Sleep wake-up is also a command issued from the top layer. Then, the parameter is parsed layer by layer, passed to the bottom layer, and finally embarked on the sleep wake-up path of standard Linux.

This section will analyze the path taken on Linux on the sleep wake-up mechanism.

On Linux, there is a Hal layer dedicated to dealing with Linux kernel devices, which is no exception here. The source code of the Hal layer of the sleep wake-up mechanism is located at @ hardware/libhardware_legacy/power. C.

The source code of this file is relatively simple. The following lists the key parts:

Enum {

Acquire_partial_wake_lock = 0,

Release_wake_lock,

Request_state,

Our_fd_count

};

Constchar * const new_paths [] = {

"/Sys/power/wake_lock ",

"/Sys/power/wake_unlock ",

"/Sys/power/state"

};

Staticint g_initialized = 0;

Staticint g_fds [our_fd_count];

Staticconst char * off_state = "mem ";

Staticconst char * on_state = "on ";

 

Staticint open_file_descriptors (const char * const paths [])

{

Int I;

For (I = 0; I <our_fd_count; I ++ ){

Int FD = open (paths [I], o_rdwr );

If (FD <0 ){

Fprintf (stderr, "Fatal error opening/" % S/"/N", paths [I]);

G_error = errno;

Return-1;

}

G_fds [I] = FD;

}

 

G_error = 0;

Return 0;

}

 

Staticinline void initialize_fds (void)

{

If (g_initialized = 0 ){

If (open_file_descriptors (new_paths) <0 ){

Open_file_descriptors (old_paths );

On_state = "Wake ";

Off_state = "standby ";

}

G_initialized = 1;

}

}

 

Int acquire_wake_lock (INT lock, const char * ID)

{

Initialize_fds ();

If (g_error) return g_error;

Int FD;

 

If (Lock = partial_wake_lock) {// lock type passed down by the upper layer

FD = g_fds [acquire_partial_wake_lock];

}

Else {

Return einval;

}

 

Return write (FD, ID, strlen (ID ));

}

 

Int release_wake_lock (const char * ID)

{

Initialize_fds ();

 

// Logi ("release_wake_lock id = '% s'/N", ID );

 

If (g_error) return g_error;

 

Ssize_t Len = write (g_fds [release_wake_lock], ID, strlen (ID ));

Return Len> = 0;

}

 

Intset_screen_state (INT on)

{

Qemu_fallback (set_screen_state (on ));

Logi ("*** set_screen_state % d", on );

 

Initialize_fds ();

If (g_error) return g_error;

 

Char Buf [32];

Int Len;

If (on)

Len = sprintf (BUF, on_state );

Else

Len = sprintf (BUF, off_state );

Len = write (g_fds [request_state], Buf, Len );

If (LEN <0 ){

LogE ("failed setting last user activity: g_error = % d/N", g_error );

}

Return 0;

}

 

The Hal-layer code is used in the JNI layer. The source code is in: Frameworks/base/CORE/JNI/android_ OS _power.cpp. The code snippet is as follows:

Staticvoid acquirewakelock (jnienv * ENV, jobject clazz, jint lock, jstring idobj)

{

If (idobj = NULL ){

Throw_nullpointerexception (ENV, "id isnull ");

Return;

}

 

Const char * id = env-> getstringutfchars (idobj, null );

 

Acquire_wake_lock (lock, ID );

 

Env-> releasestringutfchars (idobj, ID );

} // Lock the wakelock Function

Staticvoid releasewakelock (jnienv * ENV, jobject clazz, jstring idobj)

{

If (idobj = NULL ){

Throw_nullpointerexception (ENV, "id isnull ");

Return;

}

 

Const char * id = env-> getstringutfchars (idobj, null );

 

Release_wake_lock (ID );

 

Env-> releasestringutfchars (idobj, ID );

 

} // Unlock the wakelock Function

Staticint setscreenstate (jnienv * ENV, jobject clazz, jboolean on)

{

Return set_screen_state (on );

} // Sleep wake-up function

 

The JNI method can be used only when it is registered to the upper layer, and Native must be declared in the corresponding Java class at the upper layer. So where is the declaration of the method in Java? Frameworks/base/CORE/Java/Android/OS/power. java. This file defines a Java class, as follows:

Publicclass power

{

// Can't instantiate this class

Private Power ()

{

}

/**

* Wake lock that ensures that the CPU isrunning. The screen might

* Not be on.

*/

Public static final int partial_wake_lock = 1;

/**

* Wake lock that ensures that the screen is on.

*/

Public static final int full_wake_lock = 2;

Public static native void acquirewakelock (INT lock, string ID );

Public static native void releasewakelock (string ID );

...

/**

* Turn the screen on or off

*

* @ Param on whether you want the screen on or off

*/

Public static native int setscreenstate (Boolean on );

...

}

The declared JNI interface should be used by the assumerver. Here is the dedicated power management service: powermanagerservice. The specific source code is located: frameworks/base/services/Java/COM/Android/Server/powermanagerservice. java. Android also provides the Android. OS. powermanager class on the top.

(Frameworks/base/CORE/Java/Android/OS/powermanager. Java) is used by the app. The powermanager class calls the Java service powermanagerservice method to complete wakelock-related work.

@ Frameworks/base/CORE/Java/Android/OS/powermanager. Java

A wakelock class is embedded in the powermanager class, and the type of wakelock is also defined. The following is a code snippet:

Public class powermanager

{

Private Static final string tag = "powermanager ";

...

/**

* Wake lock that ensures that the CPU isrunning. The screen might

* Not be on.

*/

Public static final int partial_wake_lock = wake_bit_cpu_strong;

 

/**

* Wake lock that ensures that the screen and keyboardare on

* Full brightness.

*/

Public static final int full_wake_lock = wake_bit_cpu_weak | wake_bit_screen_bright | wake_bit_keyboard_bright;

/**

* Wake lock that ensures that the screen is on at fullbrightness;

* The keyboard backlight will be allowed to go off.

*/

Public static final int screen_bright_wake_lock = wake_bit_cpu_weak | wake_bit_screen_bright;

 

/**

* Wake lock that ensures that the screen is on (butmay be dimmed );

* The keyboard backlight will be allowed to go off.

*/

Public static final int screen_dim_wake_lock = wake_bit_cpu_weak | wake_bit_screen_dim;

 

/**

* Wake lock that turns the screen off when theproximity sensor activates.

* Since not all devices have proximity sensors, use

* {@ Link # getsupportedwakelockflags ()} to determine if

* This wake lock mode is supported.

*

* {@ Hide}

*/

Publicstatic final int proximity_screen_off_wake_lock

= Wake_bit_proximity_screen_off;

...

Public class wakelock

{

...

Wakelock (INT flags, string tag)

{

Switch (flags & lock_mask ){

Case partial_wake_lock:

Case screen_dim_wake_lock:

Case screen_bright_wake_lock:

Case full_wake_lock:

Case proximity_screen_off_wake_lock:

Break;

Default:

Throw new illegalargumentexception ();

}

 

Mflags = flags;

Mtag = tag;

Mtoken = New binder ();

}

Public void acquire ()

{

Synchronized (mtoken ){

If (! Mrefcounted | mcount ++ = 0 ){

Try {

Mservice. acquirewakelock (mflags, mtoken, mtag );

} Catch (RemoteException e ){

}

Mheld = true;

}

}

}

Public void release (INT flags)

{

Synchronized (mtoken ){

If (! Mrefcounted | -- mcount = 0 ){

Try {

Mservice. releasewakelock (mtoken, flags );

} Catch (RemoteException e ){

}

Mheld = false;

}

If (mcount <0 ){

Throw new runtimeexception ("wakelock under-locked" + mtag );

}

}

}

...

}

...

Publicwakelock newwakelock (INT flags, string tag)

{

If (TAG = NULL ){

Throw new nullpointerexception ("tag is

NULL in powermanager. newwakelock ");

}

Return new wakelock (flags, tag );

}

Public void Gotosleep (long time)

{

Try {

Mservice. Gotosleep (time );

} Catch (RemoteException e ){

}

}

...

Publicpowermanager (ipowermanager service, Handler handler)

{

Mservice = service;

Mhandler = handler;

}

 

Ipowermanager mservice;

Handler mhandler;

}

Application instance:

Powermanager PM = (powermanager) getsystemservice (context. power_service );

Powermanager. wakelock WL =

PM. newwakelock (powermanager. screen_dim_wake_lock, "tag ");

WL. Acquire (); // apply for a lock. This will call acquirewakelock () in powermanagerservice ()

...

WL. Release (); // release lock, displayed release. If the applied lock is not released here, the system will not enter sleep.

 

The following code is called to the Java service powermanagerservice:

Public void acquirewakelock (INT flags, ibinder lock, string tag ){

Int uid = binder. getcallinguid ();

If (UID! = Process. myuid ()){

Mcontext. enforcecallingorselfpermission (Android. manifest. Permission. wake_lock, null );

}

Long ident = binder. clearcallingidentity ();

Try {

Synchronized (mlocks ){

Acquirewakelocklocked (flags, lock, uid, tag); // internal Method

}

} Finally {

Binder. restorecallingidentity (ident );

}

}

 

Acquirewakelocklocked (flags, lock, uid, tag) will call the power function method:

Power. acquirewakelock (power. partial_wake_lock, partial_name ).

 

Public void releasewakelock (ibinder lock, int flags ){

Int uid = binder. getcallinguid ();

If (UID! = Process. myuid ()){

Mcontext. enforcecallingorselfpermission (Android. manifest. Permission. wake_lock, null );

}

 

Synchronized (mlocks ){

Releasewakelocklocked (lock, flags, false );

}

}

The releasewakelocklocked (lock, flags, false) function calls the power class method:

Power. releasewakelock (partial_name );

 

The upper-layer sleep wake-up method calls the powermanagerservice class:

Gotosleep ()

À gotosleepwithreason ()

À gotosleeplocked ()

À setpowerstate ()

À setscreenstatelocked ()

À power. setscreenstate ()

À JNI Method

The code analysis on the android layer is not very detailed. Here we only focus on the framework and process. Is a framework on the Internet, you can refer:

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.