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

Commit ec8384e3 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "cleanupOrphanPA's feature (1/2)*"

parents b0cf588d ad6fdf55
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ import java.lang.String;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -1187,6 +1188,53 @@ public class PhoneAccountRegistrar {
        return accounts;
    }

    /**
     * Clean up the orphan {@code PhoneAccount}. An orphan {@code PhoneAccount} is a phone
     * account that does not have a {@code UserHandle} or belongs to a deleted package.
     *
     * @return the number of orphan {@code PhoneAccount} deleted.
     */
    public int cleanupOrphanedPhoneAccounts() {
        ArrayList<PhoneAccount> badAccountsList = new ArrayList<>();
        HashMap<String, Boolean> packageLookup = new HashMap<>();
        HashMap<PhoneAccount, Boolean> userHandleLookup = new HashMap<>();

        // iterate over all accounts in registrar
        for (PhoneAccount pa : mState.accounts) {
            String packageName = pa.getAccountHandle().getComponentName().getPackageName();

            // check if the package for the PhoneAccount is uninstalled
            if (packageLookup.computeIfAbsent(packageName,
                    pn -> isPackageUninstalled(pn))) {
                badAccountsList.add(pa);
            }
            // check if PhoneAccount does not have a valid UserHandle (user was deleted)
            else if (userHandleLookup.computeIfAbsent(pa,
                    a -> isUserHandleDeletedForPhoneAccount(a))) {
                badAccountsList.add(pa);
            }
        }

        mState.accounts.removeAll(badAccountsList);

        return badAccountsList.size();
    }

    public Boolean isPackageUninstalled(String packageName) {
        try {
            mContext.getPackageManager().getPackageInfo(packageName, 0);
            return false;
        } catch (PackageManager.NameNotFoundException e) {
            return true;
        }
    }

    private Boolean isUserHandleDeletedForPhoneAccount(PhoneAccount phoneAccount) {
        UserHandle userHandle = phoneAccount.getAccountHandle().getUserHandle();
        return (userHandle == null) ||
                (mUserManager.getSerialNumberForUser(userHandle) == -1L);
    }

    //
    // State Implementation for PhoneAccountRegistrar
    //
+25 −0
Original line number Diff line number Diff line
@@ -1874,6 +1874,31 @@ public class TelecomServiceImpl {
            }
        }

        /**
         * A method intended for test to clean up orphan {@link PhoneAccount}. An orphan
         * {@link PhoneAccount} is a phone account belongs to an invalid {@link UserHandle} or a
         * deleted package.
         *
         * @return the number of orphan {@code PhoneAccount} deleted.
         */
        @Override
        public int cleanupOrphanPhoneAccounts() {
            Log.startSession("TCI.cOPA");
            try {
                synchronized (mLock) {
                    enforceShellOnly(Binder.getCallingUid(), "cleanupOrphanPhoneAccounts");
                    long token = Binder.clearCallingIdentity();
                    try {
                        return mPhoneAccountRegistrar.cleanupOrphanedPhoneAccounts();
                    } finally {
                        Binder.restoreCallingIdentity(token);
                    }
                }
            } finally {
                Log.endSession();
            }
        }

        /**
         * A method intended for use in testing to reset car mode at all priorities.
         *
+51 −0
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ import static org.mockito.Mockito.when;

import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.graphics.drawable.Icon;
@@ -82,6 +84,9 @@ public class PhoneAccountRegistrarTest extends TelecomTestCase {
    private static final int MAX_VERSION = Integer.MAX_VALUE;
    private static final String FILE_NAME = "phone-account-registrar-test-1223.xml";
    private static final String TEST_LABEL = "right";
    private final String PACKAGE_1 = "PACKAGE_1";
    private final String PACKAGE_2 = "PACKAGE_2";
    private final String COMPONENT_NAME = "com.android.server.telecom.tests.MockConnectionService";
    private PhoneAccountRegistrar mRegistrar;
    @Mock private TelecomManager mTelecomManager;
    @Mock private DefaultDialerCache mDefaultDialerCache;
@@ -1015,6 +1020,52 @@ public class PhoneAccountRegistrarTest extends TelecomTestCase {
        assertFalse(PhoneAccountHandle.areFromSamePackage(null, d));
    }

    /**
     * Tests {@link PhoneAccountRegistrar#cleanupOrphanedPhoneAccounts } cleans up / deletes an
     * orphan account.
     */
    @Test
    public void testCleanUpOrphanAccounts() throws Exception {
        // GIVEN
        mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
                Mockito.mock(IConnectionService.class));

        List<UserHandle> users = Arrays.asList(new UserHandle(0),
                new UserHandle(1000));

        PhoneAccount pa1 = new PhoneAccount.Builder(
                new PhoneAccountHandle(new ComponentName(PACKAGE_1, COMPONENT_NAME), "1234",
                        users.get(0)), "l1").build();
        PhoneAccount pa2 = new PhoneAccount.Builder(
                new PhoneAccountHandle(new ComponentName(PACKAGE_2, COMPONENT_NAME), "5678",
                        users.get(1)), "l2").build();


        registerAndEnableAccount(pa1);
        registerAndEnableAccount(pa2);

        assertEquals(1, mRegistrar.getAllPhoneAccounts(users.get(0)).size());
        assertEquals(1, mRegistrar.getAllPhoneAccounts(users.get(1)).size());


        // WHEN
        when(mContext.getPackageManager().getPackageInfo(PACKAGE_1, 0))
                .thenReturn(new PackageInfo());

        when(mContext.getPackageManager().getPackageInfo(PACKAGE_2, 0))
                .thenThrow(new PackageManager.NameNotFoundException());

        when(UserManager.get(mContext).getSerialNumberForUser(users.get(0)))
                .thenReturn(0L);

        when(UserManager.get(mContext).getSerialNumberForUser(users.get(1)))
                .thenReturn(-1L);

        // THEN
        int deletedAccounts = mRegistrar.cleanupOrphanedPhoneAccounts();
        assertEquals(1, deletedAccounts);
    }

    private static ComponentName makeQuickConnectionServiceComponentName() {
        return new ComponentName(
                "com.android.server.telecom.tests",