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

Commit 8489a3a7 authored by Jigar Thakkar's avatar Jigar Thakkar
Browse files

Fix accessibility label strings for profiles

This change adds a user type details property to specify
accessibility label for a profile and exposes it from a hidden
UserManager API. We also use this API to get the accessibility label
strings for profiles in PhoneStatusBarPolicy and other places within the
framework.

Bug: 329551064
Test: atest UserManagerTest. Also, tested manually by flashing the
changes locally and setting up private space.

Flag: ACONFIG android.multiuser.enable_private_space_features NEXTFOOD

Change-Id: Icaf26c17de32aaf63b985d69dd6902b1112a4a75
parent e9093b4f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -133,6 +133,7 @@ interface IUserManager {
    int getUserStatusBarIconResId(int userId);
    boolean hasBadge(int userId);
    int getProfileLabelResId(int userId);
    int getProfileAccessibilityLabelResId(int userId);
    boolean isUserUnlocked(int userId);
    boolean isUserRunning(int userId);
    boolean isUserForeground(int userId);
+38 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.os;

import static android.app.admin.DevicePolicyResources.Drawables.Style.SOLID_COLORED;
import static android.app.admin.DevicePolicyResources.Strings.Core.WORK_PROFILE_BADGED_LABEL;
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.STATUS_BAR_WORK_ICON_ACCESSIBILITY;
import static android.app.admin.DevicePolicyResources.UNDEFINED;

import android.Manifest;
@@ -5953,6 +5954,43 @@ public class UserManager {
        }
    }

    /**
     * Returns the string used to represent the profile associated with the given userId. This
     * string typically includes the profile name used by accessibility services like TalkBack.
     * @hide
     *
     * @return String representing the accessibility label for the given profile user.
     *
     * @throws android.content.res.Resources.NotFoundException if the user does not have a label
     * defined.
     */
    @UserHandleAware(
            requiresAnyOfPermissionsIfNotCallerProfileGroup = {
                    Manifest.permission.MANAGE_USERS,
                    Manifest.permission.QUERY_USERS,
                    Manifest.permission.INTERACT_ACROSS_USERS})
    public String getProfileAccessibilityString(int userId) {
        if (isManagedProfile(mUserId)) {
            DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
            dpm.getResources().getString(
                    STATUS_BAR_WORK_ICON_ACCESSIBILITY,
                    () -> getProfileAccessibilityLabel(userId));
        }
        return getProfileAccessibilityLabel(userId);
    }

    private String getProfileAccessibilityLabel(int userId) {
        try {
            final int resourceId = mService.getProfileAccessibilityLabelResId(userId);
            return Resources.getSystem().getString(resourceId);
        } catch (Resources.NotFoundException nfe) {
            Log.e(TAG, "Accessibility label not defined for user " + userId);
            throw nfe;
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * If the user is a {@link UserManager#isProfile profile}, checks if the user
     * shares media with its parent user (the user that created this profile).
+9 −0
Original line number Diff line number Diff line
@@ -6436,6 +6436,15 @@ ul.</string>
    <!-- Communal profile label on a screen. This can be used as a tab label for this profile in tabbed views and can be used to represent the profile in sharing surfaces, etc. [CHAR LIMIT=20] -->
    <string name="profile_label_communal">Communal</string>

    <!-- Accessibility label for managed profile user type [CHAR LIMIT=30] -->
    <string name="accessibility_label_managed_profile">Work profile</string>
    <!-- Accessibility label for private profile user type [CHAR LIMIT=30] -->
    <string name="accessibility_label_private_profile">Private space</string>
    <!-- Accessibility label for clone profile user type [CHAR LIMIT=30] -->
    <string name="accessibility_label_clone_profile">Clone</string>
    <!-- Accessibility label for clone profile user type [CHAR LIMIT=30] -->
    <string name="accessibility_label_communal_profile">Communal</string>

    <!-- Notification message used when a notification's normal message contains sensitive information [CHAR_LIMIT=NOTIF_BODY] -->
    <string name="redacted_notification_message">Sensitive notification content hidden</string>
    <!-- Notification action title used instead of a notification's normal title sensitive [CHAR_LIMIT=NOTIF_BODY] -->
+4 −0
Original line number Diff line number Diff line
@@ -1107,6 +1107,10 @@
  <java-symbol type="string" name="profile_label_work_3" />
  <java-symbol type="string" name="profile_label_test" />
  <java-symbol type="string" name="profile_label_communal" />
  <java-symbol type="string" name="accessibility_label_managed_profile" />
  <java-symbol type="string" name="accessibility_label_private_profile" />
  <java-symbol type="string" name="accessibility_label_clone_profile" />
  <java-symbol type="string" name="accessibility_label_communal_profile" />
  <java-symbol type="string" name="mediasize_unknown_portrait" />
  <java-symbol type="string" name="mediasize_unknown_landscape" />
  <java-symbol type="string" name="mediasize_iso_a0" />
+14 −3
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@ import android.view.View;

import androidx.lifecycle.Observer;

import com.android.systemui.res.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.dagger.qualifiers.Main;
@@ -56,6 +55,7 @@ import com.android.systemui.privacy.PrivacyType;
import com.android.systemui.privacy.logging.PrivacyLogger;
import com.android.systemui.qs.tiles.DndTile;
import com.android.systemui.qs.tiles.RotationLockTile;
import com.android.systemui.res.R;
import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.CommandQueue;
@@ -548,12 +548,23 @@ public class PhoneStatusBarPolicy
            try {
                final int userId = ActivityTaskManager.getService().getLastResumedActivityUserId();
                final int iconResId = mUserManager.getUserStatusBarIconResId(userId);
                // TODO(b/170249807, b/230779281): Handle non-managed-profile String
                String accessibilityString = getManagedProfileAccessibilityString();
                mMainExecutor.execute(() -> {
                    final boolean showIcon;
                    if (iconResId != Resources.ID_NULL && (!mKeyguardStateController.isShowing()
                            || mKeyguardStateController.isOccluded())) {
                        String accessibilityString = "";
                        if (android.os.Flags.allowPrivateProfile()
                                && android.multiuser.Flags.enablePrivateSpaceFeatures()) {
                            try {
                                accessibilityString =
                                        mUserManager.getProfileAccessibilityString(userId);
                            } catch (Resources.NotFoundException nfe) {
                                Log.e(TAG, "Accessibility string not found for userId:"
                                        + userId);
                            }
                        } else {
                            accessibilityString = getManagedProfileAccessibilityString();
                        }
                        showIcon = true;
                        mIconController.setIcon(mSlotManagedProfile,
                                iconResId,
Loading