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

Commit 05508e57 authored by Antonio Kantek's avatar Antonio Kantek Committed by Android (Google) Code Review
Browse files

Merge "Avoid synchronization at method level in ImeTrackerService" into main

parents b08d95b7 5cacb673
Loading
Loading
Loading
Loading
+64 −44
Original line number Original line Diff line number Diff line
@@ -60,85 +60,100 @@ public final class ImeTrackerService extends IImeTracker.Stub {
    private static final long TIMEOUT_MS = 10_000;
    private static final long TIMEOUT_MS = 10_000;


    /** Handler for registering timeouts for live entries. */
    /** Handler for registering timeouts for live entries. */
    @GuardedBy("mLock")
    private final Handler mHandler;
    private final Handler mHandler;


    /** Singleton instance of the History. */
    /** Singleton instance of the History. */
    @GuardedBy("ImeTrackerService.this")
    @GuardedBy("mLock")
    private final History mHistory = new History();
    private final History mHistory = new History();


    private final Object mLock = new Object();

    ImeTrackerService(@NonNull Looper looper) {
    ImeTrackerService(@NonNull Looper looper) {
        mHandler = new Handler(looper, null /* callback */, true /* async */);
        mHandler = new Handler(looper, null /* callback */, true /* async */);
    }
    }


    @NonNull
    @NonNull
    @Override
    @Override
    public synchronized ImeTracker.Token onRequestShow(@NonNull String tag, int uid,
    public ImeTracker.Token onRequestShow(@NonNull String tag, int uid,
            @ImeTracker.Origin int origin, @SoftInputShowHideReason int reason) {
            @ImeTracker.Origin int origin, @SoftInputShowHideReason int reason) {
        final var binder = new Binder();
        final var binder = new Binder();
        final var token = new ImeTracker.Token(binder, tag);
        final var token = new ImeTracker.Token(binder, tag);
        final var entry = new History.Entry(tag, uid, ImeTracker.TYPE_SHOW, ImeTracker.STATUS_RUN,
        final var entry = new History.Entry(tag, uid, ImeTracker.TYPE_SHOW, ImeTracker.STATUS_RUN,
                origin, reason);
                origin, reason);
        synchronized (mLock) {
            mHistory.addEntry(binder, entry);
            mHistory.addEntry(binder, entry);


            // Register a delayed task to handle the case where the new entry times out.
            // Register a delayed task to handle the case where the new entry times out.
            mHandler.postDelayed(() -> {
            mHandler.postDelayed(() -> {
            synchronized (ImeTrackerService.this) {
                synchronized (mLock) {
                mHistory.setFinished(token, ImeTracker.STATUS_TIMEOUT, ImeTracker.PHASE_NOT_SET);
                    mHistory.setFinished(token, ImeTracker.STATUS_TIMEOUT,
                            ImeTracker.PHASE_NOT_SET);
                }
                }
            }, TIMEOUT_MS);
            }, TIMEOUT_MS);

        }
        return token;
        return token;
    }
    }


    @NonNull
    @NonNull
    @Override
    @Override
    public synchronized ImeTracker.Token onRequestHide(@NonNull String tag, int uid,
    public ImeTracker.Token onRequestHide(@NonNull String tag, int uid,
            @ImeTracker.Origin int origin, @SoftInputShowHideReason int reason) {
            @ImeTracker.Origin int origin, @SoftInputShowHideReason int reason) {
        final var binder = new Binder();
        final var binder = new Binder();
        final var token = new ImeTracker.Token(binder, tag);
        final var token = new ImeTracker.Token(binder, tag);
        final var entry = new History.Entry(tag, uid, ImeTracker.TYPE_HIDE, ImeTracker.STATUS_RUN,
        final var entry = new History.Entry(tag, uid, ImeTracker.TYPE_HIDE, ImeTracker.STATUS_RUN,
                origin, reason);
                origin, reason);
        synchronized (mLock) {
            mHistory.addEntry(binder, entry);
            mHistory.addEntry(binder, entry);


            // Register a delayed task to handle the case where the new entry times out.
            // Register a delayed task to handle the case where the new entry times out.
            mHandler.postDelayed(() -> {
            mHandler.postDelayed(() -> {
            synchronized (ImeTrackerService.this) {
                synchronized (mLock) {
                mHistory.setFinished(token, ImeTracker.STATUS_TIMEOUT, ImeTracker.PHASE_NOT_SET);
                    mHistory.setFinished(token, ImeTracker.STATUS_TIMEOUT,
                            ImeTracker.PHASE_NOT_SET);
                }
                }
            }, TIMEOUT_MS);
            }, TIMEOUT_MS);

        }
        return token;
        return token;
    }
    }


    @Override
    @Override
    public synchronized void onProgress(@NonNull IBinder binder, @ImeTracker.Phase int phase) {
    public void onProgress(@NonNull IBinder binder, @ImeTracker.Phase int phase) {
        synchronized (mLock) {
            final var entry = mHistory.getEntry(binder);
            final var entry = mHistory.getEntry(binder);
            if (entry == null) return;
            if (entry == null) return;


            entry.mPhase = phase;
            entry.mPhase = phase;
        }
        }
    }


    @Override
    @Override
    public synchronized void onFailed(@NonNull ImeTracker.Token statsToken,
    public void onFailed(@NonNull ImeTracker.Token statsToken, @ImeTracker.Phase int phase) {
            @ImeTracker.Phase int phase) {
        synchronized (mLock) {
            mHistory.setFinished(statsToken, ImeTracker.STATUS_FAIL, phase);
            mHistory.setFinished(statsToken, ImeTracker.STATUS_FAIL, phase);
        }
        }
    }


    @Override
    @Override
    public synchronized void onCancelled(@NonNull ImeTracker.Token statsToken,
    public void onCancelled(@NonNull ImeTracker.Token statsToken, @ImeTracker.Phase int phase) {
            @ImeTracker.Phase int phase) {
        synchronized (mLock) {
            mHistory.setFinished(statsToken, ImeTracker.STATUS_CANCEL, phase);
            mHistory.setFinished(statsToken, ImeTracker.STATUS_CANCEL, phase);
        }
        }
    }


    @Override
    @Override
    public synchronized void onShown(@NonNull ImeTracker.Token statsToken) {
    public void onShown(@NonNull ImeTracker.Token statsToken) {
        synchronized (mLock) {
            mHistory.setFinished(statsToken, ImeTracker.STATUS_SUCCESS, ImeTracker.PHASE_NOT_SET);
            mHistory.setFinished(statsToken, ImeTracker.STATUS_SUCCESS, ImeTracker.PHASE_NOT_SET);
        }
        }
    }


    @Override
    @Override
    public synchronized void onHidden(@NonNull ImeTracker.Token statsToken) {
    public void onHidden(@NonNull ImeTracker.Token statsToken) {
        synchronized (mLock) {
            mHistory.setFinished(statsToken, ImeTracker.STATUS_SUCCESS, ImeTracker.PHASE_NOT_SET);
            mHistory.setFinished(statsToken, ImeTracker.STATUS_SUCCESS, ImeTracker.PHASE_NOT_SET);
        }
        }
    }


    /**
    /**
     * Updates the IME request tracking token with new information available in IMMS.
     * Updates the IME request tracking token with new information available in IMMS.
@@ -146,26 +161,31 @@ public final class ImeTrackerService extends IImeTracker.Stub {
     * @param statsToken the token corresponding to the current IME request.
     * @param statsToken the token corresponding to the current IME request.
     * @param requestWindowName the name of the window that created the IME request.
     * @param requestWindowName the name of the window that created the IME request.
     */
     */
    public synchronized void onImmsUpdate(@NonNull ImeTracker.Token statsToken,
    public void onImmsUpdate(@NonNull ImeTracker.Token statsToken,
            @NonNull String requestWindowName) {
            @NonNull String requestWindowName) {
        synchronized (mLock) {
            final var entry = mHistory.getEntry(statsToken.getBinder());
            final var entry = mHistory.getEntry(statsToken.getBinder());
            if (entry == null) return;
            if (entry == null) return;


            entry.mRequestWindowName = requestWindowName;
            entry.mRequestWindowName = requestWindowName;
        }
        }
    }


    /** Dumps the contents of the history. */
    /** Dumps the contents of the history. */
    public synchronized void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
    public void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
        synchronized (mLock) {
            mHistory.dump(pw, prefix);
            mHistory.dump(pw, prefix);
        }
        }
    }


    @EnforcePermission(Manifest.permission.TEST_INPUT_METHOD)
    @EnforcePermission(Manifest.permission.TEST_INPUT_METHOD)
    @Override
    @Override
    public synchronized boolean hasPendingImeVisibilityRequests() {
    public boolean hasPendingImeVisibilityRequests() {
        super.hasPendingImeVisibilityRequests_enforcePermission();
        super.hasPendingImeVisibilityRequests_enforcePermission();

        synchronized (mLock) {
            return !mHistory.mLiveEntries.isEmpty();
            return !mHistory.mLiveEntries.isEmpty();
        }
        }
    }


    /**
    /**
     * A circular buffer storing the most recent few {@link ImeTracker.Token} entries information.
     * A circular buffer storing the most recent few {@link ImeTracker.Token} entries information.