アプリのスタートアップ機能を搭載したInfinityTask v1.4

InfinityTaskの1.4をリリースしました。1.4では実験的な機能としてアプリのスタートアップを登録できる機能を追加しました。 「Startup Applications」の項目でアプリをオンにするとRespring後に自動でそのアプリが起動します。 SafariとChromeではこの起動時にOpenTabBackground++が動作するようにしました。

この起動は電話やメールと同様のサイレントな起動をしますので、通常のアプリ起動シーケンスとは異なる起動シーケンスになります。 このためアプリ側の各種初期化を行うメソッドの実装によっては望みの状態まで起動されない事もあります。(特にゲーム系はスタート画面まで行かない事が多いです)

本機能の主眼であるSafari, Chromeにおいては起動されてOTB++が動作する事を確認済みです。

Sleipnizer 3.1が出ました

Sleipnizer 3.1が出ました!

新機能

■Improved FindOnPageアクション

独自のFindOnPageを呼ぶ出すアクションを追加しました。


■Focus SearchBarアクション

検索バーにフォーカスするアクションを追加しました。

■KeepTabBarオプション

タブを残してフルスクリーンにするフルスクリーンオプションを追加しました。

■SmartBannerKillerオプション

こいつを殺せます。

■iOS 6ネイティブのオーバーレイボタンを縦画面でも表示させる

■このオーバーレイボタンに長押しジェスチャー

こいつを縦画面でも表示させます+何故か標準では長押ししても履歴が出ないので、出るようにしました。




■L/R始まりのジェスチャーの安定性を向上

時にジェスチャーが効かない事をなくしました。

■4.2でもインストール可に。

■いくつか不要と思うアクションを廃止

New tweak "InfinityTask"

InfinityTask debut on Cydia Store!

This new tweak feature is...

  • Infinite background task.

  • Add OpenTabBackground++ background task to Safari and Chrome.

  • Add Add to ReadingList background task to SpringBoard for iOS 6+.

  • ■Infinite bgtask and change idle sleep behavior.

    First, this is iOS original task completion and idle sleep behavior mechanism since iOS 4.

    Then below image is InfinityTasktweaked version of one.

    If you lock the device then after 15s, iOS go idle sleepmode for battery life(super power saving mode). Idle sleep mode stoped most HW and SW feature also TCP connection. But many background task required network connection; So system prevent idle sleep mode for background task during it running.

    Although iOS restrict 600sec for battery. InfinityTask unlock that mechanism! You can enable infinite background task one by one apps, that app's background task can prevent your selected time have passed after locking the device. I recommend enable to network connection not required bgtask type apps.

    ■Add OpenTabBackground++ background task to Safari and Chrome.

    Added new background task for Safari and Chrome monitoring clipboard to open url as new tab in background.


    ■Add Add to ReadingList background task to SpringBoard for iOS 6+.

    Said OpenTabBackground++ is background task, so that app must running background. This feature isn't require Safari running in background. When you copy URL to clipboard, automatically add to ReadingList that URL.

    NoLockScreen2 Public beta test

    NoLockScreen

    NoLockScreenご存知ですか?そこそこ古くからあるtweak(CydiaUpdates.netを見る限りは2010/10/05)でアラートがなく、パスコードロックもされていないようであればiPhoneの特徴的なslide to unlockをスキップしてくれる代物で愛用しています。

    が、初版の公開から一切のアップデートが行われておらずiOS5での新しいバナーシステムへの対応は行われていませんでした。さらにiOS6ではアプリが最前面にある状態(SpringBoardではない)でロック後にロックボタンでロックを解除すると、ロック解除後にすぐさまロックされてしまうバグがあります。

    この状態で放置されており、自分的にも欲しいtweakでしたので対応版をつくりました(こんな時オープンソースならフォークするのが楽なのにと思います、なので将来的にはgithubで公開予定です)。

    NoLockScreen2

    上述の問題点である

    • iOS 5+でロックスクリーンにバナー表示があるのに自動アンロックしてしまう対応不足
    • iOS 6でロックされてしまうバグ

    を解消したNoLockScreen2をパブリックベータテストします。iFileでインストールするのが一番楽だと思います。問題なければBigBoss行き。アイコンは四苦八苦してたら@renz0ne23さんが作ってくれました!多謝!

    jp.r-plus.nolockscreen2_0.0.1-11_iphoneos-arm.deb

    依存関係は以下です。

    Depends: mobilesubstrate, preferenceloader, firmware(>= 4.0)
    Conflicts: com.openbrew.nolockscreen

    iOS 6におけるSleipnizerフルスクリーン機能

    ■Portraitモードにおけるoverlayボタン

    v3.1からPortraitモードでもOS標準のoverlayボタンが表示されるように変更します。下記の表はそれを踏まえての遷移表です。

    ■Sleipnizerフルスクリーン遷移表

    Sleipnizer (>= 3.1)のフルスクリーン管理が非常に複雑になってきましたので、まとめておきます。左の状態からアクション後の状態が右側です。on/offの状態はoverlayボタンが出なくて不便なだけなのでならないように作ってます。

    SleipnizeriOS 6 nativeactionSleipnizeriOS 6 native
    offofftweakonon
    nativeoff (on : Relate to native)
    offontweak (Portrait)onon
    tweak (Landscape)offoff
    native (Landscape)
    onontweakoffoff
    native

    ■Relate to native

    Relate to nativeを有効にすると上記の表で1箇所だけ動作が変わります。また、iOS6からのiOS標準のフルスクリーン状態は/var/mobile/Library/Preferences/com.apple.mobilesafari.plistに保存され、Safariの起動時(Suspendから復帰ではない)にplist設定値から状態が復元されるのですが、この際にフルスクリーンがONで保存されていると起動時からフルスクリーンになります。Startup FullScreenが半分入る感じですね。

    ■Keep statusbar

    諸々の整合性からiOS6+ですとKeep statusbarが有効なのはPortraitモードのみになりました。FullScreen for Safariは完全になくしてしまったみたいですが。

    ■iPad

    iPadは標準が入ってこなかったようなので、これまで通りに使えるはずです。はず。

    libinstabanner

    libinstabannerをリリースしました。iOS5から実装されたUIAlertViewによる通知にかわる方法として上部にバナーがでるおなじみのアレですが、tweakから任意に呼び出すには結構な手間がかかる(特にSpringBoardの外からは)のでライブラリを作りました。

    使い方は1通りしかないので難しい事は何もなく、ヘッダーのUsageがもうほんとすべてです。bundleIdentifierの引数はnilチェックしてるのでそこは最低限なにか入れる必要があります。titleはnilにすると自動でDisplayNameが入ります。com.apple.Preferencesを指定して日本語なら「設定」てな感じです。

    bundleIdentifierを自由に指定できるのでこんな感じにすると・・

    [InstaBanner showBannerWithBundleIdentifier:@"eu.heinelt.ifile" title:nil message:@"libinstabanner test"];
    こうなります。タップするとそのアプリを起動できます。
    面倒なコードが1行ですむね!やったね!

    CleanActivity

    iOS 6からUIActivityViewControllerを使用したメニュー導入されました。従来使われていたUIActionSheetより生成にパワーが必要でUIActionSheetよりも起動は遅いですが、表示できるメニュー数が多くて便利ですね。便利なんですが人によっては絶対に使わないようなメニューもあるかと思います。Weiboとか、メールとか、メッセージとか。そこでOS標準提供のActivityをオン・オフ設定できるCleanActivityを作りました。これで私のBylineは2段にまとまってスッキリ!

    設定できるのは標準提供されている以下9種類のActivityです。

  • Twitter
  • Facebook
  • Weibo
  • Message
  • Mail
  • Pasteboard
  • Print
  • Assign to Contact
  • Save to CameraRoll
  • 色々とオフにするとスッキリしたメニューにできます。

    CleanActivityはgithubで公開しています。Licensed under the GPL v3です。アイコンのほうきがGPLだったので。CleanStatusのほうきと同じ画像だと思うのですがアレはちゃんとGPL守ってるのでしょうか。

    FakeClockUp v0.7.1-1

    ここ最近tsSpeed Aをオープンソース実装する事を目指してFakeClockUpをバージョンアップしてきてv0.7.1-1で達成できました。バイナリ・ソースコードともにgithubにあります。ライセンスは踏襲してApache License 2.0です。

    ■実装の雑感

    スライダーの値はfloat型でしか得られないので、スライダーの値をListの値に完全に合わせてあげなければ設定が同期しているようにならないのですが、ここで他のSpecifierの値を設定するにはobjectを引数とするメソッドを使用するので、floatもしくはdoubleからオブジェクトへ変換する際にNSNumberを使って0.100000000の値を[NSNumber numberWithDouble:0.100000000];してみると実際の値は0.099999998753みたいな値になってしまい同期がとれませんでした。なので、最終的にはNSStringとして保存する形になりました。詳しくはソースで。

    What is Tweak?



    ■What is Tweak?

    「CydiaでよくダウンロードするTweakとは何なのか?」について割りと詳しく解説してみようと思う。

    様々な便利な機能の追加や、細かい変更をOSに施すTweakは単語であるTweakの意味「ちょっとした調整」から来ている。ソフトウェアの既存動作にちょっとした調整を加える目的のソフトウェアをさす。

    では好みの動作をさせるにはどうしたらいいか。
    端的に言えばある処理をフックして好みの処理に置き換える事で実現出来る。

    フックを考えるにあたってまず、そのソフトウェアの動作を考えよう。
    iPhoneひいてはOS Xのソフトウェアは専らObjective-Cで記述されている。
    Objective-Cは非常に動的な言語で、コンパイル時点であまり警告・エラーを出さず実行時にうまいこと動けばOKって感じの言語だ。

    オブジェクト指向言語であり、クラスとメソッドとインスタンス変数があってカプセル化されているように見えるが、C言語が皮をかぶっているだけで中でランタイムがゴリゴリ動いてる印象だ。

    メソッドもC関数に皮を数枚かぶせた感じの実装で、実態はIMP型という関数ポインタだ。

    更にランタイムが非常に強力で、カプセル化されていながら、見ようと思えば何でも見れるようになっていて実にフックしやすい言語なんだ。

    フックの仕方には何種類か方法があって、木下さんの連載を参考にすると
    あたりが挙げられる。詳しくは連載の方が面白いのでそちらを見ていただくとして、簡単で便利なのはIMPの入れ替えだ。
    IMP変数を取得するための関数もランタイムで提供されているため、実に簡単にフックが行える。

    ■例を見てみよう!

    - (BOOL)shouldShowDictationKey;というインスタンスメソッドがUIKeyboardLayoutStarクラスに存在する。これは音声入力キーを表示すべきかどうかYESかNO(BOOL値)で返すメソッドだ。
    iOSの音声入力はSiriが可能な言語と今のところ同じであるので、使用中のキーボードがそれに該当するかどうかを判定してYESかNOを返していると想像がつくと思う。

    このメソッドを書き換えて常にYESやNOを返す処理に変えてしまえば、あのマイクキーが常に出るようになったり、常に表示されなくなる事も想像がつくだろう。 このメソッドをフックするには以下のようなコードで実現できる。
    IMP old, new;
    old = class_getMethodImplementation([UIKeyboardLayoutStar class], @selector(shouldShowDictationKey));
    new = class_getMethodImplementation([UIKeyboardLayoutStar class], @selector(new_shouldShowDictationKey));
    
    IMP tmp;
    tmp = old;
    old = new;
    new = tmp;
    
    オリジナルのメソッドを使う気がなければ最後のところは
    old = new;
    だけで事足りてしまう。 また、method_exchangeImplementationsなんて素敵な関数もあるのでこうも書ける。
    Method old, new;
    old = class_getInstanceMethod([UIKeyboardLayoutStar class], @selector(shouldShowDictationKey));
    new = class_getInstanceMethod([UIKeyboardLayoutStar class], @selector(new_shouldShowDictationKey));
    
    method_exchangeImplementations(old, new);
    いずれにせよ、これらの処理を行えば以後OSやアプリケーションがshouldShowDIctationKeyメソッドを呼び出すと、実際に処理が走るコードは自らが書いたnew_shouldShowDictationKeyメソッドのもととなる。 ちなみにnew_shouldShowDictationKeyは追加しなければならないので、class_addMethod関数で追加できる。
    static BOOL replaced_UIKeyboardLayoutStar_shouldShowDictationKey(UIKeyboardLayoutStar *self, SEL _cmd) { return NO; }
    
    class_addMethod([UIKeyboardLayoutStar class],
        @selector(new_shouldShowDictationKey),
        &replaced_UIKeyboardLayoutStar_shouldShowDictationKey,
        "c@:");
    
    メソッドの実装であるIMPを上書きするだけでも書き方は色々ある。
    Method method = class_getMethodImplementation([UIKeyboardLayoutStar class], @selector(shouldShowDictationKey));
    static BOOL replaced_UIKeyboardLayoutStar_shouldShowDictationKey(UIKeyboardLayoutStar *self, SEL _cmd) { return NO; }
    
    method_setImplementation(method, &replaced_UIKeyboardLayoutStar_shouldShowDictationKey);
    
    さて、これらの処理を適当な関数にまとめて、その関数を呼び出せば晴れてフックが完了するが、元々は存在しない関数だ。一体どうやって呼べばいいのか。
    そもそもこのコードを任意のタイミングで読みこませる(ロード)にはどうしたらいいのか。

    まず、動的なコードのロードはライブラリが同様の形態を持っているため、これを読み込むための環境が配備されている。OS XのサブセットであるiOSではdyld(Linuxならld-linux.so)によって読み込まれる.dylib形式(Linuxで言えば.so、Windowsなら.dll)にコンパイルしてdyldに読み込んでもらえばいい。

    次に関数の呼び出しだがアプリケーション側が呼んでくれるはずもないので、ロードされたタイミングで実行する関数をdyldに指定するオプションがある。これはgccの-initオプションの引数に関数名を記述すればいい。このオプションはDarwin linker(dyldのことだ)に引き渡される。man dyldでマニュアルを読むとこのオプションで指定された関数はdyldによって実行される事が書いてある。
    そこには__attribute__((constructor))が指定されたものも実行する事が記述されている。

    これらをまとめると、このTweakは以下のようなコードになる。

    このコードを動的にロードできるようdylib形式でコンパイルしたファイルがTweakそのものだ。

    この例だとメソッドの置換ではなく上書きにしたため、わりと短いコードですんでいるが、置換するとなると行うべき処理は多くなっていき、フックするメソッドが増えていくととても長いコードになっていく。そこで、このランタイムによる実装の置き換えを便利な関数でまとめてくれたライブラリを提供してくれるパッケージがCydiaにはある。そう、MobileSubstrateだ。

    ■MobileSubstrate

    MobileSubstrateの提供する関数はメソッドの置換や関数の置換、インスタンス変数の取得を行える関数を提供してくれている。
    では上記のコードをMobileSubstrateの一般的な関数を使用した形にすると、以下の様になる。

    種々のTweakが一様にMobileSubstrateをパッケージの依存関係に指定しているのは、MobileSubstrateが提供する関数を使用しているのもあるが、他にも重要な機能をMobileSubstrateは担っている。 ざっと以下のような構成だ。
    • MSHook系関数を提供するライブラリlibsubstrate.dylib
    • TweakをロードするSubstrateLoader.dylib
    • plistによるTweakのロードを制御(SubstrateLoader)
    • DYLD_INSERT_LIBRARIES環境変数へのMobileLoader.dylib(MobileSubstrate->SubstrateInjection->SubstrateBootstrap->SubstrateLoader)の追加
    • DYLD_INSERT_LIBRARIESを元に戻すMobileSafety
    この中で、TweakをロードするSubstrateLoaderが最重要機能といってもいいだろう。
    これはDynamicLibrariesディレクトリ以下のdylibを同名のplistの内容からロードの可否を判定してロードしてくれる。特定のアプリケーションにのみフックを適応させたい場合、このplistに条件を記述しておくことでコード本体にそのif文をかかずにすむようになっている。これがないと各Tweakは自分で自分のコードをロードする為のコードをかかなくてはならなくなってしまう。

    TweakをロードするのがSubstrateLoaderなら、SubstrateLoaderはどのようにロードされているのだろうか。SubstrateLoaderだって勝手に書かれた関数でしかないのだ。これにはDYLD_INSERT_LIBRARIESという環境変数へdylibを指定する事でdyldがロードするdylibの一つに加える事で実現している。

    DYLD_INSERT_LIBRARIESはLinuxでいうところのLD_PRELOADに非常によく似ていて、テストのために一時的に使用するライブラリのバージョンを違うものを指定したい時などに使われるものだ。LD_PRELOADを使ったフックについてはこちらのページ(LD_PRELOADを使ったテスト(C言語編))が非常にわかりやすく、行なっている内容もiOSのTweakと非常に似ている。そんなに長くないので是非読んでみてほしい。

    現在のMobileSubstrateはMobileSubstrate.dylibをDYLD_INSERT_LIBRARIESに追加している。/Library/MobileSubstrate/MobileSubstrate.dylibは/Library/Framework/CydiaSubstrate.framework/Libraries/SubstrateInjection.dylibへのシンボリックリンクとなっていて、SubstrateInjection.dylibは同ディレクトリのSubstrateBootstrap.dylibへのシンボリックリンクとなっている。
    SubstrateBootstrapからSubstrateLoader.dylibが読み込まれ、各種Tweakが読み込まれる流れだ。

    最後にMobileSafetyについて。SpringboardをクラッシュさせるTweakをインストールしてしまった場合、無限にRespringする事態におちいるのを防ぐためにTweakの導火線であるSubstrateLoader.dylibをロードするDYLD_INSERT_LIBRARIES環境変数を元の状態に戻した上でSpringboardを起動する役目を担っている。これが俗にいうSafe Modeだ。Tweakのロードを行わないだけなので、Cydiaからインストールしたフックを行わないアプリケーション(iFileとか)は普通に起動できる。SpringboardのクラッシュまでならMobileSafetyで対応できますが、Rebootループになるようなものには無力なので、最新のMobileSubstrateでは音量アップボタンを押しながら起動する事でTweakはおろかMobileSafetyもロードせずに起動できるようになりました。この場合もやっぱりiFileとかは動かせます。

    ちなみにOS XではSIMBLというLoaderが有名だ。MSHook系の関数を使用する前のようなコードを書く事でOS X向けのTweakも作成できる。

    ■theos

    最後にtheosについて。theosはiOS向けのMakefileプラットフォームで、長ったらしいMakefileを非常に簡素化できます。また、詳細は過去の記事を参照として割愛しますが、Tweak向けにマクロを用意してあり、直感的に記述できるようになります。
    上記の例示コードでいくとtheosを使用するとたった3行で記述できてしまいます。簡単だね!:)

    %hook UIKeyboardLayoutStar
    - (BOOL)shouldShowDictationKey { return NO; }
    %end

    ■終わりに、Jailbreak developerが増える事を願って。

    iOSのTweakのソースコードの多くはgithubで公開されています。
    記事上部で長々と書いたコードもtheosを使えば簡単に書けますので、「ここの動きが気に食わない」と感じるところがあれば、是非チャレンジしてみてはどうでしょうか。私も最初は大学でのC言語の授業(ポインタぐらいまで)程度の知識からスタートしましたので、そんなに難しくはないと思います。
    何より自分の作ったものが動くというのは楽しいものですよ?

    フリックキーボードの音声入力キーを無効にするNoDictation

    iOS5.1からSiriが日本語に対応した事で、日本語キーボードでも音声入力が使えるようになりましたが
    あまりの邪魔っぷりにこのキーを無効にするtweakを作りました。Require: iOS 5.1+です。

    日本語フリックキーボードの場合だけ無効にするバージョンと全てのキーボードで無効にするバージョンを作りました。
     全てのキーボードで無効にするバージョンはBigBoss提出予定です。

    https://github.com/r-plus/NoDictation/downloads

    ちなみにSiriが要らないのならSiriをOFFにすれば純正でこのボタンは無効です。
    iPadは設定から音声入力のON/OFFが純正で可能です。