そこで今回、電源メニューに「CWMで再起動」を追加してみます。
再起動の理由を"recovery"にし、/cache/recoveryに「boot」という空ファイルを作って再起動すれば、再起動後CWMで立ち上がるという仕組みです。どのタイミングかは未検証ですが、その後/cache/recovery/bootは自動的に削除されるようです。
イチから手順を書こうと思いましたが面倒なので、電源メニューに「再起動」を追加するこの記事とこの記事、および外部リソースを追加するこの記事はすでにやっているものとし、追加修正部分だけを紹介します。
前提は以下です。
・rootとってあること
・作業PCはadbコマンドが使える環境であること
・作業PCにjavaが入っていること
・端末のビルド番号は9.0.G.0.247
・CWMを導入してあること
・母艦はWindows 7
・トラブっても自力で復旧できること(つまり自己責任)
いじるファイルは、以下になります。
/system/framework/external-res.apk
/system/framework/framework.odex
/system/framework/android.policy.odex
■external-res.apk
external-res.apkの作業フォルダ内、「res」フォルダ以下のxmlにリソース追加します。
まずres\values\public.xml。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<public type="drawable" name="ic_lock_reboot" id="0x7f020000" />
<public type="string" name="global_action_reboot" id="0x7f030000" />
<public type="string" name="global_action_recovery" id="0x7f030001" />
</resources>
<resources>
<public type="drawable" name="ic_lock_reboot" id="0x7f020000" />
<public type="string" name="global_action_reboot" id="0x7f030000" />
<public type="string" name="global_action_recovery" id="0x7f030001" />
</resources>
次にres\values\strings.xml。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="global_action_reboot">Reboot</string>
<string name="global_action_recovery">CWM Reboot</string>
</resources>
<resources>
<string name="global_action_reboot">Reboot</string>
<string name="global_action_recovery">CWM Reboot</string>
</resources>
続きましてres\values-ja\strings.xml。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="global_action_reboot">再起動</string>
<string name="global_action_recovery">CWMで再起動</string>
</resources>
<resources>
<string name="global_action_reboot">再起動</string>
<string name="global_action_recovery">CWMで再起動</string>
</resources>
CWMで再起動のアイコンは、通常再起動のアイコン(ic_lock_reboot.png)を使い回しすることにします。
別にしたい場合は、drawable-xhdpiに画像を追加した上でpublic.xmlにもdrawableを追加、リソースIDを振って、android.policy.odexの方でそのIDを指定するようにしてください。その際レジスタを増やしたりする必要があると思いますが、分からなくて怖い人は我慢しましょう。
新規でexternal-res.apkをこしらえる場合は、この記事のようにaaptで作成して署名とかしないといけませんが、すでに作っている場合はapktoolで展開、編集、再ビルドで署名のし直しは不要です。
■framework.odex
framework.odexをbaksmaliした展開先の中で、以下のファイルを探してテキストエディタで開きます。
com\android\internal\app\ShutdownThread.smali
「.method public static rebootOrShutdown(ZLjava/lang/String;)V」を検索。
その7行くらい下の「if-eqz p0, :cond_31」の下、「const-string v2, "ShutdownThread"」の直前に、処理を追加します。
.method public static rebootOrShutdown(ZLjava/lang/String;)V
.registers 7
.parameter "reboot"
.parameter "reason"
.prologue
.line 487
if-eqz p0, :cond_31
.line 488
new-instance v3, Ljava/lang/StringBuilder;
.registers 7
.parameter "reboot"
.parameter "reason"
.prologue
.line 487
if-eqz p0, :cond_31
.line 488
const-string v1, "recovery" #この行から追加
invoke-virtual {p1, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v1
if-eqz v1, :cond_01
:try_start_01
new-instance v1, Ljava/io/File;
const-string v2, "/cache/recovery/boot"
invoke-direct {v1, v2}, Ljava/io/File;-><init>(Ljava/lang/String;)V
invoke-virtual {v1}, Ljava/io/File;->exists()Z
move-result v2
if-nez v2, :cond_01
invoke-virtual {v1}, Ljava/io/File;->createNewFile()Z
:try_end_02
.catch Ljava/io/IOException; {:try_start_01 .. :try_end_02} :catch_01
:catch_01
:cond_01 #この行まで追加
const-string v2, "ShutdownThread"invoke-virtual {p1, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v1
if-eqz v1, :cond_01
:try_start_01
new-instance v1, Ljava/io/File;
const-string v2, "/cache/recovery/boot"
invoke-direct {v1, v2}, Ljava/io/File;-><init>(Ljava/lang/String;)V
invoke-virtual {v1}, Ljava/io/File;->exists()Z
move-result v2
if-nez v2, :cond_01
invoke-virtual {v1}, Ljava/io/File;->createNewFile()Z
:try_end_02
.catch Ljava/io/IOException; {:try_start_01 .. :try_end_02} :catch_01
:catch_01
:cond_01 #この行まで追加
new-instance v3, Ljava/lang/StringBuilder;
ここはまさに再起動する直前の部分になるのですが、再起動の理由が"recovery"だったときに/cache/recoveryに「boot」が存在すればスルー、無ければ作るという処理です。
以上、編集が済んだら上書き保存。
■android.policy.odex
android.policy.odexをbaksmaliした展開先の中で、以下のフォルダを探して開きます。
com\android\internal\policy\impl
電源メニューに「再起動」を追加した時に「GlobalActions$9.smali」を作ったと思いますが、さらにそれを複製して「GlobalActions$10.smali」にリネーム。テキストエディタで書き換えます。
ソース内に「GlobalActions$9」が3か所くらい存在していますが、それらをすべて「GlobalActions$10」 に書き換えます。
次に「.method public onPress()V」を検索(39行目あたり)
その11行くらい下(50行目あたり)の「const-string v1, "now"」を「const-string v1, "recovery"」に書き換えます。
move-result-object v0
const-string v1, "now"
const/4 v2, 0x1
invoke-static {v0, v1, v2}, Lcom/android/internal/app/ShutdownThread;->reboot(Landroid/content/Context;Ljava/lang/String;Z)V
↓↓↓const-string v1, "now"
const/4 v2, 0x1
invoke-static {v0, v1, v2}, Lcom/android/internal/app/ShutdownThread;->reboot(Landroid/content/Context;Ljava/lang/String;Z)V
move-result-object v0
const-string v1, "recovery" #変更
const/4 v2, 0x1
invoke-static {v0, v1, v2}, Lcom/android/internal/app/ShutdownThread;->reboot(Landroid/content/Context;Ljava/lang/String;Z)V
const-string v1, "recovery" #変更
const/4 v2, 0x1
invoke-static {v0, v1, v2}, Lcom/android/internal/app/ShutdownThread;->reboot(Landroid/content/Context;Ljava/lang/String;Z)V
以上、書き換えたら上書き保存。
続きまして「GlobalActions.smali」に処理の追加です。
「.method private createDialog()Landroid/app/AlertDialog;」を検索。(394行目あたり)
その58行くらい下(452行目~458行目あたり)に、以前追加した、
new-instance v1, Lcom/android/internal/policy/impl/GlobalActions$9;
const v2, 0x7f030000
invoke-direct {v1, p0, v13, v2}, Lcom/android/internal/policy/impl/GlobalActions$9;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V
invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z
const v2, 0x7f030000
invoke-direct {v1, p0, v13, v2}, Lcom/android/internal/policy/impl/GlobalActions$9;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V
invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z
という部分があります。
この下に同じような感じで数行記述を追加し、以下のようにします。
new-instance v1, Lcom/android/internal/policy/impl/GlobalActions$9;
const v2, 0x7f030000
invoke-direct {v1, p0, v13, v2}, Lcom/android/internal/policy/impl/GlobalActions$9;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V
invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z
new-instance v1, Lcom/android/internal/policy/impl/GlobalActions$10; #追加
const v2, 0x7f030001 #追加
invoke-direct {v1, p0, v13, v2}, Lcom/android/internal/policy/impl/GlobalActions$10;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V #追加
invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z #追加
.line 193
iget-object v0, p0, Lcom/android/internal/policy/impl/GlobalActions;->mItems:Ljava/util/ArrayList;
const v2, 0x7f030000
invoke-direct {v1, p0, v13, v2}, Lcom/android/internal/policy/impl/GlobalActions$9;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V
invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z
new-instance v1, Lcom/android/internal/policy/impl/GlobalActions$10; #追加
const v2, 0x7f030001 #追加
invoke-direct {v1, p0, v13, v2}, Lcom/android/internal/policy/impl/GlobalActions$10;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V #追加
invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z #追加
.line 193
iget-object v0, p0, Lcom/android/internal/policy/impl/GlobalActions;->mItems:Ljava/util/ArrayList;
これが電源メニューの「再起動」の下に「CWMで再起動」を追加する部分になります。
これも書き換えたら上書き保存。
■仕上げ
上記変更後、deodex_framework.jarとdeodex_android.policy.jarを生成し、external-res.apkも含めCWMモードで端末に送信、dexopt-wrapper等の作業を行いつつ、/system/frameworkのexternal-res.apkとframework.odexとandroid.policy.odexを置き換えてください。
reboot後、電源メニューに「CWMで再起動」が追加され、実行したら再起動後CWMが立ち上がることを確認してください。
0 件のコメント:
コメントを投稿