プロテクションレベルの歴史とAndroid 6.0での変更点
Android6.0でパミッションモデルの大きな変更が加わりました、その中でINTERNETパミッションのプロテクションレベルがDANGEROUSからNORMALに変更されるなどパミッションのプロテクションレベルの再調整も行われました。パミッションのプロテクションレベルの変更だけではなく、プロテクションレベルの値の持ち方も変更になりましたので、簡単に解説したいと思います。只開発に役立つか?というと、特殊な領域やっている開発者以外は殆ど役立たない小ネタ知識なので、頭の隅にでもおいておいてもらえたらと思います。
PermissionInfoクラス
PermissionInfoというパミッション情報を纏めるクラスがありますが、Developer Siteを見ると、Android6.0になり記載事項が多くなっておりかなり変更があるように感じられます。実際追加された値も多くなっています。
PermissionInfoクラスの歴史
Android 6.0での変更点を説明する前に、過去にどのような変更があったのかを簡単に説明したいと思います。
パミッションのプロテクションレベルといえば、normal,dangerous,signature,signatureOrSystemの4つを思い浮かべると思います。Android 4.0までは以下のようなシンプルな形となっています。
public static final int PROTECTION_NORMAL = 0;そして、Android 4.1(API Level16)で以下のようなフラグが追加されました。
public static final int PROTECTION_DANGEROUS = 1;
public static final int PROTECTION_SIGNATURE = 2;
public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3;
public static final int PROTECTION_FLAG_SYSTEM = 0x10;
public static final int PROTECTION_FLAG_DEVELOPMENT = 0x20;
public static final int PROTECTION_MASK_BASE = 0xf;
public static final int PROTECTION_MASK_FLAGS = 0xf0;
PROTECTION_FLAG_SYSTEMとPROTECTION_FLAG_DEVELOPMENTというフラグが追加され、int protectionLevelの上位ビットにフラグを下位ビットビットに今までのプロテクションレベル(ベースプロテクションレベル)を入れるようになりました。この時代に上位ビット下位ビットだと!!と殺意が沸いたのを思い出します。
さらにFLAG_SYSTEMとSIGNATURE_SYSTEMで「SYSTEM」がダブっているので非常にわかりにくい!案の定以下のような事に…
理論的(使うかどうかは別として)には一つのベースプロテクションレベルに付4つのパターンが発生する事になります。
- dangerous
- dangerous|system
- dangerous|development
- dangerous|system|development
- signatureOrSystem
- signatureOrSystem|system
- signatureOrSystem|development
- signatureOrSystem|system|development
となり2番目と3番目が、システム、システムって何?と不明瞭ですし、また、
signatureOrSystemとsignature|system
どう違うの??と、ちょっとわけわからなくなります。
その後Android 4.2ではCONSTS_MONEYが追加
public int flags;Android 5.1では例のAPPOPが追加
public static final int FLAG_COSTS_MONEY = 1<<0;
public static final int PROTECTION_FLAG_APPOP = 0x40;といった感じで変化してきてました。
Android 6.0 (API Level23)の変更点
そして、今回のAndroid6.0では以下の変更がありました。1.PTOTECTION_FLAGS_SYSTEMの名称変更
先に述べたAPI Level16で追加された、PROTECTION_FLAG_SYSTEMが非推奨になり、代りにPROTECTION_FLAG_PRIVILEGED が追加されました。PROTECTION_FLAG_SYSTEM とPROTECTION_FLAG_PRIVILEGED は値が同じなので実質名前変更です。
2.SignatureOrSystemの名称廃止
PROTECTION_SIGNATURE_OR_SYSTEMが非推奨になり、代りにPROTECTION_SIGNATURE|PROTECTION_FLAG_PRIVILEGEDを使うようになりました。実質ベースプロテクションレベル4個が3つになりました。これで、以前のごちゃごちゃがようやくなくなりました。纏めると以下のようになります。
Android6.0前 | Android 6.0以降 |
---|---|
signature | signature |
signature|system | signature | privileged |
signatureOrSystem | signature | privileged |
signatureOrSystem|system | 使用しない |
ただManifestの方への記載は、非推奨にはなっていません。非推奨わすれなのか、影響があるアプリがあるからなのか、ちょっとどちらかかはわかりません。
http://developer.android.com/intl/ja/reference/android/R.attr.html#protectionLevel
3.複数のPROTECTION_FLAGフラグ追加
Int protectionLevelの上位ビット等ではなく、ちゃんとflag変数に保存されます- PROTECTION_FLAG_APPOP
- PROTECTION_FLAG_PRE23
- PROTECTION_FLAG_INSTALLER
- PROTECTION_FLAG_VERIFIER
- PROTECTION_FLAG_PREINSTALLED
各フラグの詳細は、なんとなく名前見ればわかりますが、Nexus 5X既に届いている人もいるのに、全然私の所には届く気配がないので、きちんと調査する気になりません。
付録
以下のToStringメソッドを読むとわかりやすいので貼っておきます/** @hide */ 190 public static String protectionToString(int level) { 191 String protLevel = "????"; 192 switch (level&PROTECTION_MASK_BASE) { 193 case PermissionInfo.PROTECTION_DANGEROUS: 194 protLevel = "dangerous"; 195 break; 196 case PermissionInfo.PROTECTION_NORMAL: 197 protLevel = "normal"; 198 break; 199 case PermissionInfo.PROTECTION_SIGNATURE: 200 protLevel = "signature"; 201 break; 202 case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM: 203 protLevel = "signatureOrSystem"; 204 break; 205 } 206 if ((level&PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 207 protLevel += "|privileged"; 208 } 209 if ((level&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 210 protLevel += "|development"; 211 } 212 if ((level&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 213 protLevel += "|appop"; 214 } 215 if ((level&PermissionInfo.PROTECTION_FLAG_PRE23) != 0) { 216 protLevel += "|pre23"; 217 } 218 if ((level&PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0) { 219 protLevel += "|installer"; 220 } 221 if ((level&PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0) { 222 protLevel += "|verifier"; 223 } 224 if ((level&PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0) { 225 protLevel += "|preinstalled"; 226 } 227 return protLevel; 228 }
最後に
普通アプリ書いてる時に、パミッションのフラグの値が.... なんて事はないと思いますので、興味がある人は少ないんじゃないかと思います。RiskFinder的にはアンドロイドのソースコードを解析プログラムにかけて情報とったりするので、こういう変更は結構いやな物です。結局新、旧両方の仕様に対応しなきゃいけませんし...といいつつ、このあたりのコードがすっきりしたので、良い変更だなと思いました。
ブログをGoogleのBloggerに変更したのですが、なかなか慣れません。
テーブルとか見にくいし、ソースコード等もいまいち見にくくて申し訳ありません。
すこすずつ改善します。