Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 518bae5f authored by Fyodor Kupolov's avatar Fyodor Kupolov Committed by Android (Google) Code Review
Browse files

Merge "Make AccountManagerServiceTest work again" into nyc-dev

parents 06da4fb5 eeca6584
Loading
Loading
Loading
Loading
+55 −42
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ import android.util.SparseArray;
import android.util.SparseBooleanArray;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
@@ -267,10 +268,10 @@ public class AccountManagerService
        private int debugDbInsertionPoint = -1;
        private SQLiteStatement statementForLogging;

        UserAccounts(Context context, int userId) {
        UserAccounts(Context context, int userId, File preNDbFile, File deDbFile) {
            this.userId = userId;
            synchronized (cacheLock) {
                openHelper = DeDatabaseHelper.create(context, userId);
                openHelper = DeDatabaseHelper.create(context, userId, preNDbFile, deDbFile);
            }
        }
    }
@@ -540,7 +541,9 @@ public class AccountManagerService
            UserAccounts accounts = mUsers.get(userId);
            boolean validateAccounts = false;
            if (accounts == null) {
                accounts = new UserAccounts(mContext, userId);
                File preNDbFile = new File(getPreNDatabaseName(userId));
                File deDbFile = new File(getDeDatabaseName(userId));
                accounts = new UserAccounts(mContext, userId, preNDbFile, deDbFile);
                initializeDebugDbSizeAndCompileSqlStatementForLogging(
                        accounts.openHelper.getWritableDatabase(), accounts);
                mUsers.append(userId, accounts);
@@ -551,8 +554,10 @@ public class AccountManagerService
            if (!accounts.openHelper.isCeDatabaseAttached() && mUnlockedUsers.get(userId)) {
                Log.i(TAG, "User " + userId + " is unlocked - opening CE database");
                synchronized (accounts.cacheLock) {
                    CeDatabaseHelper.create(mContext, userId);
                    accounts.openHelper.attachCeDatabase();
                    File preNDatabaseFile = new File(getPreNDatabaseName(userId));
                    File ceDatabaseFile = new File(getCeDatabaseName(userId));
                    CeDatabaseHelper.create(mContext, userId, preNDatabaseFile, ceDatabaseFile);
                    accounts.openHelper.attachCeDatabase(ceDatabaseFile);
                }
                syncDeCeAccountsLocked(accounts);
            }
@@ -647,7 +652,8 @@ public class AccountManagerService
        }
    }

    private void onUserUnlocked(Intent intent) {
    @VisibleForTesting
    void onUserUnlocked(Intent intent) {
        int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "onUserUnlocked " + userId);
@@ -1553,7 +1559,7 @@ public class AccountManagerService
        }
    }

    /* For testing */
    @VisibleForTesting
    protected void removeAccountInternal(Account account) {
        removeAccountInternal(getUserAccountsForCaller(), account, getCallingUid());
    }
@@ -4044,7 +4050,8 @@ public class AccountManagerService
        }
    }

    static String getPreNDatabaseName(int userId) {
    @VisibleForTesting
    String getPreNDatabaseName(int userId) {
        File systemDir = Environment.getDataSystemDirectory();
        File databaseFile = new File(Environment.getUserSystemDirectory(userId),
                PRE_N_DATABASE_NAME);
@@ -4070,13 +4077,15 @@ public class AccountManagerService
        return databaseFile.getPath();
    }

    static String getDeDatabaseName(int userId) {
    @VisibleForTesting
    String getDeDatabaseName(int userId) {
        File databaseFile = new File(Environment.getDataSystemDeDirectory(userId),
                DE_DATABASE_NAME);
        return databaseFile.getPath();
    }

    static String getCeDatabaseName(int userId) {
    @VisibleForTesting
    String getCeDatabaseName(int userId) {
        File databaseFile = new File(Environment.getDataSystemCeDirectory(userId),
                CE_DATABASE_NAME);
        return databaseFile.getPath();
@@ -4217,13 +4226,11 @@ public class AccountManagerService
    }

    static class PreNDatabaseHelper extends SQLiteOpenHelper {

        private final Context mContext;
        private final int mUserId;

        public PreNDatabaseHelper(Context context, int userId) {
            super(context, AccountManagerService.getPreNDatabaseName(userId), null,
                    PRE_N_DATABASE_VERSION);
        public PreNDatabaseHelper(Context context, int userId, String preNDatabaseName) {
            super(context, preNDatabaseName, null, PRE_N_DATABASE_VERSION);
            mContext = context;
            mUserId = userId;
        }
@@ -4360,8 +4367,8 @@ public class AccountManagerService
        private final int mUserId;
        private volatile boolean mCeAttached;

        private DeDatabaseHelper(Context context, int userId) {
            super(context, getDeDatabaseName(userId), null, DE_DATABASE_VERSION);
        private DeDatabaseHelper(Context context, int userId, String deDatabaseName) {
            super(context, deDatabaseName, null, DE_DATABASE_VERSION);
            mUserId = userId;
        }

@@ -4426,8 +4433,7 @@ public class AccountManagerService
            }
        }

        public void attachCeDatabase() {
            File ceDbFile = new File(getCeDatabaseName(mUserId));
        public void attachCeDatabase(File ceDbFile) {
            SQLiteDatabase db = getWritableDatabase();
            db.execSQL("ATTACH DATABASE '" +  ceDbFile.getPath()+ "' AS ceDb");
            mCeAttached = true;
@@ -4440,8 +4446,8 @@ public class AccountManagerService

        public SQLiteDatabase getReadableDatabaseUserIsUnlocked() {
            if(!mCeAttached) {
                Log.wtf(TAG, "getReadableDatabaseUserIsUnlocked called while user "
                        + mUserId + " is still locked ", new Throwable());
                Log.wtf(TAG, "getReadableDatabaseUserIsUnlocked called while user " + mUserId
                        + " is still locked. CE database is not yet available.", new Throwable());
            }
            return super.getReadableDatabase();
        }
@@ -4449,7 +4455,7 @@ public class AccountManagerService
        public SQLiteDatabase getWritableDatabaseUserIsUnlocked() {
            if(!mCeAttached) {
                Log.wtf(TAG, "getWritableDatabaseUserIsUnlocked called while user " + mUserId
                        + " is still locked ", new Throwable());
                        + " is still locked. CE database is not yet available.", new Throwable());
            }
            return super.getWritableDatabase();
        }
@@ -4502,20 +4508,24 @@ public class AccountManagerService
            db.execSQL("DETACH DATABASE preNDb");
        }

        static DeDatabaseHelper create(Context context, int userId) {
            File oldDb = new File(getPreNDatabaseName(userId));
            File newDb = new File(getDeDatabaseName(userId));
            boolean newDbExists = newDb.exists();
            DeDatabaseHelper deDatabaseHelper = new DeDatabaseHelper(context, userId);
        static DeDatabaseHelper create(
                Context context,
                int userId,
                File preNDatabaseFile,
                File deDatabaseFile) {
            boolean newDbExists = deDatabaseFile.exists();
            DeDatabaseHelper deDatabaseHelper = new DeDatabaseHelper(context, userId,
                    deDatabaseFile.getPath());
            // If the db just created, and there is a legacy db, migrate it
            if (!newDbExists && oldDb.exists()) {
            if (!newDbExists && preNDatabaseFile.exists()) {
                // Migrate legacy db to the latest version -  PRE_N_DATABASE_VERSION
                PreNDatabaseHelper preNDatabaseHelper = new PreNDatabaseHelper(context, userId);
                PreNDatabaseHelper preNDatabaseHelper = new PreNDatabaseHelper(context, userId,
                        preNDatabaseFile.getPath());
                // Open the database to force upgrade if required
                preNDatabaseHelper.getWritableDatabase();
                preNDatabaseHelper.close();
                // Move data without SPII to DE
                deDatabaseHelper.migratePreNDbToDe(oldDb);
                deDatabaseHelper.migratePreNDbToDe(preNDatabaseFile);
            }
            return deDatabaseHelper;
        }
@@ -4523,8 +4533,8 @@ public class AccountManagerService

    static class CeDatabaseHelper extends SQLiteOpenHelper {

        public CeDatabaseHelper(Context context, int userId) {
            super(context, getCeDatabaseName(userId), null, CE_DATABASE_VERSION);
        public CeDatabaseHelper(Context context, String ceDatabaseName) {
            super(context, ceDatabaseName, null, CE_DATABASE_VERSION);
        }

        /**
@@ -4640,27 +4650,28 @@ public class AccountManagerService
         * @param context
         * @param userId id of the user where the database is located
         */
        static CeDatabaseHelper create(Context context, int userId) {

            File oldDatabaseFile = new File(getPreNDatabaseName(userId));
            File ceDatabaseFile = new File(getCeDatabaseName(userId));
        static CeDatabaseHelper create(
                Context context,
                int userId,
                File preNDatabaseFile,
                File ceDatabaseFile) {
            boolean newDbExists = ceDatabaseFile.exists();
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Log.v(TAG, "CeDatabaseHelper.create userId=" + userId + " oldDbExists="
                        + oldDatabaseFile.exists() + " newDbExists=" + newDbExists);
                        + preNDatabaseFile.exists() + " newDbExists=" + newDbExists);
            }
            boolean removeOldDb = false;
            if (!newDbExists && oldDatabaseFile.exists()) {
                removeOldDb = migratePreNDbToCe(oldDatabaseFile, ceDatabaseFile);
            if (!newDbExists && preNDatabaseFile.exists()) {
                removeOldDb = migratePreNDbToCe(preNDatabaseFile, ceDatabaseFile);
            }
            // Try to open and upgrade if necessary
            CeDatabaseHelper ceHelper = new CeDatabaseHelper(context, userId);
            CeDatabaseHelper ceHelper = new CeDatabaseHelper(context, ceDatabaseFile.getPath());
            ceHelper.getWritableDatabase();
            ceHelper.close();
            if (removeOldDb) {
                // TODO STOPSHIP - backup file during testing. Remove file before the release
                Log.i(TAG, "Migration complete - creating backup of old db " + oldDatabaseFile);
                renameToBakFile(oldDatabaseFile);
                Log.i(TAG, "Migration complete - creating backup of old db " + preNDatabaseFile);
                renameToBakFile(preNDatabaseFile);
            }
            return ceHelper;
        }
@@ -4825,12 +4836,14 @@ public class AccountManagerService
        }
    }

    @VisibleForTesting
    protected void installNotification(final int notificationId, final Notification n,
            UserHandle user) {
        ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE))
                .notifyAsUser(null, notificationId, n, user);
    }

    @VisibleForTesting
    protected void cancelNotification(int id, UserHandle user) {
        long identityToken = clearCallingIdentity();
        try {
@@ -5368,7 +5381,7 @@ public class AccountManagerService
        HashMap<String, String> userDataForAccount = accounts.userDataCache.get(account);
        if (userDataForAccount == null) {
            // need to populate the cache for this account
            final SQLiteDatabase db = accounts.openHelper.getReadableDatabase();
            final SQLiteDatabase db = accounts.openHelper.getReadableDatabaseUserIsUnlocked();
            userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account);
            accounts.userDataCache.put(account, userDataForAccount);
        }
+120 −16
Original line number Diff line number Diff line
@@ -16,23 +16,34 @@

package com.android.server.accounts;

import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import android.accounts.Account;
import android.accounts.AuthenticatorDescription;
import android.app.AppOpsManager;
import android.app.Notification;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.RegisteredServicesCache.ServiceInfo;
import android.content.pm.RegisteredServicesCacheListener;
import android.content.pm.UserInfo;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
import android.os.UserManager;
import android.test.AndroidTestCase;
import android.test.IsolatedContext;
import android.test.RenamingDelegatingContext;
import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import android.test.mock.MockPackageManager;
import android.util.Log;

import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -41,20 +52,28 @@ import java.util.Collection;
import java.util.Comparator;

public class AccountManagerServiceTest extends AndroidTestCase {
    private static final String TAG = AccountManagerServiceTest.class.getSimpleName();

    static final String PREN_DB = "pren.db";
    static final String DE_DB = "de.db";
    static final String CE_DB = "ce.db";
    private AccountManagerService mAms;

    @Override
    protected void setUp() throws Exception {
        final String filenamePrefix = "test.";
        MockContentResolver resolver = new MockContentResolver();
        RenamingDelegatingContext targetContextWrapper = new RenamingDelegatingContext(
                new MyMockContext(), // The context that most methods are delegated to
                getContext(), // The context that file methods are delegated to
                filenamePrefix);
        Context context = new IsolatedContext(resolver, targetContextWrapper);
        setContext(context);
        Context realTestContext = getContext();
        Context mockContext = new MyMockContext(realTestContext);
        setContext(mockContext);
        mAms = new MyAccountManagerService(getContext(),
                new MyMockPackageManager(), new MockAccountAuthenticatorCache());
                new MyMockPackageManager(), new MockAccountAuthenticatorCache(), realTestContext);
    }

    @Override
    protected void tearDown() throws Exception {
        new File(mAms.getCeDatabaseName(UserHandle.USER_SYSTEM)).delete();
        new File(mAms.getDeDatabaseName(UserHandle.USER_SYSTEM)).delete();
        new File(mAms.getPreNDatabaseName(UserHandle.USER_SYSTEM)).delete();
        super.tearDown();
    }

    public class AccountSorter implements Comparator<Account> {
@@ -69,6 +88,7 @@ public class AccountManagerServiceTest extends AndroidTestCase {
    }

    public void testCheckAddAccount() throws Exception {
        unlockUser(UserHandle.USER_SYSTEM);
        Account a11 = new Account("account1", "type1");
        Account a21 = new Account("account2", "type1");
        Account a31 = new Account("account3", "type1");
@@ -109,6 +129,7 @@ public class AccountManagerServiceTest extends AndroidTestCase {
    }

    public void testPasswords() throws Exception {
        unlockUser(UserHandle.USER_SYSTEM);
        Account a11 = new Account("account1", "type1");
        Account a12 = new Account("account1", "type2");
        mAms.addAccountExplicitly(a11, "p11", null);
@@ -124,6 +145,7 @@ public class AccountManagerServiceTest extends AndroidTestCase {
    }

    public void testUserdata() throws Exception {
        unlockUser(UserHandle.USER_SYSTEM);
        Account a11 = new Account("account1", "type1");
        Bundle u11 = new Bundle();
        u11.putString("a", "a_a11");
@@ -156,6 +178,7 @@ public class AccountManagerServiceTest extends AndroidTestCase {
    }

    public void testAuthtokens() throws Exception {
        unlockUser(UserHandle.USER_SYSTEM);
        Account a11 = new Account("account1", "type1");
        Account a12 = new Account("account1", "type2");
        mAms.addAccountExplicitly(a11, "p11", null);
@@ -188,15 +211,21 @@ public class AccountManagerServiceTest extends AndroidTestCase {
        assertNull(mAms.peekAuthToken(a12, "att2"));
    }

    private void unlockUser(int userId) {
        Intent intent = new Intent();
        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
        mAms.onUserUnlocked(intent);
    }

    static public class MockAccountAuthenticatorCache implements IAccountAuthenticatorCache {
        private ArrayList<ServiceInfo<AuthenticatorDescription>> mServices;

        public MockAccountAuthenticatorCache() {
            mServices = new ArrayList<ServiceInfo<AuthenticatorDescription>>();
            mServices = new ArrayList<>();
            AuthenticatorDescription d1 = new AuthenticatorDescription("type1", "p1", 0, 0, 0, 0);
            AuthenticatorDescription d2 = new AuthenticatorDescription("type2", "p2", 0, 0, 0, 0);
            mServices.add(new ServiceInfo<AuthenticatorDescription>(d1, null, null));
            mServices.add(new ServiceInfo<AuthenticatorDescription>(d2, null, null));
            mServices.add(new ServiceInfo<>(d1, null, null));
            mServices.add(new ServiceInfo<>(d2, null, null));
        }

        @Override
@@ -232,10 +261,68 @@ public class AccountManagerServiceTest extends AndroidTestCase {
    }

    static public class MyMockContext extends MockContext {
        private Context mTestContext;
        private AppOpsManager mAppOpsManager;
        private UserManager mUserManager;

        public MyMockContext(Context testContext) {
            this.mTestContext = testContext;
            this.mAppOpsManager = mock(AppOpsManager.class);
            this.mUserManager = mock(UserManager.class);
            final UserInfo ui = new UserInfo(UserHandle.USER_SYSTEM, "user0", 0);
            when(mUserManager.getUserInfo(eq(ui.id))).thenReturn(ui);
        }

        @Override
        public int checkCallingOrSelfPermission(final String permission) {
            return PackageManager.PERMISSION_GRANTED;
        }

        @Override
        public Object getSystemService(String name) {
            if (Context.APP_OPS_SERVICE.equals(name)) {
                return mAppOpsManager;
            } else if( Context.USER_SERVICE.equals(name)) {
                return mUserManager;
            }
            return null;
        }

        @Override
        public String getSystemServiceName(Class<?> serviceClass) {
            if (AppOpsManager.class.equals(serviceClass)) {
                return Context.APP_OPS_SERVICE;
            }
            return null;
        }

        @Override
        public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
            return null;
        }

        @Override
        public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
                IntentFilter filter, String broadcastPermission, Handler scheduler) {
            return null;
        }

        @Override
        public SQLiteDatabase openOrCreateDatabase(String file, int mode,
                SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
            Log.i(TAG, "openOrCreateDatabase " + file + " mode " + mode);
            return mTestContext.openOrCreateDatabase(file, mode, factory,errorHandler);
        }

        @Override
        public void sendBroadcastAsUser(Intent intent, UserHandle user) {
            Log.i(TAG, "sendBroadcastAsUser " + intent + " " + user);
        }

        @Override
        public String getOpPackageName() {
            return null;
        }
    }

    static public class MyMockPackageManager extends MockPackageManager {
@@ -246,9 +333,11 @@ public class AccountManagerServiceTest extends AndroidTestCase {
    }

    static public class MyAccountManagerService extends AccountManagerService {
        private Context mRealTestContext;
        public MyAccountManagerService(Context context, PackageManager packageManager,
                IAccountAuthenticatorCache authenticatorCache) {
                IAccountAuthenticatorCache authenticatorCache, Context realTestContext) {
            super(context, packageManager, authenticatorCache);
            this.mRealTestContext = realTestContext;
        }

        @Override
@@ -258,5 +347,20 @@ public class AccountManagerServiceTest extends AndroidTestCase {
        @Override
        protected void cancelNotification(final int id, UserHandle user) {
        }

        @Override
        protected String getCeDatabaseName(int userId) {
            return new File(mRealTestContext.getCacheDir(), CE_DB).getPath();
        }

        @Override
        protected String getDeDatabaseName(int userId) {
            return new File(mRealTestContext.getCacheDir(), DE_DB).getPath();
        }

        @Override
        String getPreNDatabaseName(int userId) {
            return new File(mRealTestContext.getCacheDir(), PREN_DB).getPath();
        }
    }
}