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

Commit c1fcd63b authored by Mark Fasheh's avatar Mark Fasheh Committed by Automerger Merge Worker
Browse files

Merge "Add an ActivityManager callback for UID frozen state changes" into udc-dev am: ef37edbf

parents a2db9c4c ef37edbf
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -18,10 +18,18 @@ package android.app {

  public class ActivityManager {
    method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void addHomeVisibilityListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.HomeVisibilityListener);
    method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void registerUidFrozenStateChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.app.ActivityManager.UidFrozenStateChangedCallback);
    method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void removeHomeVisibilityListener(@NonNull android.app.HomeVisibilityListener);
    method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void unregisterUidFrozenStateChangedCallback(@NonNull android.app.ActivityManager.UidFrozenStateChangedCallback);
    method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String);
  }

  public static interface ActivityManager.UidFrozenStateChangedCallback {
    method public void onUidFrozenStateChanged(@NonNull int[], @NonNull int[]);
    field public static final int UID_FROZEN_STATE_FROZEN = 1; // 0x1
    field public static final int UID_FROZEN_STATE_UNFROZEN = 2; // 0x2
  }

  public class AppOpsManager {
    field public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";
  }
+127 −0
Original line number Diff line number Diff line
@@ -230,6 +230,133 @@ public class ActivityManager {

    final ArrayMap<OnUidImportanceListener, UidObserver> mImportanceListeners = new ArrayMap<>();

    /**
     * Map of callbacks that have registered for {@link UidFrozenStateChanged} events.
     * Will be called when a Uid has become frozen or unfrozen.
     */
    final ArrayMap<UidFrozenStateChangedCallback, Executor> mFrozenStateChangedCallbacks =
             new ArrayMap<>();

    private final IUidFrozenStateChangedCallback mFrozenStateChangedCallback =
            new IUidFrozenStateChangedCallback.Stub() {
            @Override
            public void onUidFrozenStateChanged(int[] uids, int[] frozenStates) {
                synchronized (mFrozenStateChangedCallbacks) {
                    mFrozenStateChangedCallbacks.forEach((callback, executor) -> {
                        executor.execute(
                                () -> callback.onUidFrozenStateChanged(uids, frozenStates));
                    });
                }
            }
        };

    /**
     * Callback object for {@link #registerUidFrozenStateChangedCallback}
     *
     * @hide
     */
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    public interface UidFrozenStateChangedCallback {
        /**
         * Indicates that the UID was frozen.
         *
         * @hide
         */
        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
        int UID_FROZEN_STATE_FROZEN = 1;

        /**
         * Indicates that the UID was unfrozen.
         *
         * @hide
         */
        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
        int UID_FROZEN_STATE_UNFROZEN = 2;

        /**
         * @hide
         */
        @Retention(RetentionPolicy.SOURCE)
        @IntDef(flag = false, prefix = {"UID_FROZEN_STATE_"}, value = {
                UID_FROZEN_STATE_FROZEN,
                UID_FROZEN_STATE_UNFROZEN,
        })
        public @interface UidFrozenState {}

        /**
         * @param uids The UIDs for which the frozen state has changed
         * @param frozenStates Frozen state for each UID index, Will be set to
         *               {@link UidFrozenStateChangedCallback#UID_FROZEN_STATE_FROZEN}
         *               when the UID is frozen. When the UID is unfrozen,
         *               {@link UidFrozenStateChangedCallback#UID_FROZEN_STATE_UNFROZEN}
         *               will be set.
         *
         * @hide
         */
        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
        void onUidFrozenStateChanged(@NonNull int[] uids,
                @NonNull @UidFrozenState int[] frozenStates);
    }

    /**
     * Register a {@link UidFrozenStateChangedCallback} object to receive notification
     * when a UID is frozen or unfrozen. Will throw an exception if the same
     * callback object is registered more than once.
     *
     * @param executor The executor that the callback will be run from.
     * @param callback The callback to be registered. Callbacks for previous frozen/unfrozen
     *                 UID changes will not be delivered. Only changes in state from the point of
     *                 registration onward will be reported.
     * @throws IllegalStateException if the {@code callback} is already registered.
     *
     * @hide
     */
    @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    public void registerUidFrozenStateChangedCallback(
            @NonNull Executor executor,
            @NonNull UidFrozenStateChangedCallback callback) {
        synchronized (mFrozenStateChangedCallbacks) {
            if (mFrozenStateChangedCallbacks.containsKey(callback)) {
                throw new IllegalArgumentException("Callback already registered: " + callback);
            }
            mFrozenStateChangedCallbacks.put(callback, executor);
            if (mFrozenStateChangedCallbacks.size() > 1) {
                /* There's no need to register more than one binder interface */
                return;
            }

            try {
                getService().registerUidFrozenStateChangedCallback(mFrozenStateChangedCallback);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }

    /**
     * Unregister a {@link UidFrozenStateChangedCallback} callback.
     * @param callback The callback to be unregistered.
     *
     * @hide
     */
    @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    public void unregisterUidFrozenStateChangedCallback(
            @NonNull UidFrozenStateChangedCallback callback) {
        synchronized (mFrozenStateChangedCallbacks) {
            mFrozenStateChangedCallbacks.remove(callback);
            if (mFrozenStateChangedCallbacks.isEmpty()) {
                try {
                    getService().unregisterUidFrozenStateChangedCallback(
                            mFrozenStateChangedCallback);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
        }
    }

    /**
     * <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code
     * <meta-data>}</a> name for a 'home' Activity that declares a package that is to be
+4 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.app.IServiceConnection;
import android.app.IStopUserCallback;
import android.app.ITaskStackListener;
import android.app.IUiAutomationConnection;
import android.app.IUidFrozenStateChangedCallback;
import android.app.IUidObserver;
import android.app.IUserSwitchObserver;
import android.app.Notification;
@@ -877,4 +878,7 @@ interface IActivityManager {

    /** Logs API state change to associate with an FGS, used for FGS Type Metrics */
    void logFgsApiStateChanged(int apiType, int state, int appUid, int appPid);

    void registerUidFrozenStateChangedCallback(in IUidFrozenStateChangedCallback callback);
    void unregisterUidFrozenStateChangedCallback(in IUidFrozenStateChangedCallback callback);
}
+25 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.app;

/** {@hide} */
oneway interface IUidFrozenStateChangedCallback {
    /**
     * Report a new frozen state for the Uid list.
     */
    void onUidFrozenStateChanged(in int[] uids, in int[] frozenStates);
}
+63 −0
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@ import android.app.ActivityManager.PendingIntentInfo;
import android.app.ActivityManager.ProcessCapability;
import android.app.ActivityManager.RestrictionLevel;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.UidFrozenStateChangedCallback.UidFrozenState;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerInternal.BindServiceEventListener;
import android.app.ActivityManagerInternal.BroadcastEventListener;
@@ -208,6 +209,7 @@ import android.app.IServiceConnection;
import android.app.IStopUserCallback;
import android.app.ITaskStackListener;
import android.app.IUiAutomationConnection;
import android.app.IUidFrozenStateChangedCallback;
import android.app.IUidObserver;
import android.app.IUnsafeIntentStrictModeCallback;
import android.app.IUserSwitchObserver;
@@ -316,6 +318,7 @@ import android.os.PowerManager.ServiceType;
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RemoteCallback;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -7761,6 +7764,66 @@ public class ActivityManagerService extends IActivityManager.Stub
        return uidRecord != null && !uidRecord.isSetIdle();
    }
    @GuardedBy("mUidFrozenStateChangedCallbackList")
    private final RemoteCallbackList<IUidFrozenStateChangedCallback>
            mUidFrozenStateChangedCallbackList = new RemoteCallbackList<>();
    /**
     * Register a {@link IUidFrozenStateChangedCallback} to receive Uid frozen state events.
     *
     * @param callback remote callback object to be registered
     */
    public void registerUidFrozenStateChangedCallback(
            @NonNull IUidFrozenStateChangedCallback callback) {
        synchronized (mUidFrozenStateChangedCallbackList) {
            boolean registered = mUidFrozenStateChangedCallbackList.register(callback);
            if (!registered) {
                Slog.w(TAG, "Failed to register with RemoteCallbackList!");
            }
        }
    }
    /**
     * Unregister a {@link IUidFrozenStateChangedCallback}.
     *
     * @param callback remote callback object to be unregistered
     */
    public void unregisterUidFrozenStateChangedCallback(
            @NonNull IUidFrozenStateChangedCallback callback) {
        synchronized (mUidFrozenStateChangedCallbackList) {
            mUidFrozenStateChangedCallbackList.unregister(callback);
        }
    }
    /**
     * Notify the system that a UID has been frozen or unfrozen.
     *
     * @param uids The Uid(s) in question
     * @param frozenStates Frozen state for each UID index
     *
     * @hide
     */
    public void reportUidFrozenStateChanged(@NonNull int[] uids,
            @UidFrozenState int[] frozenStates) {
        synchronized (mUidFrozenStateChangedCallbackList) {
            final int n = mUidFrozenStateChangedCallbackList.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
                    mUidFrozenStateChangedCallbackList.getBroadcastItem(i).onUidFrozenStateChanged(
                            uids, frozenStates);
                } catch (RemoteException e) {
                    /*
                    * The process at the other end has died or otherwise gone away.
                    * According to spec, RemoteCallbacklist will take care of unregistering any
                    * object associated with that process - we are safe to ignore the exception
                    * here.
                    */
                }
            }
            mUidFrozenStateChangedCallbackList.finishBroadcast();
        }
    }
    @Override
    public void setPersistentVrThread(int tid) {
        mActivityTaskManager.setPersistentVrThread(tid);
Loading