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

Commit 13b2112c authored by Danning Chen's avatar Danning Chen Committed by Android (Google) Code Review
Browse files

Merge "Run PeopleService.onUserUnlocked() on worker thread instead of main thread" into rvc-dev

parents 342f7206 a44febc6
Loading
Loading
Loading
Loading
+15 −19
Original line number Diff line number Diff line
@@ -89,10 +89,8 @@ class ConversationStore {
     * Loads conversations from disk to memory in a background thread. This should be called
     * after the device powers on and the user has been unlocked.
     */
    @MainThread
    void loadConversationsFromDisk() {
        mScheduledExecutorService.execute(() -> {
            synchronized (this) {
    @WorkerThread
    synchronized void loadConversationsFromDisk() {
        ConversationInfosProtoDiskReadWriter conversationInfosProtoDiskReadWriter =
                getConversationInfosProtoDiskReadWriter();
        if (conversationInfosProtoDiskReadWriter == null) {
@@ -107,8 +105,6 @@ class ConversationStore {
            updateConversationsInMemory(conversationInfo);
        }
    }
        });
    }

    /**
     * Immediately flushes current conversations to disk. This should be called when device is
+111 −93
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.app.prediction.AppTarget;
import android.app.prediction.AppTargetEvent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -87,13 +88,13 @@ public class DataManager {

    private static final String TAG = "DataManager";

    private static final long QUERY_EVENTS_MAX_AGE_MS = DateUtils.DAY_IN_MILLIS;
    private static final long QUERY_EVENTS_MAX_AGE_MS = 5L * DateUtils.MINUTE_IN_MILLIS;
    private static final long USAGE_STATS_QUERY_INTERVAL_SEC = 120L;

    private final Context mContext;
    private final Injector mInjector;
    private final ScheduledExecutorService mUsageStatsQueryExecutor;
    private final ScheduledExecutorService mDiskReadWriterExecutor;
    private final ScheduledExecutorService mScheduledExecutor;
    private final Object mLock = new Object();

    private final SparseArray<UserData> mUserDataArray = new SparseArray<>();
    private final SparseArray<BroadcastReceiver> mBroadcastReceivers = new SparseArray<>();
@@ -118,8 +119,7 @@ public class DataManager {
    DataManager(Context context, Injector injector) {
        mContext = context;
        mInjector = injector;
        mUsageStatsQueryExecutor = mInjector.createScheduledExecutor();
        mDiskReadWriterExecutor = mInjector.createScheduledExecutor();
        mScheduledExecutor = mInjector.createScheduledExecutor();
    }

    /** Initialization. Called when the system services are up running. */
@@ -138,68 +138,21 @@ public class DataManager {

    /** This method is called when a user is unlocked. */
    public void onUserUnlocked(int userId) {
        synchronized (mLock) {
            UserData userData = mUserDataArray.get(userId);
            if (userData == null) {
            userData = new UserData(userId, mDiskReadWriterExecutor);
                userData = new UserData(userId, mScheduledExecutor);
                mUserDataArray.put(userId, userData);
            }
            userData.setUserUnlocked();
        updateDefaultDialer(userData);
        updateDefaultSmsApp(userData);

        ScheduledFuture<?> scheduledFuture = mUsageStatsQueryExecutor.scheduleAtFixedRate(
                new UsageStatsQueryRunnable(userId), 1L, USAGE_STATS_QUERY_INTERVAL_SEC,
                TimeUnit.SECONDS);
        mUsageStatsQueryFutures.put(userId, scheduledFuture);

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED);
        intentFilter.addAction(SmsApplication.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL);
        BroadcastReceiver broadcastReceiver = new PerUserBroadcastReceiver(userId);
        mBroadcastReceivers.put(userId, broadcastReceiver);
        mContext.registerReceiverAsUser(
                broadcastReceiver, UserHandle.of(userId), intentFilter, null, null);

        ContentObserver contactsContentObserver = new ContactsContentObserver(
                BackgroundThread.getHandler());
        mContactsContentObservers.put(userId, contactsContentObserver);
        mContext.getContentResolver().registerContentObserver(
                Contacts.CONTENT_URI, /* notifyForDescendants= */ true,
                contactsContentObserver, userId);

        NotificationListener notificationListener = new NotificationListener();
        mNotificationListeners.put(userId, notificationListener);
        try {
            notificationListener.registerAsSystemService(mContext,
                    new ComponentName(mContext, getClass()), userId);
        } catch (RemoteException e) {
            // Should never occur for local calls.
        }

        PackageMonitor packageMonitor = new PerUserPackageMonitor();
        packageMonitor.register(mContext, null, UserHandle.of(userId), true);
        mPackageMonitors.put(userId, packageMonitor);

        if (userId == UserHandle.USER_SYSTEM) {
            // The call log and MMS/SMS messages are shared across user profiles. So only need to
            // register the content observers once for the primary user.
            // TODO: Register observers after the conversations and events being loaded from disk.
            mCallLogContentObserver = new CallLogContentObserver(BackgroundThread.getHandler());
            mContext.getContentResolver().registerContentObserver(
                    CallLog.CONTENT_URI, /* notifyForDescendants= */ true,
                    mCallLogContentObserver, UserHandle.USER_SYSTEM);

            mMmsSmsContentObserver = new MmsSmsContentObserver(BackgroundThread.getHandler());
            mContext.getContentResolver().registerContentObserver(
                    MmsSms.CONTENT_URI, /* notifyForDescendants= */ false,
                    mMmsSmsContentObserver, UserHandle.USER_SYSTEM);
        }

        DataMaintenanceService.scheduleJob(mContext, userId);
        mScheduledExecutor.execute(() -> setupUser(userId));
    }

    /** This method is called when a user is stopping. */
    public void onUserStopping(int userId) {
        synchronized (mLock) {
            ContentResolver contentResolver = mContext.getContentResolver();
            if (mUserDataArray.indexOfKey(userId) >= 0) {
                mUserDataArray.get(userId).setUserStopped();
            }
@@ -210,8 +163,7 @@ public class DataManager {
                mContext.unregisterReceiver(mBroadcastReceivers.get(userId));
            }
            if (mContactsContentObservers.indexOfKey(userId) >= 0) {
            mContext.getContentResolver().unregisterContentObserver(
                    mContactsContentObservers.get(userId));
                contentResolver.unregisterContentObserver(mContactsContentObservers.get(userId));
            }
            if (mNotificationListeners.indexOfKey(userId) >= 0) {
                try {
@@ -225,17 +177,18 @@ public class DataManager {
            }
            if (userId == UserHandle.USER_SYSTEM) {
                if (mCallLogContentObserver != null) {
                mContext.getContentResolver().unregisterContentObserver(mCallLogContentObserver);
                    contentResolver.unregisterContentObserver(mCallLogContentObserver);
                    mCallLogContentObserver = null;
                }
                if (mMmsSmsContentObserver != null) {
                mContext.getContentResolver().unregisterContentObserver(mMmsSmsContentObserver);
                    contentResolver.unregisterContentObserver(mMmsSmsContentObserver);
                    mCallLogContentObserver = null;
                }
            }

            DataMaintenanceService.cancelJob(mContext, userId);
        }
    }

    /**
     * Iterates through all the {@link PackageData}s owned by the unlocked users who are in the
@@ -288,6 +241,9 @@ public class DataManager {
            return;
        }
        UserData userData = getUnlockedUserData(appTarget.getUser().getIdentifier());
        if (userData == null) {
            return;
        }
        PackageData packageData = userData.getOrCreatePackageData(appTarget.getPackageName());
        String mimeType = intentFilter != null ? intentFilter.getDataType(0) : null;
        @Event.EventType int eventType = mimeTypeToShareEventType(mimeType);
@@ -353,6 +309,68 @@ public class DataManager {
        userData.restore(payload);
    }

    private void setupUser(@UserIdInt int userId) {
        synchronized (mLock) {
            UserData userData = getUnlockedUserData(userId);
            if (userData == null) {
                return;
            }
            userData.loadUserData();

            updateDefaultDialer(userData);
            updateDefaultSmsApp(userData);

            ScheduledFuture<?> scheduledFuture = mScheduledExecutor.scheduleAtFixedRate(
                    new UsageStatsQueryRunnable(userId), 1L, USAGE_STATS_QUERY_INTERVAL_SEC,
                    TimeUnit.SECONDS);
            mUsageStatsQueryFutures.put(userId, scheduledFuture);

            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED);
            intentFilter.addAction(SmsApplication.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL);
            BroadcastReceiver broadcastReceiver = new PerUserBroadcastReceiver(userId);
            mBroadcastReceivers.put(userId, broadcastReceiver);
            mContext.registerReceiverAsUser(
                    broadcastReceiver, UserHandle.of(userId), intentFilter, null, null);

            ContentObserver contactsContentObserver = new ContactsContentObserver(
                    BackgroundThread.getHandler());
            mContactsContentObservers.put(userId, contactsContentObserver);
            mContext.getContentResolver().registerContentObserver(
                    Contacts.CONTENT_URI, /* notifyForDescendants= */ true,
                    contactsContentObserver, userId);

            NotificationListener notificationListener = new NotificationListener();
            mNotificationListeners.put(userId, notificationListener);
            try {
                notificationListener.registerAsSystemService(mContext,
                        new ComponentName(mContext, getClass()), userId);
            } catch (RemoteException e) {
                // Should never occur for local calls.
            }

            PackageMonitor packageMonitor = new PerUserPackageMonitor();
            packageMonitor.register(mContext, null, UserHandle.of(userId), true);
            mPackageMonitors.put(userId, packageMonitor);

            if (userId == UserHandle.USER_SYSTEM) {
                // The call log and MMS/SMS messages are shared across user profiles. So only need
                // to register the content observers once for the primary user.
                mCallLogContentObserver = new CallLogContentObserver(BackgroundThread.getHandler());
                mContext.getContentResolver().registerContentObserver(
                        CallLog.CONTENT_URI, /* notifyForDescendants= */ true,
                        mCallLogContentObserver, UserHandle.USER_SYSTEM);

                mMmsSmsContentObserver = new MmsSmsContentObserver(BackgroundThread.getHandler());
                mContext.getContentResolver().registerContentObserver(
                        MmsSms.CONTENT_URI, /* notifyForDescendants= */ false,
                        mMmsSmsContentObserver, UserHandle.USER_SYSTEM);
            }

            DataMaintenanceService.scheduleJob(mContext, userId);
        }
    }

    private int mimeTypeToShareEventType(String mimeType) {
        if (mimeType.startsWith("text/")) {
            return Event.TYPE_SHARE_TEXT;
+11 −15
Original line number Diff line number Diff line
@@ -17,9 +17,9 @@
package com.android.server.people.data;

import android.annotation.IntDef;
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.WorkerThread;
import android.net.Uri;
import android.util.ArrayMap;

@@ -90,10 +90,8 @@ class EventStore {
     * Loads existing {@link EventHistoryImpl}s from disk. This should be called when device powers
     * on and user is unlocked.
     */
    @MainThread
    void loadFromDisk() {
        mScheduledExecutorService.execute(() -> {
            synchronized (this) {
    @WorkerThread
    synchronized void loadFromDisk() {
        for (@EventCategory int category = 0; category < mEventsCategoryDirs.size();
                category++) {
            File categoryDir = mEventsCategoryDirs.get(category);
@@ -103,8 +101,6 @@ class EventStore {
            mEventHistoryMaps.get(category).putAll(existingEventHistoriesImpl);
        }
    }
        });
    }

    /**
     * Flushes all {@link EventHistoryImpl}s to disk. Should be called when device is shutting down.
+2 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static com.android.server.people.data.EventStore.CATEGORY_SMS;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
import android.content.LocusId;
import android.os.FileUtils;
import android.text.TextUtils;
@@ -77,6 +78,7 @@ public class PackageData {
     * Returns a map of package directory names as keys and their associated {@link PackageData}.
     * This should be called when device is powered on and unlocked.
     */
    @WorkerThread
    @NonNull
    static Map<String, PackageData> packagesDataFromDisk(@UserIdInt int userId,
            @NonNull Predicate<String> isDefaultDialerPredicate,
+10 −6
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.people.data;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
import android.os.Environment;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -75,12 +76,6 @@ class UserData {

    void setUserUnlocked() {
        mIsUnlocked = true;

        // Ensures per user root directory for people data is present, and attempt to load
        // data from disk.
        mPerUserPeopleDataDir.mkdirs();
        mPackageDataMap.putAll(PackageData.packagesDataFromDisk(mUserId, this::isDefaultDialer,
                this::isDefaultSmsApp, mScheduledExecutorService, mPerUserPeopleDataDir));
    }

    void setUserStopped() {
@@ -91,6 +86,15 @@ class UserData {
        return mIsUnlocked;
    }

    @WorkerThread
    void loadUserData() {
        mPerUserPeopleDataDir.mkdir();
        Map<String, PackageData> packageDataMap = PackageData.packagesDataFromDisk(
                mUserId, this::isDefaultDialer, this::isDefaultSmsApp, mScheduledExecutorService,
                mPerUserPeopleDataDir);
        mPackageDataMap.putAll(packageDataMap);
    }

    /**
     * Gets the {@link PackageData} for the specified {@code packageName} if exists; otherwise
     * creates a new instance and returns it.
Loading