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

Commit fb4443c6 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 7506386 from 2ce2d91d to sc-release

Change-Id: Ie2216b4d3af1600d38e1f94c97391e02343d1ddc
parents a494f05f 2ce2d91d
Loading
Loading
Loading
Loading
+39 −11
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.inputmethod;

import static android.perftests.utils.ManualBenchmarkState.StatsReport;
import static android.perftests.utils.PerfTestActivity.ID_EDITOR;
import static android.perftests.utils.TestUtils.getOnMainSync;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;

@@ -25,6 +26,7 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat

import static org.junit.Assert.assertTrue;

import android.annotation.UiThread;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
@@ -64,6 +66,7 @@ import java.io.InputStreamReader;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;

@@ -72,6 +75,7 @@ import java.util.concurrent.atomic.AtomicReference;
public class ImePerfTest extends ImePerfTestBase
        implements ManualBenchmarkState.CustomizedIterationListener {
    private static final String TAG = ImePerfTest.class.getSimpleName();
    private static final long ANIMATION_NOT_STARTED = -1;

    @Rule
    public final PerfManualStatusReporter mPerfStatusReporter = new PerfManualStatusReporter();
@@ -304,36 +308,54 @@ public class ImePerfTest extends ImePerfTestBase
                latchEnd.set(new CountDownLatch(2));
                // For measuring hide, lets show IME first.
                if (!show) {
                    activity.runOnUiThread(() -> {
                    AtomicBoolean showCalled = new AtomicBoolean();
                    getInstrumentation().runOnMainSync(() -> {
                        if (!isImeVisible(activity)) {
                            controller.show(WindowInsets.Type.ime());
                            showCalled.set(true);
                        }
                    });
                    if (showCalled.get()) {
                        PollingCheck.check("IME show animation should finish ", TIMEOUT_1_S_IN_MS,
                                () -> latchStart.get().getCount() == 1
                                        && latchEnd.get().getCount() == 1);
                    }
                }
                if (!mIsTraceStarted && !state.isWarmingUp()) {
                    startAsyncAtrace();
                    mIsTraceStarted = true;
                }

                AtomicLong startTime = new AtomicLong();
                activity.runOnUiThread(() -> {
                AtomicBoolean unexpectedVisibility = new AtomicBoolean();
                getInstrumentation().runOnMainSync(() -> {
                    boolean isVisible = isImeVisible(activity);
                    startTime.set(SystemClock.elapsedRealtimeNanos());
                    if (show) {

                    if (show && !isVisible) {
                        controller.show(WindowInsets.Type.ime());
                    } else {
                    } else if (!show && isVisible) {
                        controller.hide(WindowInsets.Type.ime());
                    } else {
                        // ignore this iteration as unexpected IME visibility was encountered.
                        unexpectedVisibility.set(true);
                    }
                });

                measuredTimeNs = waitForAnimationStart(latchStart, startTime);
                if (!unexpectedVisibility.get()) {
                    long timeElapsed = waitForAnimationStart(latchStart, startTime);
                    if (timeElapsed != ANIMATION_NOT_STARTED) {
                        measuredTimeNs = timeElapsed;
                    }
                }

                // hide IME before next iteration.
                if (show) {
                    activity.runOnUiThread(() -> controller.hide(WindowInsets.Type.ime()));
                    try {
                        latchEnd.get().await(TIMEOUT_1_S_IN_MS * 5, TimeUnit.MILLISECONDS);
                        if (latchEnd.get().getCount() != 0) {
                        if (latchEnd.get().getCount() != 0
                                && getOnMainSync(() -> isImeVisible(activity))) {
                            Assert.fail("IME hide animation should finish.");
                        }
                    } catch (InterruptedException e) {
@@ -350,12 +372,18 @@ public class ImePerfTest extends ImePerfTestBase
        addResultToState(state);
    }

    @UiThread
    private boolean isImeVisible(@NonNull final Activity activity) {
        return activity.getWindow().getDecorView().getRootWindowInsets().isVisible(
                WindowInsets.Type.ime());
    }

    private long waitForAnimationStart(
            AtomicReference<CountDownLatch> latchStart, AtomicLong startTime) {
        try {
            latchStart.get().await(TIMEOUT_1_S_IN_MS * 5, TimeUnit.MILLISECONDS);
            if (latchStart.get().getCount() != 0) {
                Assert.fail("IME animation should start " + latchStart.get().getCount());
                return ANIMATION_NOT_STARTED;
            }
        } catch (InterruptedException e) { }

+44 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.perftests.utils;

import android.app.Instrumentation;

import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;

import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;

public final class TestUtils {

    /**
     * Retrieves a value that needs to be obtained on the main thread.
     *
     * <p>A simple utility method that helps to return an object from the UI thread.</p>
     *
     * @param supplier callback to be called on the UI thread to return a value
     * @param <T> Type of the value to be returned
     * @return Value returned from {@code supplier}
     */
    public static <T> T getOnMainSync(@NonNull Supplier<T> supplier) {
        final AtomicReference<T> result = new AtomicReference<>();
        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
        instrumentation.runOnMainSync(() -> result.set(supplier.get()));
        return result.get();
    }
}
+8 −18
Original line number Diff line number Diff line
@@ -25,29 +25,19 @@ public interface AppStateTracker {
    String TAG = "AppStateTracker";

    /**
     * Register a {@link ForcedAppStandbyListener} to listen for forced-app-standby changes that
     * should affect services etc.
     * Register a {@link ServiceStateListener} to listen for forced-app-standby changes that should
     * affect services.
     */
    void addForcedAppStandbyListener(@NonNull ForcedAppStandbyListener listener);
    void addServiceStateListener(@NonNull ServiceStateListener listener);

    /**
     * @return {code true} if the given UID/package has been in forced app standby mode.
     * A listener to listen to forced-app-standby changes that should affect services.
     */
    boolean isAppInForcedAppStandby(int uid, @NonNull String packageName);

    /**
     * A listener to listen to forced-app-standby changes that should affect services etc.
     */
    interface ForcedAppStandbyListener {
        /**
         * Called when an app goes in/out of forced app standby.
         */
        void updateForceAppStandbyForUidPackage(int uid, String packageName, boolean standby);

    interface ServiceStateListener {
        /**
         * Called when all apps' forced-app-standby states need to be re-evaluated, due to
         * enable/disable certain feature flags.
         * Called when an app goes into forced app standby and its foreground
         * services need to be removed from that state.
         */
        void updateForcedAppStandbyForAllApps();
        void stopForegroundServicesForUidPackage(int uid, String packageName);
    }
}
+10 −85
Original line number Diff line number Diff line
@@ -60,10 +60,8 @@ import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * Class to keep track of the information related to "force app standby", which includes:
@@ -162,46 +160,16 @@ public class AppStateTrackerImpl implements AppStateTracker {
    @GuardedBy("mLock")
    boolean mForcedAppStandbyEnabled;

    /**
     * A lock-free set of (uid, packageName) pairs in forced app standby mode.
     *
     * <p>
     * It's bascially shadowing the {@link #mRunAnyRestrictedPackages} together with
     * the {@link #mForcedAppStandbyEnabled} and the {@link #mForceAllAppsStandby} - mutations on
     * them would result in copy-on-write.
     *
     * Note: when {@link #mForcedAppStandbyEnabled} is {@code false}, it'll be set to an empty set.
     *       when {@link #mForceAllAppsStandby} is {@code true}, it'll be set to null;
     * </p>
     */
    volatile Set<Pair<Integer, String>> mForcedAppStandbyUidPackages = Collections.emptySet();

    @Override
    public void addForcedAppStandbyListener(@NonNull ForcedAppStandbyListener listener) {
    public void addServiceStateListener(@NonNull ServiceStateListener listener) {
        addListener(new Listener() {
            @Override
            public void updateForceAppStandbyForUidPackage(int uid, String packageName,
                    boolean standby) {
                listener.updateForceAppStandbyForUidPackage(uid, packageName, standby);
            }

            @Override
            public void updateForcedAppStandbyForAllApps() {
                listener.updateForcedAppStandbyForAllApps();
            public void stopForegroundServicesForUidPackage(int uid, String packageName) {
                listener.stopForegroundServicesForUidPackage(uid, packageName);
            }
        });
    }

    @Override
    public boolean isAppInForcedAppStandby(int uid, @NonNull String packageName) {
        final Set<Pair<Integer, String>> fasUidPkgs = mForcedAppStandbyUidPackages;
        if (fasUidPkgs == null) {
            // Meaning the mForceAllAppsStandby is true.
            return true;
        }
        return fasUidPkgs.contains(Pair.create(uid, packageName));
    }

    interface Stats {
        int UID_FG_STATE_CHANGED = 0;
        int UID_ACTIVE_STATE_CHANGED = 1;
@@ -265,7 +233,6 @@ public class AppStateTrackerImpl implements AppStateTracker {
                        return;
                    }
                    mForcedAppStandbyEnabled = enabled;
                    updateForcedAppStandbyUidPackagesLocked();
                    if (DEBUG) {
                        Slog.d(TAG, "Forced app standby feature flag changed: "
                                + mForcedAppStandbyEnabled);
@@ -310,11 +277,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
            if (!sender.isRunAnyInBackgroundAppOpsAllowed(uid, packageName)) {
                Slog.v(TAG, "Package " + packageName + "/" + uid
                        + " toggled into fg service restriction");
                updateForceAppStandbyForUidPackage(uid, packageName, true);
            } else {
                Slog.v(TAG, "Package " + packageName + "/" + uid
                        + " toggled out of fg service restriction");
                updateForceAppStandbyForUidPackage(uid, packageName, false);
                stopForegroundServicesForUidPackage(uid, packageName);
            }
        }

@@ -379,7 +342,6 @@ public class AppStateTrackerImpl implements AppStateTracker {
        private void onForceAllAppsStandbyChanged(AppStateTrackerImpl sender) {
            updateAllJobs();
            updateAllAlarms();
            updateForcedAppStandbyForAllApps();
        }

        /**
@@ -404,17 +366,10 @@ public class AppStateTrackerImpl implements AppStateTracker {
        }

        /**
         * Called when an app goes in/out of forced app standby.
         * Called when an app goes into forced app standby and its foreground
         * services need to be removed from that state.
         */
        public void updateForceAppStandbyForUidPackage(int uid, String packageName,
                boolean standby) {
        }

        /**
         * Called when all apps' forced-app-standby states need to be re-evaluated due to changes of
         * feature flags such as {@link #mForcedAppStandbyEnabled} or {@link #mForceAllAppsStandby}.
         */
        public void updateForcedAppStandbyForAllApps() {
        public void stopForegroundServicesForUidPackage(int uid, String packageName) {
        }

        /**
@@ -483,13 +438,10 @@ public class AppStateTrackerImpl implements AppStateTracker {
                        final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
                        // No need to notify for state change as all the alarms and jobs should be
                        // removed too.
                        synchronized (mLock) {
                        mExemptedBucketPackages.remove(userId, pkgName);
                        mRunAnyRestrictedPackages.remove(Pair.create(uid, pkgName));
                            updateForcedAppStandbyUidPackagesLocked();
                        mActiveUids.delete(uid);
                    }
                    }
                    break;
            }
        }
@@ -628,29 +580,6 @@ public class AppStateTrackerImpl implements AppStateTracker {
                }
            }
        }
        updateForcedAppStandbyUidPackagesLocked();
    }

    /**
     * Update the {@link #mForcedAppStandbyUidPackages} upon mutations on
     * {@link #mRunAnyRestrictedPackages}, {@link #mForcedAppStandbyEnabled} or
     * {@link #mForceAllAppsStandby}.
     */
    @GuardedBy("mLock")
    private void updateForcedAppStandbyUidPackagesLocked() {
        if (!mForcedAppStandbyEnabled) {
            mForcedAppStandbyUidPackages = Collections.emptySet();
            return;
        }
        if (mForceAllAppsStandby) {
            mForcedAppStandbyUidPackages = null;
            return;
        }
        Set<Pair<Integer, String>> fasUidPkgs = new ArraySet<>();
        for (int i = 0, size = mRunAnyRestrictedPackages.size(); i < size; i++) {
            fasUidPkgs.add(mRunAnyRestrictedPackages.valueAt(i));
        }
        mForcedAppStandbyUidPackages = Collections.unmodifiableSet(fasUidPkgs);
    }

    private void updateForceAllAppStandbyState() {
@@ -672,7 +601,6 @@ public class AppStateTrackerImpl implements AppStateTracker {
            return;
        }
        mForceAllAppsStandby = enable;
        updateForcedAppStandbyUidPackagesLocked();

        mHandler.notifyForceAllAppsStandbyChanged();
    }
@@ -717,7 +645,6 @@ public class AppStateTrackerImpl implements AppStateTracker {
        } else {
            mRunAnyRestrictedPackages.removeAt(index);
        }
        updateForcedAppStandbyUidPackagesLocked();
        return true;
    }

@@ -969,7 +896,6 @@ public class AppStateTrackerImpl implements AppStateTracker {
                        if (unblockAlarms) {
                            l.unblockAllUnrestrictedAlarms();
                        }
                        l.updateForcedAppStandbyForAllApps();
                    }
                    mStatLogger.logDurationStat(
                            Stats.FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED, start);
@@ -1040,7 +966,6 @@ public class AppStateTrackerImpl implements AppStateTracker {
                    mRunAnyRestrictedPackages.removeAt(i);
                }
            }
            updateForcedAppStandbyUidPackagesLocked();
            cleanUpArrayForUser(mActiveUids, removedUserId);
            mExemptedBucketPackages.remove(removedUserId);
        }
+0 −2528

File changed.

Preview size limit exceeded, changes collapsed.

Loading