Account Managerについて調べる中で、
プログラムからアカウントが自動登録できないか挑戦してみました。
http://developer.android.com/reference/android/accounts/AccountManager.html#addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle)
このaddAccountExplicitlyと既存のアカウント、PWがあればいけるか?
と思いManifestに
AUTHENTICATE_ACCOUNTSを追加してやってみたのですがSecurity Exception発生。
呼び出し元のアプリのUidが権限ありませんよ、とのこと。
ちなみに今回のアカウントはGoogleアカウント。
ソースをたどるとこんな感じ。
frameworks/base/core/java/android/accounts/AccountManager.java
482 public boolean addAccountExplicitly(Account account, String password, Bundle userdata) {
483 if (account == null) throw new IllegalArgumentException("account is null");
484 try {
485 return
mService.addAccount(account, password, userdata);
486 } catch (RemoteException e) {
487 // won't ever happen
488 throw new RuntimeException(e);
489 }
490 }
mServiceはIAccountManagerのインスタンス。
79 public class
AccountManagerService
80 extends
IAccountManager.Stub
81 implements RegisteredServicesCacheListener<AuthenticatorDescription> {
そして、ソースを追ってAccountManagerServiceへ、
/frameworks/base/core/java/android/accounts/AccountManagerService.java
AddAccountメソッド
387 public boolean addAccount(Account account, String password, Bundle extras) {
388 if (account == null) throw new IllegalArgumentException("account is null");
389
checkAuthenticateAccountsPermission(account);
390
391 // fails if the account already exists
392 long identityToken = clearCallingIdentity();
393 try {
394 return insertAccountIntoDatabase(account, password, extras);
395 } finally {
396 restoreCallingIdentity(identityToken);
397 }
398 }
checkAuthenticateAccountsPermissionメソッド
1882 private void checkAuthenticateAccountsPermission(Account account) {
1883 checkBinderPermission(Manifest.permission.AUTHENTICATE_ACCOUNTS);
1884
checkCallingUidAgainstAuthenticator(account);
1885 }
Manifestのチェックと,Uidのチェック
checkCallingUidAgainstAuthenticatorメソッド
1838 private boolean hasAuthenticatorUid(String accountType, int callingUid) {
1839 for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo :
1840 mAuthenticatorCache.getAllServices()) {
1841 if (serviceInfo.type.type.equals(accountType)) {
1842 return (serviceInfo.uid == callingUid) ||
1843 (
mContext.getPackageManager().checkSignatures(serviceInfo.uid, callingUid)
1844 == PackageManager.SIGNATURE_MATCH);
1845 }
1846 }
1847 return false;
serviceInfoに格納されているuidと呼び出し元のuidが同一かどうかチェックしています。
自家製のアプリではuidが同じではないので、Security Exception発生という流れ。
自前サービスのアカウントならいけるのか?というのは今後の検討。