2回目の記事まででとりあえず動くようにはしましたが、アプリキル部分のコードを見直してみました。
より素直な挙動になるのではないかと思います。
なお今回の記事は、前々回、前回のカスタムをすでにやっていることが前提となります。
前提は以下です。
・rootとってあること
・作業PCはadbコマンドが使える環境であること
・作業PCにjavaが入っていること
・端末のビルド番号は9.0.G.1.76
・CWMを導入してあること
・母艦はWindows 7
・トラブっても自力で復旧できること(つまり自己責任)
いじるファイルは、以下になります。
/system/framework/android.policy.odex
■android.policy.odex
android.policy.odexをbaksmaliした展開先の中で、以下のフォルダを探して開きます。
com\android\internal\policy\impl
前回作成した「PhoneWindowManager$KillConcept.smali」ファイルの内容を書き換えます。
内容は以下になります。
.class Lcom/android/internal/policy/impl/PhoneWindowManager$KillConcept;
.super Ljava/lang/Object;
.source "PhoneWindowManager.java"
# interfaces
.implements Ljava/lang/Runnable;
# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
value = Lcom/android/internal/policy/impl/PhoneWindowManager;
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x0
name = null
.end annotation
# instance fields
.field final synthetic this$0:Lcom/android/internal/policy/impl/PhoneWindowManager;
# direct methods
.method constructor <init>(Lcom/android/internal/policy/impl/PhoneWindowManager;)V
.registers 2
.parameter
.prologue
.line 4204
iput-object p1, p0, Lcom/android/internal/policy/impl/PhoneWindowManager$KillConcept;->this$0:Lcom/android/internal/policy/impl/PhoneWindowManager;
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
# virtual methods
.method public run()V
.registers 10
.prologue
iget-object v0, p0, Lcom/android/internal/policy/impl/PhoneWindowManager$KillConcept;->this$0:Lcom/android/internal/policy/impl/PhoneWindowManager;
const/4 v1, 0x0
const/4 v2, 0x0
const/4 v3, 0x0
invoke-virtual {v0, v1, v2, v3}, Lcom/android/internal/policy/impl/PhoneWindowManager;->performHapticFeedbackLw(Landroid/view/WindowManagerPolicy$WindowState;IZ)Z
iget-object v1, v0, Lcom/android/internal/policy/impl/PhoneWindowManager;->mContext:Landroid/content/Context;
new-instance v2, Landroid/content/Intent;
const-string v3, "android.intent.action.MAIN"
invoke-direct {v2, v3}, Landroid/content/Intent;-><init>(Ljava/lang/String;)V
const-string v3, "android.intent.category.HOME"
invoke-virtual {v2, v3}, Landroid/content/Intent;->addCategory(Ljava/lang/String;)Landroid/content/Intent;
invoke-virtual {v1}, Landroid/content/Context;->getPackageManager()Landroid/content/pm/PackageManager;
move-result-object v3
const/4 v4, 0x0
invoke-virtual {v3, v2, v4}, Landroid/content/pm/PackageManager;->resolveActivity(Landroid/content/Intent;I)Landroid/content/pm/ResolveInfo;
move-result-object v2
iget-object v2, v2, Landroid/content/pm/ResolveInfo;->activityInfo:Landroid/content/pm/ActivityInfo;
if-eqz v2, :cond_1
iget-object v2, v2, Landroid/content/pm/ActivityInfo;->packageName:Ljava/lang/String;
const-string v3, "android"
invoke-virtual {v3, v2}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v3
if-nez v3, :cond_1
goto :cond_2
:cond_1
const-string v2, "com.android.launcher"
:cond_2
const-string v3, "activity"
invoke-virtual {v1, v3}, Landroid/content/Context;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
move-result-object v3
check-cast v3, Landroid/app/ActivityManager;
const/4 v4, 0x1
invoke-virtual {v3, v4}, Landroid/app/ActivityManager;->getRunningTasks(I)Ljava/util/List;
move-result-object v4
invoke-interface {v4}, Ljava/util/List;->iterator()Ljava/util/Iterator;
move-result-object v4
invoke-interface {v4}, Ljava/util/Iterator;->hasNext()Z
move-result v5
if-eqz v5, :cond_10
invoke-interface {v4}, Ljava/util/Iterator;->next()Ljava/lang/Object;
move-result-object v4
check-cast v4, Landroid/app/ActivityManager$RunningTaskInfo;
iget-object v5, v4, Landroid/app/ActivityManager$RunningTaskInfo;->topActivity:Landroid/content/ComponentName;
invoke-virtual {v5}, Landroid/content/ComponentName;->getPackageName()Ljava/lang/String;
move-result-object v5
invoke-virtual {v2, v5}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v6
if-nez v6, :cond_10
invoke-static {}, Landroid/app/ActivityManagerNative;->getDefault()Landroid/app/IActivityManager;
move-result-object v6
invoke-interface {v6}, Landroid/app/IActivityManager;->getRunningAppProcesses()Ljava/util/List;
move-result-object v6
invoke-interface {v6}, Ljava/util/List;->iterator()Ljava/util/Iterator;
move-result-object v6
:cond_3
invoke-interface {v6}, Ljava/util/Iterator;->hasNext()Z
move-result v7
if-eqz v7, :cond_10
invoke-interface {v6}, Ljava/util/Iterator;->next()Ljava/lang/Object;
move-result-object v7
check-cast v7, Landroid/app/ActivityManager$RunningAppProcessInfo;
iget-object v8, v7, Landroid/app/ActivityManager$RunningAppProcessInfo;->processName:Ljava/lang/String;
invoke-virtual {v5, v8}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v8
if-eqz v8, :cond_3
iget v5, v4, Landroid/app/ActivityManager$RunningTaskInfo;->id:I
const/4 v2, 0x1
invoke-virtual {v3, v5, v2}, Landroid/app/ActivityManager;->removeTask(II)Z
const/4 v6, 0x1
const-string v2, "com.android.externalres"
const/4 v3, 0x4
invoke-virtual {v1, v2, v3}, Landroid/content/Context;->createPackageContext(Ljava/lang/String;I)Landroid/content/Context;
move-result-object v2
invoke-virtual {v2}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;
move-result-object v2
const v3, 0x7f030002
invoke-virtual {v2, v3}, Landroid/content/res/Resources;->getText(I)Ljava/lang/CharSequence;
move-result-object v2
const/4 v3, 0x0
invoke-static {v1, v2, v3}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v2
invoke-virtual {v2}, Landroid/widget/Toast;->show()V
:cond_10
return-void
.end method
.super Ljava/lang/Object;
.source "PhoneWindowManager.java"
# interfaces
.implements Ljava/lang/Runnable;
# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
value = Lcom/android/internal/policy/impl/PhoneWindowManager;
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x0
name = null
.end annotation
# instance fields
.field final synthetic this$0:Lcom/android/internal/policy/impl/PhoneWindowManager;
# direct methods
.method constructor <init>(Lcom/android/internal/policy/impl/PhoneWindowManager;)V
.registers 2
.parameter
.prologue
.line 4204
iput-object p1, p0, Lcom/android/internal/policy/impl/PhoneWindowManager$KillConcept;->this$0:Lcom/android/internal/policy/impl/PhoneWindowManager;
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
# virtual methods
.method public run()V
.registers 10
.prologue
iget-object v0, p0, Lcom/android/internal/policy/impl/PhoneWindowManager$KillConcept;->this$0:Lcom/android/internal/policy/impl/PhoneWindowManager;
const/4 v1, 0x0
const/4 v2, 0x0
const/4 v3, 0x0
invoke-virtual {v0, v1, v2, v3}, Lcom/android/internal/policy/impl/PhoneWindowManager;->performHapticFeedbackLw(Landroid/view/WindowManagerPolicy$WindowState;IZ)Z
iget-object v1, v0, Lcom/android/internal/policy/impl/PhoneWindowManager;->mContext:Landroid/content/Context;
new-instance v2, Landroid/content/Intent;
const-string v3, "android.intent.action.MAIN"
invoke-direct {v2, v3}, Landroid/content/Intent;-><init>(Ljava/lang/String;)V
const-string v3, "android.intent.category.HOME"
invoke-virtual {v2, v3}, Landroid/content/Intent;->addCategory(Ljava/lang/String;)Landroid/content/Intent;
invoke-virtual {v1}, Landroid/content/Context;->getPackageManager()Landroid/content/pm/PackageManager;
move-result-object v3
const/4 v4, 0x0
invoke-virtual {v3, v2, v4}, Landroid/content/pm/PackageManager;->resolveActivity(Landroid/content/Intent;I)Landroid/content/pm/ResolveInfo;
move-result-object v2
iget-object v2, v2, Landroid/content/pm/ResolveInfo;->activityInfo:Landroid/content/pm/ActivityInfo;
if-eqz v2, :cond_1
iget-object v2, v2, Landroid/content/pm/ActivityInfo;->packageName:Ljava/lang/String;
const-string v3, "android"
invoke-virtual {v3, v2}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v3
if-nez v3, :cond_1
goto :cond_2
:cond_1
const-string v2, "com.android.launcher"
:cond_2
const-string v3, "activity"
invoke-virtual {v1, v3}, Landroid/content/Context;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
move-result-object v3
check-cast v3, Landroid/app/ActivityManager;
const/4 v4, 0x1
invoke-virtual {v3, v4}, Landroid/app/ActivityManager;->getRunningTasks(I)Ljava/util/List;
move-result-object v4
invoke-interface {v4}, Ljava/util/List;->iterator()Ljava/util/Iterator;
move-result-object v4
invoke-interface {v4}, Ljava/util/Iterator;->hasNext()Z
move-result v5
if-eqz v5, :cond_10
invoke-interface {v4}, Ljava/util/Iterator;->next()Ljava/lang/Object;
move-result-object v4
check-cast v4, Landroid/app/ActivityManager$RunningTaskInfo;
iget-object v5, v4, Landroid/app/ActivityManager$RunningTaskInfo;->topActivity:Landroid/content/ComponentName;
invoke-virtual {v5}, Landroid/content/ComponentName;->getPackageName()Ljava/lang/String;
move-result-object v5
invoke-virtual {v2, v5}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v6
if-nez v6, :cond_10
invoke-static {}, Landroid/app/ActivityManagerNative;->getDefault()Landroid/app/IActivityManager;
move-result-object v6
invoke-interface {v6}, Landroid/app/IActivityManager;->getRunningAppProcesses()Ljava/util/List;
move-result-object v6
invoke-interface {v6}, Ljava/util/List;->iterator()Ljava/util/Iterator;
move-result-object v6
:cond_3
invoke-interface {v6}, Ljava/util/Iterator;->hasNext()Z
move-result v7
if-eqz v7, :cond_10
invoke-interface {v6}, Ljava/util/Iterator;->next()Ljava/lang/Object;
move-result-object v7
check-cast v7, Landroid/app/ActivityManager$RunningAppProcessInfo;
iget-object v8, v7, Landroid/app/ActivityManager$RunningAppProcessInfo;->processName:Ljava/lang/String;
invoke-virtual {v5, v8}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v8
if-eqz v8, :cond_3
iget v5, v4, Landroid/app/ActivityManager$RunningTaskInfo;->id:I
const/4 v2, 0x1
invoke-virtual {v3, v5, v2}, Landroid/app/ActivityManager;->removeTask(II)Z
const/4 v6, 0x1
const-string v2, "com.android.externalres"
const/4 v3, 0x4
invoke-virtual {v1, v2, v3}, Landroid/content/Context;->createPackageContext(Ljava/lang/String;I)Landroid/content/Context;
move-result-object v2
invoke-virtual {v2}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;
move-result-object v2
const v3, 0x7f030002
invoke-virtual {v2, v3}, Landroid/content/res/Resources;->getText(I)Ljava/lang/CharSequence;
move-result-object v2
const/4 v3, 0x0
invoke-static {v1, v2, v3}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v2
invoke-virtual {v2}, Landroid/widget/Toast;->show()V
:cond_10
return-void
.end method
アプリ終了を実行する部分です。
「removeTask」というメソッドを呼び出し、フォアグラウンドアプリをキルするようにしています。
途中の「const v5, 0x7f030002」という部分はもちろん、external-res.apkに追加した文字列のIDに合わせてください。
■仕上げ
上記変更後、deodex_android.policy.jarを生成し、CWMモードで端末に送信、dexopt-wrapper等の作業を行いつつ、/system/frameworkのandroid.policy.odexを置き換えてください。
はじめまして、Xperia ULのMODファイルを作成しています。
返信削除キューブキューブさんを含めいろいろな方の情報を参考にしてコード移植しているだけですが、電源メニューの再起動追加もできました。(テスト漏れで電源長押し時のアラートダイアログ表示がミスってるのは内緒です)
アセンブラのコードで move-result-objectというのがあるのですが、どう解釈していいのか悩んでます。
教えていただけないでしょうか?
あと、戻るキー長押しでアプリキルのコード移植をしたのですが、「開発者オプションの表示は確認済み」で「戻るキーを押してもタスクキルされてない」という状況です。ZModのソースを参考にさせていただき、PhoneWindowManager.smaliを少し修正すれば使えるとにらんだのですが、甘かったようです。
何か見るポイントありますでしょうか?
自己解決しました。PhoneWindowManager.smaliのコード移植でレジスタの操作をミスしていました。PhoneWindowManager$KillConcept.smaliはそのまま使用させていただいており、実装完了しました。
削除本当に有益な情報を載せていただきありがとうございます。
これからも待ってます。
おめでとうございます。
削除ちなみに、もうお調べになられたのであれば恐縮ですが、move-result-objectは、その直前のinvoke(関数呼び出し)の戻り値をレジスタに入れる命令です。
「-object」が付いてるのは、レジスタに入るのが数値とかのプリミティブ型ではなくて、オブジェクトであるということを表しています。
smaliに関する記事はいつかまとめたいとは思ってるのですが、分量が多くて、いつになるやら…。
貴重な情報をありがとうございました。やっぱり戻り値を入れる命令だったんですね。
削除アセンブラのコードを見てて、そんな気はしてたんですが、命令セットの意味に確信が持てなくて、いれていいのか悪いのか悩んでたので、すごく助かります。
まとめるのは確かに大変ですよね。コード見て理解できなければ手を出せないのも事実ですし…。
カメラ関係に手を出したいのですが、Zのオリジナルソースを所持していないので、変更点が分からず、移植するのに手をこまねいてます。
スクリーンショット消音でしたら、Zの場合
削除SystemUI.odex
com\android\systemui\screenshot\GlobalScreenshot$3.smali
61行目あたりの
invoke-virtual {v0, v1}, Landroid/media/MediaActionSound;->play(I)V
を削除かコメントアウトでいけますね。
カメラ音オプションの有効化は、これもZの場合ですが、
SemcCameraUI.apk\smali\com\sonyericsson\android\camera\configuration\SystemPropertiesReader.smali
.method private constructor ()V メソッド内、
73行目を、「const/4 v1, 0x1」→「const/4 v1, 0x0」
また、
SemcCamera3D.apk\smali\com\sonyericsson\android\camera3d\CameraConfigManager.smali
.method private setForceSound(Ljava/lang/String;)V メソッド内、
6261行目を「const/4 v1, 0x1」→「const/4 v1, 0x0」
これでいけたそうです。
(自分では試してないですが、Z持ちの方がいけたと言ってました。)
カメラ音オプションの有効化はULでもそれでOKです。
削除スクリーンショットはこんなとこにあったんですね。ファイルを削除して対応するのが簡単だったんですが、貴重な情報ですm_ _m
UL_MODですが、下記まで実装して公開してます。
加えて、ローカルではボリュームキーでスタンバイ復帰も実装しました。
ただキューブキューブさん達のを移植させていただいてるだけですが、本当に恐縮です。
(1) シャッター音設定
(2) ナビバー5キー(サーチとメニュー追加)
(3) バッテリアイコン非表示
(4) 全アプリ終了ボタン位置変更
(5) ステータスバーのアイコンを見やすくした
(6) ドック使用時の自動回転無効化
(7) 充電完了時にLEDを消灯
(8) Wi-Fiアイコンとアンテナ表示統合
(9) 画面の最低輝度の変更(20->5)
(10)ナビゲーションバー高さの変更(48->40)
(11)ステータスバーに日付/時刻2段階表示追加
(12)通知領域開いた時の右の日付表示消去
(13)キャッシュスクロール無効
(14)電源長押しで再起動項目追加(再起動しますか?のダイアログも実装)
<0.5.1~0.5.4は実験中の施策Verで0.5.5で完了>
(15)戻るキー長押しタスクキル
※設定→開発者向けオプション→長押しでアプリ終了にチェックを入れてください
(16)ボリューム調整値変更
受話音量、着信、音楽、アラーム、メディア、BlueTooth
いやいや、素晴らしい。どんどん移植してください。
削除Xperiaに繁栄あらんことを。
こんにちわ。
返信削除先日までXperiaを使っていたのですが、嫁に渡したため、
現在、HTC ONEを使っています。
そこで、この便利なMODを一部でも移植をしたいと考えているのですが、
Xperia以外への移植というのは可能なのでしょうか?
(ひとまず、アプリKillは欲しい)
正直、コードは全く読めないのでどの部分のコードを書くかなどは勘で行こうかと思います。
可能なのでしょうか?お手数ですが、教えて下さい。
同じAndroidですので、コードはそう変わらないと思いますし、カスタム方法は同じなはずです。可能かどうかで言えば、可能です。
削除ただし、レジスタ番号等が機種によって変わっていたりすることも多々ありますので、若干プログラミングの心得が無いと厳しいかもしれません。
そうですか。。。ちょっと厳しそうですね。
削除Xposedで作るという考えもあるかと思うのですが、
このMODをXposedに移植する計画などは無いでしょうか?
頑張ってXposedを覚えたほうが早い気がしてきました。
Xposedは諸々の理由で個人的には敬遠しております。
削除変更に再起動が必要なのが大きいですね。
まあ食わず嫌いでもあるのですが。