MTK android 4.2.2添加重启功能

接触Android框架层也有一段时间了,但是基本上都没有对遇到的问题写总结,当遇到同样的问题也只能凭着模糊的记忆去解决。打算从今天开始每天抽点时间对工作中遇到的问题进行总结。
今天要说的是为Android添加一个重启按钮,在Nine的客户需求中需要添加这项功能,在长按电源键弹出的菜单中没有重启选项,谨以此文记录自己添加这个功能的过程:
修改涉及到的文件如下:
frameworks\base\core\java\android\view\WindowManagerPolicy.java
frameworks\base\core\res\res\values\strings.xml
frameworks\base\core\res\res\values-zh-rCN\strings.xml
frameworks\base\policy\src\com\android\internal\policy\impl\GlobalActions.java
frameworks\base\services\java\com\android\server\wm\windowManagerService.java
frameworks\base\services\java\com\android\server\power\ShutdownThread.java
frameworks\base\core\res\res\values\symbols.xml

首先找到长按电源键弹出的对话框,在 frameworks\base\policy\src\com\android\internal\policy\impl\GlobalActions.java文件中
[java] view plain copy
  1.   /** 
  2.    * Create the global actions dialog. 
  3.    * @return A new dialog. 
  4.    */  
  5.   private GlobalActionsDialog createDialog() {  
  6.       ...  
  7.       ...  
  8.       mItems = new ArrayList<Action>();  
  9.       // first: power off  
  10.       mItems.add(  
  11.           new SinglePressAction(  
  12.                   com.android.internal.R.drawable.ic_lock_power_off,  
  13.                   R.string.global_action_power_off) {  
  14.               public void onPress() {  
  15.                   // shutdown by making sure radio and power are handled accordingly.  
  16.                   mWindowManagerFuncs.shutdown(true);  
  17.               }  
  18.               public boolean onLongPress() {  
  19.                   mWindowManagerFuncs.rebootSafeMode(true);  
  20.                   return true;  
  21.               }  
  22.               public boolean showDuringKeyguard() {  
  23.                   return true;  
  24.               }  
  25.               public boolean showBeforeProvisioning() {  
  26.                   return true;  
  27.               }  
  28.           });  
  29.           //xiaoyuguang 20130616 add reboot item  
  30.    mItems.add(  
  31.           new SinglePressAction(  
  32.                   com.android.internal.R.drawable.ic_lock_power_off,  
  33.                   R.string.global_action_reboot) {  
  34.               public void onPress() {  
  35. // reboot  
  36.                   mWindowManagerFuncs.reboot(true);  
  37. }  
  38.               public boolean onLongPress() {  
  39.                   return true;  
  40.               }  
  41.               public boolean showDuringKeyguard() {  
  42.                   return true;  
  43.               }  
  44.               public boolean showBeforeProvisioning() {  
  45.                   return true;  
  46.               }  
  47.           });  
  48. //end xiaoyuguang 20130616  
  49.       ...  
  50.       ...}  

在GlobalActionsDialog方法可以看 mItems.add这个方法是添加菜单选项的,该菜单的添加的第一个选项就是关机选项。可以仿照关机的Item添加一个重启的选项,如上面的代码所示;这样就解决了在长按的电源键弹出的对话框中添加一个重启选项了。当然这仅仅是添加一个显示而已,接下来就为这个选项添加逻辑控制代码了。

在上面的代码中使用的mWindowManagerFuncs.reboot方法和R.string.global_action_reboot资源(资源的添加放到最后说),默认是不存在的,所以需要在自己手动添加。

首先在找到WindowManagerFuncs这个所在的位置,在frameworks\base\core\java\android\view\WindowManagerPolicy.java中
[java] view plain copy
  1. /** 
  2.  * Interface for calling back in to the window manager that is private 
  3.  * between it and the policy. 
  4.  */  
  5. public interface WindowManagerFuncs {  
  6.     ...  
  7.     ...  
  8.     /** 
  9.      * Switch the keyboard layout for the given device. 
  10.      * Direction should be +1 or -1 to go to the next or previous keyboard layout. 
  11.      */  
  12.     public void switchKeyboardLayout(int deviceId, int direction);  
  13.     public void shutdown(boolean confirm);  
  14.     public void rebootSafeMode(boolean confirm)   
  15.     //xiaoyuguang  
  16.     public void reboot(boolean confirm);  
  17.   
  18. }  
添加reboot方法。 但这只是添加接口而已,它的具体实现在呢?找了许久在 frameworks\base\services\java\com\android\server\wm\windowManagerService.java中找到了这个接口的实现。
[java] view plain copy
  1. /** {@hide} */  
  2. public class WindowManagerService extends IWindowManager.Stub  
  3.         implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs,  
  4.                 DisplayManagerService.WindowManagerFuncs, DisplayManager.DisplayListener {  
  5.      ...  
  6.      ...  
  7.      // Called by window manager policy.  Not exposed externally.  
  8.     @Override  
  9.     public void shutdown(boolean confirm) {  
  10.         ShutdownThread.shutdown(mContext, confirm);  
  11.     }  
  12.     //xiaoyuguang 20130616 add reboot  
  13.     @Override  
  14.     public void reboot(boolean confirm){  
  15.         ShutdownThread.reboot(mContext, null, confirm);  
  16.     }  
  17.     //end xiaoyuguang  
  18.     // Called by window manager policy.  Not exposed externally.  
  19.     @Override  
  20.     public void rebootSafeMode(boolean confirm) {  
  21.         ShutdownThread.rebootSafeMode(mContext, confirm);  
  22.     }  
  23.     ...  
  24.     ...}  

同样在仿照关机的原理添加reboot的具体实现代码,既然在ShutdownThread这个类中提供了shutdown和rebootSafeMode的方法,那按理也应该有reboot的方法,或者类似reboot的方法。找到Shutdown.java文件,在frameworks\base\services\java\com\android\server\power\ShutdownThread.java中,
[java] view plain copy
  1. public final class ShutdownThread extends Thread {  
  2.     ...  
  3.     ...  
  4.         /** 
  5.      * Request a clean shutdown, waiting for subsystems to clean up their 
  6.      * state etc.  Must be called from a Looper thread in which its UI 
  7.      * is shown. 
  8.      * 
  9.      * @param context Context used to display the shutdown progress dialog. 
  10.      * @param confirm true if user confirmation is needed before shutting down. 
  11.      */  
  12.     public static void shutdown(final Context context, boolean confirm) {  
  13.     ...  
  14.     }  
  15.         /** 
  16.      * Request a clean shutdown, waiting for subsystems to clean up their 
  17.      * state etc.  Must be called from a Looper thread in which its UI 
  18.      * is shown. 
  19.      * 
  20.      * @param context Context used to display the shutdown progress dialog. 
  21.      * @param reason code to pass to the kernel (e.g. "recovery"), or null. 
  22.      * @param confirm true if user confirmation is needed before shutting down. 
  23.      */  
  24.     public static void reboot(final Context context, String reason, boolean confirm) {  
  25.         mReboot = true;  
  26.         mRebootSafeMode = false;  
  27.         mRebootReason = reason;  
  28.         Log.d(TAG, "reboot");  
  29.         shutdownInner(context, confirm);  
  30.     }  
  31.     ...  
  32.     ...  
  33. }  

其中提供了一个静态的reboot方法,所以在windowManagerService.java中的reboot实现中直接调用ShutdownThread中reboot即可。
 public static void reboot(final Context context, String reason, boolean confirm);有三个参数,后两个参数解释如下: reason  如果值为是null,正常重启;如果是recovery,系统重启进入recovery mode ;confirm为true显示关机提示框,需要用户【确认】;false不显示提示框,直接关机。

到此重启功能基本上可以使用了(除资源还没有添加之外),但是此时选择重启选项时,其提示还是不够关机的提示,所以还要修改选择“重启”时的对话框的提示。
在frameworks\base\services\java\com\android\server\power\ShutdownThread.java中
[java] view plain copy
  1. static void shutdownInner(final Context context, boolean confirm) {  
  2.     ...  
  3.     ...  
  4.         final int resourceId = mRebootSafeMode  
  5.             ? com.android.internal.R.string.reboot_safemode_confirm  
  6.             : (longPressBehavior == 2  
  7.                     ? com.android.internal.R.string.shutdown_confirm_question  
  8.                     : com.android.internal.R.string.shutdown_confirm);  
  9.     ...  
  10.     ...      
  11.         sConfirmDialog = new AlertDialog.Builder(context)  
  12.                     .setTitle(mRebootSafeMode  
  13.                             ? com.android.internal.R.string.reboot_safemode_title  
  14.                             : com.android.internal.R.string.power_off)  
  15.                     .setMessage(resourceId)  
  16.     ...  
  17.     ...  
  18. }  

修改如下:

[java] view plain copy
  1.      final int resourceId = mReboot  
  2. ? com.android.internal.R.string.reboot_confirm  
  3. : (mRebootSafeMode  
  4.     ? com.android.internal.R.string.reboot_safemode_confirm  
  5.     : (longPressBehavior == 2  
  6.             ? com.android.internal.R.string.shutdown_confirm_question  
  7.             : com.android.internal.R.string.shutdown_confirm));  
  8.          ...  
  9.          ...  
  10.              sConfirmDialog = new AlertDialog.Builder(context)  
  11.                  .setTitle(mReboot  
  12.                 ? com.android.internal.R.string.global_action_reboot  
  13.                 : (mRebootSafeMode  
  14.                     ? com.android.internal.R.string.reboot_safemode_title  
  15.                     : com.android.internal.R.string.power_off))  
  16.                  .setMessage(resourceId)  

至此关于代码部分的改动全部完成,接下就添加需要添加使用到的资源了,就是其中使用的字符串,为了简单起见就添加了英文和简体中文:
在对应的资源文件中添加:
frameworks\base\core\res\res\values\strings.xml
[html] view plain copy
  1. <!-- xiaoyuguang 20130616 -->  
  2. <!-- label for item that turns reboot in device options dialog -->  
  3.        <string name="global_action_reboot">Reboot</string>  
  4.        <string name="reboot_confirm"> Do you want to reboot your device?</string>  
  5. <!-- end xiaoyuguang 20130616 -->  
frameworks\base\core\res\res\values-zh-rCN\strings.xml
[html] view plain copy
  1. <!-- xiaoyuguang 20130616 -->  
  2. <string name="global_action_reboot">重启</string>  
  3. <string name="reboot_confirm">您要重新启动您的设备吗?</string>  
  4. <!-- end xiaoyuguang 20130616-->  

现在已经添加了好这些资源,但是现在还不能使用,此时编译会出现找不到该资源的错误,还需要在 frameworks\base\core\res\res\values\symbols.xml (在4.1中是在 frameworks\base\core\res\res\values\public.xml) 文件中进行资源声明:
[html] view plain copy
  1. <java-symbol type="string" name="global_action_reboot" />  
  2. <java-symbol type="string" name="reboot_confirm" />  

至此重启功能添加完毕,在编译前执行./mk -t update-api (因为新添加了接口)。
当然这仅仅是从框架层上进行修改,其底层的具体实现暂时还未探讨,有时间在去看看了。

你可能感兴趣的:(MTK android 4.2.2添加重启功能)