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

Commit b0994ef7 authored by yw.bae's avatar yw.bae Committed by Angela Wang
Browse files

Implement FlashNotificationsController for AccessibilityManagerService.



Flash Notification is an alternative feature for hearing impaired, which translate phone call, alarm sound, and audible notifications into visible alerts like camera torch or flashing screen overlay.

Bug: 237628564
Test: atest FlashNotificationsControllerTest
Change-Id: I4043d1b5f339c8b43d886fa919e2b0af06dc8ed1
Signed-off-by: default avataryw.bae <yw.bae@samsung.corp-partner.google.com>
Signed-off-by: default avatarAngela Wang <angelala@google.com>
parent 32338521
Loading
Loading
Loading
Loading
+121 −0
Original line number Diff line number Diff line
@@ -186,6 +186,18 @@ public final class AccessibilityManager {
     */
    public static final int ACCESSIBILITY_SHORTCUT_KEY = 1;

    /** @hide */
    public static final int FLASH_REASON_CALL = 1;

    /** @hide */
    public static final int FLASH_REASON_ALARM = 2;

    /** @hide */
    public static final int FLASH_REASON_NOTIFICATION = 3;

    /** @hide */
    public static final int FLASH_REASON_PREVIEW = 4;

    /**
     * Annotations for the shortcut type.
     * @hide
@@ -209,6 +221,19 @@ public final class AccessibilityManager {
    })
    public @interface ContentFlag {}

    /**
     * Annotations for reason of Flash notification.
     * @hide
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = { "FLASH_REASON_" }, value = {
            FLASH_REASON_CALL,
            FLASH_REASON_ALARM,
            FLASH_REASON_NOTIFICATION,
            FLASH_REASON_PREVIEW
    })
    public @interface FlashNotificationReason {}

    /**
     * Use this flag to indicate the content of a UI that times out contains icons.
     *
@@ -316,6 +341,13 @@ public final class AccessibilityManager {
     */
    private SparseArray<List<AccessibilityRequestPreparer>> mRequestPreparerLists;

    /**
     * Binder for flash notification.
     *
     * @see #startFlashNotificationSequence(Context, int)
     */
    private final Binder mBinder = new Binder();

    /**
     * Listener for the system accessibility state. To listen for changes to the
     * accessibility state on the device, implement this interface and register
@@ -2096,6 +2128,95 @@ public final class AccessibilityManager {
        }
    }

    /**
     * Start sequence (infinite) type of flash notification. Use
     * {@code Context.getOpPackageName()} as the identifier of this flash notification.
     * The notification can be cancelled later by calling {@link #stopFlashNotificationSequence}
     * with same {@code Context.getOpPackageName()}.
     * If the binder associated with this {@link AccessibilityManager} instance dies then the
     * sequence will stop automatically. It is strongly recommended to call
     * {@link #stopFlashNotificationSequence} within a reasonable amount of time after calling
     * this method.
     *
     * @param context The context in which this manager operates.
     * @param reason The triggering reason of flash notification.
     * @return {@code true} if flash notification works properly.
     * @hide
     */
    public boolean startFlashNotificationSequence(@NonNull Context context,
            @FlashNotificationReason int reason) {
        final IAccessibilityManager service;
        synchronized (mLock) {
            service = getServiceLocked();
            if (service == null) {
                return false;
            }
        }

        try {
            return service.startFlashNotificationSequence(context.getOpPackageName(),
                    reason, mBinder);
        } catch (RemoteException re) {
            Log.e(LOG_TAG, "Error while start flash notification sequence", re);
            return false;
        }
    }

    /**
     * Stop sequence (infinite) type of flash notification. The flash notification with
     * {@code Context.getOpPackageName()} as identifier will be stopped if exist.
     * It is strongly recommended to call this method within a reasonable amount of time after
     * calling {@link #startFlashNotificationSequence} method.
     *
     * @param context The context in which this manager operates.
     * @return {@code true} if flash notification stops properly.
     * @hide
     */
    public boolean stopFlashNotificationSequence(@NonNull Context context) {
        final IAccessibilityManager service;
        synchronized (mLock) {
            service = getServiceLocked();
            if (service == null) {
                return false;
            }
        }

        try {
            return service.stopFlashNotificationSequence(context.getOpPackageName());
        } catch (RemoteException re) {
            Log.e(LOG_TAG, "Error while stop flash notification sequence", re);
            return false;
        }
    }

    /**
     * Start event (finite) type of flash notification.
     *
     * @param context The context in which this manager operates.
     * @param reason The triggering reason of flash notification.
     * @param reasonPkg The package that trigger the flash notification.
     * @return {@code true} if flash notification works properly.
     * @hide
     */
    public boolean startFlashNotificationEvent(@NonNull Context context,
            @FlashNotificationReason int reason, @Nullable String reasonPkg) {
        final IAccessibilityManager service;
        synchronized (mLock) {
            service = getServiceLocked();
            if (service == null) {
                return false;
            }
        }

        try {
            return service.startFlashNotificationEvent(context.getOpPackageName(),
                    reason, reasonPkg);
        } catch (RemoteException re) {
            Log.e(LOG_TAG, "Error while start flash notification event", re);
            return false;
        }
    }

    private IAccessibilityManager getServiceLocked() {
        if (mService == null) {
            tryConnectToServiceLocked(null);
+4 −0
Original line number Diff line number Diff line
@@ -120,4 +120,8 @@ interface IAccessibilityManager {
    void injectInputEventToInputFilter(in InputEvent event);

    float getUiContrast();

    boolean startFlashNotificationSequence(String opPkg, int reason, IBinder token);
    boolean stopFlashNotificationSequence(String opPkg);
    boolean startFlashNotificationEvent(String opPkg, int reason, String reasonPkg);
}
+39 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_MENU
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
import static android.view.accessibility.AccessibilityManager.CONTRAST_DEFAULT_VALUE;
import static android.view.accessibility.AccessibilityManager.CONTRAST_NOT_SET;
import static android.view.accessibility.AccessibilityManager.FlashNotificationReason;
import static android.view.accessibility.AccessibilityManager.ShortcutType;

import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
@@ -314,6 +315,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
    boolean mInputSessionRequested;
    private SparseArray<SurfaceControl> mA11yOverlayLayers = new SparseArray<>();

    private final FlashNotificationsController mFlashNotificationsController;

    private AccessibilityUserState getCurrentUserStateLocked() {
        return getUserStateLocked(mCurrentUserId);
    }
@@ -440,6 +443,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
            mInputFilter = inputFilter;
            mHasInputFilter = true;
        }
        mFlashNotificationsController = new FlashNotificationsController(mContext);
        init();
    }

@@ -470,6 +474,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        mMagnificationProcessor = new MagnificationProcessor(mMagnificationController);
        mCaptioningManagerImpl = new CaptioningManagerImpl(mContext);
        mProxyManager = new ProxyManager(mLock, mA11yWindowManager);
        mFlashNotificationsController = new FlashNotificationsController(mContext);
        init();
    }

@@ -3871,6 +3876,40 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        }
    }

    @Override
    public boolean startFlashNotificationSequence(String opPkg,
            @FlashNotificationReason int reason, IBinder token) {
        final long identity = Binder.clearCallingIdentity();
        try {
            return mFlashNotificationsController.startFlashNotificationSequence(opPkg,
                    reason, token);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    @Override
    public boolean stopFlashNotificationSequence(String opPkg) {
        final long identity = Binder.clearCallingIdentity();
        try {
            return mFlashNotificationsController.stopFlashNotificationSequence(opPkg);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    @Override
    public boolean startFlashNotificationEvent(String opPkg,
            @FlashNotificationReason int reason, String reasonPkg) {
        final long identity = Binder.clearCallingIdentity();
        try {
            return mFlashNotificationsController.startFlashNotificationEvent(opPkg,
                    reason, reasonPkg);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    @Override
    public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
        if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
+936 −0

File added.

Preview size limit exceeded, changes collapsed.

+509 −0

File added.

Preview size limit exceeded, changes collapsed.