SHARPのエコ技を実装してみた

  • 7,423 views
Uploaded on

2013/05/06 PF部 勉強会

2013/05/06 PF部 勉強会

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
7,423
On Slideshare
0
From Embeds
0
Number of Embeds
6

Actions

Shares
Downloads
0
Comments
0
Likes
17

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. SHARPのエコ技を実装してみた@androidsola
  • 2. 自己紹介●twitter ID は @androidsola●最近はカスタム ROM の開発してます。JCROM(Japanese custom rom)https://sites.google.com/site/jcromproject/
  • 3. JCROM(Japanese custom rom)●最近の状況– JCROM 用のキャラクターを作ったテーマの配信を Google Play を使用して行う予定– NFC を使用したテーマ変更と解除(最近事故ってる残念な人もいるので...)
  • 4. 今回の話●エコ技とは●エコ技を取り上げた理由●実装するエコ技の仕様●エコ技の実装●実装したエコ技の動作確認●次にやること
  • 5. エコ技とは●SHARPが開発した独自の省エネ機能AQUOS PHONE 102SHの説明
  • 6. エコ技を取り上げた理由●Android プラットフォームを改造するネタをあまりみかけない?このあたりを改造するネタを増やしたい(JCROM 以外で)
  • 7. エコ技を取り上げた理由●エコ技は Android Framework を改造している。(公開されている仕様を確認する限りでは)●Google 先生に聞いても、実装したようなネタのブログ等が見当たらない。●102SH のサイトの説明通りだと、素晴らしい省エネ効果があるので、JCROM(Japanese custom rom)で使えると良いかも?
  • 8. 実装するエコ技の仕様●SH Developers Square で公開されています。https://sh-dev.sharp.co.jp/android/
  • 9. エコ技は2種類ある●2011年冬-2012年春と2012年夏-2012年秋モデルで仕様が異なる。
  • 10. 2011年冬-2012年春モデルの仕様●Broadcast Intent の動作を抑制する。動作条件は以下の二つ– エコ技設定で、省エネ待受機能をONにしていること– 画面が消灯していることACTION_SCREEN_OFF が通知されてからACTION_SCREEN_ON が通知されるまでの期間を指す
  • 11. 2011年冬-2012年春モデルの仕様●抑止対象のアプリケーション以下二つの条件のどちらかに一致するものは対象から除外される。– フォアグラウンドで動作中のアプリケーション– 省エネ待受対象外リストに登録されているアプリケーション
  • 12. 2011年冬-2012年春モデルの仕様●抑止対象の Broadcast IntentAndroidManifest.xml に定義するものが対象で、プログラム上で registerReceiver を使用して登録するものは対象外となる。AndroidManifest.xml に定義する例<receiver android:name="net.jcrom.ecotest.myReciever" ><intent-filter><action android:name="android.intent.action.KASSY_ZANNEN" /></intent-filter></receiver>
  • 13. 2012年夏-2012年秋モデルの仕様●Broadcast Intent の通知制限、データ通信制限、自動同期処理の遅延を行う。動作条件は以下の二つ– エコ技設定で、省エネ待受機能をONにしていること– 画面が消灯していることACTION_SCREEN_OFF が通知されてからACTION_SCREEN_ON が通知されるまでの期間を指す
  • 14. 2012年夏-2012年秋モデルの仕様●抑止対象のアプリケーション以下二つの条件のどちらかに一致するものは対象から除外される。– フォアグラウンドで動作中のアプリケーション– 省エネ待受対象外リストに登録されているアプリケーション
  • 15. 2012年夏-2012年秋モデルの仕様●抑止対象の Broadcast IntentAndroidManifest.xml に定義するもの、プログラム上で registerReceiver を使用して登録するもの全てを対象にする。ただし、以下の Broadcast Intent は抑止対象外– android.intent.action.BOOT_COMPLETED– android.intent.action.SCREEN_OFF– android.intent.action.SCREEN_ON– com.google.android.c2dm.intent.RECEIVE
  • 16. 2012年夏-2012年秋モデルの仕様●データ通信制限各アプリのデータ通信を制限する機能。●自動同期処理の遅延自動同期処理を次回画面点灯時まで遅延させる機能。
  • 17. 2011年冬-2012年春モデル 2012年夏-2012年秋モデル動作を抑止する条件 ●省エネ待受機能をONにしていること●画面が消灯していること●バックグラウンドで動作中であること●省エネ待受対象外リストに登録されていないこと●左と同じBroadcast Intent の制限 ●AndroidManifest.xml に定義するものが対象で、プログラム上でregisterReceiver を使用して登録するものは対象外。●以下の Broadcast Intent 以外は全て対象となる。android.intent.action.BOOT_COMPLETEDandroid.intent.action.SCREEN_OFFandroid.intent.action.SCREEN_ONcom.google.android.c2dm.intent.RECEIVEデータ通信の制限 ●未対応 ●各アプリのデータ通信を制限する機能自動同期処理の遅延 ●未対応 ●自動同期処理を、次回画面点灯時まで遅延させる機能エコ技の仕様を整理
  • 18. 2011年冬-2012年春モデル 2012年夏-2012年秋モデル動作を抑止する条件 ●省エネ待受機能をONにしていること●画面が消灯していること●バックグラウンドで動作中であること●省エネ待受対象外リストに登録されていないこと※今回はとりあえず全てを対象に●左と同じBroadcast Intent の制限 ●AndroidManifest.xml に定義するものが対象で、プログラム上でregisterReceiver を使用して登録するものは対象外。●以下の Broadcast Intent 以外は全て対象となる。android.intent.action.BOOT_COMPLETEDandroid.intent.action.SCREEN_OFFandroid.intent.action.SCREEN_ONcom.google.android.c2dm.intent.RECEIVEデータ通信の制限 ●未対応 ●各アプリのデータ通信を制限する機能自動同期処理の遅延 ●未対応 ●自動同期処理を、次回画面点灯時まで遅延させる機能今回実装するエコ技の仕様
  • 19. エコ技の実装
  • 20. その前に気になる仕様の調査
  • 21. Broadcast Intent の動作(予想)●Broadcast Receiver の登録方法による動作の違い– AndroidManifest.xml に定義するもの– プログラム上で registerReceiver を使用して登録するもの初期のエコ技では片方(AndroidManifest.xml)しか対応していなかったので、おそらく動きが違うはず。●Broadcast Intent を投げてる奴が AndroidFramework のどこかにいる。(この手のものは ActivityManagerService あたりかと大雑把に予想した。)
  • 22. Broadcast Intent ってどこから来る?
  • 23. Broadcast Intent の動作を調べる●デバッグ機能を有効にした状態で Broadcast Intentを投げてログを確認する。ActivityManagerService.java に定義されているDEBUG_BROADCAST がフラグ。ActivityManagerService.java に定義されている値変更前static final boolean DEBUG_BROADCAST = localLOGV || false;static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;変更後static final boolean DEBUG_BROADCAST = localLOGV || true;static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
  • 24. 便利そうなデバッグ機能●ActivityManagerService.java には DEBUG_BROADCAST以外にもたくさん定義が存在する。static final boolean DEBUG_SWITCH = localLOGV || false;static final boolean DEBUG_TASKS = localLOGV || false;static final boolean DEBUG_THUMBNAILS = localLOGV || false;static final boolean DEBUG_PAUSE = localLOGV || false;static final boolean DEBUG_OOM_ADJ = localLOGV || false;static final boolean DEBUG_TRANSITION = localLOGV || false;static final boolean DEBUG_BROADCAST = localLOGV || true;static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;static final boolean DEBUG_SERVICE = localLOGV || false;static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;static final boolean DEBUG_VISBILITY = localLOGV || false;
  • 25. 便利そうなデバッグ機能●ActivityManagerService.java には DEBUG_BROADCAST以外にもたくさん定義が存在する。static final boolean DEBUG_PROCESSES = localLOGV || false;static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;static final boolean DEBUG_CLEANUP = localLOGV || false;static final boolean DEBUG_PROVIDER = localLOGV || false;static final boolean DEBUG_URI_PERMISSION = localLOGV || false;static final boolean DEBUG_USER_LEAVING = localLOGV || false;static final boolean DEBUG_RESULTS = localLOGV || false;static final boolean DEBUG_BACKUP = localLOGV || false;static final boolean DEBUG_CONFIGURATION = localLOGV || false;static final boolean DEBUG_POWER = localLOGV || false;static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;static final boolean DEBUG_MU = localLOGV || false;
  • 26. Broadcast Intent の動作を調べる●動作確認用の Broadcast receiver を用意する。AndroidManifest.xml に定義するもので、受信するとログを出力するだけのもの。Receiverpublic class myReciever extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Log.d("ECO_WAZA_MANIFEST", "Received KASSY_ZANNEN");}}AndroidManifest.xml<receiver android:name="net.jcrom.eco.manifest.myReciever" ><intent-filter><action android:name="android.intent.action.KASSY_ZANNEN" /></intent-filter></receiver>
  • 27. Broadcast Intent の動作を調べる●動作確認用の Broadcast receiver を用意する。プログラム上で registerReceiver を使用して登録するもので、受信するとログを出力するだけのもの。Receiverprivate BroadcastReceiver mReceiver;private void registerReceiver(){mReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {Log.d("ECO_WAZA_PROGRAM", "Received KASSY_HENTAI");}};IntentFilter filter = newIntentFilter("android.intent.action.KASSY_HENTAI");registerReceiver(mReceiver, filter);}
  • 28. Broadcast Intent の動作を調べる●動作確認用の Broadcast Intent をコマンドラインから投げる。$ adb shellroot@android:/ # logcat &AndroidManifest.xml に定義するものの動作を確認するroot@android:/ # am broadcast -a android.intent.action.KASSY_ZANNENプログラム上で registerReceiver を使用して登録するものの動作を確認するroot@android:/ # am broadcast -a android.intent.action.KASSY_HENTAI
  • 29. Receiver を AndroidManifest.xml に定義するケースのものを調べる
  • 30. Broadcast Intent の動作を調べる●DEBUG_BROADCAST が有効になったログを確認する。root@android:/ # am broadcast -a android.intent.action.KASSY_ZANNENActivityManager からのログV/ActivityManager( 287): Broadcast: Intent { act=android.intent.action.KASSY_ZANNENflg=0x10 } ordered=true userid=-1V/ActivityManager( 287): Enqueing broadcast: android.intent.action.KASSY_ZANNENreplacePending=falseI/ActivityManager( 287): Broadcast intent Intent{ act=android.intent.action.KASSY_ZANNEN flg=0x10 } on background queueV/ActivityManager( 287): Enqueueing ordered broadcast BroadcastRecord{410f5648 u-1android.intent.action.KASSY_ZANNEN}: prev had 0I/ActivityManager( 287): Enqueueing broadcast android.intent.action.KASSY_ZANNENseq=-1・・・次のスライドに続く
  • 31. Broadcast Intent の動作を調べる●DEBUG_BROADCAST が有効になったログを確認する。BroadcastQueue からのログV/BroadcastQueue( 287): Schedule broadcasts [background]: current=falseV/BroadcastQueue( 287): Received BROADCAST_INTENT_MSGV/BroadcastQueue( 287): processNextBroadcast [background]: 0 broadcasts, 1 orderedbroadcastsV/BroadcastQueue( 287): Processing ordered broadcast [background]BroadcastRecord{410f5648 u-1 android.intent.action.KASSY_ZANNEN}V/BroadcastQueue( 287): Submitting BROADCAST_TIMEOUT_MSG [background] forBroadcastRecord{410f5648 u-1 android.intent.action.KASSY_ZANNEN} at 254845V/BroadcastQueue( 287): Process cur broadcast BroadcastRecord{410f5648 u-1android.intent.action.KASSY_ZANNEN} for app ProcessRecord{4111d258788:net.jcrom.eco.manifest/u0a10045}V/BroadcastQueue( 287): Delivering to componentComponentInfo{net.jcrom.eco.manifest/net.jcrom.eco.manifest.myReciever}:BroadcastRecord{410f5648 u-1 android.intent.action.KASSY_ZANNEN}D/ECO_WAZA_MANIFEST( 788): Received KASSY_ZANNEN
  • 32. Broadcast Intent の動作を調べる●DEBUG_BROADCAST が有効になったログを確認する。BroadcastQueue からのログV/BroadcastQueue( 287): Schedule broadcasts [background]: current=falseV/BroadcastQueue( 287): Received BROADCAST_INTENT_MSGV/BroadcastQueue( 287): processNextBroadcast [background]: 0 broadcasts, 1 orderedbroadcastsV/BroadcastQueue( 287): Processing ordered broadcast [background]BroadcastRecord{410f5648 u-1 android.intent.action.KASSY_ZANNEN}V/BroadcastQueue( 287): Submitting BROADCAST_TIMEOUT_MSG [background] forBroadcastRecord{410f5648 u-1 android.intent.action.KASSY_ZANNEN} at 254845V/BroadcastQueue( 287): Process cur broadcast BroadcastRecord{410f5648 u-1android.intent.action.KASSY_ZANNEN} for app ProcessRecord{4111d258788:net.jcrom.eco.manifest/u0a10045}V/BroadcastQueue( 287): Delivering to componentComponentInfo{net.jcrom.eco.manifest/net.jcrom.eco.manifest.myReciever}:BroadcastRecord{410f5648 u-1 android.intent.action.KASSY_ZANNEN}D/ECO_WAZA_MANIFEST( 788): Received KASSY_ZANNEN
  • 33. Broadcast Intent の動作を調べる●BroadcastQueue.java で Delivering to componentを出力している場所を探す。210行目private final void processCurBroadcastLocked(BroadcastRecord r,ProcessRecord app) throws RemoteException {〜中略〜// Tell the application to launch this receiver.r.intent.setComponent(r.curComponent);boolean started = false;try {if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,"Delivering to component " + r.curComponent+ ": " + r);
  • 34. Broadcast Intent の動作を調べる●BroadcastQueue.java で processCurBroadcastLockedを呼び出している場所を探す。– 254行目 sendPendingBroadcastsLocked の中– 778行目 processNextBroadcast の中
  • 35. Broadcast Intent の動作を調べる●BroadcastQueue.java で processCurBroadcastLockedを呼び出している場所を探す。– 254行目 sendPendingBroadcastsLocked の中– 778行目 processNextBroadcast の中ログを出してみると、processNextBroadcast から呼ばれていた。AndroidManifest.xml に定義するものは、BoradcastQueue.java の processNextBroadcast から呼ばれてる事が分かった。
  • 36. プログラム上で registerReceiver を使用してReceiver を登録するものを調べる
  • 37. Broadcast Intent の動作を調べる●DEBUG_BROADCAST が有効になったログを確認する。root@android:/ # am broadcast -a android.intent.action.KASSY_HENTAIActivityManager からのログV/ActivityManager( 287): Broadcast: Intent { act=android.intent.action.KASSY_HENTAIflg=0x10 } ordered=true userid=-1V/ActivityManager( 287): Enqueing broadcast: android.intent.action.KASSY_HENTAIreplacePending=falseI/ActivityManager( 287): Broadcast intent Intent{ act=android.intent.action.KASSY_HENTAI flg=0x10 } on background queueV/ActivityManager( 287): Enqueueing ordered broadcast BroadcastRecord{41154910 u-1android.intent.action.KASSY_HENTAI}: prev had 0I/ActivityManager( 287): Enqueueing broadcast android.intent.action.KASSY_HENTAIseq=-1・・・次のスライドに続く
  • 38. Broadcast Intent の動作を調べる●DEBUG_BROADCAST が有効になったログを確認する。BroadcastQueue からのログV/BroadcastQueue( 287): Schedule broadcasts [background]: current=falseV/BroadcastQueue( 287): Received BROADCAST_INTENT_MSGV/BroadcastQueue( 287): processNextBroadcast [background]: 0 broadcasts, 1 orderedbroadcastsV/BroadcastQueue( 287): Processing ordered broadcast [background]BroadcastRecord{41154910 u-1 android.intent.action.KASSY_HENTAI}V/BroadcastQueue( 287): Submitting BROADCAST_TIMEOUT_MSG [background] forBroadcastRecord{41154910 u-1 android.intent.action.KASSY_HENTAI} at 34768193V/BroadcastQueue( 287): Delivering ordered [background] to registeredBroadcastFilter{4102e4a8 u0 ReceiverList{4102e400 807 net.jcrom.eco.program/10046/u0remote:4102def0}}: BroadcastRecord{41154910 u-1 android.intent.action.KASSY_HENTAI}I/BroadcastQueue( 287): Delivering to BroadcastFilter{4102e4a8 u0ReceiverList{4102e400 807 net.jcrom.eco.program/10046/u0 remote:4102def0}} (seq=-1):BroadcastRecord{41154910 u-1 android.intent.action.KASSY_HENTAI}D/ECO_WAZA_PROGRAM( 807): Received KASSY_HENTAI
  • 39. Broadcast Intent の動作を調べる●DEBUG_BROADCAST が有効になったログを確認する。BroadcastQueue からのログV/BroadcastQueue( 287): Schedule broadcasts [background]: current=falseV/BroadcastQueue( 287): Received BROADCAST_INTENT_MSGV/BroadcastQueue( 287): processNextBroadcast [background]: 0 broadcasts, 1 orderedbroadcastsV/BroadcastQueue( 287): Processing ordered broadcast [background]BroadcastRecord{41154910 u-1 android.intent.action.KASSY_HENTAI}V/BroadcastQueue( 287): Submitting BROADCAST_TIMEOUT_MSG [background] forBroadcastRecord{41154910 u-1 android.intent.action.KASSY_HENTAI} at 34768193V/BroadcastQueue( 287): Delivering ordered [background] to registeredBroadcastFilter{4102e4a8 u0 ReceiverList{4102e400 807 net.jcrom.eco.program/10046/u0remote:4102def0}}: BroadcastRecord{41154910 u-1 android.intent.action.KASSY_HENTAI}I/BroadcastQueue( 287): Delivering to BroadcastFilter{4102e4a8 u0ReceiverList{4102e400 807 net.jcrom.eco.program/10046/u0 remote:4102def0}} (seq=-1):BroadcastRecord{41154910 u-1 android.intent.action.KASSY_HENTAI}D/ECO_WAZA_PROGRAM( 807): Received KASSY_HENTAI
  • 40. Broadcast Intent の動作を調べる●AndroidManifest.xml に定義するものとログの出方が異なっていた。以下は Reciever が実行される直前のログ。AndroidManifest.xml に定義するものV/BroadcastQueue( 287): Delivering to componentComponentInfo{net.jcrom.eco.manifest/net.jcrom.eco.manifest.myReciever}:BroadcastRecord{410f5648 u-1 android.intent.action.KASSY_ZANNEN}プログラム上で registerReceiver を使用して登録するものI/BroadcastQueue( 287): Delivering to BroadcastFilter{4102e4a8 u0ReceiverList{4102e400 807 net.jcrom.eco.program/10046/u0 remote:4102def0}}(seq=-1): BroadcastRecord{41154910 u-1 android.intent.action.KASSY_HENTAI}
  • 41. Broadcast Intent の動作を調べる●BroadcastQueue.java で Delivering toBroadcastFilter を出力している場所を探す。436行目private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,BroadcastFilter filter, boolean ordered) {try {if (DEBUG_BROADCAST_LIGHT) {int seq = r.intent.getIntExtra("seq", -1);Slog.i(TAG, "Delivering to " + filter+ " (seq=" + seq + "): " + r);}performReceiveLocked(filter.receiverList.app,filter.receiverList.receiver,new Intent(r.intent), r.resultCode, r.resultData,r.resultExtras, r.ordered, r.initialSticky, r.userId);
  • 42. Broadcast Intent の動作を調べる●BroadcastQueue.java でdeliverToRegisteredReceiverLocked を呼び出している場所を探す。– 487行目 processNextBroadcast の中– 646行目 processNextBroadcast の中同じメソッド内で分散してるので、1箇所で動作抑制出来るように別の方法を探してみることにした。
  • 43. Broadcast Intent の動作を調べる●registerReceiver を使用して登録する方法なので、registerReceiver を確認してみた。– 登録リストみたいなものがあれば、Receiver を呼び出す前にリストを確認してるのではと予想。
  • 44. Broadcast Intent の動作を調べる●registerReceiver を調べてみた結果– ActivityManagerService.java で定義されている。– 登録する Receiver は mRegisteredReceivers に格納される。(mRegisteredReceivers は HashMap)登録された Receiver は、broadcastIntentLocked で読み出されている。11909行目 receivers.add(registeredReceivers.get(ir));この receivers に add されたものが、Broadcast Intent 受信時に呼ばれるらしい。なので add の前に判定処理を追加すると、1箇所の処理で出来そう。
  • 45. 調べ物が終わったので、エコ技を実装する
  • 46. 実装する内容●Broadcast Intent の動作を抑制する処理の追加する– BoradcastQueue.java の processNextBroadcast(778行目の前)に Broadcast Receiver を呼び出すかの判定処理を追加する– ActivityManagerService.java のbroadcastIntentLocked(11909行目の前)にBroadcastReceiver を呼び出すかの判定処理を追加する●画面消灯時にフラグを設定する– ACTION_SCREEN_OFF で OFF、ACTION_SCREEN_ON で ON●通知する Receiver のプロセスがフォアグラウンドかどうかの判定を行う●エコ技の有効・無効を設定する項目を追加する
  • 47. フォアグラウンドか判定するBoradcastQueue.java への改造内容boolean broadcast_skip = false; //Broadcast Intent を抑制するかどうかのフラグtry {List<RunningAppProcessInfo> appProcesses =ActivityManagerNative.getDefault().getRunningAppProcesses(); //プロセスの情報を取得for(RunningAppProcessInfo appProcess : appProcesses) {if(appProcess.processName.equals(app.processName)) {if(!(appProcess.importance ==RunningAppProcessInfo.IMPORTANCE_FOREGROUND)) { //フォアグラウンドか確認broadcast_skip = true;}break;}}} catch (RemoteException e) {}プロセスの状態は RunningAppProcessInfo のimportance の値を見ると分かる。http://developer.android.com/reference/android/app/ActivityManager.RunningAppProcessInfo.html
  • 48. フォアグラウンドか判定するActivityManagerService.java への改造内容boolean broadcast_skip = false; //Broadcast Intent を抑制するかどうかのフラグtry {List<RunningAppProcessInfo> appProcesses =ActivityManagerNative.getDefault().getRunningAppProcesses(); //プロセスの情報を取得for(RunningAppProcessInfo appProcess : appProcesses) {if(appProcess.processName.equals((registeredReceivers.get(ir)).packageName)){if(!(appProcess.importance ==RunningAppProcessInfo.IMPORTANCE_FOREGROUND)) { //フォアグラウンドか確認broadcast_skip = true;}break;}}} catch (RemoteException e) {}registeredReceivers.get で登録しているreceiver を取得し、パッケージ名を確認する。
  • 49. 画面消灯時にフラグを設定する処理●Broadcast Intent の動作を抑制する処理の前に追加する。※エコ技管理アプリを作っても良いが、Receiver が呼ばれる前に確実に処理出来ると考えた。BoradcastQueue.java での処理例フラグはシステムプロパティ(persist.sys.screen.eco)を用意して管理する。if (r.intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {SystemProperties.set("persist.sys.screen.eco", "on");} else if (r.intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {SystemProperties.set("persist.sys.screen.eco", "off");}if("off".equals(SystemProperties.get("persist.sys.screen.eco"))) {//Broadcast Intent の動作抑制処理}
  • 50. エコ技の有効・無効を設定する●設定アプリにエコ技の有効・無効のチェックボックスを追加有効・無効はシステムプロパティ(persist.sys.eco.enable)を使用して管理する。チェックボックスにチェック有り → trueチェックボックスにチェック無し → false
  • 51. Broadcast Intent の動作を抑制する処理BoradcastQueue.java への改造内容boolean eco_skip = false;//抑止対象外の Broadcast と画面消灯の管理if (r.intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {eco_skip = true; SystemProperties.set("persist.sys.screen.eco", "on");} else if (r.intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {eco_skip = true; SystemProperties.set("persist.sys.screen.eco", "off");} else if (r.intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED) ||r.intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {eco_skip = true;}boolean broadcast_skip = false;if(!eco_skip) {if(("true".equals(SystemProperties.get("persist.sys.eco.enable"))) &&("off".equals(SystemProperties.get("persist.sys.screen.eco")))) {//フォアグラウンドか判定する処理} //フォアグラウンドでなければ broadcast_skip が true になる。}if(broadcast_skip) { //Broadcast Intent を抑制する場合は後の処理をさせないようにするreturn;}
  • 52. Broadcast Intent の動作を抑制する処理ActivityManagerService.java への改造内容boolean eco_skip = false;//抑止対象外の Broadcast と画面消灯の管理if (r.intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {eco_skip = true; SystemProperties.set("persist.sys.screen.eco", "on");} else if (r.intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {eco_skip = true; SystemProperties.set("persist.sys.screen.eco", "off");} else if (r.intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED) ||r.intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {eco_skip = true;}boolean broadcast_skip = false;if(!eco_skip) {if(("true".equals(SystemProperties.get("persist.sys.eco.enable"))) &&("off".equals(SystemProperties.get("persist.sys.screen.eco")))) {//フォアグラウンドか判定する処理} //フォアグラウンドでなければ broadcast_skip が true になる。}if(!broadcast_skip) { //Broadcast Intent を抑制する場合は receivers.add を呼ばないreceivers.add(registeredReceivers.get(ir));}
  • 53. 実装したエコ技の動作確認
  • 54. 動作確認環境●android-4.2.2_r1.2 から作成した Emulator とGalaxy Nexus●Broadcast Intent は am コマンドを使用して投げる
  • 55. 実装したエコ技の動作確認●画面を消灯し、am コマンドで Broadcast Intent を投げた結果。エコ技無効時root@android:/ # am broadcast -a android.intent.action.KASSY_ZANNEND/ECO_WAZA_MANIFEST( 942): Received KASSY_ZANNENroot@android:/ # am broadcast -a android.intent.action.KASSY_HENTAID/ECO_WAZA_PROGRAM( 963): Received KASSY_HENTAIエコ技有効時root@android:/ # am broadcast -a android.intent.action.KASSY_ZANNENroot@android:/ # am broadcast -a android.intent.action.KASSY_HENTAI※Receiver が呼び出されない。
  • 56. 結果のログを貼っても分かり難いので、Galaxy Nexus を使用したデモ
  • 57. 2011年冬-2012年春モデル 2012年夏-2012年秋モデル動作を抑止する条件 ●省エネ待受機能をONにしていること●画面が消灯していること●バックグラウンドで動作中であること●省エネ待受対象外リストに登録されていないこと※対象外リストを作る●左と同じBroadcast Intent の制限 ●AndroidManifest.xml に定義するものが対象で、プログラム上でregisterReceiver を使用して登録するものは対象外。●以下の Broadcast Intent 以外は全て対象となる。android.intent.action.BOOT_COMPLETEDandroid.intent.action.SCREEN_OFFandroid.intent.action.SCREEN_ONcom.google.android.c2dm.intent.RECEIVEデータ通信の制限 ●未対応 ●各アプリのデータ通信を制限する機能自動同期処理の遅延 ●未対応 ●自動同期処理を、次回画面点灯時まで遅延させる機能次にやること
  • 58. 次にやること●電話帳アクセスモニター
  • 59. 動作確認して気が付いたこと●AndroidManifest.xml に Receiver を定義してると、Broadcast Intent が投げられた時にアプリが起動して Receiver が動作する。BroadcastQueue.java の 804行目// Not running -- get it started, to be executed when the app comes up.if (DEBUG_BROADCAST) Slog.v(TAG,"Need to start app ["+ mQueueName + "] " + targetProcess + " for broadcast " + r);if ((r.curApp=mService.startProcessLocked(targetProcess,info.activityInfo.applicationInfo, true,r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,"broadcast", r.curComponent,(r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false))== null) {
  • 60. 今回作成したものは Github に登録済み●素の AOSP(Galaxy Nexus)に対してエコ技だけ追加した環境ソースコード取得$ repo init -u https://github.com/sola-dolphin1/platform_manifest.git -bjb-4.2$ repo syncGalaxy Nexus 向けにビルドする$ cd device/samsung/maguro/$ ./download-blobs.sh$ cd -$ cd selfbuild/samsung/maguro/proprietary/$ ./extract-files.sh ※sudo を使用してるので、パスワード聞かれます。$ cd -$ source build/envsetup.sh$ lunch full_maguro-userdebug$ make otapackage
  • 61. 終了