diff options
149 files changed, 2622 insertions, 693 deletions
diff --git a/core/java/android/app/ActivityClient.java b/core/java/android/app/ActivityClient.java index 4cf48abc2ed3..324b8e7a784f 100644 --- a/core/java/android/app/ActivityClient.java +++ b/core/java/android/app/ActivityClient.java @@ -227,12 +227,13 @@ public class ActivityClient { } /** - * Returns the windowing mode of the task that hosts the activity, or {@code -1} if task is not - * found. + * Returns the {@link Configuration} of the task which hosts the Activity, or {@code null} if + * the task {@link Configuration} cannot be obtained. */ - public int getTaskWindowingMode(IBinder activityToken) { + @Nullable + public Configuration getTaskConfiguration(IBinder activityToken) { try { - return getActivityClientController().getTaskWindowingMode(activityToken); + return getActivityClientController().getTaskConfiguration(activityToken); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/IActivityClientController.aidl b/core/java/android/app/IActivityClientController.aidl index 62481ba8f251..8b655b9bf315 100644 --- a/core/java/android/app/IActivityClientController.aidl +++ b/core/java/android/app/IActivityClientController.aidl @@ -78,7 +78,11 @@ interface IActivityClientController { boolean willActivityBeVisible(in IBinder token); int getDisplayId(in IBinder activityToken); int getTaskForActivity(in IBinder token, in boolean onlyRoot); - int getTaskWindowingMode(in IBinder activityToken); + /** + * Returns the {@link Configuration} of the task which hosts the Activity, or {@code null} if + * the task {@link Configuration} cannot be obtained. + */ + Configuration getTaskConfiguration(in IBinder activityToken); IBinder getActivityTokenBelow(IBinder token); ComponentName getCallingActivity(in IBinder token); String getCallingPackage(in IBinder token); diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index fd45fca53722..ed59456e2281 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7776,6 +7776,13 @@ public final class Settings { "high_text_contrast_enabled"; /** + * The color contrast, float in [-1, 1], 1 being the highest contrast. + * + * @hide + */ + public static final String CONTRAST_LEVEL = "contrast_level"; + + /** * Setting that specifies whether the display magnification is enabled via a system-wide * triple tap gesture. Display magnifications allows the user to zoom in the display content * and is targeted to low vision users. The current magnification scale is controlled by diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java index fc526203beed..23167382ec3b 100644 --- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java @@ -17,18 +17,15 @@ package com.android.internal.app; import android.annotation.IntDef; import android.annotation.Nullable; +import android.annotation.NonNull; +import android.annotation.UserIdInt; import android.app.AppGlobals; -import android.app.admin.DevicePolicyEventLogger; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.IPackageManager; -import android.content.pm.ResolveInfo; -import android.os.AsyncTask; import android.os.Trace; import android.os.UserHandle; -import android.os.UserManager; -import android.stats.devicepolicy.DevicePolicyEnums; import android.view.View; import android.view.ViewGroup; import android.widget.Button; @@ -60,73 +57,31 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { private final Context mContext; private int mCurrentPage; private OnProfileSelectedListener mOnProfileSelectedListener; - private OnSwitchOnWorkSelectedListener mOnSwitchOnWorkSelectedListener; private Set<Integer> mLoadedPages; - private final UserHandle mPersonalProfileUserHandle; + private final EmptyStateProvider mEmptyStateProvider; private final UserHandle mWorkProfileUserHandle; - private Injector mInjector; - private boolean mIsWaitingToEnableWorkProfile; + private final QuietModeManager mQuietModeManager; AbstractMultiProfilePagerAdapter(Context context, int currentPage, - UserHandle personalProfileUserHandle, + EmptyStateProvider emptyStateProvider, + QuietModeManager quietModeManager, UserHandle workProfileUserHandle) { mContext = Objects.requireNonNull(context); mCurrentPage = currentPage; mLoadedPages = new HashSet<>(); - mPersonalProfileUserHandle = personalProfileUserHandle; mWorkProfileUserHandle = workProfileUserHandle; - UserManager userManager = context.getSystemService(UserManager.class); - mInjector = new Injector() { - @Override - public boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId, - int targetUserId) { - return AbstractMultiProfilePagerAdapter.this - .hasCrossProfileIntents(intents, sourceUserId, targetUserId); - } - - @Override - public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { - return userManager.isQuietModeEnabled(workProfileUserHandle); - } - - @Override - public void requestQuietModeEnabled(boolean enabled, UserHandle workProfileUserHandle) { - AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> { - userManager.requestQuietModeEnabled(enabled, workProfileUserHandle); - }); - mIsWaitingToEnableWorkProfile = true; - } - }; - } - - protected void markWorkProfileEnabledBroadcastReceived() { - mIsWaitingToEnableWorkProfile = false; - } - - protected boolean isWaitingToEnableWorkProfile() { - return mIsWaitingToEnableWorkProfile; - } - - /** - * Overrides the default {@link Injector} for testing purposes. - */ - @VisibleForTesting - public void setInjector(Injector injector) { - mInjector = injector; + mEmptyStateProvider = emptyStateProvider; + mQuietModeManager = quietModeManager; } - protected boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { - return mInjector.isQuietModeEnabled(workProfileUserHandle); + private boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { + return mQuietModeManager.isQuietModeEnabled(workProfileUserHandle); } void setOnProfileSelectedListener(OnProfileSelectedListener listener) { mOnProfileSelectedListener = listener; } - void setOnSwitchOnWorkSelectedListener(OnSwitchOnWorkSelectedListener listener) { - mOnSwitchOnWorkSelectedListener = listener; - } - Context getContext() { return mContext; } @@ -280,8 +235,6 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { abstract @Nullable ViewGroup getInactiveAdapterView(); - abstract String getMetricsCategory(); - /** * Rebuilds the tab that is currently visible to the user. * <p>Returns {@code true} if rebuild has completed. @@ -317,41 +270,18 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { } private boolean rebuildTab(ResolverListAdapter activeListAdapter, boolean doPostProcessing) { - if (shouldShowNoCrossProfileIntentsEmptyState(activeListAdapter)) { + if (shouldSkipRebuild(activeListAdapter)) { activeListAdapter.postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ true); return false; } return activeListAdapter.rebuildList(doPostProcessing); } - private boolean shouldShowNoCrossProfileIntentsEmptyState( - ResolverListAdapter activeListAdapter) { - UserHandle listUserHandle = activeListAdapter.getUserHandle(); - return UserHandle.myUserId() != listUserHandle.getIdentifier() - && allowShowNoCrossProfileIntentsEmptyState() - && !mInjector.hasCrossProfileIntents(activeListAdapter.getIntents(), - UserHandle.myUserId(), listUserHandle.getIdentifier()); - } - - boolean allowShowNoCrossProfileIntentsEmptyState() { - return true; + private boolean shouldSkipRebuild(ResolverListAdapter activeListAdapter) { + EmptyState emptyState = mEmptyStateProvider.getEmptyState(activeListAdapter); + return emptyState != null && emptyState.shouldSkipDataRebuild(); } - protected abstract void showWorkProfileOffEmptyState( - ResolverListAdapter activeListAdapter, View.OnClickListener listener); - - protected abstract void showNoPersonalToWorkIntentsEmptyState( - ResolverListAdapter activeListAdapter); - - protected abstract void showNoPersonalAppsAvailableEmptyState( - ResolverListAdapter activeListAdapter); - - protected abstract void showNoWorkAppsAvailableEmptyState( - ResolverListAdapter activeListAdapter); - - protected abstract void showNoWorkToPersonalIntentsEmptyState( - ResolverListAdapter activeListAdapter); - /** * The empty state screens are shown according to their priority: * <ol> @@ -366,103 +296,88 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { * anyway. */ void showEmptyResolverListEmptyState(ResolverListAdapter listAdapter) { - if (maybeShowNoCrossProfileIntentsEmptyState(listAdapter)) { + final EmptyState emptyState = mEmptyStateProvider.getEmptyState(listAdapter); + + if (emptyState == null) { return; } - if (maybeShowWorkProfileOffEmptyState(listAdapter)) { - return; + + emptyState.onEmptyStateShown(); + + View.OnClickListener clickListener = null; + + if (emptyState.getButtonClickListener() != null) { + clickListener = v -> emptyState.getButtonClickListener().onClick(() -> { + ProfileDescriptor descriptor = getItem( + userHandleToPageIndex(listAdapter.getUserHandle())); + AbstractMultiProfilePagerAdapter.this.showSpinner(descriptor.getEmptyStateView()); + }); } - maybeShowNoAppsAvailableEmptyState(listAdapter); + + showEmptyState(listAdapter, emptyState, clickListener); } - private boolean maybeShowNoCrossProfileIntentsEmptyState(ResolverListAdapter listAdapter) { - if (!shouldShowNoCrossProfileIntentsEmptyState(listAdapter)) { - return false; - } - if (listAdapter.getUserHandle().equals(mPersonalProfileUserHandle)) { - DevicePolicyEventLogger.createEvent( - DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL) - .setStrings(getMetricsCategory()) - .write(); - showNoWorkToPersonalIntentsEmptyState(listAdapter); - } else { - DevicePolicyEventLogger.createEvent( - DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK) - .setStrings(getMetricsCategory()) - .write(); - showNoPersonalToWorkIntentsEmptyState(listAdapter); + /** + * Class to get user id of the current process + */ + public static class MyUserIdProvider { + /** + * @return user id of the current process + */ + public int getMyUserId() { + return UserHandle.myUserId(); } - return true; } /** - * Returns {@code true} if the work profile off empty state screen is shown. + * Utility class to check if there are cross profile intents, it is in a separate class so + * it could be mocked in tests */ - private boolean maybeShowWorkProfileOffEmptyState(ResolverListAdapter listAdapter) { - UserHandle listUserHandle = listAdapter.getUserHandle(); - if (!listUserHandle.equals(mWorkProfileUserHandle) - || !mInjector.isQuietModeEnabled(mWorkProfileUserHandle) - || listAdapter.getCount() == 0) { - return false; - } - DevicePolicyEventLogger - .createEvent(DevicePolicyEnums.RESOLVER_EMPTY_STATE_WORK_APPS_DISABLED) - .setStrings(getMetricsCategory()) - .write(); - showWorkProfileOffEmptyState(listAdapter, - v -> { - ProfileDescriptor descriptor = getItem( - userHandleToPageIndex(listAdapter.getUserHandle())); - showSpinner(descriptor.getEmptyStateView()); - if (mOnSwitchOnWorkSelectedListener != null) { - mOnSwitchOnWorkSelectedListener.onSwitchOnWorkSelected(); - } - mInjector.requestQuietModeEnabled(false, mWorkProfileUserHandle); - }); - return true; - } - - private void maybeShowNoAppsAvailableEmptyState(ResolverListAdapter listAdapter) { - UserHandle listUserHandle = listAdapter.getUserHandle(); - if (mWorkProfileUserHandle != null - && (UserHandle.myUserId() == listUserHandle.getIdentifier() - || !hasAppsInOtherProfile(listAdapter))) { - DevicePolicyEventLogger.createEvent( - DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_APPS_RESOLVED) - .setStrings(getMetricsCategory()) - .setBoolean(/*isPersonalProfile*/ listUserHandle == mPersonalProfileUserHandle) - .write(); - if (listUserHandle == mPersonalProfileUserHandle) { - showNoPersonalAppsAvailableEmptyState(listAdapter); - } else { - showNoWorkAppsAvailableEmptyState(listAdapter); - } - } else if (mWorkProfileUserHandle == null) { - showConsumerUserNoAppsAvailableEmptyState(listAdapter); + public static class CrossProfileIntentsChecker { + + private final ContentResolver mContentResolver; + + public CrossProfileIntentsChecker(@NonNull ContentResolver contentResolver) { + mContentResolver = contentResolver; } - } - protected void showEmptyState(ResolverListAdapter activeListAdapter, String title, - String subtitle) { - showEmptyState(activeListAdapter, title, subtitle, /* buttonOnClick */ null); + /** + * Returns {@code true} if at least one of the provided {@code intents} can be forwarded + * from {@code source} (user id) to {@code target} (user id). + */ + public boolean hasCrossProfileIntents(List<Intent> intents, @UserIdInt int source, + @UserIdInt int target) { + IPackageManager packageManager = AppGlobals.getPackageManager(); + + return intents.stream().anyMatch(intent -> + null != IntentForwarderActivity.canForward(intent, source, target, + packageManager, mContentResolver)); + } } - protected void showEmptyState(ResolverListAdapter activeListAdapter, - String title, String subtitle, View.OnClickListener buttonOnClick) { + protected void showEmptyState(ResolverListAdapter activeListAdapter, EmptyState emptyState, + View.OnClickListener buttonOnClick) { ProfileDescriptor descriptor = getItem( userHandleToPageIndex(activeListAdapter.getUserHandle())); descriptor.rootView.findViewById(R.id.resolver_list).setVisibility(View.GONE); ViewGroup emptyStateView = descriptor.getEmptyStateView(); - resetViewVisibilitiesForWorkProfileEmptyState(emptyStateView); + resetViewVisibilitiesForEmptyState(emptyStateView); emptyStateView.setVisibility(View.VISIBLE); View container = emptyStateView.findViewById(R.id.resolver_empty_state_container); setupContainerPadding(container); TextView titleView = emptyStateView.findViewById(R.id.resolver_empty_state_title); - titleView.setText(title); + String title = emptyState.getTitle(); + if (title != null) { + titleView.setVisibility(View.VISIBLE); + titleView.setText(title); + } else { + titleView.setVisibility(View.GONE); + } TextView subtitleView = emptyStateView.findViewById(R.id.resolver_empty_state_subtitle); + String subtitle = emptyState.getSubtitle(); if (subtitle != null) { subtitleView.setVisibility(View.VISIBLE); subtitleView.setText(subtitle); @@ -470,6 +385,9 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { subtitleView.setVisibility(View.GONE); } + View defaultEmptyText = emptyStateView.findViewById(R.id.empty); + defaultEmptyText.setVisibility(emptyState.useDefaultEmptyView() ? View.VISIBLE : View.GONE); + Button button = emptyStateView.findViewById(R.id.resolver_empty_state_button); button.setVisibility(buttonOnClick != null ? View.VISIBLE : View.GONE); button.setOnClickListener(buttonOnClick); @@ -483,22 +401,6 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { */ protected void setupContainerPadding(View container) {} - private void showConsumerUserNoAppsAvailableEmptyState(ResolverListAdapter activeListAdapter) { - ProfileDescriptor descriptor = getItem( - userHandleToPageIndex(activeListAdapter.getUserHandle())); - descriptor.rootView.findViewById(R.id.resolver_list).setVisibility(View.GONE); - View emptyStateView = descriptor.getEmptyStateView(); - resetViewVisibilitiesForConsumerUserEmptyState(emptyStateView); - emptyStateView.setVisibility(View.VISIBLE); - - activeListAdapter.markTabLoaded(); - } - - private boolean isSpinnerShowing(View emptyStateView) { - return emptyStateView.findViewById(R.id.resolver_empty_state_progress).getVisibility() - == View.VISIBLE; - } - private void showSpinner(View emptyStateView) { emptyStateView.findViewById(R.id.resolver_empty_state_title).setVisibility(View.INVISIBLE); emptyStateView.findViewById(R.id.resolver_empty_state_button).setVisibility(View.INVISIBLE); @@ -506,7 +408,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { emptyStateView.findViewById(R.id.empty).setVisibility(View.GONE); } - private void resetViewVisibilitiesForWorkProfileEmptyState(View emptyStateView) { + private void resetViewVisibilitiesForEmptyState(View emptyStateView) { emptyStateView.findViewById(R.id.resolver_empty_state_title).setVisibility(View.VISIBLE); emptyStateView.findViewById(R.id.resolver_empty_state_subtitle).setVisibility(View.VISIBLE); emptyStateView.findViewById(R.id.resolver_empty_state_button).setVisibility(View.INVISIBLE); @@ -514,14 +416,6 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { emptyStateView.findViewById(R.id.empty).setVisibility(View.GONE); } - private void resetViewVisibilitiesForConsumerUserEmptyState(View emptyStateView) { - emptyStateView.findViewById(R.id.resolver_empty_state_title).setVisibility(View.GONE); - emptyStateView.findViewById(R.id.resolver_empty_state_subtitle).setVisibility(View.GONE); - emptyStateView.findViewById(R.id.resolver_empty_state_button).setVisibility(View.GONE); - emptyStateView.findViewById(R.id.resolver_empty_state_progress).setVisibility(View.GONE); - emptyStateView.findViewById(R.id.empty).setVisibility(View.VISIBLE); - } - protected void showListView(ResolverListAdapter activeListAdapter) { ProfileDescriptor descriptor = getItem( userHandleToPageIndex(activeListAdapter.getUserHandle())); @@ -530,33 +424,6 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { emptyStateView.setVisibility(View.GONE); } - private boolean hasCrossProfileIntents(List<Intent> intents, int source, int target) { - IPackageManager packageManager = AppGlobals.getPackageManager(); - ContentResolver contentResolver = mContext.getContentResolver(); - for (Intent intent : intents) { - if (IntentForwarderActivity.canForward(intent, source, target, packageManager, - contentResolver) != null) { - return true; - } - } - return false; - } - - private boolean hasAppsInOtherProfile(ResolverListAdapter adapter) { - if (mWorkProfileUserHandle == null) { - return false; - } - List<ResolverActivity.ResolvedComponentInfo> resolversForIntent = - adapter.getResolversForUser(UserHandle.of(UserHandle.myUserId())); - for (ResolverActivity.ResolvedComponentInfo info : resolversForIntent) { - ResolveInfo resolveInfo = info.getResolveInfoAt(0); - if (resolveInfo.targetUserId != UserHandle.USER_CURRENT) { - return true; - } - } - return false; - } - boolean shouldShowEmptyStateScreen(ResolverListAdapter listAdapter) { int count = listAdapter.getUnfilteredCount(); return (count == 0 && listAdapter.getPlaceholderCount() == 0) @@ -600,6 +467,98 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { } /** + * Returns an empty state to show for the current profile page (tab) if necessary. + * This could be used e.g. to show a blocker on a tab if device management policy doesn't + * allow to use it or there are no apps available. + */ + public interface EmptyStateProvider { + /** + * When a non-null empty state is returned the corresponding profile page will show + * this empty state + * @param resolverListAdapter the current adapter + */ + @Nullable + default EmptyState getEmptyState(ResolverListAdapter resolverListAdapter) { + return null; + } + } + + /** + * Empty state provider that combines multiple providers. Providers earlier in the list have + * priority, that is if there is a provider that returns non-null empty state then all further + * providers will be ignored. + */ + public static class CompositeEmptyStateProvider implements EmptyStateProvider { + + private final EmptyStateProvider[] mProviders; + + public CompositeEmptyStateProvider(EmptyStateProvider... providers) { + mProviders = providers; + } + + @Nullable + @Override + public EmptyState getEmptyState(ResolverListAdapter resolverListAdapter) { + for (EmptyStateProvider provider : mProviders) { + EmptyState emptyState = provider.getEmptyState(resolverListAdapter); + if (emptyState != null) { + return emptyState; + } + } + return null; + } + } + + /** + * Describes how the blocked empty state should look like for a profile tab + */ + public interface EmptyState { + /** + * Title that will be shown on the empty state + */ + @Nullable + default String getTitle() { return null; } + + /** + * Subtitle that will be shown underneath the title on the empty state + */ + @Nullable + default String getSubtitle() { return null; } + + /** + * If non-null then a button will be shown and this listener will be called + * when the button is clicked + */ + @Nullable + default ClickListener getButtonClickListener() { return null; } + + /** + * If true then default text ('No apps can perform this action') and style for the empty + * state will be applied, title and subtitle will be ignored. + */ + default boolean useDefaultEmptyView() { return false; } + + /** + * Returns true if for this empty state we should skip rebuilding of the apps list + * for this tab. + */ + default boolean shouldSkipDataRebuild() { return false; } + + /** + * Called when empty state is shown, could be used e.g. to track analytics events + */ + default void onEmptyStateShown() {} + + interface ClickListener { + void onClick(TabControl currentTab); + } + + interface TabControl { + void showSpinner(); + } + } + + /** * Listener for when the user switches on the work profile from the work tab. */ interface OnSwitchOnWorkSelectedListener { @@ -612,14 +571,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { /** * Describes an injector to be used for cross profile functionality. Overridable for testing. */ - @VisibleForTesting - public interface Injector { - /** - * Returns {@code true} if at least one of the provided {@code intents} can be forwarded - * from {@code sourceUserId} to {@code targetUserId}. - */ - boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId, int targetUserId); - + public interface QuietModeManager { /** * Returns whether the given profile is in quiet mode or not. */ @@ -629,5 +581,15 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { * Enables or disables quiet mode for a managed profile. */ void requestQuietModeEnabled(boolean enabled, UserHandle workProfileUserHandle); + + /** + * Should be called when the work profile enabled broadcast received + */ + void markWorkProfileEnabledBroadcastReceived(); + + /** + * Returns true if enabling of work profile is in progress + */ + boolean isWaitingToEnableWorkProfile(); } }
\ No newline at end of file diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 2676396cb997..1fcfe7dd5b6f 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -16,6 +16,14 @@ package com.android.internal.app; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_PERSONAL; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_WORK; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_PERSONAL; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_WORK; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROSS_PROFILE_BLOCKED_TITLE; +import static android.stats.devicepolicy.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL; +import static android.stats.devicepolicy.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK; + import static com.android.internal.util.LatencyTracker.ACTION_LOAD_SHARE_SHEET; import static java.lang.annotation.RetentionPolicy.SOURCE; @@ -114,6 +122,9 @@ import android.widget.TextView; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyState; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider; +import com.android.internal.app.NoCrossProfileEmptyStateProvider.DevicePolicyBlockerEmptyState; import com.android.internal.app.ResolverListAdapter.ActivityInfoPresentationGetter; import com.android.internal.app.ResolverListAdapter.ViewHolder; import com.android.internal.app.chooser.ChooserTargetInfo; @@ -830,6 +841,41 @@ public class ChooserActivity extends ResolverActivity implements return mChooserMultiProfilePagerAdapter; } + @Override + protected EmptyStateProvider createBlockerEmptyStateProvider() { + final boolean isSendAction = isSendAction(getTargetIntent()); + + final EmptyState noWorkToPersonalEmptyState = + new DevicePolicyBlockerEmptyState( + /* context= */ this, + /* devicePolicyStringTitleId= */ RESOLVER_CROSS_PROFILE_BLOCKED_TITLE, + /* defaultTitleResource= */ R.string.resolver_cross_profile_blocked, + /* devicePolicyStringSubtitleId= */ + isSendAction ? RESOLVER_CANT_SHARE_WITH_PERSONAL : RESOLVER_CANT_ACCESS_PERSONAL, + /* defaultSubtitleResource= */ + isSendAction ? R.string.resolver_cant_share_with_personal_apps_explanation + : R.string.resolver_cant_access_personal_apps_explanation, + /* devicePolicyEventId= */ RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL, + /* devicePolicyEventCategory= */ ResolverActivity.METRICS_CATEGORY_CHOOSER); + + final EmptyState noPersonalToWorkEmptyState = + new DevicePolicyBlockerEmptyState( + /* context= */ this, + /* devicePolicyStringTitleId= */ RESOLVER_CROSS_PROFILE_BLOCKED_TITLE, + /* defaultTitleResource= */ R.string.resolver_cross_profile_blocked, + /* devicePolicyStringSubtitleId= */ + isSendAction ? RESOLVER_CANT_SHARE_WITH_WORK : RESOLVER_CANT_ACCESS_WORK, + /* defaultSubtitleResource= */ + isSendAction ? R.string.resolver_cant_share_with_work_apps_explanation + : R.string.resolver_cant_access_work_apps_explanation, + /* devicePolicyEventId= */ RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK, + /* devicePolicyEventCategory= */ ResolverActivity.METRICS_CATEGORY_CHOOSER); + + return new NoCrossProfileEmptyStateProvider(getPersonalProfileUserHandle(), + noWorkToPersonalEmptyState, noPersonalToWorkEmptyState, + createCrossProfileIntentsChecker(), createMyUserIdProvider()); + } + private ChooserMultiProfilePagerAdapter createChooserMultiProfilePagerAdapterForOneProfile( Intent[] initialIntents, List<ResolveInfo> rList, @@ -844,9 +890,10 @@ public class ChooserActivity extends ResolverActivity implements return new ChooserMultiProfilePagerAdapter( /* context */ this, adapter, - getPersonalProfileUserHandle(), + createEmptyStateProvider(/* workProfileUserHandle= */ null), + mQuietModeManager, /* workProfileUserHandle= */ null, - isSendAction(getTargetIntent()), mMaxTargetsPerRow); + mMaxTargetsPerRow); } private ChooserMultiProfilePagerAdapter createChooserMultiProfilePagerAdapterForTwoProfiles( @@ -872,10 +919,11 @@ public class ChooserActivity extends ResolverActivity implements /* context */ this, personalAdapter, workAdapter, + createEmptyStateProvider(/* workProfileUserHandle= */ getWorkProfileUserHandle()), + mQuietModeManager, selectedProfile, - getPersonalProfileUserHandle(), getWorkProfileUserHandle(), - isSendAction(getTargetIntent()), mMaxTargetsPerRow); + mMaxTargetsPerRow); } private int findSelectedProfile() { diff --git a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java index df1130be5ec6..0509b6754218 100644 --- a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java @@ -16,17 +16,7 @@ package com.android.internal.app; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_PERSONAL; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_WORK; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_PERSONAL; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_WORK; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROSS_PROFILE_BLOCKED_TITLE; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_NO_PERSONAL_APPS; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_NO_WORK_APPS; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_WORK_PAUSED_TITLE; - import android.annotation.Nullable; -import android.app.admin.DevicePolicyManager; import android.content.Context; import android.os.UserHandle; import android.view.LayoutInflater; @@ -47,37 +37,37 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd private static final int SINGLE_CELL_SPAN_SIZE = 1; private final ChooserProfileDescriptor[] mItems; - private final boolean mIsSendAction; private int mBottomOffset; private int mMaxTargetsPerRow; ChooserMultiProfilePagerAdapter(Context context, ChooserActivity.ChooserGridAdapter adapter, - UserHandle personalProfileUserHandle, + EmptyStateProvider emptyStateProvider, + QuietModeManager quietModeManager, UserHandle workProfileUserHandle, - boolean isSendAction, int maxTargetsPerRow) { - super(context, /* currentPage */ 0, personalProfileUserHandle, workProfileUserHandle); + int maxTargetsPerRow) { + super(context, /* currentPage */ 0, emptyStateProvider, quietModeManager, + workProfileUserHandle); mItems = new ChooserProfileDescriptor[] { createProfileDescriptor(adapter) }; - mIsSendAction = isSendAction; mMaxTargetsPerRow = maxTargetsPerRow; } ChooserMultiProfilePagerAdapter(Context context, ChooserActivity.ChooserGridAdapter personalAdapter, ChooserActivity.ChooserGridAdapter workAdapter, + EmptyStateProvider emptyStateProvider, + QuietModeManager quietModeManager, @Profile int defaultProfile, - UserHandle personalProfileUserHandle, UserHandle workProfileUserHandle, - boolean isSendAction, int maxTargetsPerRow) { - super(context, /* currentPage */ defaultProfile, personalProfileUserHandle, - workProfileUserHandle); + int maxTargetsPerRow) { + super(context, /* currentPage */ defaultProfile, emptyStateProvider, + quietModeManager, workProfileUserHandle); mItems = new ChooserProfileDescriptor[] { createProfileDescriptor(personalAdapter), createProfileDescriptor(workAdapter) }; - mIsSendAction = isSendAction; mMaxTargetsPerRow = maxTargetsPerRow; } @@ -192,112 +182,6 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd return getListViewForIndex(1 - getCurrentPage()); } - @Override - String getMetricsCategory() { - return ResolverActivity.METRICS_CATEGORY_CHOOSER; - } - - @Override - protected void showWorkProfileOffEmptyState(ResolverListAdapter activeListAdapter, - View.OnClickListener listener) { - showEmptyState(activeListAdapter, - getWorkAppPausedTitle(), - /* subtitle = */ null, - listener); - } - - @Override - protected void showNoPersonalToWorkIntentsEmptyState(ResolverListAdapter activeListAdapter) { - if (mIsSendAction) { - showEmptyState(activeListAdapter, - getCrossProfileBlockedTitle(), - getCantShareWithWorkMessage()); - } else { - showEmptyState(activeListAdapter, - getCrossProfileBlockedTitle(), - getCantAccessWorkMessage()); - } - } - - @Override - protected void showNoWorkToPersonalIntentsEmptyState(ResolverListAdapter activeListAdapter) { - if (mIsSendAction) { - showEmptyState(activeListAdapter, - getCrossProfileBlockedTitle(), - getCantShareWithPersonalMessage()); - } else { - showEmptyState(activeListAdapter, - getCrossProfileBlockedTitle(), - getCantAccessPersonalMessage()); - } - } - - @Override - protected void showNoPersonalAppsAvailableEmptyState(ResolverListAdapter listAdapter) { - showEmptyState(listAdapter, getNoPersonalAppsAvailableMessage(), /* subtitle= */ null); - - } - - @Override - protected void showNoWorkAppsAvailableEmptyState(ResolverListAdapter listAdapter) { - showEmptyState(listAdapter, getNoWorkAppsAvailableMessage(), /* subtitle = */ null); - } - - private String getWorkAppPausedTitle() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_WORK_PAUSED_TITLE, - () -> getContext().getString(R.string.resolver_turn_on_work_apps)); - } - - private String getCrossProfileBlockedTitle() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CROSS_PROFILE_BLOCKED_TITLE, - () -> getContext().getString(R.string.resolver_cross_profile_blocked)); - } - - private String getCantShareWithWorkMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CANT_SHARE_WITH_WORK, - () -> getContext().getString( - R.string.resolver_cant_share_with_work_apps_explanation)); - } - - private String getCantShareWithPersonalMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CANT_SHARE_WITH_PERSONAL, - () -> getContext().getString( - R.string.resolver_cant_share_with_personal_apps_explanation)); - } - - private String getCantAccessWorkMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CANT_ACCESS_WORK, - () -> getContext().getString( - R.string.resolver_cant_access_work_apps_explanation)); - } - - private String getCantAccessPersonalMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CANT_ACCESS_PERSONAL, - () -> getContext().getString( - R.string.resolver_cant_access_personal_apps_explanation)); - } - - private String getNoWorkAppsAvailableMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_NO_WORK_APPS, - () -> getContext().getString( - R.string.resolver_no_work_apps_available)); - } - - private String getNoPersonalAppsAvailableMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_NO_PERSONAL_APPS, - () -> getContext().getString( - R.string.resolver_no_personal_apps_available)); - } - - void setEmptyStateBottomOffset(int bottomOffset) { mBottomOffset = bottomOffset; } diff --git a/core/java/com/android/internal/app/NoAppsAvailableEmptyStateProvider.java b/core/java/com/android/internal/app/NoAppsAvailableEmptyStateProvider.java new file mode 100644 index 000000000000..34249f2457c7 --- /dev/null +++ b/core/java/com/android/internal/app/NoAppsAvailableEmptyStateProvider.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2022 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 com.android.internal.app; + +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_NO_PERSONAL_APPS; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_NO_WORK_APPS; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.app.admin.DevicePolicyEventLogger; +import android.app.admin.DevicePolicyManager; +import android.content.Context; +import android.content.pm.ResolveInfo; +import android.os.UserHandle; +import android.stats.devicepolicy.nano.DevicePolicyEnums; + +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyState; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider; +import com.android.internal.R; + +import java.util.List; + +/** + * Chooser/ResolverActivity empty state provider that returns empty state which is shown when + * there are no apps available. + */ +public class NoAppsAvailableEmptyStateProvider implements EmptyStateProvider { + + @NonNull + private final Context mContext; + @Nullable + private final UserHandle mWorkProfileUserHandle; + @Nullable + private final UserHandle mPersonalProfileUserHandle; + @NonNull + private final String mMetricsCategory; + @NonNull + private final MyUserIdProvider mMyUserIdProvider; + + public NoAppsAvailableEmptyStateProvider(Context context, UserHandle workProfileUserHandle, + UserHandle personalProfileUserHandle, String metricsCategory, + MyUserIdProvider myUserIdProvider) { + mContext = context; + mWorkProfileUserHandle = workProfileUserHandle; + mPersonalProfileUserHandle = personalProfileUserHandle; + mMetricsCategory = metricsCategory; + mMyUserIdProvider = myUserIdProvider; + } + + @Nullable + @Override + @SuppressWarnings("ReferenceEquality") + public EmptyState getEmptyState(ResolverListAdapter resolverListAdapter) { + UserHandle listUserHandle = resolverListAdapter.getUserHandle(); + + if (mWorkProfileUserHandle != null + && (mMyUserIdProvider.getMyUserId() == listUserHandle.getIdentifier() + || !hasAppsInOtherProfile(resolverListAdapter))) { + + String title; + if (listUserHandle == mPersonalProfileUserHandle) { + title = mContext.getSystemService( + DevicePolicyManager.class).getResources().getString( + RESOLVER_NO_PERSONAL_APPS, + () -> mContext.getString(R.string.resolver_no_personal_apps_available)); + } else { + title = mContext.getSystemService( + DevicePolicyManager.class).getResources().getString( + RESOLVER_NO_WORK_APPS, + () -> mContext.getString(R.string.resolver_no_work_apps_available)); + } + + return new NoAppsAvailableEmptyState( + title, mMetricsCategory, + /* isPersonalProfile= */ listUserHandle == mPersonalProfileUserHandle + ); + } else if (mWorkProfileUserHandle == null) { + // Return default empty state without tracking + return new DefaultEmptyState(); + } + + return null; + } + + private boolean hasAppsInOtherProfile(ResolverListAdapter adapter) { + if (mWorkProfileUserHandle == null) { + return false; + } + List<ResolverActivity.ResolvedComponentInfo> resolversForIntent = + adapter.getResolversForUser(UserHandle.of(mMyUserIdProvider.getMyUserId())); + for (ResolverActivity.ResolvedComponentInfo info : resolversForIntent) { + ResolveInfo resolveInfo = info.getResolveInfoAt(0); + if (resolveInfo.targetUserId != UserHandle.USER_CURRENT) { + return true; + } + } + return false; + } + + public static class DefaultEmptyState implements EmptyState { + @Override + public boolean useDefaultEmptyView() { + return true; + } + } + + public static class NoAppsAvailableEmptyState implements EmptyState { + + @NonNull + private String mTitle; + + @NonNull + private String mMetricsCategory; + + private boolean mIsPersonalProfile; + + public NoAppsAvailableEmptyState(String title, String metricsCategory, + boolean isPersonalProfile) { + mTitle = title; + mMetricsCategory = metricsCategory; + mIsPersonalProfile = isPersonalProfile; + } + + @Nullable + @Override + public String getTitle() { + return mTitle; + } + + @Override + public void onEmptyStateShown() { + DevicePolicyEventLogger.createEvent( + DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_APPS_RESOLVED) + .setStrings(mMetricsCategory) + .setBoolean(/*isPersonalProfile*/ mIsPersonalProfile) + .write(); + } + } +}
\ No newline at end of file diff --git a/core/java/com/android/internal/app/NoCrossProfileEmptyStateProvider.java b/core/java/com/android/internal/app/NoCrossProfileEmptyStateProvider.java new file mode 100644 index 000000000000..2e7d5bf00e27 --- /dev/null +++ b/core/java/com/android/internal/app/NoCrossProfileEmptyStateProvider.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2022 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 com.android.internal.app; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.StringRes; +import android.app.admin.DevicePolicyEventLogger; +import android.app.admin.DevicePolicyManager; +import android.content.Context; +import android.os.UserHandle; + +import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyState; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider; + +/** + * Empty state provider that does not allow cross profile sharing, it will return a blocker + * in case if the profile of the current tab is not the same as the profile of the calling app. + */ +public class NoCrossProfileEmptyStateProvider implements EmptyStateProvider { + + private final UserHandle mPersonalProfileUserHandle; + private final EmptyState mNoWorkToPersonalEmptyState; + private final EmptyState mNoPersonalToWorkEmptyState; + private final CrossProfileIntentsChecker mCrossProfileIntentsChecker; + private final MyUserIdProvider mUserIdProvider; + + public NoCrossProfileEmptyStateProvider(UserHandle personalUserHandle, + EmptyState noWorkToPersonalEmptyState, + EmptyState noPersonalToWorkEmptyState, + CrossProfileIntentsChecker crossProfileIntentsChecker, + MyUserIdProvider myUserIdProvider) { + mPersonalProfileUserHandle = personalUserHandle; + mNoWorkToPersonalEmptyState = noWorkToPersonalEmptyState; + mNoPersonalToWorkEmptyState = noPersonalToWorkEmptyState; + mCrossProfileIntentsChecker = crossProfileIntentsChecker; + mUserIdProvider = myUserIdProvider; + } + + @Nullable + @Override + public EmptyState getEmptyState(ResolverListAdapter resolverListAdapter) { + boolean shouldShowBlocker = + mUserIdProvider.getMyUserId() != resolverListAdapter.getUserHandle().getIdentifier() + && !mCrossProfileIntentsChecker + .hasCrossProfileIntents(resolverListAdapter.getIntents(), + mUserIdProvider.getMyUserId(), + resolverListAdapter.getUserHandle().getIdentifier()); + + if (!shouldShowBlocker) { + return null; + } + + if (resolverListAdapter.getUserHandle().equals(mPersonalProfileUserHandle)) { + return mNoWorkToPersonalEmptyState; + } else { + return mNoPersonalToWorkEmptyState; + } + } + + + /** + * Empty state that gets strings from the device policy manager and tracks events into + * event logger of the device policy events. + */ + public static class DevicePolicyBlockerEmptyState implements EmptyState { + + @NonNull + private final Context mContext; + private final String mDevicePolicyStringTitleId; + @StringRes + private final int mDefaultTitleResource; + private final String mDevicePolicyStringSubtitleId; + @StringRes + private final int mDefaultSubtitleResource; + private final int mEventId; + @NonNull + private final String mEventCategory; + + public DevicePolicyBlockerEmptyState(Context context, String devicePolicyStringTitleId, + @StringRes int defaultTitleResource, String devicePolicyStringSubtitleId, + @StringRes int defaultSubtitleResource, + int devicePolicyEventId, String devicePolicyEventCategory) { + mContext = context; + mDevicePolicyStringTitleId = devicePolicyStringTitleId; + mDefaultTitleResource = defaultTitleResource; + mDevicePolicyStringSubtitleId = devicePolicyStringSubtitleId; + mDefaultSubtitleResource = defaultSubtitleResource; + mEventId = devicePolicyEventId; + mEventCategory = devicePolicyEventCategory; + } + + @Nullable + @Override + public String getTitle() { + return mContext.getSystemService(DevicePolicyManager.class).getResources().getString( + mDevicePolicyStringTitleId, + () -> mContext.getString(mDefaultTitleResource)); + } + + @Nullable + @Override + public String getSubtitle() { + return mContext.getSystemService(DevicePolicyManager.class).getResources().getString( + mDevicePolicyStringSubtitleId, + () -> mContext.getString(mDefaultSubtitleResource)); + } + + @Override + public void onEmptyStateShown() { + DevicePolicyEventLogger.createEvent(mEventId) + .setStrings(mEventCategory) + .write(); + } + + @Override + public boolean shouldSkipDataRebuild() { + return true; + } + } +} diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 5dfabcdb2af6..f8b764be582b 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -19,6 +19,9 @@ package com.android.internal.app; import static android.Manifest.permission.INTERACT_ACROSS_PROFILES; import static android.app.admin.DevicePolicyResources.Strings.Core.FORWARD_INTENT_TO_PERSONAL; import static android.app.admin.DevicePolicyResources.Strings.Core.FORWARD_INTENT_TO_WORK; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_PERSONAL; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_WORK; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROSS_PROFILE_BLOCKED_TITLE; import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_PERSONAL_TAB; import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_PERSONAL_TAB_ACCESSIBILITY; import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_WORK_PROFILE_NOT_SUPPORTED; @@ -26,6 +29,8 @@ import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_WORK import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_WORK_TAB_ACCESSIBILITY; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.PermissionChecker.PID_UNKNOWN; +import static android.stats.devicepolicy.nano.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL; +import static android.stats.devicepolicy.nano.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; import android.annotation.Nullable; @@ -57,6 +62,7 @@ import android.content.res.TypedArray; import android.graphics.Insets; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.PatternMatcher; @@ -93,7 +99,14 @@ import android.widget.Toast; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.CompositeEmptyStateProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.OnSwitchOnWorkSelectedListener; import com.android.internal.app.AbstractMultiProfilePagerAdapter.Profile; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.QuietModeManager; +import com.android.internal.app.NoCrossProfileEmptyStateProvider.DevicePolicyBlockerEmptyState; import com.android.internal.app.chooser.ChooserTargetInfo; import com.android.internal.app.chooser.DisplayResolveInfo; import com.android.internal.app.chooser.TargetInfo; @@ -186,6 +199,8 @@ public class ResolverActivity extends Activity implements @VisibleForTesting protected AbstractMultiProfilePagerAdapter mMultiProfilePagerAdapter; + protected QuietModeManager mQuietModeManager; + // Intent extra for connected audio devices public static final String EXTRA_IS_AUDIO_CAPTURE_DEVICE = "is_audio_capture_device"; @@ -217,6 +232,9 @@ public class ResolverActivity extends Activity implements private UserHandle mWorkProfileUserHandle; + @Nullable + private OnSwitchOnWorkSelectedListener mOnSwitchOnWorkSelectedListener; + protected final LatencyTracker mLatencyTracker = getLatencyTracker(); private LatencyTracker getLatencyTracker() { @@ -375,6 +393,8 @@ public class ResolverActivity extends Activity implements setTheme(appliedThemeResId()); super.onCreate(savedInstanceState); + mQuietModeManager = createQuietModeManager(); + // Determine whether we should show that intent is forwarded // from managed profile to owner or other way around. setProfileSwitchMessage(intent.getContentUserHint()); @@ -475,6 +495,111 @@ public class ResolverActivity extends Activity implements return resolverMultiProfilePagerAdapter; } + @VisibleForTesting + protected MyUserIdProvider createMyUserIdProvider() { + return new MyUserIdProvider(); + } + + @VisibleForTesting + protected CrossProfileIntentsChecker createCrossProfileIntentsChecker() { + return new CrossProfileIntentsChecker(getContentResolver()); + } + + @VisibleForTesting + protected QuietModeManager createQuietModeManager() { + UserManager userManager = getSystemService(UserManager.class); + return new QuietModeManager() { + + private boolean mIsWaitingToEnableWorkProfile = false; + + @Override + public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { + return userManager.isQuietModeEnabled(workProfileUserHandle); + } + + @Override + public void requestQuietModeEnabled(boolean enabled, UserHandle workProfileUserHandle) { + AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> { + userManager.requestQuietModeEnabled(enabled, workProfileUserHandle); + }); + mIsWaitingToEnableWorkProfile = true; + } + + @Override + public void markWorkProfileEnabledBroadcastReceived() { + mIsWaitingToEnableWorkProfile = false; + } + + @Override + public boolean isWaitingToEnableWorkProfile() { + return mIsWaitingToEnableWorkProfile; + } + }; + } + + protected EmptyStateProvider createBlockerEmptyStateProvider() { + final boolean shouldShowNoCrossProfileIntentsEmptyState = getUser().equals(getIntentUser()); + + if (!shouldShowNoCrossProfileIntentsEmptyState) { + // Implementation that doesn't show any blockers + return new EmptyStateProvider() {}; + } + + final AbstractMultiProfilePagerAdapter.EmptyState + noWorkToPersonalEmptyState = + new DevicePolicyBlockerEmptyState(/* context= */ this, + /* devicePolicyStringTitleId= */ RESOLVER_CROSS_PROFILE_BLOCKED_TITLE, + /* defaultTitleResource= */ R.string.resolver_cross_profile_blocked, + /* devicePolicyStringSubtitleId= */ RESOLVER_CANT_ACCESS_PERSONAL, + /* defaultSubtitleResource= */ + R.string.resolver_cant_access_personal_apps_explanation, + /* devicePolicyEventId= */ RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL, + /* devicePolicyEventCategory= */ ResolverActivity.METRICS_CATEGORY_RESOLVER); + + final AbstractMultiProfilePagerAdapter.EmptyState noPersonalToWorkEmptyState = + new DevicePolicyBlockerEmptyState(/* context= */ this, + /* devicePolicyStringTitleId= */ RESOLVER_CROSS_PROFILE_BLOCKED_TITLE, + /* defaultTitleResource= */ R.string.resolver_cross_profile_blocked, + /* devicePolicyStringSubtitleId= */ RESOLVER_CANT_ACCESS_WORK, + /* defaultSubtitleResource= */ + R.string.resolver_cant_access_work_apps_explanation, + /* devicePolicyEventId= */ RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK, + /* devicePolicyEventCategory= */ ResolverActivity.METRICS_CATEGORY_RESOLVER); + + return new NoCrossProfileEmptyStateProvider(getPersonalProfileUserHandle(), + noWorkToPersonalEmptyState, noPersonalToWorkEmptyState, + createCrossProfileIntentsChecker(), createMyUserIdProvider()); + } + + protected EmptyStateProvider createEmptyStateProvider( + @Nullable UserHandle workProfileUserHandle) { + final EmptyStateProvider blockerEmptyStateProvider = createBlockerEmptyStateProvider(); + + final EmptyStateProvider workProfileOffEmptyStateProvider = + new WorkProfilePausedEmptyStateProvider(this, workProfileUserHandle, + mQuietModeManager, + /* onSwitchOnWorkSelectedListener= */ + () -> { if (mOnSwitchOnWorkSelectedListener != null) { + mOnSwitchOnWorkSelectedListener.onSwitchOnWorkSelected(); + }}, + getMetricsCategory()); + + final EmptyStateProvider noAppsEmptyStateProvider = new NoAppsAvailableEmptyStateProvider( + this, + workProfileUserHandle, + getPersonalProfileUserHandle(), + getMetricsCategory(), + createMyUserIdProvider() + ); + + // Return composite provider, the order matters (the higher, the more priority) + return new CompositeEmptyStateProvider( + blockerEmptyStateProvider, + workProfileOffEmptyStateProvider, + noAppsEmptyStateProvider + ); + } + private ResolverMultiProfilePagerAdapter createResolverMultiProfilePagerAdapterForOneProfile( Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) { @@ -485,10 +610,12 @@ public class ResolverActivity extends Activity implements rList, filterLastUsed, /* userHandle */ UserHandle.of(UserHandle.myUserId())); + QuietModeManager quietModeManager = createQuietModeManager(); return new ResolverMultiProfilePagerAdapter( /* context */ this, adapter, - getPersonalProfileUserHandle(), + createEmptyStateProvider(/* workProfileUserHandle= */ null), + quietModeManager, /* workProfileUserHandle= */ null); } @@ -539,14 +666,15 @@ public class ResolverActivity extends Activity implements (filterLastUsed && UserHandle.myUserId() == workProfileUserHandle.getIdentifier()), /* userHandle */ workProfileUserHandle); + QuietModeManager quietModeManager = createQuietModeManager(); return new ResolverMultiProfilePagerAdapter( /* context */ this, personalAdapter, workAdapter, + createEmptyStateProvider(getWorkProfileUserHandle()), + quietModeManager, selectedProfile, - getPersonalProfileUserHandle(), - getWorkProfileUserHandle(), - /* shouldShowNoCrossProfileIntentsEmptyState= */ getUser().equals(intentUser)); + getWorkProfileUserHandle()); } protected int appliedThemeResId() { @@ -853,9 +981,9 @@ public class ResolverActivity extends Activity implements } mRegistered = true; } - if (shouldShowTabs() && mMultiProfilePagerAdapter.isWaitingToEnableWorkProfile()) { - if (mMultiProfilePagerAdapter.isQuietModeEnabled(getWorkProfileUserHandle())) { - mMultiProfilePagerAdapter.markWorkProfileEnabledBroadcastReceived(); + if (shouldShowTabs() && mQuietModeManager.isWaitingToEnableWorkProfile()) { + if (mQuietModeManager.isQuietModeEnabled(getWorkProfileUserHandle())) { + mQuietModeManager.markWorkProfileEnabledBroadcastReceived(); } } mMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged(); @@ -1815,13 +1943,12 @@ public class ResolverActivity extends Activity implements onHorizontalSwipeStateChanged(state); } }); - mMultiProfilePagerAdapter.setOnSwitchOnWorkSelectedListener( - () -> { - final View workTab = tabHost.getTabWidget().getChildAt(1); - workTab.setFocusable(true); - workTab.setFocusableInTouchMode(true); - workTab.requestFocus(); - }); + mOnSwitchOnWorkSelectedListener = () -> { + final View workTab = tabHost.getTabWidget().getChildAt(1); + workTab.setFocusable(true); + workTab.setFocusableInTouchMode(true); + workTab.requestFocus(); + }; } private String getPersonalTabLabel() { @@ -2082,7 +2209,7 @@ public class ResolverActivity extends Activity implements public void onHandlePackagesChanged(ResolverListAdapter listAdapter) { if (listAdapter == mMultiProfilePagerAdapter.getActiveListAdapter()) { if (listAdapter.getUserHandle().equals(getWorkProfileUserHandle()) - && mMultiProfilePagerAdapter.isWaitingToEnableWorkProfile()) { + && mQuietModeManager.isWaitingToEnableWorkProfile()) { // We have just turned on the work profile and entered the pass code to start it, // now we are waiting to receive the ACTION_USER_UNLOCKED broadcast. There is no // point in reloading the list now, since the work profile user is still @@ -2134,7 +2261,7 @@ public class ResolverActivity extends Activity implements } mWorkProfileHasBeenEnabled = true; - mMultiProfilePagerAdapter.markWorkProfileEnabledBroadcastReceived(); + mQuietModeManager.markWorkProfileEnabledBroadcastReceived(); } else { // Must be an UNAVAILABLE broadcast, so we watch for the next availability mWorkProfileHasBeenEnabled = false; @@ -2150,7 +2277,6 @@ public class ResolverActivity extends Activity implements }; } - @VisibleForTesting public static final class ResolvedComponentInfo { public final ComponentName name; private final List<Intent> mIntents = new ArrayList<>(); diff --git a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java index 0b33501fd875..9922051c1b0b 100644 --- a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java @@ -16,15 +16,7 @@ package com.android.internal.app; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_PERSONAL; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_WORK; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROSS_PROFILE_BLOCKED_TITLE; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_NO_PERSONAL_APPS; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_NO_WORK_APPS; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_WORK_PAUSED_TITLE; - import android.annotation.Nullable; -import android.app.admin.DevicePolicyManager; import android.content.Context; import android.os.UserHandle; import android.view.LayoutInflater; @@ -43,34 +35,33 @@ import com.android.internal.widget.PagerAdapter; public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerAdapter { private final ResolverProfileDescriptor[] mItems; - private final boolean mShouldShowNoCrossProfileIntentsEmptyState; private boolean mUseLayoutWithDefault; ResolverMultiProfilePagerAdapter(Context context, ResolverListAdapter adapter, - UserHandle personalProfileUserHandle, + EmptyStateProvider emptyStateProvider, + QuietModeManager quietModeManager, UserHandle workProfileUserHandle) { - super(context, /* currentPage */ 0, personalProfileUserHandle, workProfileUserHandle); + super(context, /* currentPage */ 0, emptyStateProvider, quietModeManager, + workProfileUserHandle); mItems = new ResolverProfileDescriptor[] { createProfileDescriptor(adapter) }; - mShouldShowNoCrossProfileIntentsEmptyState = true; } ResolverMultiProfilePagerAdapter(Context context, ResolverListAdapter personalAdapter, ResolverListAdapter workAdapter, + EmptyStateProvider emptyStateProvider, + QuietModeManager quietModeManager, @Profile int defaultProfile, - UserHandle personalProfileUserHandle, - UserHandle workProfileUserHandle, - boolean shouldShowNoCrossProfileIntentsEmptyState) { - super(context, /* currentPage */ defaultProfile, personalProfileUserHandle, + UserHandle workProfileUserHandle) { + super(context, /* currentPage */ defaultProfile, emptyStateProvider, quietModeManager, workProfileUserHandle); mItems = new ResolverProfileDescriptor[] { createProfileDescriptor(personalAdapter), createProfileDescriptor(workAdapter) }; - mShouldShowNoCrossProfileIntentsEmptyState = shouldShowNoCrossProfileIntentsEmptyState; } private ResolverProfileDescriptor createProfileDescriptor( @@ -170,93 +161,6 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA return getListViewForIndex(1 - getCurrentPage()); } - @Override - String getMetricsCategory() { - return ResolverActivity.METRICS_CATEGORY_RESOLVER; - } - - @Override - boolean allowShowNoCrossProfileIntentsEmptyState() { - return mShouldShowNoCrossProfileIntentsEmptyState; - } - - @Override - protected void showWorkProfileOffEmptyState(ResolverListAdapter activeListAdapter, - View.OnClickListener listener) { - showEmptyState(activeListAdapter, - getWorkAppPausedTitle(), - /* subtitle = */ null, - listener); - } - - @Override - protected void showNoPersonalToWorkIntentsEmptyState(ResolverListAdapter activeListAdapter) { - showEmptyState(activeListAdapter, - getCrossProfileBlockedTitle(), - getCantAccessWorkMessage()); - } - - @Override - protected void showNoWorkToPersonalIntentsEmptyState(ResolverListAdapter activeListAdapter) { - showEmptyState(activeListAdapter, - getCrossProfileBlockedTitle(), - getCantAccessPersonalMessage()); - } - - @Override - protected void showNoPersonalAppsAvailableEmptyState(ResolverListAdapter listAdapter) { - showEmptyState(listAdapter, - getNoPersonalAppsAvailableMessage(), - /* subtitle = */ null); - } - - @Override - protected void showNoWorkAppsAvailableEmptyState(ResolverListAdapter listAdapter) { - showEmptyState(listAdapter, - getNoWorkAppsAvailableMessage(), - /* subtitle= */ null); - } - - private String getWorkAppPausedTitle() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_WORK_PAUSED_TITLE, - () -> getContext().getString(R.string.resolver_turn_on_work_apps)); - } - - private String getCrossProfileBlockedTitle() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CROSS_PROFILE_BLOCKED_TITLE, - () -> getContext().getString(R.string.resolver_cross_profile_blocked)); - } - - private String getCantAccessWorkMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CANT_ACCESS_WORK, - () -> getContext().getString( - R.string.resolver_cant_access_work_apps_explanation)); - } - - private String getCantAccessPersonalMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CANT_ACCESS_PERSONAL, - () -> getContext().getString( - R.string.resolver_cant_access_personal_apps_explanation)); - } - - private String getNoWorkAppsAvailableMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_NO_WORK_APPS, - () -> getContext().getString( - R.string.resolver_no_work_apps_available)); - } - - private String getNoPersonalAppsAvailableMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_NO_PERSONAL_APPS, - () -> getContext().getString( - R.string.resolver_no_personal_apps_available)); - } - void setUseLayoutWithDefault(boolean useLayoutWithDefault) { mUseLayoutWithDefault = useLayoutWithDefault; } diff --git a/core/java/com/android/internal/app/WorkProfilePausedEmptyStateProvider.java b/core/java/com/android/internal/app/WorkProfilePausedEmptyStateProvider.java new file mode 100644 index 000000000000..6a88557663b1 --- /dev/null +++ b/core/java/com/android/internal/app/WorkProfilePausedEmptyStateProvider.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2022 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 com.android.internal.app; + +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_WORK_PAUSED_TITLE; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.app.admin.DevicePolicyEventLogger; +import android.app.admin.DevicePolicyManager; +import android.content.Context; +import android.os.UserHandle; +import android.stats.devicepolicy.nano.DevicePolicyEnums; + +import com.android.internal.R; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyState; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.OnSwitchOnWorkSelectedListener; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.QuietModeManager; + +/** + * Chooser/ResolverActivity empty state provider that returns empty state which is shown when + * work profile is paused and we need to show a button to enable it. + */ +public class WorkProfilePausedEmptyStateProvider implements EmptyStateProvider { + + private final UserHandle mWorkProfileUserHandle; + private final QuietModeManager mQuietModeManager; + private final String mMetricsCategory; + private final OnSwitchOnWorkSelectedListener mOnSwitchOnWorkSelectedListener; + private final Context mContext; + + public WorkProfilePausedEmptyStateProvider(@NonNull Context context, + @Nullable UserHandle workProfileUserHandle, + @NonNull QuietModeManager quietModeManager, + @Nullable OnSwitchOnWorkSelectedListener onSwitchOnWorkSelectedListener, + @NonNull String metricsCategory) { + mContext = context; + mWorkProfileUserHandle = workProfileUserHandle; + mQuietModeManager = quietModeManager; + mMetricsCategory = metricsCategory; + mOnSwitchOnWorkSelectedListener = onSwitchOnWorkSelectedListener; + } + + @Nullable + @Override + public EmptyState getEmptyState(ResolverListAdapter resolverListAdapter) { + if (!resolverListAdapter.getUserHandle().equals(mWorkProfileUserHandle) + || !mQuietModeManager.isQuietModeEnabled(mWorkProfileUserHandle) + || resolverListAdapter.getCount() == 0) { + return null; + } + + final String title = mContext.getSystemService(DevicePolicyManager.class) + .getResources().getString(RESOLVER_WORK_PAUSED_TITLE, + () -> mContext.getString(R.string.resolver_turn_on_work_apps)); + + return new WorkProfileOffEmptyState(title, (tab) -> { + tab.showSpinner(); + if (mOnSwitchOnWorkSelectedListener != null) { + mOnSwitchOnWorkSelectedListener.onSwitchOnWorkSelected(); + } + mQuietModeManager.requestQuietModeEnabled(false, mWorkProfileUserHandle); + }, mMetricsCategory); + } + + public static class WorkProfileOffEmptyState implements EmptyState { + + private final String mTitle; + private final ClickListener mOnClick; + private final String mMetricsCategory; + + public WorkProfileOffEmptyState(String title, @NonNull ClickListener onClick, + @NonNull String metricsCategory) { + mTitle = title; + mOnClick = onClick; + mMetricsCategory = metricsCategory; + } + + @Nullable + @Override + public String getTitle() { + return mTitle; + } + + @Nullable + @Override + public ClickListener getButtonClickListener() { + return mOnClick; + } + + @Override + public void onEmptyStateShown() { + DevicePolicyEventLogger + .createEvent(DevicePolicyEnums.RESOLVER_EMPTY_STATE_WORK_APPS_DISABLED) + .setStrings(mMetricsCategory) + .write(); + } + } +} diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto index 285258a979e4..556636ddd210 100644 --- a/core/proto/android/providers/settings/secure.proto +++ b/core/proto/android/providers/settings/secure.proto @@ -88,6 +88,7 @@ message SecureSettingsProto { optional SettingProto odi_captions_volume_ui_enabled = 42 [ (android.privacy).dest = DEST_AUTOMATIC ]; // Setting for accessibility magnification for following typing. optional SettingProto accessibility_magnification_follow_typing_enabled = 43 [ (android.privacy).dest = DEST_AUTOMATIC ]; + optional SettingProto contrast_level = 44 [ (android.privacy).dest = DEST_AUTOMATIC ]; } optional Accessibility accessibility = 2; diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index b86ce04e5b24..40503f5ee955 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -2122,7 +2122,7 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifications"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Paramètres rapides"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Boîte de dialogue sur l\'alimentation"</string> - <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Écran de verrouillage"</string> + <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Verrouiller l\'écran"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Capture d\'écran"</string> <string name="accessibility_system_action_headset_hook_label" msgid="8524691721287425468">"Crochet de casque d\'écoute"</string> <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Raccourci d\'accessibilité à l\'écran"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index c0d252657037..af908071badc 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1958,7 +1958,7 @@ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Questa app richiede maggiore sicurezza. Prova a usare il telefono."</string> <string name="app_streaming_blocked_message_for_settings_dialog" product="tv" msgid="820334666354451145">"Non è possibile accedere a questa impostazione su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il dispositivo Android TV."</string> <string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Non è possibile accedere a questa impostazione su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il tablet."</string> - <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Non è possibile accedere a questa impostazione su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il telefono."</string> + <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Non è possibile accedere su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il telefono."</string> <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Questa app è stata realizzata per una versione precedente di Android e potrebbe non funzionare correttamente. Prova a verificare la disponibilità di aggiornamenti o contatta lo sviluppatore."</string> <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Cerca aggiornamenti"</string> <string name="new_sms_notification_title" msgid="6528758221319927107">"Hai nuovi messaggi"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 66f0bdd26b9e..1d52fc35fced 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1209,7 +1209,7 @@ <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> tiếp tục dừng"</string> <string name="aerr_process_repeated" msgid="1153152413537954974">"<xliff:g id="PROCESS">%1$s</xliff:g> tiếp tục dừng"</string> <string name="aerr_restart" msgid="2789618625210505419">"Mở lại ứng dụng"</string> - <string name="aerr_report" msgid="3095644466849299308">"Gửi phản hồi"</string> + <string name="aerr_report" msgid="3095644466849299308">"Gửi ý kiến phản hồi"</string> <string name="aerr_close" msgid="3398336821267021852">"Đóng"</string> <string name="aerr_mute" msgid="2304972923480211376">"Tắt tiếng cho đến khi thiết bị khởi động lại"</string> <string name="aerr_wait" msgid="3198677780474548217">"Đợi"</string> diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java index 875cd0bb4e16..eead4edb6f90 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java @@ -16,9 +16,11 @@ package com.android.internal.app; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; -import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; import android.database.Cursor; @@ -26,10 +28,12 @@ import android.graphics.Bitmap; import android.os.UserHandle; import android.util.Pair; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.QuietModeManager; import com.android.internal.app.chooser.TargetInfo; import com.android.internal.logging.MetricsLogger; -import java.util.List; import java.util.function.BiFunction; import java.util.function.Function; @@ -71,7 +75,10 @@ public class ChooserActivityOverrideData { public boolean isQuietModeEnabled; public boolean isWorkProfileUserRunning; public boolean isWorkProfileUserUnlocked; - public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector; + public Integer myUserId; + public QuietModeManager mQuietModeManager; + public MyUserIdProvider mMyUserIdProvider; + public CrossProfileIntentsChecker mCrossProfileIntentsChecker; public PackageManager packageManager; public void reset() { @@ -95,14 +102,9 @@ public class ChooserActivityOverrideData { isQuietModeEnabled = false; isWorkProfileUserRunning = true; isWorkProfileUserUnlocked = true; + myUserId = null; packageManager = null; - multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() { - @Override - public boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId, - int targetUserId) { - return hasCrossProfileIntents; - } - + mQuietModeManager = new QuietModeManager() { @Override public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { return isQuietModeEnabled; @@ -113,7 +115,27 @@ public class ChooserActivityOverrideData { UserHandle workProfileUserHandle) { isQuietModeEnabled = enabled; } + + @Override + public void markWorkProfileEnabledBroadcastReceived() { + } + + @Override + public boolean isWaitingToEnableWorkProfile() { + return false; + } }; + + mMyUserIdProvider = new MyUserIdProvider() { + @Override + public int getMyUserId() { + return myUserId != null ? myUserId : UserHandle.myUserId(); + } + }; + + mCrossProfileIntentsChecker = mock(CrossProfileIntentsChecker.class); + when(mCrossProfileIntentsChecker.hasCrossProfileIntents(any(), anyInt(), anyInt())) + .thenAnswer(invocation -> hasCrossProfileIntents); } private ChooserActivityOverrideData() {} diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityWorkProfileTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityWorkProfileTest.java new file mode 100644 index 000000000000..c6537c0fbfb3 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityWorkProfileTest.java @@ -0,0 +1,450 @@ +/* + * Copyright (C) 2022 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 com.android.internal.app; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.action.ViewActions.swipeUp; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; + +import static com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.ExpectedBlocker.NO_BLOCKER; +import static com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.ExpectedBlocker.PERSONAL_PROFILE_ACCESS_BLOCKER; +import static com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.ExpectedBlocker.PERSONAL_PROFILE_SHARE_BLOCKER; +import static com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.ExpectedBlocker.WORK_PROFILE_ACCESS_BLOCKER; +import static com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.ExpectedBlocker.WORK_PROFILE_SHARE_BLOCKER; +import static com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.Tab.PERSONAL; +import static com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.Tab.WORK; +import static com.android.internal.app.ChooserWrapperActivity.sOverrides; + +import static org.hamcrest.CoreMatchers.not; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import android.companion.DeviceFilter; +import android.content.Intent; +import android.os.UserHandle; + +import androidx.test.InstrumentationRegistry; +import androidx.test.espresso.NoMatchingViewException; +import androidx.test.rule.ActivityTestRule; + +import com.android.internal.R; +import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; +import com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.Tab; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.mockito.Mockito; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +@DeviceFilter.MediumType +@RunWith(Parameterized.class) +public class ChooserActivityWorkProfileTest { + + private static final UserHandle PERSONAL_USER_HANDLE = InstrumentationRegistry + .getInstrumentation().getTargetContext().getUser(); + private static final UserHandle WORK_USER_HANDLE = UserHandle.of(10); + + @Rule + public ActivityTestRule<ChooserWrapperActivity> mActivityRule = + new ActivityTestRule<>(ChooserWrapperActivity.class, false, + false); + private final TestCase mTestCase; + + public ChooserActivityWorkProfileTest(TestCase testCase) { + mTestCase = testCase; + } + + @Before + public void cleanOverrideData() { + sOverrides.reset(); + } + + @Test + public void testBlocker() { + setUpPersonalAndWorkComponentInfos(); + sOverrides.hasCrossProfileIntents = mTestCase.hasCrossProfileIntents(); + sOverrides.myUserId = mTestCase.getMyUserHandle().getIdentifier(); + + launchActivity(mTestCase.getIsSendAction()); + switchToTab(mTestCase.getTab()); + + switch (mTestCase.getExpectedBlocker()) { + case NO_BLOCKER: + assertNoBlockerDisplayed(); + break; + case PERSONAL_PROFILE_SHARE_BLOCKER: + assertCantSharePersonalAppsBlockerDisplayed(); + break; + case WORK_PROFILE_SHARE_BLOCKER: + assertCantShareWorkAppsBlockerDisplayed(); + break; + case PERSONAL_PROFILE_ACCESS_BLOCKER: + assertCantAccessPersonalAppsBlockerDisplayed(); + break; + case WORK_PROFILE_ACCESS_BLOCKER: + assertCantAccessWorkAppsBlockerDisplayed(); + break; + } + } + + @Parameterized.Parameters(name = "{0}") + public static Collection tests() { + return Arrays.asList( + new TestCase( + /* isSendAction= */ true, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), +// TODO(b/256869196) ChooserActivity goes into requestLayout loop +// new TestCase( +// /* isSendAction= */ true, +// /* hasCrossProfileIntents= */ false, +// /* myUserHandle= */ WORK_USER_HANDLE, +// /* tab= */ WORK, +// /* expectedBlocker= */ NO_BLOCKER +// ), + new TestCase( + /* isSendAction= */ true, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ true, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ WORK_PROFILE_SHARE_BLOCKER + ), + new TestCase( + /* isSendAction= */ true, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), +// TODO(b/256869196) ChooserActivity goes into requestLayout loop +// new TestCase( +// /* isSendAction= */ true, +// /* hasCrossProfileIntents= */ false, +// /* myUserHandle= */ WORK_USER_HANDLE, +// /* tab= */ PERSONAL, +// /* expectedBlocker= */ PERSONAL_PROFILE_SHARE_BLOCKER +// ), + new TestCase( + /* isSendAction= */ true, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ true, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ WORK_PROFILE_ACCESS_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ PERSONAL_PROFILE_ACCESS_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ) + ); + } + + private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile( + int numberOfResults, int userId) { + List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults); + for (int i = 0; i < numberOfResults; i++) { + infoList.add( + ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId)); + } + return infoList; + } + + private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) { + List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults); + for (int i = 0; i < numberOfResults; i++) { + infoList.add(ResolverDataProvider.createResolvedComponentInfo(i)); + } + return infoList; + } + + private void setUpPersonalAndWorkComponentInfos() { + // enable the work tab feature flag + ResolverActivity.ENABLE_TABBED_VIEW = true; + markWorkProfileUserAvailable(); + int workProfileTargets = 4; + List<ResolvedComponentInfo> personalResolvedComponentInfos = + createResolvedComponentsForTestWithOtherProfile(3, + /* userId */ WORK_USER_HANDLE.getIdentifier()); + List<ResolvedComponentInfo> workResolvedComponentInfos = + createResolvedComponentsForTest(workProfileTargets); + setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); + } + + private void setupResolverControllers( + List<ResolvedComponentInfo> personalResolvedComponentInfos, + List<ResolvedComponentInfo> workResolvedComponentInfos) { + when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos); + when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class), + eq(UserHandle.SYSTEM))) + .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + } + + private void waitForIdle() { + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + } + + private void markWorkProfileUserAvailable() { + ChooserWrapperActivity.sOverrides.workProfileUserHandle = WORK_USER_HANDLE; + } + + private void assertCantAccessWorkAppsBlockerDisplayed() { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(isDisplayed())); + onView(withText(R.string.resolver_cant_access_work_apps_explanation)) + .check(matches(isDisplayed())); + } + + private void assertCantAccessPersonalAppsBlockerDisplayed() { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(isDisplayed())); + onView(withText(R.string.resolver_cant_access_personal_apps_explanation)) + .check(matches(isDisplayed())); + } + + private void assertCantShareWorkAppsBlockerDisplayed() { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(isDisplayed())); + onView(withText(R.string.resolver_cant_share_with_work_apps_explanation)) + .check(matches(isDisplayed())); + } + + private void assertCantSharePersonalAppsBlockerDisplayed() { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(isDisplayed())); + onView(withText(R.string.resolver_cant_share_with_personal_apps_explanation)) + .check(matches(isDisplayed())); + } + + private void assertNoBlockerDisplayed() { + try { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(not(isDisplayed()))); + } catch (NoMatchingViewException ignored) { + } + } + + private void switchToTab(Tab tab) { + final int stringId = tab == Tab.WORK ? R.string.resolver_work_tab + : R.string.resolver_personal_tab; + + onView(withText(stringId)).perform(click()); + waitForIdle(); + + onView(withId(R.id.contentPanel)) + .perform(swipeUp()); + waitForIdle(); + } + + private Intent createTextIntent(boolean isSendAction) { + Intent sendIntent = new Intent(); + if (isSendAction) { + sendIntent.setAction(Intent.ACTION_SEND); + } + sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending"); + sendIntent.setType("text/plain"); + return sendIntent; + } + + private void launchActivity(boolean isSendAction) { + Intent sendIntent = createTextIntent(isSendAction); + mActivityRule.launchActivity(Intent.createChooser(sendIntent, "Test")); + waitForIdle(); + } + + public static class TestCase { + private final boolean mIsSendAction; + private final boolean mHasCrossProfileIntents; + private final UserHandle mMyUserHandle; + private final Tab mTab; + private final ExpectedBlocker mExpectedBlocker; + + public enum ExpectedBlocker { + NO_BLOCKER, + PERSONAL_PROFILE_SHARE_BLOCKER, + WORK_PROFILE_SHARE_BLOCKER, + PERSONAL_PROFILE_ACCESS_BLOCKER, + WORK_PROFILE_ACCESS_BLOCKER + } + + public enum Tab { + WORK, + PERSONAL + } + + public TestCase(boolean isSendAction, boolean hasCrossProfileIntents, + UserHandle myUserHandle, Tab tab, ExpectedBlocker expectedBlocker) { + mIsSendAction = isSendAction; + mHasCrossProfileIntents = hasCrossProfileIntents; + mMyUserHandle = myUserHandle; + mTab = tab; + mExpectedBlocker = expectedBlocker; + } + + public boolean getIsSendAction() { + return mIsSendAction; + } + + public boolean hasCrossProfileIntents() { + return mHasCrossProfileIntents; + } + + public UserHandle getMyUserHandle() { + return mMyUserHandle; + } + + public Tab getTab() { + return mTab; + } + + public ExpectedBlocker getExpectedBlocker() { + return mExpectedBlocker; + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder("test"); + + if (mTab == WORK) { + result.append("WorkTab_"); + } else { + result.append("PersonalTab_"); + } + + if (mIsSendAction) { + result.append("sendAction_"); + } else { + result.append("notSendAction_"); + } + + if (mHasCrossProfileIntents) { + result.append("hasCrossProfileIntents_"); + } else { + result.append("doesNotHaveCrossProfileIntents_"); + } + + if (mMyUserHandle.equals(PERSONAL_USER_HANDLE)) { + result.append("myUserIsPersonal_"); + } else { + result.append("myUserIsWork_"); + } + + if (mExpectedBlocker == ExpectedBlocker.NO_BLOCKER) { + result.append("thenNoBlocker"); + } else if (mExpectedBlocker == PERSONAL_PROFILE_ACCESS_BLOCKER) { + result.append("thenAccessBlockerOnPersonalProfile"); + } else if (mExpectedBlocker == PERSONAL_PROFILE_SHARE_BLOCKER) { + result.append("thenShareBlockerOnPersonalProfile"); + } else if (mExpectedBlocker == WORK_PROFILE_ACCESS_BLOCKER) { + result.append("thenAccessBlockerOnWorkProfile"); + } else if (mExpectedBlocker == WORK_PROFILE_SHARE_BLOCKER) { + result.append("thenShareBlockerOnWorkProfile"); + } + + return result.toString(); + } + } +} diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java index 4c3235ca8ac0..5dc0c8b24218 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java @@ -16,6 +16,10 @@ package com.android.internal.app; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.annotation.Nullable; @@ -34,6 +38,8 @@ import android.os.UserHandle; import android.util.Pair; import android.util.Size; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider; import com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter; import com.android.internal.app.chooser.DisplayResolveInfo; import com.android.internal.app.chooser.TargetInfo; @@ -60,15 +66,6 @@ public class ChooserWrapperActivity extends ChooserActivity implements IChooserW } @Override - protected AbstractMultiProfilePagerAdapter createMultiProfilePagerAdapter( - Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) { - AbstractMultiProfilePagerAdapter multiProfilePagerAdapter = - super.createMultiProfilePagerAdapter(initialIntents, rList, filterLastUsed); - multiProfilePagerAdapter.setInjector(sOverrides.multiPagerAdapterInjector); - return multiProfilePagerAdapter; - } - - @Override public ChooserListAdapter createChooserListAdapter(Context context, List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed, ResolverListController resolverListController) { @@ -135,6 +132,30 @@ public class ChooserWrapperActivity extends ChooserActivity implements IChooserW } @Override + protected MyUserIdProvider createMyUserIdProvider() { + if (sOverrides.mMyUserIdProvider != null) { + return sOverrides.mMyUserIdProvider; + } + return super.createMyUserIdProvider(); + } + + @Override + protected CrossProfileIntentsChecker createCrossProfileIntentsChecker() { + if (sOverrides.mCrossProfileIntentsChecker != null) { + return sOverrides.mCrossProfileIntentsChecker; + } + return super.createCrossProfileIntentsChecker(); + } + + @Override + protected AbstractMultiProfilePagerAdapter.QuietModeManager createQuietModeManager() { + if (sOverrides.mQuietModeManager != null) { + return sOverrides.mQuietModeManager; + } + return super.createQuietModeManager(); + } + + @Override public void safelyStartActivity(com.android.internal.app.chooser.TargetInfo cti) { if (sOverrides.onSafelyStartCallback != null && sOverrides.onSafelyStartCallback.apply(cti)) { diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityWorkProfileTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityWorkProfileTest.java new file mode 100644 index 000000000000..ce68906a5bff --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityWorkProfileTest.java @@ -0,0 +1,429 @@ +/* + * Copyright (C) 2022 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 com.android.internal.app; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.action.ViewActions.swipeUp; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; + +import static com.android.internal.app.ResolverActivityWorkProfileTest.TestCase.ExpectedBlocker.NO_BLOCKER; +import static com.android.internal.app.ResolverActivityWorkProfileTest.TestCase.ExpectedBlocker.PERSONAL_PROFILE_BLOCKER; +import static com.android.internal.app.ResolverActivityWorkProfileTest.TestCase.ExpectedBlocker.WORK_PROFILE_BLOCKER; +import static com.android.internal.app.ResolverActivityWorkProfileTest.TestCase.Tab.PERSONAL; +import static com.android.internal.app.ResolverActivityWorkProfileTest.TestCase.Tab.WORK; +import static com.android.internal.app.ResolverWrapperActivity.sOverrides; + +import static org.hamcrest.CoreMatchers.not; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import android.annotation.Nullable; +import android.companion.DeviceFilter; +import android.content.Intent; +import android.os.UserHandle; + +import androidx.test.InstrumentationRegistry; +import androidx.test.espresso.NoMatchingViewException; +import androidx.test.rule.ActivityTestRule; + +import com.android.internal.R; +import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; +import com.android.internal.app.ResolverActivityWorkProfileTest.TestCase.Tab; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.mockito.Mockito; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +@DeviceFilter.MediumType +@RunWith(Parameterized.class) +public class ResolverActivityWorkProfileTest { + + private static final UserHandle PERSONAL_USER_HANDLE = InstrumentationRegistry + .getInstrumentation().getTargetContext().getUser(); + private static final UserHandle WORK_USER_HANDLE = UserHandle.of(10); + + @Rule + public ActivityTestRule<ResolverWrapperActivity> mActivityRule = + new ActivityTestRule<>(ResolverWrapperActivity.class, false, + false); + private final TestCase mTestCase; + + public ResolverActivityWorkProfileTest(TestCase testCase) { + mTestCase = testCase; + } + + @Before + public void cleanOverrideData() { + sOverrides.reset(); + } + + @Test + public void testBlocker() { + setUpPersonalAndWorkComponentInfos(); + sOverrides.hasCrossProfileIntents = mTestCase.hasCrossProfileIntents(); + sOverrides.myUserId = mTestCase.getMyUserHandle().getIdentifier(); + + launchActivity(/* callingUser= */ mTestCase.getExtraCallingUser()); + switchToTab(mTestCase.getTab()); + + switch (mTestCase.getExpectedBlocker()) { + case NO_BLOCKER: + assertNoBlockerDisplayed(); + break; + case PERSONAL_PROFILE_BLOCKER: + assertCantAccessPersonalAppsBlockerDisplayed(); + break; + case WORK_PROFILE_BLOCKER: + assertCantAccessWorkAppsBlockerDisplayed(); + break; + } + } + + @Parameterized.Parameters(name = "{0}") + public static Collection tests() { + return Arrays.asList( + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ WORK_PROFILE_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ PERSONAL_PROFILE_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ) + ); + } + + private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile( + int numberOfResults, int userId) { + List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults); + for (int i = 0; i < numberOfResults; i++) { + infoList.add( + ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId)); + } + return infoList; + } + + private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) { + List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults); + for (int i = 0; i < numberOfResults; i++) { + infoList.add(ResolverDataProvider.createResolvedComponentInfo(i)); + } + return infoList; + } + + private void setUpPersonalAndWorkComponentInfos() { + // enable the work tab feature flag + ResolverActivity.ENABLE_TABBED_VIEW = true; + markWorkProfileUserAvailable(); + int workProfileTargets = 4; + List<ResolvedComponentInfo> personalResolvedComponentInfos = + createResolvedComponentsForTestWithOtherProfile(3, + /* userId */ WORK_USER_HANDLE.getIdentifier()); + List<ResolvedComponentInfo> workResolvedComponentInfos = + createResolvedComponentsForTest(workProfileTargets); + setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); + } + + private void setupResolverControllers( + List<ResolvedComponentInfo> personalResolvedComponentInfos, + List<ResolvedComponentInfo> workResolvedComponentInfos) { + when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos); + when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class), + eq(UserHandle.SYSTEM))) + .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + } + + private void waitForIdle() { + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + } + + private void markWorkProfileUserAvailable() { + ResolverWrapperActivity.sOverrides.workProfileUserHandle = WORK_USER_HANDLE; + } + + private void assertCantAccessWorkAppsBlockerDisplayed() { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(isDisplayed())); + onView(withText(R.string.resolver_cant_access_work_apps_explanation)) + .check(matches(isDisplayed())); + } + + private void assertCantAccessPersonalAppsBlockerDisplayed() { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(isDisplayed())); + onView(withText(R.string.resolver_cant_access_personal_apps_explanation)) + .check(matches(isDisplayed())); + } + + private void assertNoBlockerDisplayed() { + try { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(not(isDisplayed()))); + } catch (NoMatchingViewException ignored) { + } + } + + private void switchToTab(Tab tab) { + final int stringId = tab == Tab.WORK ? R.string.resolver_work_tab + : R.string.resolver_personal_tab; + + onView(withText(stringId)).perform(click()); + waitForIdle(); + + onView(withId(R.id.contentPanel)) + .perform(swipeUp()); + waitForIdle(); + } + + private Intent createSendImageIntent() { + Intent sendIntent = new Intent(); + sendIntent.setAction(Intent.ACTION_SEND); + sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending"); + sendIntent.setType("image/jpeg"); + return sendIntent; + } + + private void launchActivity(UserHandle callingUser) { + Intent sendIntent = createSendImageIntent(); + sendIntent.setType("TestType"); + + if (callingUser != null) { + sendIntent.putExtra(ResolverActivity.EXTRA_CALLING_USER, callingUser); + } + + mActivityRule.launchActivity(sendIntent); + waitForIdle(); + } + + public static class TestCase { + @Nullable + private final UserHandle mExtraCallingUser; + private final boolean mHasCrossProfileIntents; + private final UserHandle mMyUserHandle; + private final Tab mTab; + private final ExpectedBlocker mExpectedBlocker; + + public enum ExpectedBlocker { + NO_BLOCKER, + PERSONAL_PROFILE_BLOCKER, + WORK_PROFILE_BLOCKER + } + + public enum Tab { + WORK, + PERSONAL + } + + public TestCase(@Nullable UserHandle extraCallingUser, boolean hasCrossProfileIntents, + UserHandle myUserHandle, Tab tab, ExpectedBlocker expectedBlocker) { + mExtraCallingUser = extraCallingUser; + mHasCrossProfileIntents = hasCrossProfileIntents; + mMyUserHandle = myUserHandle; + mTab = tab; + mExpectedBlocker = expectedBlocker; + } + + @Nullable + public UserHandle getExtraCallingUser() { + return mExtraCallingUser; + } + + public boolean hasCrossProfileIntents() { + return mHasCrossProfileIntents; + } + + public UserHandle getMyUserHandle() { + return mMyUserHandle; + } + + public Tab getTab() { + return mTab; + } + + public ExpectedBlocker getExpectedBlocker() { + return mExpectedBlocker; + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder("test"); + + if (mTab == WORK) { + result.append("WorkTab_"); + } else { + result.append("PersonalTab_"); + } + + if (mExtraCallingUser != null + && !mExtraCallingUser.equals(PERSONAL_USER_HANDLE)) { + result.append("callingUserIsNonPersonal_"); + } else { + result.append("callingUserIsPersonal_"); + } + + if (mHasCrossProfileIntents) { + result.append("hasCrossProfileIntents_"); + } else { + result.append("doesNotHaveCrossProfileIntents_"); + } + + if (mMyUserHandle.equals(PERSONAL_USER_HANDLE)) { + result.append("myUserIsPersonal_"); + } else { + result.append("myUserIsWork_"); + } + + if (mExpectedBlocker == ExpectedBlocker.NO_BLOCKER) { + result.append("thenNoBlocker"); + } else if (mExpectedBlocker == ExpectedBlocker.PERSONAL_PROFILE_BLOCKER) { + result.append("thenBlockerOnPersonalProfile"); + } else if (mExpectedBlocker == WORK_PROFILE_BLOCKER) { + result.append("thenBlockerOnWorkProfile"); + } + + return result.toString(); + } + } +} diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java index 4cf9c3fe75b9..c778dfeaf376 100644 --- a/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java +++ b/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java @@ -16,6 +16,8 @@ package com.android.internal.app; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -27,6 +29,9 @@ import android.content.pm.ResolveInfo; import android.os.Bundle; import android.os.UserHandle; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.QuietModeManager; import com.android.internal.app.chooser.TargetInfo; import java.util.List; @@ -52,12 +57,27 @@ public class ResolverWrapperActivity extends ResolverActivity { } @Override - protected AbstractMultiProfilePagerAdapter createMultiProfilePagerAdapter( - Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) { - AbstractMultiProfilePagerAdapter multiProfilePagerAdapter = - super.createMultiProfilePagerAdapter(initialIntents, rList, filterLastUsed); - multiProfilePagerAdapter.setInjector(sOverrides.multiPagerAdapterInjector); - return multiProfilePagerAdapter; + protected MyUserIdProvider createMyUserIdProvider() { + if (sOverrides.mMyUserIdProvider != null) { + return sOverrides.mMyUserIdProvider; + } + return super.createMyUserIdProvider(); + } + + @Override + protected CrossProfileIntentsChecker createCrossProfileIntentsChecker() { + if (sOverrides.mCrossProfileIntentsChecker != null) { + return sOverrides.mCrossProfileIntentsChecker; + } + return super.createCrossProfileIntentsChecker(); + } + + @Override + protected QuietModeManager createQuietModeManager() { + if (sOverrides.mQuietModeManager != null) { + return sOverrides.mQuietModeManager; + } + return super.createQuietModeManager(); } ResolverWrapperAdapter getAdapter() { @@ -137,9 +157,12 @@ public class ResolverWrapperActivity extends ResolverActivity { public ResolverListController workResolverListController; public Boolean isVoiceInteraction; public UserHandle workProfileUserHandle; + public Integer myUserId; public boolean hasCrossProfileIntents; public boolean isQuietModeEnabled; - public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector; + public QuietModeManager mQuietModeManager; + public MyUserIdProvider mMyUserIdProvider; + public CrossProfileIntentsChecker mCrossProfileIntentsChecker; public void reset() { onSafelyStartCallback = null; @@ -148,15 +171,11 @@ public class ResolverWrapperActivity extends ResolverActivity { resolverListController = mock(ResolverListController.class); workResolverListController = mock(ResolverListController.class); workProfileUserHandle = null; + myUserId = null; hasCrossProfileIntents = true; isQuietModeEnabled = false; - multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() { - @Override - public boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId, - int targetUserId) { - return hasCrossProfileIntents; - } + mQuietModeManager = new QuietModeManager() { @Override public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { return isQuietModeEnabled; @@ -167,7 +186,27 @@ public class ResolverWrapperActivity extends ResolverActivity { UserHandle workProfileUserHandle) { isQuietModeEnabled = enabled; } + + @Override + public void markWorkProfileEnabledBroadcastReceived() { + } + + @Override + public boolean isWaitingToEnableWorkProfile() { + return false; + } }; + + mMyUserIdProvider = new MyUserIdProvider() { + @Override + public int getMyUserId() { + return myUserId != null ? myUserId : UserHandle.myUserId(); + } + }; + + mCrossProfileIntentsChecker = mock(CrossProfileIntentsChecker.class); + when(mCrossProfileIntentsChecker.hasCrossProfileIntents(any(), anyInt(), anyInt())) + .thenAnswer(invocation -> hasCrossProfileIntents); } } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index c06548ad81a1..4df2d7d82f6a 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -41,7 +41,6 @@ import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAs import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenStacked; import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPAND_FAILED_NO_TF_INFO; import static androidx.window.extensions.embedding.SplitPresenter.getActivityIntentMinDimensionsPair; -import static androidx.window.extensions.embedding.SplitPresenter.getNonEmbeddedActivityBounds; import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSplit; import android.app.Activity; @@ -464,7 +463,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // parentInfo#isVisibleRequested is true. return; } - onTaskContainerInfoChanged(taskContainer, parentInfo.getConfiguration()); if (isInPictureInPicture(parentInfo.getConfiguration())) { // No need to update presentation in PIP until the Task exit PIP. return; @@ -614,12 +612,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen } } - @GuardedBy("mLock") - private void onTaskContainerInfoChanged(@NonNull TaskContainer taskContainer, - @NonNull Configuration config) { - taskContainer.setTaskBounds(config.windowConfiguration.getBounds()); - } - /** Returns whether the given {@link TaskContainer} may show in split. */ // Suppress GuardedBy warning because lint asks to mark this method as // @GuardedBy(mPresenter.mController.mLock), which is mLock itself @@ -1235,13 +1227,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen final TaskContainer taskContainer = mTaskContainers.get(taskId); final TaskFragmentContainer container = new TaskFragmentContainer(pendingAppearedActivity, pendingAppearedIntent, taskContainer, this); - if (!taskContainer.isTaskBoundsInitialized()) { - // Get the initial bounds before the TaskFragment has appeared. - final Rect taskBounds = getNonEmbeddedActivityBounds(activityInTask); - if (!taskContainer.setTaskBounds(taskBounds)) { - Log.w(TAG, "Can't find bounds from activity=" + activityInTask); - } - } return container; } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java index f494b32cff14..5395fb2ef5ed 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java @@ -932,11 +932,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { if (taskContainer != null) { return taskContainer.getTaskProperties(); } - // Use a copy of configuration because activity's configuration may be updated later, - // or we may get unexpected TaskContainer's configuration if Activity's configuration is - // updated. An example is Activity is going to be in split. - return new TaskProperties(activity.getDisplayId(), - new Configuration(activity.getResources().getConfiguration())); + return TaskProperties.getTaskPropertiesFromActivity(activity); } @NonNull @@ -950,16 +946,4 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { // TODO(b/190433398): Supply correct insets. return new WindowMetrics(taskBounds, WindowInsets.CONSUMED); } - - /** Obtains the bounds from a non-embedded Activity. */ - @NonNull - static Rect getNonEmbeddedActivityBounds(@NonNull Activity activity) { - final WindowConfiguration windowConfiguration = - activity.getResources().getConfiguration().windowConfiguration; - if (!activity.isInMultiWindowMode()) { - // In fullscreen mode the max bounds should correspond to the task bounds. - return windowConfiguration.getMaxBounds(); - } - return windowConfiguration.getBounds(); - } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java index 231da0542e95..dba5a7a1cf3c 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java @@ -20,14 +20,17 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; +import static android.app.WindowConfiguration.inMultiWindowMode; import android.app.Activity; +import android.app.ActivityClient; import android.app.WindowConfiguration; import android.app.WindowConfiguration.WindowingMode; import android.content.res.Configuration; import android.graphics.Rect; import android.os.IBinder; import android.util.ArraySet; +import android.util.Log; import android.window.TaskFragmentInfo; import android.window.TaskFragmentParentInfo; import android.window.WindowContainerTransaction; @@ -41,14 +44,11 @@ import java.util.Set; /** Represents TaskFragments and split pairs below a Task. */ class TaskContainer { + private static final String TAG = TaskContainer.class.getSimpleName(); /** The unique task id. */ private final int mTaskId; - // TODO(b/240219484): consolidate to mConfiguration - /** Available window bounds of this Task. */ - private final Rect mTaskBounds = new Rect(); - /** Active TaskFragments in this Task. */ @NonNull final List<TaskFragmentContainer> mContainers = new ArrayList<>(); @@ -86,10 +86,10 @@ class TaskContainer { throw new IllegalArgumentException("Invalid Task id"); } mTaskId = taskId; - // Make a copy in case the activity's config is updated, and updates the TaskContainer's - // config unexpectedly. - mConfiguration = new Configuration(activityInTask.getResources().getConfiguration()); - mDisplayId = activityInTask.getDisplayId(); + final TaskProperties taskProperties = TaskProperties + .getTaskPropertiesFromActivity(activityInTask); + mConfiguration = taskProperties.getConfiguration(); + mDisplayId = taskProperties.getDisplayId(); // Note that it is always called when there's a new Activity is started, which implies // the host task is visible. mIsVisible = true; @@ -108,25 +108,6 @@ class TaskContainer { } @NonNull - Rect getTaskBounds() { - return mTaskBounds; - } - - /** Returns {@code true} if the bounds is changed. */ - boolean setTaskBounds(@NonNull Rect taskBounds) { - if (!taskBounds.isEmpty() && !mTaskBounds.equals(taskBounds)) { - mTaskBounds.set(taskBounds); - return true; - } - return false; - } - - /** Whether the Task bounds has been initialized. */ - boolean isTaskBoundsInitialized() { - return !mTaskBounds.isEmpty(); - } - - @NonNull Configuration getConfiguration() { // Make a copy in case the config is updated unexpectedly. return new Configuration(mConfiguration); @@ -261,5 +242,45 @@ class TaskContainer { Configuration getConfiguration() { return mConfiguration; } + + /** + * Obtains the {@link TaskProperties} for the task that the provided {@link Activity} is + * associated with. + * <p> + * Note that for most case, caller should use + * {@link SplitPresenter#getTaskProperties(Activity)} instead. This method is used before + * the {@code activity} goes into split. + * </p><p> + * If the {@link Activity} is in fullscreen, override + * {@link WindowConfiguration#getBounds()} with {@link WindowConfiguration#getMaxBounds()} + * in case the {@link Activity} is letterboxed. Otherwise, get the Task + * {@link Configuration} from the server side or use {@link Activity}'s + * {@link Configuration} as a fallback if the Task {@link Configuration} cannot be obtained. + */ + @NonNull + static TaskProperties getTaskPropertiesFromActivity(@NonNull Activity activity) { + final int displayId = activity.getDisplayId(); + // Use a copy of configuration because activity's configuration may be updated later, + // or we may get unexpected TaskContainer's configuration if Activity's configuration is + // updated. An example is Activity is going to be in split. + final Configuration activityConfig = new Configuration( + activity.getResources().getConfiguration()); + final WindowConfiguration windowConfiguration = activityConfig.windowConfiguration; + final int windowingMode = windowConfiguration.getWindowingMode(); + if (!inMultiWindowMode(windowingMode)) { + // Use the max bounds in fullscreen in case the Activity is letterboxed. + windowConfiguration.setBounds(windowConfiguration.getMaxBounds()); + return new TaskProperties(displayId, activityConfig); + } + final Configuration taskConfig = ActivityClient.getInstance() + .getTaskConfiguration(activity.getActivityToken()); + if (taskConfig == null) { + Log.w(TAG, "Could not obtain task configuration for activity:" + activity); + // Still report activity config if task config cannot be obtained from the server + // side. + return new TaskProperties(displayId, activityConfig); + } + return new TaskProperties(displayId, taskConfig); + } } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java index a7d47ef81687..13afa4910ae1 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java @@ -86,13 +86,23 @@ class TaskFragmentAnimationSpec { /** Animation for target that is opening in a change transition. */ @NonNull Animation createChangeBoundsOpenAnimation(@NonNull RemoteAnimationTarget target) { - final Rect bounds = target.localBounds; - // The target will be animated in from left or right depends on its position. - final int startLeft = bounds.left == 0 ? -bounds.width() : bounds.width(); + final Rect parentBounds = target.taskInfo.configuration.windowConfiguration.getBounds(); + final Rect bounds = target.screenSpaceBounds; + final int startLeft; + final int startTop; + if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) { + // The window will be animated in from left or right depending on its position. + startTop = 0; + startLeft = parentBounds.left == bounds.left ? -bounds.width() : bounds.width(); + } else { + // The window will be animated in from top or bottom depending on its position. + startTop = parentBounds.top == bounds.top ? -bounds.height() : bounds.height(); + startLeft = 0; + } // The position should be 0-based as we will post translate in // TaskFragmentAnimationAdapter#onAnimationUpdate - final Animation animation = new TranslateAnimation(startLeft, 0, 0, 0); + final Animation animation = new TranslateAnimation(startLeft, 0, startTop, 0); animation.setInterpolator(mFastOutExtraSlowInInterpolator); animation.setDuration(CHANGE_ANIMATION_DURATION); animation.initialize(bounds.width(), bounds.height(), bounds.width(), bounds.height()); @@ -103,13 +113,24 @@ class TaskFragmentAnimationSpec { /** Animation for target that is closing in a change transition. */ @NonNull Animation createChangeBoundsCloseAnimation(@NonNull RemoteAnimationTarget target) { - final Rect bounds = target.localBounds; - // The target will be animated out to left or right depends on its position. - final int endLeft = bounds.left == 0 ? -bounds.width() : bounds.width(); + final Rect parentBounds = target.taskInfo.configuration.windowConfiguration.getBounds(); + // TODO(b/258126915): we want to keep track of the closing start bounds + final Rect bounds = target.screenSpaceBounds; + final int endTop; + final int endLeft; + if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) { + // The window will be animated out to left or right depending on its position. + endTop = 0; + endLeft = parentBounds.left == bounds.left ? -bounds.width() : bounds.width(); + } else { + // The window will be animated out to top or bottom depending on its position. + endTop = parentBounds.top == bounds.top ? -bounds.height() : bounds.height(); + endLeft = 0; + } // The position should be 0-based as we will post translate in // TaskFragmentAnimationAdapter#onAnimationUpdate - final Animation animation = new TranslateAnimation(0, endLeft, 0, 0); + final Animation animation = new TranslateAnimation(0, endLeft, 0, endTop); animation.setInterpolator(mFastOutExtraSlowInInterpolator); animation.setDuration(CHANGE_ANIMATION_DURATION); animation.initialize(bounds.width(), bounds.height(), bounds.width(), bounds.height()); diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java index 2192b5ca219c..b70b320eee3c 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java @@ -35,7 +35,6 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.IBinder; import android.util.ArrayMap; -import android.window.WindowContext; import android.window.WindowProvider; import androidx.annotation.NonNull; @@ -310,20 +309,21 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { } final int windowingMode; if (context instanceof Activity) { - windowingMode = ActivityClient.getInstance().getTaskWindowingMode( + final Configuration taskConfig = ActivityClient.getInstance().getTaskConfiguration( context.getActivityToken()); + if (taskConfig == null) { + // If we cannot determine the task configuration for any reason, it is likely that + // we won't be able to determine its position correctly as well. DisplayFeatures' + // bounds in this case can't be computed correctly, so we should skip. + return false; + } + windowingMode = taskConfig.windowConfiguration.getWindowingMode(); } else { // TODO(b/242674941): use task windowing mode for window context that associates with // activity. windowingMode = context.getResources().getConfiguration().windowConfiguration .getWindowingMode(); } - if (windowingMode == -1) { - // If we cannot determine the task windowing mode for any reason, it is likely that we - // won't be able to determine its position correctly as well. DisplayFeatures' bounds - // in this case can't be computed correctly, so we should skip. - return false; - } // It is recommended not to report any display features in multi-window mode, since it // won't be possible to synchronize the display feature positions with window movement. return !WindowConfiguration.inMultiWindowMode(windowingMode); diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java index 87d027899eb4..8c1b87a650e0 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java @@ -261,7 +261,7 @@ public class SplitControllerTest { assertNotNull(tf); assertNotNull(taskContainer); - assertEquals(TASK_BOUNDS, taskContainer.getTaskBounds()); + assertEquals(TASK_BOUNDS, taskContainer.getConfiguration().windowConfiguration.getBounds()); } @Test diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java index af9c6ba5c162..95328ce700e3 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java @@ -23,7 +23,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.Display.DEFAULT_DISPLAY; -import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_BOUNDS; import static androidx.window.extensions.embedding.EmbeddingTestUtils.createTestTaskContainer; import static org.junit.Assert.assertEquals; @@ -68,28 +67,6 @@ public class TaskContainerTest { } @Test - public void testIsTaskBoundsInitialized() { - final TaskContainer taskContainer = createTestTaskContainer(); - - assertFalse(taskContainer.isTaskBoundsInitialized()); - - taskContainer.setTaskBounds(TASK_BOUNDS); - - assertTrue(taskContainer.isTaskBoundsInitialized()); - } - - @Test - public void testSetTaskBounds() { - final TaskContainer taskContainer = createTestTaskContainer(); - - assertFalse(taskContainer.setTaskBounds(new Rect())); - - assertTrue(taskContainer.setTaskBounds(TASK_BOUNDS)); - - assertFalse(taskContainer.setTaskBounds(TASK_BOUNDS)); - } - - @Test public void testGetWindowingModeForSplitTaskFragment() { final TaskContainer taskContainer = createTestTaskContainer(); final Rect splitBounds = new Rect(0, 0, 500, 1000); diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml index f328d5959b6d..dfce50174bda 100644 --- a/libs/WindowManager/Shell/res/values-af/strings.xml +++ b/libs/WindowManager/Shell/res/values-af/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Laat los"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Program sal dalk nie met verdeelde skerm werk nie."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Program steun nie verdeelde skerm nie."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Program sal dalk nie op \'n sekondêre skerm werk nie."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Program steun nie begin op sekondêre skerms nie."</string> <string name="accessibility_divider" msgid="703810061635792791">"Skermverdeler"</string> diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml index 08420fe9b076..343e10e847fa 100644 --- a/libs/WindowManager/Shell/res/values-am/strings.xml +++ b/libs/WindowManager/Shell/res/values-am/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"መተግበሪያ ከተከፈለ ማያ ገጽ ጋር ላይሠራ ይችላል"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"መተግበሪያው የተከፈለ ማያ ገጽን አይደግፍም።"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"መተግበሪያ በሁለተኛ ማሳያ ላይ ላይሠራ ይችላል።"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"መተግበሪያ በሁለተኛ ማሳያዎች ላይ ማስጀመርን አይደግፍም።"</string> <string name="accessibility_divider" msgid="703810061635792791">"የተከፈለ የማያ ገጽ ከፋይ"</string> diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml index ae590a9443cb..bf7b638587f8 100644 --- a/libs/WindowManager/Shell/res/values-ar/strings.xml +++ b/libs/WindowManager/Shell/res/values-ar/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"إظهار"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"قد لا يعمل التطبيق بشكل سليم في وضع \"تقسيم الشاشة\"."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"التطبيق لا يتيح تقسيم الشاشة."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"قد لا يعمل التطبيق على شاشة عرض ثانوية."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"لا يمكن تشغيل التطبيق على شاشات عرض ثانوية."</string> <string name="accessibility_divider" msgid="703810061635792791">"أداة تقسيم الشاشة"</string> diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml index 0e584609053a..655e53f64254 100644 --- a/libs/WindowManager/Shell/res/values-as/strings.xml +++ b/libs/WindowManager/Shell/res/values-as/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"দেখুৱাওক"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"এপ্টোৱে বিভাজিত স্ক্ৰীনৰ সৈতে কাম নকৰিব পাৰে।"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"এপ্টোৱে বিভাজিত স্ক্ৰীন সমৰ্থন নকৰে।"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"গৌণ ডিছপ্লেত এপে সঠিকভাৱে কাম নকৰিব পাৰে।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"গৌণ ডিছপ্লেত এপ্ লঞ্চ কৰিব নোৱাৰি।"</string> <string name="accessibility_divider" msgid="703810061635792791">"স্প্লিট স্ক্ৰীনৰ বিভাজক"</string> diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml index 954b12011fb1..d3d20587cb68 100644 --- a/libs/WindowManager/Shell/res/values-az/strings.xml +++ b/libs/WindowManager/Shell/res/values-az/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Güvənli məkandan çıxarın"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Tətbiq bölünmüş ekran ilə işləməyə bilər."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Tətbiq ekran bölünməsini dəstəkləmir."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Tətbiq ikinci ekranda işləməyə bilər."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Tətbiq ikinci ekranda başlamağı dəstəkləmir."</string> <string name="accessibility_divider" msgid="703810061635792791">"Bölünmüş ekran ayırıcısı"</string> diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml index aa68a5b465a2..839ecb60e395 100644 --- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml +++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Uklonite iz tajne memorije"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikacija možda neće raditi sa podeljenim ekranom."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacija ne podržava podeljeni ekran."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće funkcionisati na sekundarnom ekranu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string> <string name="accessibility_divider" msgid="703810061635792791">"Razdelnik podeljenog ekrana"</string> diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml index 878175c7e2ba..b227cf12a1b0 100644 --- a/libs/WindowManager/Shell/res/values-be/strings.xml +++ b/libs/WindowManager/Shell/res/values-be/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Паказаць"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Праграма можа не працаваць у рэжыме падзеленага экрана."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Праграма не падтрымлівае функцыю дзялення экрана."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Праграма можа не працаваць на дадатковых экранах."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Праграма не падтрымлівае запуск на дадатковых экранах."</string> <string name="accessibility_divider" msgid="703810061635792791">"Раздзяляльнік падзеленага экрана"</string> diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml index 0f614f943e6c..20f40387665e 100644 --- a/libs/WindowManager/Shell/res/values-bg/strings.xml +++ b/libs/WindowManager/Shell/res/values-bg/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Отмяна на съхраняването"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Приложението може да не работи в режим на разделен екран."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Приложението не поддържа разделен екран."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Възможно е приложението да не работи на алтернативни дисплеи."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Приложението не поддържа използването на алтернативни дисплеи."</string> <string name="accessibility_divider" msgid="703810061635792791">"Разделител в режима за разделен екран"</string> diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml index 47025866a28d..4add02eec96d 100644 --- a/libs/WindowManager/Shell/res/values-bn/strings.xml +++ b/libs/WindowManager/Shell/res/values-bn/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"আনস্ট্যাস করুন"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"অ্যাপটি স্প্লিট স্ক্রিনে কাজ নাও করতে পারে।"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"অ্যাপ্লিকেশান বিভক্ত-স্ক্রিন সমর্থন করে না৷"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"সেকেন্ডারি ডিসপ্লেতে অ্যাপটি কাজ নাও করতে পারে।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"সেকেন্ডারি ডিসপ্লেতে অ্যাপ লঞ্চ করা যাবে না।"</string> <string name="accessibility_divider" msgid="703810061635792791">"বিভক্ত-স্ক্রিন বিভাজক"</string> diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml index 77e99fe0f7a7..1444b89e2504 100644 --- a/libs/WindowManager/Shell/res/values-bs/strings.xml +++ b/libs/WindowManager/Shell/res/values-bs/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Vađenje iz stasha"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikacija možda neće raditi na podijeljenom ekranu."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacija ne podržava dijeljenje ekrana."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće raditi na sekundarnom ekranu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string> <string name="accessibility_divider" msgid="703810061635792791">"Razdjelnik podijeljenog ekrana"</string> diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml index 033b3b78adbf..a0bec428499e 100644 --- a/libs/WindowManager/Shell/res/values-ca/strings.xml +++ b/libs/WindowManager/Shell/res/values-ca/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Deixa d\'amagar"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"És possible que l\'aplicació no funcioni amb la pantalla dividida."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"L\'aplicació no admet la pantalla dividida."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"És possible que l\'aplicació no funcioni en una pantalla secundària."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'aplicació no es pot obrir en pantalles secundàries."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalles"</string> diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml index 0e5f952b7b47..332e9568b6d8 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Zrušit uložení"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikace v režimu rozdělené obrazovky nemusí fungovat."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikace nepodporuje režim rozdělené obrazovky."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikace na sekundárním displeji nemusí fungovat."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikace nepodporuje spuštění na sekundárních displejích."</string> <string name="accessibility_divider" msgid="703810061635792791">"Čára rozdělující obrazovku"</string> diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml index 44e561df5011..a7fb175b69f9 100644 --- a/libs/WindowManager/Shell/res/values-da/strings.xml +++ b/libs/WindowManager/Shell/res/values-da/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Vis"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Appen fungerer muligvis ikke i opdelt skærm."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Appen understøtter ikke opdelt skærm."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen fungerer muligvis ikke på sekundære skærme."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan ikke åbnes på sekundære skærme."</string> <string name="accessibility_divider" msgid="703810061635792791">"Adskiller til opdelt skærm"</string> diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml index d271f61448f2..8d69eb4c9daf 100644 --- a/libs/WindowManager/Shell/res/values-de/strings.xml +++ b/libs/WindowManager/Shell/res/values-de/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Aus Stash entfernen"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Die App funktioniert unter Umständen im Modus für geteilten Bildschirm nicht."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Das Teilen des Bildschirms wird in dieser App nicht unterstützt."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Die App funktioniert auf einem sekundären Display möglicherweise nicht."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Die App unterstützt den Start auf sekundären Displays nicht."</string> <string name="accessibility_divider" msgid="703810061635792791">"Bildschirmteiler"</string> diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml index f53ea9e5af65..613e5b075e0f 100644 --- a/libs/WindowManager/Shell/res/values-el/strings.xml +++ b/libs/WindowManager/Shell/res/values-el/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Κατάργηση απόκρυψης"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Η εφαρμογή ενδέχεται να μην λειτουργεί με διαχωρισμό οθόνης."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Η εφαρμογή δεν υποστηρίζει διαχωρισμό οθόνης."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Η εφαρμογή ίσως να μην λειτουργήσει σε δευτερεύουσα οθόνη."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Η εφαρμογή δεν υποστηρίζει την εκκίνηση σε δευτερεύουσες οθόνες."</string> <string name="accessibility_divider" msgid="703810061635792791">"Διαχωριστικό οθόνης"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml index f714ca255529..5619617c9f76 100644 --- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"App may not work with split-screen."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"App does not support split-screen."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml index 6ed6584277de..9f156697f5c7 100644 --- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"App may not work with split-screen."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"App does not support split-screen."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split-screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml index f714ca255529..5619617c9f76 100644 --- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"App may not work with split-screen."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"App does not support split-screen."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml index f714ca255529..5619617c9f76 100644 --- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"App may not work with split-screen."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"App does not support split-screen."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml index 4a9cc939b77f..2b474db99f60 100644 --- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"App may not work with split-screen."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"App does not support split-screen."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split-screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml index 9a1b9e9d3337..67386c4f31ea 100644 --- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml +++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Dejar de almacenar de manera segura"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Es posible que la app no funcione en el modo de pantalla dividida."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"La app no es compatible con la función de pantalla dividida."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Es posible que la app no funcione en una pantalla secundaria."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"La app no puede iniciarse en pantallas secundarias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalla dividida"</string> diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index e5a618473e9c..d4a6b6ce7347 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"No esconder"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Es posible que la aplicación no funcione con la pantalla dividida."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"La aplicación no admite la pantalla dividida."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Es posible que la aplicación no funcione en una pantalla secundaria."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"La aplicación no se puede abrir en pantallas secundarias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Dividir la pantalla"</string> diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml index b8ca91e0ba9b..df84e7c923de 100644 --- a/libs/WindowManager/Shell/res/values-et/strings.xml +++ b/libs/WindowManager/Shell/res/values-et/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Eemalda hoidlast"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Rakendus ei pruugi poolitatud ekraaniga töötada."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Rakendus ei toeta jagatud ekraani."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Rakendus ei pruugi teisesel ekraanil töötada."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Rakendus ei toeta teisestel ekraanidel käivitamist."</string> <string name="accessibility_divider" msgid="703810061635792791">"Ekraanijagaja"</string> diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml index 749fbd7ec181..ae2bfffd7f24 100644 --- a/libs/WindowManager/Shell/res/values-eu/strings.xml +++ b/libs/WindowManager/Shell/res/values-eu/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Ez gorde"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Baliteke aplikazioak ez funtzionatzea pantaila zatituan."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikazioak ez du onartzen pantaila zatitua"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Baliteke aplikazioak ez funtzionatzea bigarren mailako pantailetan."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikazioa ezin da abiarazi bigarren mailako pantailatan."</string> <string name="accessibility_divider" msgid="703810061635792791">"Pantaila-zatitzailea"</string> diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index b6a01edf9271..c062b928c2ec 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"لغو مخفیسازی"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ممکن است برنامه با «صفحهٔ دونیمه» کار نکند."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"برنامه از تقسیم صفحه پشتیبانی نمیکند."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ممکن است برنامه در نمایشگر ثانویه کار نکند."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"برنامه از راهاندازی در نمایشگرهای ثانویه پشتیبانی نمیکند."</string> <string name="accessibility_divider" msgid="703810061635792791">"تقسیمکننده صفحه"</string> diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml index 01bc9f13d84a..6efb770d2727 100644 --- a/libs/WindowManager/Shell/res/values-fi/strings.xml +++ b/libs/WindowManager/Shell/res/values-fi/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Poista turvasäilytyksestä"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Sovellus ei ehkä toimi jaetulla näytöllä."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Sovellus ei tue jaetun näytön tilaa."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Sovellus ei ehkä toimi toissijaisella näytöllä."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Sovellus ei tue käynnistämistä toissijaisilla näytöillä."</string> <string name="accessibility_divider" msgid="703810061635792791">"Näytön jakaja"</string> diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index 76f3b62ac3dd..0c2e1b1298ca 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Retirer de la réserve"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Il est possible que l\'application ne fonctionne pas en mode Écran partagé."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"L\'application n\'est pas compatible avec l\'écran partagé."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'application ne peut pas être lancée sur des écrans secondaires."</string> <string name="accessibility_divider" msgid="703810061635792791">"Séparateur d\'écran partagé"</string> diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index 4353c79cfcbe..b7147180126f 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Il est possible que l\'application ne fonctionne pas en mode Écran partagé."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Application incompatible avec l\'écran partagé."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'application ne peut pas être lancée sur des écrans secondaires."</string> <string name="accessibility_divider" msgid="703810061635792791">"Séparateur d\'écran partagé"</string> diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml index 5bfd802cbf13..952d5329bcd0 100644 --- a/libs/WindowManager/Shell/res/values-gl/strings.xml +++ b/libs/WindowManager/Shell/res/values-gl/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Non esconder"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Pode que a aplicación non funcione coa pantalla dividida."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"A aplicación non é compatible coa función de pantalla dividida."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É posible que a aplicación non funcione nunha pantalla secundaria."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"A aplicación non se pode iniciar en pantallas secundarias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalla dividida"</string> diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml index 2976a8a042b8..4bde170710f2 100644 --- a/libs/WindowManager/Shell/res/values-gu/strings.xml +++ b/libs/WindowManager/Shell/res/values-gu/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"બતાવો"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"વિભાજિત-સ્ક્રીન સાથે ઍપ કદાચ કામ ન કરે."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ઍપ્લિકેશન સ્ક્રીન-વિભાજનનું સમર્થન કરતી નથી."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર કદાચ કામ ન કરે."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર લૉન્ચનું સમર્થન કરતી નથી."</string> <string name="accessibility_divider" msgid="703810061635792791">"સ્પ્લિટ-સ્ક્રીન વિભાજક"</string> diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index aa91d7d35e24..9229fc2ae1e1 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"दिखाएं"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ऐप्लिकेशन शायद स्प्लिट स्क्रीन मोड में काम न करे."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ऐप विभाजित स्क्रीन का समर्थन नहीं करता है."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"हो सकता है कि ऐप प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर काम न करे."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर ऐप लॉन्च नहीं किया जा सकता."</string> <string name="accessibility_divider" msgid="703810061635792791">"विभाजित स्क्रीन विभाजक"</string> diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml index 1d618547620f..67488f994468 100644 --- a/libs/WindowManager/Shell/res/values-hr/strings.xml +++ b/libs/WindowManager/Shell/res/values-hr/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Poništite sakrivanje"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikacija možda neće funkcionirati s podijeljenim zaslonom."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacija ne podržava podijeljeni zaslon."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće funkcionirati na sekundarnom zaslonu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim zaslonima."</string> <string name="accessibility_divider" msgid="703810061635792791">"Razdjelnik podijeljenog zaslona"</string> diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml index faa6cb916668..41d2d3176994 100644 --- a/libs/WindowManager/Shell/res/values-hu/strings.xml +++ b/libs/WindowManager/Shell/res/values-hu/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Félretevés megszüntetése"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Lehet, hogy az alkalmazás nem működik osztott képernyős nézetben."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Az alkalmazás nem támogatja az osztott képernyős nézetet."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Előfordulhat, hogy az alkalmazás nem működik másodlagos kijelzőn."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Az alkalmazást nem lehet másodlagos kijelzőn elindítani."</string> <string name="accessibility_divider" msgid="703810061635792791">"Elválasztó az osztott nézetben"</string> diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml index b2f3c38d67bf..502bfb15c932 100644 --- a/libs/WindowManager/Shell/res/values-hy/strings.xml +++ b/libs/WindowManager/Shell/res/values-hy/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Ցուցադրել"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Հավելվածը չի կարող աշխատել տրոհված էկրանի ռեժիմում։"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Հավելվածը չի աջակցում էկրանի տրոհումը:"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Հավելվածը կարող է չաշխատել լրացուցիչ էկրանի վրա"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Հավելվածը չի աջակցում գործարկումը լրացուցիչ էկրանների վրա"</string> <string name="accessibility_divider" msgid="703810061635792791">"Տրոհված էկրանի բաժանիչ"</string> diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml index 0bb76bb04a77..561df7269bcf 100644 --- a/libs/WindowManager/Shell/res/values-in/strings.xml +++ b/libs/WindowManager/Shell/res/values-in/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Batalkan stash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikasi mungkin tidak berfungsi dengan layar terpisah."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"App tidak mendukung layar terpisah."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikasi mungkin tidak berfungsi pada layar sekunder."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikasi tidak mendukung peluncuran pada layar sekunder."</string> <string name="accessibility_divider" msgid="703810061635792791">"Pembagi layar terpisah"</string> diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml index f3cb13d896f8..355968bfb6eb 100644 --- a/libs/WindowManager/Shell/res/values-is/strings.xml +++ b/libs/WindowManager/Shell/res/values-is/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Taka úr geymslu"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Hugsanlega virkar forritið ekki með skjáskiptingu."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Forritið styður ekki að skjánum sé skipt."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Hugsanlegt er að forritið virki ekki á öðrum skjá."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Forrit styður ekki opnun á öðrum skjá."</string> <string name="accessibility_divider" msgid="703810061635792791">"Skjáskipting"</string> diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml index d486128a1794..1417d0021658 100644 --- a/libs/WindowManager/Shell/res/values-it/strings.xml +++ b/libs/WindowManager/Shell/res/values-it/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Annulla accantonamento"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"L\'app potrebbe non funzionare con lo schermo diviso."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"L\'app non supporta la modalità Schermo diviso."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"L\'app potrebbe non funzionare su un display secondario."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'app non supporta l\'avvio su display secondari."</string> <string name="accessibility_divider" msgid="703810061635792791">"Strumento per schermo diviso"</string> diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml index acab582f9be0..b3c0b655ccb1 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ביטול ההסתרה הזמנית"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ייתכן שהאפליקציה לא תפעל במסך מפוצל."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"האפליקציה אינה תומכת במסך מפוצל."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ייתכן שהאפליקציה לא תפעל במסך משני."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"האפליקציה אינה תומכת בהפעלה במסכים משניים."</string> <string name="accessibility_divider" msgid="703810061635792791">"מחלק מסך מפוצל"</string> diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml index 15349a2016fc..a5b0f21882f7 100644 --- a/libs/WindowManager/Shell/res/values-ja/strings.xml +++ b/libs/WindowManager/Shell/res/values-ja/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"表示"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"アプリは分割画面では動作しないことがあります。"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"アプリで分割画面がサポートされていません。"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"アプリはセカンダリ ディスプレイでは動作しないことがあります。"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"アプリはセカンダリ ディスプレイでの起動に対応していません。"</string> <string name="accessibility_divider" msgid="703810061635792791">"分割画面の分割線"</string> diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml index b29c48ef45c8..a85efb433360 100644 --- a/libs/WindowManager/Shell/res/values-ka/strings.xml +++ b/libs/WindowManager/Shell/res/values-ka/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"გადანახვის გაუქმება"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"აპმა შეიძლება არ იმუშაოს გაყოფილი ეკრანის რეჟიმში."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ეკრანის გაყოფა არ არის მხარდაჭერილი აპის მიერ."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"აპმა შეიძლება არ იმუშაოს მეორეულ ეკრანზე."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"აპს არ გააჩნია მეორეული ეკრანის მხარდაჭერა."</string> <string name="accessibility_divider" msgid="703810061635792791">"გაყოფილი ეკრანის რეჟიმის გამყოფი"</string> diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml index 151810c07f69..9c0c15cd6665 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Көрсету"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Қолданба экранды бөлу режимінде жұмыс істемеуі мүмкін."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Қодланба бөлінген экранды қолдамайды."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Қолданба қосымша дисплейде жұмыс істемеуі мүмкін."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Қолданба қосымша дисплейлерде іске қосуды қолдамайды."</string> <string name="accessibility_divider" msgid="703810061635792791">"Бөлінген экран бөлгіші"</string> diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml index afe55bc1babe..d56d6a5c5a78 100644 --- a/libs/WindowManager/Shell/res/values-km/strings.xml +++ b/libs/WindowManager/Shell/res/values-km/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ឈប់លាក់ជាបណ្ដោះអាសន្ន"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"កម្មវិធីអាចនឹងមិនដំណើរការជាមួយមុខងារបំបែកអេក្រង់ទេ។"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"កម្មវិធីមិនគាំទ្រអេក្រង់បំបែកជាពីរទេ"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"កម្មវិធីនេះប្រហែលជាមិនដំណើរការនៅលើអេក្រង់បន្ទាប់បន្សំទេ។"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"កម្មវិធីនេះមិនអាចចាប់ផ្តើមនៅលើអេក្រង់បន្ទាប់បន្សំបានទេ។"</string> <string name="accessibility_divider" msgid="703810061635792791">"កម្មវិធីចែកអេក្រង់បំបែក"</string> diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml index 48c8bba4569c..1b31a6f883bb 100644 --- a/libs/WindowManager/Shell/res/values-kn/strings.xml +++ b/libs/WindowManager/Shell/res/values-kn/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ಅನ್ಸ್ಟ್ಯಾಶ್ ಮಾಡಿ"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ವಿಭಜಿಸಿದ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ಆ್ಯಪ್ ಕೆಲಸ ಮಾಡದೇ ಇರಬಹುದು."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ಅಪ್ಲಿಕೇಶನ್ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ಸೆಕೆಂಡರಿ ಡಿಸ್ಪ್ಲೇಗಳಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕಾರ್ಯ ನಿರ್ವಹಿಸದೇ ಇರಬಹುದು."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ಸೆಕೆಂಡರಿ ಡಿಸ್ಪ್ಲೇಗಳಲ್ಲಿ ಪ್ರಾರಂಭಿಸುವಿಕೆಯನ್ನು ಅಪ್ಲಿಕೇಶನ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string> <string name="accessibility_divider" msgid="703810061635792791">"ಸ್ಪ್ಲಿಟ್-ಪರದೆ ಡಿವೈಡರ್"</string> diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml index f740076ccec4..563db5b7e7c2 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"숨기기 취소"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"앱이 분할 화면에서 작동하지 않을 수 있습니다."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"앱이 화면 분할을 지원하지 않습니다."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"앱이 보조 디스플레이에서 작동하지 않을 수도 있습니다."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"앱이 보조 디스플레이에서의 실행을 지원하지 않습니다."</string> <string name="accessibility_divider" msgid="703810061635792791">"화면 분할기"</string> diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml index 5b33fc7a8b3f..0497d15671ed 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Сейфтен чыгаруу"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Колдонмодо экран бөлүнбөшү мүмкүн."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Колдонмодо экран бөлүнбөйт."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Колдонмо кошумча экранда иштебей коюшу мүмкүн."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Колдонмону кошумча экрандарда иштетүүгө болбойт."</string> <string name="accessibility_divider" msgid="703810061635792791">"Экранды бөлгүч"</string> diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml index 91cd78d84339..35aecaaada6c 100644 --- a/libs/WindowManager/Shell/res/values-lo/strings.xml +++ b/libs/WindowManager/Shell/res/values-lo/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ເອົາອອກຈາກບ່ອນເກັບສ່ວນຕົວ"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ແອັບອາດໃຊ້ບໍ່ໄດ້ກັບການແບ່ງໜ້າຈໍ."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ແອັບບໍ່ຮອງຮັບໜ້າຈໍແບບແຍກກັນ."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ແອັບອາດບໍ່ສາມາດໃຊ້ໄດ້ໃນໜ້າຈໍທີສອງ."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ແອັບບໍ່ຮອງຮັບການເປີດໃນໜ້າຈໍທີສອງ."</string> <string name="accessibility_divider" msgid="703810061635792791">"ຕົວຂັ້ນການແບ່ງໜ້າຈໍ"</string> diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml index 75f0fd4cfa41..f4ed192f2fa8 100644 --- a/libs/WindowManager/Shell/res/values-lt/strings.xml +++ b/libs/WindowManager/Shell/res/values-lt/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Nebeslėpti"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Programa gali neveikti naudojant išskaidyto ekrano režimą."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Programoje nepalaikomas skaidytas ekranas."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Programa gali neveikti antriniame ekrane."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Programa nepalaiko paleisties antriniuose ekranuose."</string> <string name="accessibility_divider" msgid="703810061635792791">"Skaidyto ekrano daliklis"</string> diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml index e3bbf78f9439..ffb9ddb9f4b0 100644 --- a/libs/WindowManager/Shell/res/values-lv/strings.xml +++ b/libs/WindowManager/Shell/res/values-lv/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Rādīt"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Iespējams, lietotne nedarbosies ekrāna sadalīšanas režīmā."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Lietotnē netiek atbalstīta ekrāna sadalīšana."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Lietotne, iespējams, nedarbosies sekundārajā displejā."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Lietotnē netiek atbalstīta palaišana sekundārajos displejos."</string> <string name="accessibility_divider" msgid="703810061635792791">"Ekrāna sadalītājs"</string> diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml index 512518072f84..cf6b9d5bf627 100644 --- a/libs/WindowManager/Shell/res/values-mk/strings.xml +++ b/libs/WindowManager/Shell/res/values-mk/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Прикажете"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Апликацијата може да не работи со поделен екран."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Апликацијата не поддржува поделен екран."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апликацијата може да не функционира на друг екран."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Апликацијата не поддржува стартување на други екрани."</string> <string name="accessibility_divider" msgid="703810061635792791">"Разделник на поделен екран"</string> diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml index ab904c05591b..05e28ac5f13c 100644 --- a/libs/WindowManager/Shell/res/values-ml/strings.xml +++ b/libs/WindowManager/Shell/res/values-ml/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"അൺസ്റ്റാഷ് ചെയ്യൽ"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"സ്ക്രീൻ വിഭജന മോഡിൽ ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"സ്പ്ലിറ്റ്-സ്ക്രീനിനെ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"രണ്ടാം ഡിസ്പ്ലേയിൽ ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"രണ്ടാം ഡിസ്പ്ലേകളിൽ സമാരംഭിക്കുന്നതിനെ ആപ്പ് അനുവദിക്കുന്നില്ല."</string> <string name="accessibility_divider" msgid="703810061635792791">"സ്പ്ലിറ്റ്-സ്ക്രീൻ ഡിവൈഡർ"</string> diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml index 43e67c2dbb3b..54513d1866ee 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Ил гаргах"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Апп хуваагдсан дэлгэц дээр ажиллахгүй байж болзошгүй."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Энэ апп нь дэлгэц хуваах тохиргоог дэмждэггүй."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апп хоёрдогч дэлгэцэд ажиллахгүй."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Аппыг хоёрдогч дэлгэцэд эхлүүлэх боломжгүй."</string> <string name="accessibility_divider" msgid="703810061635792791">"\"Дэлгэц хуваах\" хуваагч"</string> diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml index a0ce393b5763..283348028979 100644 --- a/libs/WindowManager/Shell/res/values-mr/strings.xml +++ b/libs/WindowManager/Shell/res/values-mr/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"अनस्टॅश करा"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"अॅप कदाचित स्प्लिट स्क्रीनसह काम करू शकत नाही."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"अॅप स्क्रीन-विभाजनास समर्थन देत नाही."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"दुसऱ्या डिस्प्लेवर अॅप कदाचित चालणार नाही."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"दुसऱ्या डिस्प्लेवर अॅप लाँच होणार नाही."</string> <string name="accessibility_divider" msgid="703810061635792791">"विभाजित-स्क्रीन विभाजक"</string> diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml index e1d4947e9013..20f8ff69ebc1 100644 --- a/libs/WindowManager/Shell/res/values-ms/strings.xml +++ b/libs/WindowManager/Shell/res/values-ms/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Tunjukkan"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Apl mungkin tidak berfungsi dengan skrin pisah."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Apl tidak menyokong skrin pisah."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Apl mungkin tidak berfungsi pada paparan kedua."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Apl tidak menyokong pelancaran pada paparan kedua."</string> <string name="accessibility_divider" msgid="703810061635792791">"Pembahagi skrin pisah"</string> diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml index 70d4f3d07485..6081a1cb6c60 100644 --- a/libs/WindowManager/Shell/res/values-my/strings.xml +++ b/libs/WindowManager/Shell/res/values-my/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"မသိုဝှက်ရန်"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းဖြင့် အက်ပ်သည် အလုပ်မလုပ်ပါ။"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"အက်ပ်သည် မျက်နှာပြင်ခွဲပြရန် ပံ့ပိုးထားခြင်းမရှိပါ။"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ဤအက်ပ်အနေဖြင့် ဒုတိယဖန်သားပြင်ပေါ်တွင် အလုပ်လုပ်မည် မဟုတ်ပါ။"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ဤအက်ပ်အနေဖြင့် ဖွင့်ရန်စနစ်ကို ဒုတိယဖန်သားပြင်မှ အသုံးပြုရန် ပံ့ပိုးမထားပါ။"</string> <string name="accessibility_divider" msgid="703810061635792791">"မျက်နှာပြင်ခွဲခြမ်း ပိုင်းခြားပေးသည့်စနစ်"</string> diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml index 649bb727c121..dd2750b339a2 100644 --- a/libs/WindowManager/Shell/res/values-nb/strings.xml +++ b/libs/WindowManager/Shell/res/values-nb/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Avslutt oppbevaring"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Det kan hende at appen ikke fungerer med delt skjerm."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Appen støtter ikke delt skjerm."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen fungerer kanskje ikke på en sekundær skjerm."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan ikke kjøres på sekundære skjermer."</string> <string name="accessibility_divider" msgid="703810061635792791">"Skilleelement for delt skjerm"</string> diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml index 976f4018ac61..4a937cf92d12 100644 --- a/libs/WindowManager/Shell/res/values-ne/strings.xml +++ b/libs/WindowManager/Shell/res/values-ne/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"अनस्ट्यास गर्नुहोस्"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"एप विभाजित स्क्रिनमा काम नगर्न सक्छ।"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"अनुप्रयोगले विभाजित-स्क्रिनलाई समर्थन गर्दैन।"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"यो एपले सहायक प्रदर्शनमा काम नगर्नसक्छ।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"अनुप्रयोगले सहायक प्रदर्शनहरूमा लञ्च सुविधालाई समर्थन गर्दैन।"</string> <string name="accessibility_divider" msgid="703810061635792791">"विभाजित-स्क्रिन छुट्याउने"</string> diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml index 3dee016f84bf..054f05f4bb8d 100644 --- a/libs/WindowManager/Shell/res/values-nl/strings.xml +++ b/libs/WindowManager/Shell/res/values-nl/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Niet meer verbergen"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"De app werkt mogelijk niet met gesplitst scherm."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"App biedt geen ondersteuning voor gesplitst scherm."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App werkt mogelijk niet op een secundair scherm."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App kan niet op secundaire displays worden gestart."</string> <string name="accessibility_divider" msgid="703810061635792791">"Scheiding voor gesplitst scherm"</string> diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml index b5e87c479b15..d0971a35e622 100644 --- a/libs/WindowManager/Shell/res/values-or/strings.xml +++ b/libs/WindowManager/Shell/res/values-or/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ଦେଖାନ୍ତୁ"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରିନରେ ଆପ୍ କାମ କରିନପାରେ।"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ଆପ୍ ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରୀନକୁ ସପୋର୍ଟ କରେ ନାହିଁ।"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍ କାମ ନକରିପାରେ।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍ ଲଞ୍ଚ ସପୋର୍ଟ କରେ ନାହିଁ।"</string> <string name="accessibility_divider" msgid="703810061635792791">"ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରୀନ ବିଭାଜକ"</string> diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml index 8e0f103c2152..989f8fce4f50 100644 --- a/libs/WindowManager/Shell/res/values-pa/strings.xml +++ b/libs/WindowManager/Shell/res/values-pa/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ਅਣਸਟੈਸ਼"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ।"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ।"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇ \'ਤੇ ਕੰਮ ਨਾ ਕਰੇ।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇਆਂ \'ਤੇ ਲਾਂਚ ਕਰਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string> <string name="accessibility_divider" msgid="703810061635792791">"ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਡਿਵਾਈਡਰ"</string> diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml index 69ea2eabfee3..3458f261dfdd 100644 --- a/libs/WindowManager/Shell/res/values-pl/strings.xml +++ b/libs/WindowManager/Shell/res/values-pl/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Zabierz ze schowka"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikacja może nie działać przy podzielonym ekranie."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacja nie obsługuje dzielonego ekranu."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacja może nie działać na dodatkowym ekranie."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacja nie obsługuje uruchamiania na dodatkowych ekranach."</string> <string name="accessibility_divider" msgid="703810061635792791">"Linia dzielenia ekranu"</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml index cb4395397a69..0a77c64bf6ed 100644 --- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Exibir"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"É possível que o app não funcione com a tela dividida."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"O app não é compatível com a divisão de tela."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É possível que o app não funcione em uma tela secundária."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"O app não é compatível com a inicialização em telas secundárias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de tela"</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml index 19b1771db6e6..aeb7f9a296b3 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Remover do armazenamento"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"A app pode não funcionar com o ecrã dividido."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"A app não é compatível com o ecrã dividido."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"A app pode não funcionar num ecrã secundário."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"A app não é compatível com o início em ecrãs secundários."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor do ecrã dividido"</string> diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml index cb4395397a69..0a77c64bf6ed 100644 --- a/libs/WindowManager/Shell/res/values-pt/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Exibir"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"É possível que o app não funcione com a tela dividida."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"O app não é compatível com a divisão de tela."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É possível que o app não funcione em uma tela secundária."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"O app não é compatível com a inicialização em telas secundárias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de tela"</string> diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml index d8058f814f54..23b209940490 100644 --- a/libs/WindowManager/Shell/res/values-ro/strings.xml +++ b/libs/WindowManager/Shell/res/values-ro/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Anulează stocarea"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Este posibil ca aplicația să nu funcționeze cu ecranul împărțit."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplicația nu acceptă ecranul împărțit."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Este posibil ca aplicația să nu funcționeze pe un ecran secundar."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplicația nu acceptă lansare pe ecrane secundare."</string> <string name="accessibility_divider" msgid="703810061635792791">"Separator pentru ecranul împărțit"</string> diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml index f6bfb5317839..c1dfb19162fe 100644 --- a/libs/WindowManager/Shell/res/values-ru/strings.xml +++ b/libs/WindowManager/Shell/res/values-ru/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Показать"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"В режиме разделения экрана приложение может работать нестабильно."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Приложение не поддерживает разделение экрана."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Приложение может не работать на дополнительном экране"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Приложение не поддерживает запуск на дополнительных экранах"</string> <string name="accessibility_divider" msgid="703810061635792791">"Разделитель экрана"</string> diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml index 4504500c37a4..5e51003e4429 100644 --- a/libs/WindowManager/Shell/res/values-si/strings.xml +++ b/libs/WindowManager/Shell/res/values-si/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"සඟවා තැබීම ඉවත් කරන්න"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"යෙදුම බෙදුම් තිරය සමග ක්රියා නොකළ හැකිය"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"යෙදුම බෙදුණු-තිරය සඳහා සහාය නොදක්වයි."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"යෙදුම ද්විතියික සංදර්ශකයක ක්රියා නොකළ හැකිය."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"යෙදුම ද්විතීයික සංදර්ශක මත දියත් කිරීම සඳහා සහාය නොදක්වයි."</string> <string name="accessibility_divider" msgid="703810061635792791">"බෙදුම්-තිර වෙන්කරණය"</string> diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml index f597113b3bef..baf03241dcc6 100644 --- a/libs/WindowManager/Shell/res/values-sk/strings.xml +++ b/libs/WindowManager/Shell/res/values-sk/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Zrušiť skrytie"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikácia nemusí fungovať s rozdelenou obrazovkou."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikácia nepodporuje rozdelenú obrazovku."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikácia nemusí fungovať na sekundárnej obrazovke."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikácia nepodporuje spúšťanie na sekundárnych obrazovkách."</string> <string name="accessibility_divider" msgid="703810061635792791">"Rozdeľovač obrazovky"</string> diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml index 3ca193f83138..2a12a64b6076 100644 --- a/libs/WindowManager/Shell/res/values-sl/strings.xml +++ b/libs/WindowManager/Shell/res/values-sl/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Razkrij"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikacija morda ne deluje v načinu razdeljenega zaslona."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacija ne podpira načina razdeljenega zaslona."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija morda ne bo delovala na sekundarnem zaslonu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podpira zagona na sekundarnih zaslonih."</string> <string name="accessibility_divider" msgid="703810061635792791">"Razdelilnik zaslonov"</string> diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml index d1d215f5875a..eb0199f55eed 100644 --- a/libs/WindowManager/Shell/res/values-sq/strings.xml +++ b/libs/WindowManager/Shell/res/values-sq/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Mos e fshih"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikacioni mund të mos funksionojë me ekranin e ndarë."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacioni nuk mbështet ekranin e ndarë."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacioni mund të mos funksionojë në një ekran dytësor."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacioni nuk mbështet nisjen në ekrane dytësore."</string> <string name="accessibility_divider" msgid="703810061635792791">"Ndarësi i ekranit të ndarë"</string> diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml index 085b9e509be2..6e6019c160fe 100644 --- a/libs/WindowManager/Shell/res/values-sr/strings.xml +++ b/libs/WindowManager/Shell/res/values-sr/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Уклоните из тајне меморије"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Апликација можда неће радити са подељеним екраном."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Апликација не подржава подељени екран."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апликација можда неће функционисати на секундарном екрану."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Апликација не подржава покретање на секундарним екранима."</string> <string name="accessibility_divider" msgid="703810061635792791">"Разделник подељеног екрана"</string> diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml index 2b7997cd1d48..419c31d3fb83 100644 --- a/libs/WindowManager/Shell/res/values-sv/strings.xml +++ b/libs/WindowManager/Shell/res/values-sv/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Återställ stash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Appen kanske inte fungerar med delad skärm."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Appen har inte stöd för delad skärm."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen kanske inte fungerar på en sekundär skärm."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan inte köras på en sekundär skärm."</string> <string name="accessibility_divider" msgid="703810061635792791">"Avdelare för delad skärm"</string> diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml index 61b6c07bf064..2f734250438a 100644 --- a/libs/WindowManager/Shell/res/values-sw/strings.xml +++ b/libs/WindowManager/Shell/res/values-sw/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Fichua"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Huenda programu isifanye kazi kwenye skrini inayogawanywa."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Programu haiwezi kutumia skrini iliyogawanywa."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Huenda programu isifanye kazi kwenye dirisha lingine."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Programu hii haiwezi kufunguliwa kwenye madirisha mengine."</string> <string name="accessibility_divider" msgid="703810061635792791">"Kitenganishi cha skrini inayogawanywa"</string> diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml index dfc03bc9f17e..6c152ce71b23 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"திரைப் பிரிப்பு அம்சத்தில் ஆப்ஸ் செயல்படாமல் போகக்கூடும்."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"திரையைப் பிரிப்பதைப் ஆப்ஸ் ஆதரிக்கவில்லை."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"இரண்டாம்நிலைத் திரையில் ஆப்ஸ் வேலை செய்யாமல் போகக்கூடும்."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"இரண்டாம்நிலைத் திரைகளில் பயன்பாட்டைத் தொடங்க முடியாது."</string> <string name="accessibility_divider" msgid="703810061635792791">"திரையைப் பிரிக்கும் பிரிப்பான்"</string> diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml index d13ebb62d5a2..0c9b96d5e36c 100644 --- a/libs/WindowManager/Shell/res/values-te/strings.xml +++ b/libs/WindowManager/Shell/res/values-te/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ఆన్స్టాచ్"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"స్క్రీన్ విభజనతో యాప్ పని చేయకపోవచ్చు."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"యాప్లో స్క్రీన్ విభజనకు మద్దతు లేదు."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ప్రత్యామ్నాయ డిస్ప్లేలో యాప్ పని చేయకపోవచ్చు."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ప్రత్యామ్నాయ డిస్ప్లేల్లో ప్రారంభానికి యాప్ మద్దతు లేదు."</string> <string name="accessibility_divider" msgid="703810061635792791">"విభజన స్క్రీన్ విభాగిని"</string> diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml index d1d0d9f25017..94abe5b97845 100644 --- a/libs/WindowManager/Shell/res/values-th/strings.xml +++ b/libs/WindowManager/Shell/res/values-th/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"เอาออกจากที่เก็บส่วนตัว"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"แอปอาจใช้ไม่ได้กับโหมดแบ่งหน้าจอ"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"แอปไม่สนับสนุนการแยกหน้าจอ"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"แอปอาจไม่ทำงานในจอแสดงผลรอง"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"แอปไม่รองรับการเรียกใช้ในจอแสดงผลรอง"</string> <string name="accessibility_divider" msgid="703810061635792791">"เส้นแบ่งหน้าจอ"</string> diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml index db0f033021e3..589bedd023c5 100644 --- a/libs/WindowManager/Shell/res/values-tl/strings.xml +++ b/libs/WindowManager/Shell/res/values-tl/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"I-unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Posibleng hindi gumana ang app sa split screen."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Hindi sinusuportahan ng app ang split-screen."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Maaaring hindi gumana ang app sa pangalawang display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Hindi sinusuportahan ng app ang paglulunsad sa mga pangalawang display."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divider ng split-screen"</string> diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml index 7b737781343e..6b73f2f7ed7b 100644 --- a/libs/WindowManager/Shell/res/values-tr/strings.xml +++ b/libs/WindowManager/Shell/res/values-tr/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Depolama"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Uygulama bölünmüş ekranda çalışmayabilir."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Uygulama bölünmüş ekranı desteklemiyor."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Uygulama ikincil ekranda çalışmayabilir."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Uygulama ikincil ekranlarda başlatılmayı desteklemiyor."</string> <string name="accessibility_divider" msgid="703810061635792791">"Bölünmüş ekran ayırıcı"</string> diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml index 893e005f5e11..2650b761e7c1 100644 --- a/libs/WindowManager/Shell/res/values-uk/strings.xml +++ b/libs/WindowManager/Shell/res/values-uk/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Показати"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Додаток може не працювати в режимі розділеного екрана."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Додаток не підтримує розділення екрана."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Додаток може не працювати на додатковому екрані."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Додаток не підтримує запуск на додаткових екранах."</string> <string name="accessibility_divider" msgid="703810061635792791">"Розділювач екрана"</string> diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml index c7c7843e0ed6..50908cc24fbd 100644 --- a/libs/WindowManager/Shell/res/values-ur/strings.xml +++ b/libs/WindowManager/Shell/res/values-ur/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ممکن ہے کہ ایپ اسپلٹ اسکرین کے ساتھ کام نہ کرے۔"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ایپ سپلٹ اسکرین کو سپورٹ نہیں کرتی۔"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ممکن ہے ایپ ثانوی ڈسپلے پر کام نہ کرے۔"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ایپ ثانوی ڈسپلیز پر شروعات کا تعاون نہیں کرتی۔"</string> <string name="accessibility_divider" msgid="703810061635792791">"سپلٹ اسکرین تقسیم کار"</string> diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml index 7f8ec01d238f..e0b802e6b0b9 100644 --- a/libs/WindowManager/Shell/res/values-uz/strings.xml +++ b/libs/WindowManager/Shell/res/values-uz/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Chiqarish"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Bu ilova ekranni ikkiga ajratish rejimini dastaklamaydi."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Bu ilova ekranni bo‘lish xususiyatini qo‘llab-quvvatlamaydi."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Bu ilova qo‘shimcha ekranda ishlamasligi mumkin."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Bu ilova qo‘shimcha ekranlarda ishga tushmaydi."</string> <string name="accessibility_divider" msgid="703810061635792791">"Ekranni ikkiga bo‘lish chizig‘i"</string> diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml index e66ccf4872f8..71c3632714f1 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Hiện"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Ứng dụng có thể không hoạt động với tính năng chia đôi màn hình."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Ứng dụng không hỗ trợ chia đôi màn hình."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Ứng dụng có thể không hoạt động trên màn hình phụ."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Ứng dụng không hỗ trợ khởi chạy trên màn hình phụ."</string> <string name="accessibility_divider" msgid="703810061635792791">"Bộ chia chia đôi màn hình"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml index c88d49fb5ef6..35ff2f22be03 100644 --- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"取消隐藏"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"应用可能无法在分屏模式下正常运行。"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"应用不支持分屏。"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"应用可能无法在辅显示屏上正常运行。"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"应用不支持在辅显示屏上启动。"</string> <string name="accessibility_divider" msgid="703810061635792791">"分屏分隔线"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index 8bf304eccc00..9c17f64b881f 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"取消保護"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"應用程式可能無法在分割畫面中運作。"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"應用程式不支援分割畫面。"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"應用程式可能無法在次要顯示屏上運作。"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"應用程式無法在次要顯示屏上啟動。"</string> <string name="accessibility_divider" msgid="703810061635792791">"分割畫面分隔線"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml index 17ea42d3a0e1..c4d9ca467a82 100644 --- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"取消暫時隱藏"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"應用程式可能無法在分割畫面中運作。"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"這個應用程式不支援分割畫面。"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"應用程式可能無法在次要顯示器上運作。"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"應用程式無法在次要顯示器上啟動。"</string> <string name="accessibility_divider" msgid="703810061635792791">"分割畫面分隔線"</string> diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml index 414706fe429f..4d8f7e33d47e 100644 --- a/libs/WindowManager/Shell/res/values-zu/strings.xml +++ b/libs/WindowManager/Shell/res/values-zu/strings.xml @@ -33,6 +33,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Susa isiteshi"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Izinhlelo zokusebenza kungenzeka zingasebenzi ngesikrini esihlukanisiwe."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Uhlelo lokusebenza alusekeli isikrini esihlukanisiwe."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Uhlelo lokusebenza kungenzeka lungasebenzi kusibonisi sesibili."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Uhlelo lokusebenza alusekeli ukuqalisa kuzibonisi zesibili."</string> <string name="accessibility_divider" msgid="703810061635792791">"Isihlukanisi sokuhlukanisa isikrini"</string> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java index 65a7d09dafa3..d10a6744b5f1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java @@ -86,11 +86,11 @@ class ActivityEmbeddingAnimationSpec { final int startLeft; final int startTop; if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) { - // The window will be animated in from left or right depends on its position. + // The window will be animated in from left or right depending on its position. startTop = 0; startLeft = parentBounds.left == bounds.left ? -bounds.width() : bounds.width(); } else { - // The window will be animated in from top or bottom depends on its position. + // The window will be animated in from top or bottom depending on its position. startTop = parentBounds.top == bounds.top ? -bounds.height() : bounds.height(); startLeft = 0; } @@ -114,11 +114,11 @@ class ActivityEmbeddingAnimationSpec { final int endTop; final int endLeft; if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) { - // The window will be animated out to left or right depends on its position. + // The window will be animated out to left or right depending on its position. endTop = 0; endLeft = parentBounds.left == bounds.left ? -bounds.width() : bounds.width(); } else { - // The window will be animated out to top or bottom depends on its position. + // The window will be animated out to top or bottom depending on its position. endTop = parentBounds.top == bounds.top ? -bounds.height() : bounds.height(); endLeft = 0; } diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java index 3d08959901b1..552a42300839 100644 --- a/media/java/android/media/AudioDeviceInfo.java +++ b/media/java/android/media/AudioDeviceInfo.java @@ -624,7 +624,6 @@ public final class AudioDeviceInfo { INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, TYPE_BLUETOOTH_A2DP); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, TYPE_BLUETOOTH_A2DP); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI, TYPE_HDMI); - INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, TYPE_DOCK); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, TYPE_DOCK); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_ACCESSORY, TYPE_USB_ACCESSORY); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_DEVICE, TYPE_USB_DEVICE); @@ -652,7 +651,6 @@ public final class AudioDeviceInfo { INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_HDMI, TYPE_HDMI); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_TELEPHONY_RX, TYPE_TELEPHONY); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BACK_MIC, TYPE_BUILTIN_MIC); - INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET, TYPE_DOCK); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_DGTL_DOCK_HEADSET, TYPE_DOCK); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_ACCESSORY, TYPE_USB_ACCESSORY); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_DEVICE, TYPE_USB_DEVICE); @@ -687,7 +685,7 @@ public final class AudioDeviceInfo { EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_DEVICE, AudioSystem.DEVICE_OUT_USB_DEVICE); EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_HEADSET, AudioSystem.DEVICE_OUT_USB_HEADSET); EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_ACCESSORY, AudioSystem.DEVICE_OUT_USB_ACCESSORY); - EXT_TO_INT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET); + EXT_TO_INT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET); EXT_TO_INT_DEVICE_MAPPING.put(TYPE_FM, AudioSystem.DEVICE_OUT_FM); EXT_TO_INT_DEVICE_MAPPING.put(TYPE_TELEPHONY, AudioSystem.DEVICE_OUT_TELEPHONY_TX); EXT_TO_INT_DEVICE_MAPPING.put(TYPE_AUX_LINE, AudioSystem.DEVICE_OUT_AUX_LINE); @@ -710,7 +708,7 @@ public final class AudioDeviceInfo { TYPE_WIRED_HEADSET, AudioSystem.DEVICE_IN_WIRED_HEADSET); EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_HDMI, AudioSystem.DEVICE_IN_HDMI); EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_TELEPHONY, AudioSystem.DEVICE_IN_TELEPHONY_RX); - EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_IN_DGTL_DOCK_HEADSET); EXT_TO_INT_INPUT_DEVICE_MAPPING.put( TYPE_USB_ACCESSORY, AudioSystem.DEVICE_IN_USB_ACCESSORY); EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_USB_DEVICE, AudioSystem.DEVICE_IN_USB_DEVICE); diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 0731b6baf721..216fd614dc63 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -242,7 +242,7 @@ <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver y usar los dispositivos disponibles, activa la depuración inalámbrica"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Vincular dispositivo mediante código QR"</string> <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Vincular dispositivos nuevos mediante escáner de código QR"</string> - <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Vincular dispositivo con código de sincronización"</string> + <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Vincular dispositivo con un código de vinculación"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Vincular dispositivos nuevos mediante código de seis dígitos"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Dispositivos vinculados"</string> <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Conectado actualmente"</string> diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java index 8946516af8a2..92a938cb0b47 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java @@ -53,6 +53,7 @@ public class SecureSettings { Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, + Settings.Secure.CONTRAST_LEVEL, Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, Settings.Secure.ACCESSIBILITY_CAPTIONING_LOCALE, diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index cbf79530a6b6..eabf4cc8edfd 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java @@ -86,6 +86,7 @@ public class SecureSettingsValidators { VALIDATORS.put(Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, BOOLEAN_VALIDATOR); + VALIDATORS.put(Secure.CONTRAST_LEVEL, new InclusiveFloatRangeValidator(-1f, 1f)); VALIDATORS.put( Secure.ACCESSIBILITY_CAPTIONING_PRESET, new DiscreteValueValidator(new String[] {"-1", "0", "1", "2", "3", "4"})); diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index aa3a983e9971..a78faaf90c37 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -1756,6 +1756,9 @@ class SettingsProtoDumpUtil { Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, SecureSettingsProto.Accessibility.HIGH_TEXT_CONTRAST_ENABLED); dumpSetting(s, p, + Settings.Secure.CONTRAST_LEVEL, + SecureSettingsProto.Accessibility.CONTRAST_LEVEL); + dumpSetting(s, p, Settings.Secure.FONT_WEIGHT_ADJUSTMENT, SecureSettingsProto.FONT_WEIGHT_ADJUSTMENT); dumpSetting(s, p, diff --git a/packages/SystemUI/res/values-h700dp/dimens.xml b/packages/SystemUI/customization/res/values-h700dp/dimens.xml index fbd985eaa751..2a15981ab940 100644 --- a/packages/SystemUI/res/values-h700dp/dimens.xml +++ b/packages/SystemUI/customization/res/values-h700dp/dimens.xml @@ -1,5 +1,5 @@ <!-- - ~ Copyright (C) 2021 The Android Open Source Project + ~ Copyright (C) 2022 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. @@ -17,4 +17,4 @@ <resources> <!-- Large clock maximum font size (dp is intentional, to prevent any further scaling) --> <dimen name="large_clock_text_size">170dp</dimen> -</resources> +</resources>
\ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-h800dp/dimens.xml b/packages/SystemUI/customization/res/values-h800dp/dimens.xml new file mode 100644 index 000000000000..60afc8a97a71 --- /dev/null +++ b/packages/SystemUI/customization/res/values-h800dp/dimens.xml @@ -0,0 +1,20 @@ +<!-- + ~ Copyright (C) 2022 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 + --> + +<resources> + <!-- Large clock maximum font size (dp is intentional, to prevent any further scaling) --> + <dimen name="large_clock_text_size">200dp</dimen> +</resources> diff --git a/packages/SystemUI/customization/res/values/dimens.xml b/packages/SystemUI/customization/res/values/dimens.xml index 8f90f0fefdb5..ba8f2843cdfc 100644 --- a/packages/SystemUI/customization/res/values/dimens.xml +++ b/packages/SystemUI/customization/res/values/dimens.xml @@ -17,8 +17,8 @@ --> <resources> <!-- Clock maximum font size (dp is intentional, to prevent any further scaling) --> - <dimen name="large_clock_text_size">150sp</dimen> - <dimen name="small_clock_text_size">86sp</dimen> + <dimen name="large_clock_text_size">150dp</dimen> + <dimen name="small_clock_text_size">86dp</dimen> <!-- Default line spacing multiplier between hours and minutes of the keyguard clock --> <item name="keyguard_clock_line_spacing_scale" type="dimen" format="float">.7</item> diff --git a/packages/SystemUI/res/drawable/ic_ring_volume.xml b/packages/SystemUI/res/drawable/ic_ring_volume.xml new file mode 100644 index 000000000000..343fe5d4cb69 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_ring_volume.xml @@ -0,0 +1,26 @@ +<!-- + Copyright (C) 2022 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?android:attr/colorControlNormal"> + <path + android:pathData="M11,7V2H13V7ZM17.6,9.85 L16.2,8.4 19.75,4.85 21.15,6.3ZM6.4,9.85 L2.85,6.3 4.25,4.85 7.8,8.4ZM12,12Q14.95,12 17.812,13.188Q20.675,14.375 22.9,16.75Q23.2,17.05 23.2,17.45Q23.2,17.85 22.9,18.15L20.6,20.4Q20.325,20.675 19.963,20.7Q19.6,20.725 19.3,20.5L16.4,18.3Q16.2,18.15 16.1,17.95Q16,17.75 16,17.5V14.65Q15.05,14.35 14.05,14.175Q13.05,14 12,14Q10.95,14 9.95,14.175Q8.95,14.35 8,14.65V17.5Q8,17.75 7.9,17.95Q7.8,18.15 7.6,18.3L4.7,20.5Q4.4,20.725 4.038,20.7Q3.675,20.675 3.4,20.4L1.1,18.15Q0.8,17.85 0.8,17.45Q0.8,17.05 1.1,16.75Q3.3,14.375 6.175,13.188Q9.05,12 12,12ZM6,15.35Q5.275,15.725 4.6,16.212Q3.925,16.7 3.2,17.3L4.2,18.3L6,16.9ZM18,15.4V16.9L19.8,18.3L20.8,17.35Q20.075,16.7 19.4,16.225Q18.725,15.75 18,15.4ZM6,15.35Q6,15.35 6,15.35Q6,15.35 6,15.35ZM18,15.4Q18,15.4 18,15.4Q18,15.4 18,15.4Z" + android:fillColor="?android:attr/colorPrimary"/> + +</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_ring_volume_off.xml b/packages/SystemUI/res/drawable/ic_ring_volume_off.xml new file mode 100644 index 000000000000..74f30d1a44d2 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_ring_volume_off.xml @@ -0,0 +1,34 @@ +<!-- + Copyright (C) 2022 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?android:attr/colorControlNormal"> +<path + android:pathData="M0.8,4.2l8.1,8.1c-2.2,0.5 -5.2,1.6 -7.8,4.4c-0.4,0.4 -0.4,1 0,1.4l2.3,2.3c0.3,0.3 0.9,0.4 1.3,0.1l2.9,-2.2C7.8,18.1 8,17.8 8,17.5v-2.9c0.9,-0.3 1.7,-0.5 2.7,-0.6l8.5,8.5l1.4,-1.4L2.2,2.8L0.8,4.2z" + android:fillColor="?android:attr/colorPrimary"/> + <path + android:pathData="M11,2h2v5h-2z" + android:fillColor="?android:attr/colorPrimary"/> + <path + android:pathData="M21.2,6.3l-1.4,-1.4l-3.6,3.6l1.4,1.4C17.6,9.8 21,6.3 21.2,6.3z" + android:fillColor="?android:attr/colorPrimary"/> + <path + android:pathData="M22.9,16.7c-2.8,-3 -6.2,-4.1 -8.4,-4.5l7.2,7.2l1.3,-1.3C23.3,17.7 23.3,17.1 22.9,16.7z" + android:fillColor="?android:attr/colorPrimary"/> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_speaker_mute.xml b/packages/SystemUI/res/drawable/ic_speaker_mute.xml new file mode 100644 index 000000000000..4e402cf530e4 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_speaker_mute.xml @@ -0,0 +1,25 @@ +<!-- + ~ Copyright (C) 2022 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. + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?android:attr/textColorPrimary" + android:autoMirrored="true"> + <path android:fillColor="#FFFFFFFF" + android:pathData="M19.8,22.6 L16.775,19.575Q16.15,19.975 15.45,20.263Q14.75,20.55 14,20.725V18.675Q14.35,18.55 14.688,18.425Q15.025,18.3 15.325,18.125L12,14.8V20L7,15H3V9H6.2L1.4,4.2L2.8,2.8L21.2,21.2ZM19.6,16.8 L18.15,15.35Q18.575,14.575 18.788,13.725Q19,12.875 19,11.975Q19,9.625 17.625,7.775Q16.25,5.925 14,5.275V3.225Q17.1,3.925 19.05,6.362Q21,8.8 21,11.975Q21,13.3 20.638,14.525Q20.275,15.75 19.6,16.8ZM16.25,13.45 L14,11.2V7.95Q15.175,8.5 15.838,9.6Q16.5,10.7 16.5,12Q16.5,12.375 16.438,12.738Q16.375,13.1 16.25,13.45ZM12,9.2 L9.4,6.6 12,4ZM10,15.15V12.8L8.2,11H5V13H7.85ZM9.1,11.9Z"/> +</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_speaker_on.xml b/packages/SystemUI/res/drawable/ic_speaker_on.xml new file mode 100644 index 000000000000..2a90e051b83b --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_speaker_on.xml @@ -0,0 +1,25 @@ +<!-- + ~ Copyright (C) 2022 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. + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?android:attr/textColorPrimary" + android:autoMirrored="true"> + <path android:fillColor="#FFFFFFFF" + android:pathData="M14,20.725V18.675Q16.25,18.025 17.625,16.175Q19,14.325 19,11.975Q19,9.625 17.625,7.775Q16.25,5.925 14,5.275V3.225Q17.1,3.925 19.05,6.362Q21,8.8 21,11.975Q21,15.15 19.05,17.587Q17.1,20.025 14,20.725ZM3,15V9H7L12,4V20L7,15ZM14,16V7.95Q15.175,8.5 15.838,9.6Q16.5,10.7 16.5,12Q16.5,13.275 15.838,14.362Q15.175,15.45 14,16ZM10,8.85 L7.85,11H5V13H7.85L10,15.15ZM7.5,12Z"/> +</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/screenrecord_options_spinner_popup_background.xml b/packages/SystemUI/res/drawable/screenrecord_options_spinner_popup_background.xml new file mode 100644 index 000000000000..9a022960d1e3 --- /dev/null +++ b/packages/SystemUI/res/drawable/screenrecord_options_spinner_popup_background.xml @@ -0,0 +1,21 @@ +<!-- + ~ Copyright (C) 2022 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. + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:shape="rectangle"> + <corners android:radius="@dimen/screenrecord_spinner_background_radius"/> + <solid android:color="?androidprv:attr/colorAccentSecondary" /> +</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/screenshare_options_spinner_background.xml b/packages/SystemUI/res/drawable/screenshare_options_spinner_background.xml new file mode 100644 index 000000000000..34e7d0afcd97 --- /dev/null +++ b/packages/SystemUI/res/drawable/screenshare_options_spinner_background.xml @@ -0,0 +1,35 @@ +<!-- + ~ Copyright (C) 2022 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. + --> +<layer-list xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:paddingMode="stack"> + <item> + <shape android:shape="rectangle"> + <corners android:radius="@dimen/screenrecord_spinner_background_radius" /> + <stroke + android:width="1dp" + android:color="?androidprv:attr/textColorTertiary" /> + <solid android:color="@android:color/transparent"/> + </shape> + </item> + <item + android:drawable="@drawable/ic_ksh_key_down" + android:gravity="end|center_vertical" + android:textColor="?androidprv:attr/textColorPrimary" + android:width="@dimen/screenrecord_spinner_arrow_size" + android:height="@dimen/screenrecord_spinner_arrow_size" + android:end="20dp" /> +</layer-list>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/screen_record_options.xml b/packages/SystemUI/res/layout/screen_record_options.xml index d6c9e98d8b4d..3f0eea9004a6 100644 --- a/packages/SystemUI/res/layout/screen_record_options.xml +++ b/packages/SystemUI/res/layout/screen_record_options.xml @@ -16,7 +16,8 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical"> + android:orientation="vertical" + android:paddingBottom="@dimen/screenrecord_options_padding_bottom"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" @@ -72,7 +73,7 @@ android:gravity="center_vertical" android:text="@string/screenrecord_taps_label" android:textAppearance="?android:attr/textAppearanceMedium" - android:fontFamily="@*android:string/config_headlineFontFamily" + android:fontFamily="@*android:string/config_bodyFontFamily" android:textColor="?android:attr/textColorPrimary" android:contentDescription="@string/screenrecord_taps_label"/> <Switch diff --git a/packages/SystemUI/res/layout/screen_share_dialog.xml b/packages/SystemUI/res/layout/screen_share_dialog.xml index ac46cdb1be24..bd719894e25f 100644 --- a/packages/SystemUI/res/layout/screen_share_dialog.xml +++ b/packages/SystemUI/res/layout/screen_share_dialog.xml @@ -16,7 +16,7 @@ <!-- Scrollview is necessary to fit everything in landscape layout --> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" android:id="@+id/screen_share_permission_dialog" android:layout_width="match_parent" android:layout_height="match_parent"> @@ -32,10 +32,11 @@ android:gravity="center_horizontal"> <ImageView + android:id="@+id/screen_share_dialog_icon" android:layout_width="@dimen/screenrecord_logo_size" android:layout_height="@dimen/screenrecord_logo_size" - android:src="@drawable/ic_screenrecord" - android:tint="@color/screenrecord_icon_color" + android:src="@drawable/ic_media_projection_permission" + android:tint="?androidprv:attr/colorAccentPrimary" android:importantForAccessibility="no"/> <TextView android:id="@+id/screen_share_dialog_title" @@ -43,34 +44,37 @@ android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:fontFamily="@*android:string/config_headlineFontFamily" - android:layout_marginTop="22dp" - android:layout_marginBottom="15dp"/> + android:layout_marginTop="@dimen/screenrecord_title_margin_top" + android:gravity="center"/> <Spinner android:id="@+id/screen_share_mode_spinner" - android:layout_width="320dp" - android:layout_height="72dp" - android:layout_marginTop="24dp" - android:layout_marginBottom="24dp" /> + android:layout_width="match_parent" + android:layout_height="@dimen/screenrecord_spinner_height" + android:layout_marginTop="@dimen/screenrecord_spinner_margin" + android:layout_marginBottom="@dimen/screenrecord_spinner_margin" + android:gravity="center_vertical" + android:background="@drawable/screenshare_options_spinner_background" + android:popupBackground="@drawable/screenrecord_options_spinner_popup_background"/> <ViewStub android:id="@+id/options_stub" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content"/> <TextView android:id="@+id/text_warning" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/screenrecord_description" android:textAppearance="?android:attr/textAppearanceSmall" android:textColor="?android:textColorSecondary" android:gravity="start" - android:layout_marginBottom="20dp"/> + android:lineHeight="@dimen/screenrecord_warning_line_height"/> <!-- Buttons --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:layout_marginTop="36dp"> + android:layout_marginTop="@dimen/screenrecord_buttons_margin_top"> <TextView android:id="@+id/button_cancel" android:layout_width="wrap_content" diff --git a/packages/SystemUI/res/layout/screen_share_dialog_spinner_item_text.xml b/packages/SystemUI/res/layout/screen_share_dialog_spinner_item_text.xml new file mode 100644 index 000000000000..66c215599949 --- /dev/null +++ b/packages/SystemUI/res/layout/screen_share_dialog_spinner_item_text.xml @@ -0,0 +1,27 @@ +<!-- + Copyright (C) 2022 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. + --> +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:id="@android:id/text1" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textColor="?androidprv:attr/textColorOnAccent" + android:singleLine="true" + android:layout_width="match_parent" + android:layout_height="@dimen/screenrecord_spinner_height" + android:gravity="center_vertical" + android:ellipsize="marquee" + android:paddingStart="@dimen/screenrecord_spinner_text_padding_start" + android:paddingEnd="@dimen/screenrecord_spinner_text_padding_end"/>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/screen_share_dialog_spinner_text.xml b/packages/SystemUI/res/layout/screen_share_dialog_spinner_text.xml new file mode 100644 index 000000000000..4cc4cbae3569 --- /dev/null +++ b/packages/SystemUI/res/layout/screen_share_dialog_spinner_text.xml @@ -0,0 +1,26 @@ +<!-- + Copyright (C) 2022 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. + --> +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:textAppearance="?android:attr/textAppearanceMedium" + android:fontFamily="@*android:string/config_bodyFontFamily" + android:textColor="?android:textColorPrimary" + android:singleLine="true" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center_vertical" + android:ellipsize="marquee" + android:paddingStart="@dimen/screenrecord_spinner_text_padding_start" + android:paddingEnd="@dimen/screenrecord_spinner_text_padding_end"/>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-h800dp/dimens.xml b/packages/SystemUI/res/values-h800dp/dimens.xml index 94fe20955ce6..8efd6f0b7995 100644 --- a/packages/SystemUI/res/values-h800dp/dimens.xml +++ b/packages/SystemUI/res/values-h800dp/dimens.xml @@ -15,9 +15,6 @@ --> <resources> - <!-- Large clock maximum font size (dp is intentional, to prevent any further scaling) --> - <dimen name="large_clock_text_size">200dp</dimen> - <!-- With the large clock, move up slightly from the center --> <dimen name="keyguard_large_clock_top_margin">-112dp</dimen> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index b7d4eb8b5f7d..738981db6823 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1167,7 +1167,7 @@ <!-- Screen record dialog --> <dimen name="screenrecord_option_padding">18dp</dimen> - <dimen name="screenrecord_logo_size">26dp</dimen> + <dimen name="screenrecord_logo_size">30dp</dimen> <dimen name="screenrecord_option_icon_size">24dp</dimen> <!-- Screen record status bar icon --> <dimen name="screenrecord_status_text_size">14sp</dimen> @@ -1175,6 +1175,18 @@ <dimen name="screenrecord_status_icon_width">21dp</dimen> <dimen name="screenrecord_status_icon_height">17.5dp</dimen> <dimen name="screenrecord_status_icon_bg_radius">8dp</dimen> + <!-- Screen record spinner --> + <dimen name="screenrecord_spinner_height">72dp</dimen> + <dimen name="screenrecord_spinner_margin">24dp</dimen> + <dimen name="screenrecord_spinner_text_padding_start">20dp</dimen> + <dimen name="screenrecord_spinner_text_padding_end">80dp</dimen> + <dimen name="screenrecord_spinner_arrow_size">24dp</dimen> + <dimen name="screenrecord_spinner_background_radius">28dp</dimen> + + <dimen name="screenrecord_title_margin_top">20dp</dimen> + <dimen name="screenrecord_warning_line_height">20dp</dimen> + <dimen name="screenrecord_options_padding_bottom">16dp</dimen> + <dimen name="screenrecord_buttons_margin_top">20dp</dimen> <!-- Keyguard user switcher --> <dimen name="kg_user_switcher_text_size">16sp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index 3790a31c6a39..a70b791691ed 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -207,10 +207,6 @@ object Flags { unreleasedFlag(508, "qs_secondary_data_sub_info", teamfood = true) // 600- status bar - // TODO(b/254513246): Tracking Bug - val STATUS_BAR_USER_SWITCHER = - resourceBooleanFlag(602, R.bool.flag_user_switcher_chip, "status_bar_user_switcher") - // TODO(b/254512623): Tracking Bug @Deprecated("Replaced by mobile and wifi specific flags.") val NEW_STATUS_BAR_PIPELINE_BACKEND = diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt index f4d59a8dd6a6..db0052a4d99e 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt @@ -23,8 +23,11 @@ import android.view.ViewStub import android.view.WindowManager import android.widget.AdapterView import android.widget.ArrayAdapter +import android.widget.ImageView import android.widget.Spinner import android.widget.TextView +import androidx.annotation.ColorRes +import androidx.annotation.DrawableRes import androidx.annotation.LayoutRes import androidx.annotation.StringRes import com.android.systemui.R @@ -34,7 +37,9 @@ import com.android.systemui.statusbar.phone.SystemUIDialog open class BaseScreenSharePermissionDialog( context: Context?, private val screenShareOptions: List<ScreenShareOption>, - private val appName: String? + private val appName: String?, + @DrawableRes private val dialogIconDrawable: Int? = null, + @ColorRes private val dialogIconTint: Int? = null ) : SystemUIDialog(context), AdapterView.OnItemSelectedListener { private lateinit var dialogTitle: TextView private lateinit var startButton: TextView @@ -53,10 +58,21 @@ open class BaseScreenSharePermissionDialog( warning = findViewById(R.id.text_warning) startButton = findViewById(R.id.button_start) findViewById<TextView>(R.id.button_cancel).setOnClickListener { dismiss() } + updateIcon() initScreenShareOptions() createOptionsView(getOptionsViewLayoutId()) } + private fun updateIcon() { + val icon = findViewById<ImageView>(R.id.screen_share_dialog_icon) + if (dialogIconTint != null) { + icon.setColorFilter(context.getColor(dialogIconTint)) + } + if (dialogIconDrawable != null) { + icon.setImageDrawable(context.getDrawable(dialogIconDrawable)) + } + } + protected fun initScreenShareOptions() { selectedScreenShareOption = screenShareOptions.first() warning.text = warningText @@ -69,8 +85,12 @@ open class BaseScreenSharePermissionDialog( private fun initScreenShareSpinner() { val options = screenShareOptions.map { context.getString(it.spinnerText) }.toTypedArray() val adapter = - ArrayAdapter(context.applicationContext, android.R.layout.simple_spinner_item, options) - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + ArrayAdapter( + context.applicationContext, + R.layout.screen_share_dialog_spinner_text, + options + ) + adapter.setDropDownViewResource(R.layout.screen_share_dialog_spinner_item_text) screenShareModeSpinner = findViewById(R.id.screen_share_mode_spinner) screenShareModeSpinner.adapter = adapter screenShareModeSpinner.onItemSelectedListener = this diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt index 15b0bc4a356a..e56ab997e605 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt @@ -41,14 +41,14 @@ class MediaProjectionPermissionDialog( private fun createOptionList(): List<ScreenShareOption> { return listOf( ScreenShareOption( - SINGLE_APP, - R.string.media_projection_permission_dialog_option_single_app, - R.string.media_projection_permission_dialog_warning_single_app - ), - ScreenShareOption( ENTIRE_SCREEN, R.string.media_projection_permission_dialog_option_entire_screen, R.string.media_projection_permission_dialog_warning_entire_screen + ), + ScreenShareOption( + SINGLE_APP, + R.string.media_projection_permission_dialog_option_single_app, + R.string.media_projection_permission_dialog_warning_single_app ) ) } diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt index 19bb15a5c2d8..44b18ec4639b 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt @@ -46,7 +46,14 @@ class ScreenRecordPermissionDialog( private val dialogLaunchAnimator: DialogLaunchAnimator, private val userContextProvider: UserContextProvider, private val onStartRecordingClicked: Runnable? -) : BaseScreenSharePermissionDialog(context, createOptionList(), null) { +) : + BaseScreenSharePermissionDialog( + context, + createOptionList(), + null, + R.drawable.ic_screenrecord, + R.color.screenrecord_icon_color + ) { private lateinit var tapsSwitch: Switch private lateinit var tapsView: View private lateinit var audioSwitch: Switch @@ -169,14 +176,14 @@ class ScreenRecordPermissionDialog( private fun createOptionList(): List<ScreenShareOption> { return listOf( ScreenShareOption( - SINGLE_APP, - R.string.screenrecord_option_single_app, - R.string.screenrecord_warning_single_app - ), - ScreenShareOption( ENTIRE_SCREEN, R.string.screenrecord_option_entire_screen, R.string.screenrecord_warning_entire_screen + ), + ScreenShareOption( + SINGLE_APP, + R.string.screenrecord_option_single_app, + R.string.screenrecord_warning_single_app ) ) } diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenShareOption.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenShareOption.kt index 914d29a52b53..3d39fd82ac63 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenShareOption.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenShareOption.kt @@ -20,11 +20,11 @@ import androidx.annotation.StringRes import kotlin.annotation.Retention @Retention(AnnotationRetention.SOURCE) -@IntDef(SINGLE_APP, ENTIRE_SCREEN) +@IntDef(ENTIRE_SCREEN, SINGLE_APP) annotation class ScreenShareMode -const val SINGLE_APP = 0 -const val ENTIRE_SCREEN = 1 +const val ENTIRE_SCREEN = 0 +const val SINGLE_APP = 1 class ScreenShareOption( @ScreenShareMode val mode: Int, diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index d94c8277b82c..8609e4af13f6 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -739,10 +739,14 @@ public class ScreenshotController { mLongScreenshotHolder.setLongScreenshot(longScreenshot); mLongScreenshotHolder.setTransitionDestinationCallback( - (transitionDestination, onTransitionEnd) -> + (transitionDestination, onTransitionEnd) -> { mScreenshotView.startLongScreenshotTransition( transitionDestination, onTransitionEnd, - longScreenshot)); + longScreenshot); + // TODO: Do this via ActionIntentExecutor instead. + mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); + } + ); final Intent intent = new Intent(mContext, LongScreenshotActivity.class); intent.putExtra(LongScreenshotActivity.EXTRA_SCREENSHOT_USER_HANDLE, diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java index 0a4b550882c9..7641554ede3d 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java @@ -898,6 +898,7 @@ public class ScreenshotView extends FrameLayout implements void startLongScreenshotTransition(Rect destination, Runnable onTransitionEnd, ScrollCaptureController.LongScreenshot longScreenshot) { + mPendingSharedTransition = true; AnimatorSet animSet = new AnimatorSet(); ValueAnimator scrimAnim = ValueAnimator.ofFloat(0, 1); diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index aa17bf206f2c..101dd456a004 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -72,6 +72,7 @@ import android.os.Message; import android.os.SystemClock; import android.os.Trace; import android.os.VibrationEffect; +import android.provider.DeviceConfig; import android.provider.Settings; import android.provider.Settings.Global; import android.text.InputFilter; @@ -108,6 +109,8 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.graphics.drawable.BackgroundBlurDrawable; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.view.RotationPolicy; @@ -125,11 +128,15 @@ import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.util.AlphaTintDrawableWrapper; +import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.RoundedCornerProgressDrawable; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.Executor; import java.util.function.Consumer; /** @@ -186,6 +193,9 @@ public class VolumeDialogImpl implements VolumeDialog, private ViewGroup mDialogRowsView; private ViewGroup mRinger; + private DeviceConfigProxy mDeviceConfigProxy; + private Executor mExecutor; + /** * Container for the top part of the dialog, which contains the ringer, the ringer drawer, the * volume rows, and the ellipsis button. This does not include the live caption button. @@ -274,6 +284,13 @@ public class VolumeDialogImpl implements VolumeDialog, private BackgroundBlurDrawable mDialogRowsViewBackground; private final InteractionJankMonitor mInteractionJankMonitor; + private boolean mSeparateNotification; + + @VisibleForTesting + int mVolumeRingerIconDrawableId; + @VisibleForTesting + int mVolumeRingerMuteIconDrawableId; + public VolumeDialogImpl( Context context, VolumeDialogController volumeDialogController, @@ -283,7 +300,9 @@ public class VolumeDialogImpl implements VolumeDialog, MediaOutputDialogFactory mediaOutputDialogFactory, VolumePanelFactory volumePanelFactory, ActivityStarter activityStarter, - InteractionJankMonitor interactionJankMonitor) { + InteractionJankMonitor interactionJankMonitor, + DeviceConfigProxy deviceConfigProxy, + Executor executor) { mContext = new ContextThemeWrapper(context, R.style.volume_dialog_theme); mController = volumeDialogController; @@ -323,6 +342,50 @@ public class VolumeDialogImpl implements VolumeDialog, } initDimens(); + + mDeviceConfigProxy = deviceConfigProxy; + mExecutor = executor; + mSeparateNotification = mDeviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, + SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, false); + updateRingerModeIconSet(); + } + + /** + * If ringer and notification are the same stream (T and earlier), use notification-like bell + * icon set. + * If ringer and notification are separated, then use generic speaker icons. + */ + private void updateRingerModeIconSet() { + if (mSeparateNotification) { + mVolumeRingerIconDrawableId = R.drawable.ic_speaker_on; + mVolumeRingerMuteIconDrawableId = R.drawable.ic_speaker_mute; + } else { + mVolumeRingerIconDrawableId = R.drawable.ic_volume_ringer; + mVolumeRingerMuteIconDrawableId = R.drawable.ic_volume_ringer_mute; + } + + if (mRingerDrawerMuteIcon != null) { + mRingerDrawerMuteIcon.setImageResource(mVolumeRingerMuteIconDrawableId); + } + if (mRingerDrawerNormalIcon != null) { + mRingerDrawerNormalIcon.setImageResource(mVolumeRingerIconDrawableId); + } + } + + /** + * Change icon for ring stream (not ringer mode icon) + */ + private void updateRingRowIcon() { + Optional<VolumeRow> volumeRow = mRows.stream().filter(row -> row.stream == STREAM_RING) + .findFirst(); + if (volumeRow.isPresent()) { + VolumeRow volRow = volumeRow.get(); + volRow.iconRes = mSeparateNotification ? R.drawable.ic_ring_volume + : R.drawable.ic_volume_ringer; + volRow.iconMuteRes = mSeparateNotification ? R.drawable.ic_ring_volume_off + : R.drawable.ic_volume_ringer_mute; + volRow.setIcon(volRow.iconRes, mContext.getTheme()); + } } @Override @@ -339,6 +402,9 @@ public class VolumeDialogImpl implements VolumeDialog, mController.getState(); mConfigurationController.addCallback(this); + + mDeviceConfigProxy.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI, + mExecutor, this::onDeviceConfigChange); } @Override @@ -346,6 +412,24 @@ public class VolumeDialogImpl implements VolumeDialog, mController.removeCallback(mControllerCallbackH); mHandler.removeCallbacksAndMessages(null); mConfigurationController.removeCallback(this); + mDeviceConfigProxy.removeOnPropertiesChangedListener(this::onDeviceConfigChange); + } + + /** + * Update ringer mode icon based on the config + */ + private void onDeviceConfigChange(DeviceConfig.Properties properties) { + Set<String> changeSet = properties.getKeyset(); + if (changeSet.contains(SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION)) { + boolean newVal = properties.getBoolean( + SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, false); + if (newVal != mSeparateNotification) { + mSeparateNotification = newVal; + updateRingerModeIconSet(); + updateRingRowIcon(); + + } + } } @Override @@ -552,6 +636,8 @@ public class VolumeDialogImpl implements VolumeDialog, mRingerDrawerNormalIcon = mDialog.findViewById(R.id.volume_drawer_normal_icon); mRingerDrawerNewSelectionBg = mDialog.findViewById(R.id.volume_drawer_selection_background); + updateRingerModeIconSet(); + setupRingerDrawer(); mODICaptionsView = mDialog.findViewById(R.id.odi_captions); @@ -575,8 +661,14 @@ public class VolumeDialogImpl implements VolumeDialog, addRow(AudioManager.STREAM_MUSIC, R.drawable.ic_volume_media, R.drawable.ic_volume_media_mute, true, true); if (!AudioSystem.isSingleVolume(mContext)) { - addRow(AudioManager.STREAM_RING, - R.drawable.ic_volume_ringer, R.drawable.ic_volume_ringer_mute, true, false); + if (mSeparateNotification) { + addRow(AudioManager.STREAM_RING, R.drawable.ic_ring_volume, + R.drawable.ic_ring_volume_off, true, false); + } else { + addRow(AudioManager.STREAM_RING, R.drawable.ic_volume_ringer, + R.drawable.ic_volume_ringer, true, false); + } + addRow(STREAM_ALARM, R.drawable.ic_alarm, R.drawable.ic_volume_alarm_mute, true, false); addRow(AudioManager.STREAM_VOICE_CALL, @@ -1532,8 +1624,8 @@ public class VolumeDialogImpl implements VolumeDialog, mRingerIcon.setTag(Events.ICON_STATE_VIBRATE); break; case AudioManager.RINGER_MODE_SILENT: - mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute); - mSelectedRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute); + mRingerIcon.setImageResource(mVolumeRingerMuteIconDrawableId); + mSelectedRingerIcon.setImageResource(mVolumeRingerMuteIconDrawableId); mRingerIcon.setTag(Events.ICON_STATE_MUTE); addAccessibilityDescription(mRingerIcon, RINGER_MODE_SILENT, mContext.getString(R.string.volume_ringer_hint_unmute)); @@ -1542,14 +1634,14 @@ public class VolumeDialogImpl implements VolumeDialog, default: boolean muted = (mAutomute && ss.level == 0) || ss.muted; if (!isZenMuted && muted) { - mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute); - mSelectedRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute); + mRingerIcon.setImageResource(mVolumeRingerMuteIconDrawableId); + mSelectedRingerIcon.setImageResource(mVolumeRingerMuteIconDrawableId); addAccessibilityDescription(mRingerIcon, RINGER_MODE_NORMAL, mContext.getString(R.string.volume_ringer_hint_unmute)); mRingerIcon.setTag(Events.ICON_STATE_MUTE); } else { - mRingerIcon.setImageResource(R.drawable.ic_volume_ringer); - mSelectedRingerIcon.setImageResource(R.drawable.ic_volume_ringer); + mRingerIcon.setImageResource(mVolumeRingerIconDrawableId); + mSelectedRingerIcon.setImageResource(mVolumeRingerIconDrawableId); if (mController.hasVibrator()) { addAccessibilityDescription(mRingerIcon, RINGER_MODE_NORMAL, mContext.getString(R.string.volume_ringer_hint_vibrate)); diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java index c5792b923e48..8f10fa619c14 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java +++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java @@ -20,6 +20,7 @@ import android.content.Context; import android.media.AudioManager; import com.android.internal.jank.InteractionJankMonitor; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.media.dialog.MediaOutputDialogFactory; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.VolumeDialog; @@ -27,11 +28,14 @@ import com.android.systemui.plugins.VolumeDialogController; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.volume.VolumeComponent; import com.android.systemui.volume.VolumeDialogComponent; import com.android.systemui.volume.VolumeDialogImpl; import com.android.systemui.volume.VolumePanelFactory; +import java.util.concurrent.Executor; + import dagger.Binds; import dagger.Module; import dagger.Provides; @@ -55,7 +59,9 @@ public interface VolumeModule { MediaOutputDialogFactory mediaOutputDialogFactory, VolumePanelFactory volumePanelFactory, ActivityStarter activityStarter, - InteractionJankMonitor interactionJankMonitor) { + InteractionJankMonitor interactionJankMonitor, + DeviceConfigProxy deviceConfigProxy, + @Main Executor executor) { VolumeDialogImpl impl = new VolumeDialogImpl( context, volumeDialogController, @@ -65,7 +71,9 @@ public interface VolumeModule { mediaOutputDialogFactory, volumePanelFactory, activityStarter, - interactionJankMonitor); + interactionJankMonitor, + deviceConfigProxy, + executor); impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false); impl.setAutomute(true); impl.setSilentMode(false); diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java index 2e74bf5474f9..a0b4eab1d5df 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java @@ -18,6 +18,7 @@ package com.android.systemui.volume; import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS; +import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -28,6 +29,7 @@ import static org.mockito.Mockito.verify; import android.app.KeyguardManager; import android.media.AudioManager; import android.os.SystemClock; +import android.provider.DeviceConfig; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.InputDevice; @@ -38,6 +40,7 @@ import android.view.accessibility.AccessibilityManager; import androidx.test.filters.SmallTest; +import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.jank.InteractionJankMonitor; import com.android.systemui.Prefs; import com.android.systemui.R; @@ -49,6 +52,9 @@ import com.android.systemui.plugins.VolumeDialogController.State; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.util.DeviceConfigProxyFake; +import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.time.FakeSystemClock; import org.junit.Before; import org.junit.Test; @@ -71,6 +77,8 @@ public class VolumeDialogImplTest extends SysuiTestCase { View mDrawerVibrate; View mDrawerMute; View mDrawerNormal; + private DeviceConfigProxyFake mDeviceConfigProxy; + private FakeExecutor mExecutor; @Mock VolumeDialogController mVolumeDialogController; @@ -97,6 +105,9 @@ public class VolumeDialogImplTest extends SysuiTestCase { getContext().addMockSystemService(KeyguardManager.class, mKeyguard); + mDeviceConfigProxy = new DeviceConfigProxyFake(); + mExecutor = new FakeExecutor(new FakeSystemClock()); + mDialog = new VolumeDialogImpl( getContext(), mVolumeDialogController, @@ -106,7 +117,9 @@ public class VolumeDialogImplTest extends SysuiTestCase { mMediaOutputDialogFactory, mVolumePanelFactory, mActivityStarter, - mInteractionJankMonitor); + mInteractionJankMonitor, + mDeviceConfigProxy, + mExecutor); mDialog.init(0, null); State state = createShellState(); mDialog.onStateChangedH(state); @@ -123,6 +136,9 @@ public class VolumeDialogImplTest extends SysuiTestCase { VolumePrefs.SHOW_RINGER_TOAST_COUNT + 1); Prefs.putBoolean(mContext, Prefs.Key.HAS_SEEN_ODI_CAPTIONS_TOOLTIP, false); + + mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, + SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false); } private State createShellState() { @@ -292,6 +308,35 @@ public class VolumeDialogImplTest extends SysuiTestCase { AudioManager.RINGER_MODE_NORMAL, false); } + /** + * Ideally we would look at the ringer ImageView and check its assigned drawable id, but that + * API does not exist. So we do the next best thing; we check the cached icon id. + */ + @Test + public void notificationVolumeSeparated_theRingerIconChanges() { + mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, + SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false); + + mExecutor.runAllReady(); // for the config change to take effect + + // assert icon is new based on res id + assertEquals(mDialog.mVolumeRingerIconDrawableId, + R.drawable.ic_speaker_on); + assertEquals(mDialog.mVolumeRingerMuteIconDrawableId, + R.drawable.ic_speaker_mute); + } + + @Test + public void notificationVolumeNotSeparated_theRingerIconRemainsTheSame() { + mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, + SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false); + + mExecutor.runAllReady(); + + assertEquals(mDialog.mVolumeRingerIconDrawableId, R.drawable.ic_volume_ringer); + assertEquals(mDialog.mVolumeRingerMuteIconDrawableId, R.drawable.ic_volume_ringer_mute); + } + /* @Test public void testContentDescriptions() { diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 2ec744fd4bb8..c868f533bb7c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -248,6 +248,8 @@ final class ActivityManagerShellCommand extends ShellCommand { return runForceStop(pw); case "stop-app": return runStopApp(pw); + case "clear-recent-apps": + return runClearRecentApps(pw); case "fgs-notification-rate-limit": return runFgsNotificationRateLimit(pw); case "crash": @@ -1192,6 +1194,11 @@ final class ActivityManagerShellCommand extends ShellCommand { return 0; } + int runClearRecentApps(PrintWriter pw) throws RemoteException { + mTaskInterface.removeAllVisibleRecentTasks(); + return 0; + } + int runFgsNotificationRateLimit(PrintWriter pw) throws RemoteException { final String toggleValue = getNextArgRequired(); final boolean enable; diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java index 741141d9e463..da6e7e8436eb 100644 --- a/services/core/java/com/android/server/wm/ActivityClientController.java +++ b/services/core/java/com/android/server/wm/ActivityClientController.java @@ -580,17 +580,18 @@ class ActivityClientController extends IActivityClientController.Stub { } /** - * Returns the windowing mode of the task that hosts the activity, or {@code -1} if task is not - * found. + * Returns the {@link Configuration} of the task which hosts the Activity, or {@code null} if + * the task {@link Configuration} cannot be obtained. */ @Override - public int getTaskWindowingMode(IBinder activityToken) { + @Nullable + public Configuration getTaskConfiguration(IBinder activityToken) { synchronized (mGlobalLock) { final ActivityRecord ar = ActivityRecord.isInAnyTask(activityToken); if (ar == null) { - return -1; + return null; } - return ar.getTask().getWindowingMode(); + return ar.getTask().getConfiguration(); } } diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java index e0145e661660..28307d270134 100644 --- a/telephony/java/android/telephony/SmsMessage.java +++ b/telephony/java/android/telephony/SmsMessage.java @@ -1020,6 +1020,17 @@ public class SmsMessage { } /** + * Return the encoding type of a received SMS message, which is specified using ENCODING_* + * GSM: defined in android.telephony.SmsConstants + * CDMA: defined in android.telephony.cdma.UserData + * + * @hide + */ + public int getReceivedEncodingType() { + return mWrappedSmsMessage.getReceivedEncodingType(); + } + + /** * Determines whether or not to use CDMA format for MO SMS. * If SMS over IMS is supported, then format is based on IMS SMS format, * otherwise format is based on current phone type. diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java index 6d46ed3b8416..0cc1e98ec165 100644 --- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java +++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java @@ -16,6 +16,8 @@ package com.android.internal.telephony; +import static com.android.internal.telephony.SmsConstants.ENCODING_UNKNOWN; + import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.telephony.SmsMessage; @@ -94,6 +96,15 @@ public abstract class SmsMessageBase { protected boolean mMwiDontStore; /** + * The encoding type of a received SMS message, which is specified using ENCODING_* + * GSM: defined in android.telephony.SmsConstants + * CDMA: defined in android.telephony.cdma.UserData + * + * @hide + */ + protected int mReceivedEncodingType = ENCODING_UNKNOWN; + + /** * Indicates status for messages stored on the ICC. */ protected int mStatusOnIcc = -1; @@ -512,4 +523,8 @@ public abstract class SmsMessageBase { return mRecipientAddress.getAddressString(); } + + public int getReceivedEncodingType() { + return mReceivedEncodingType; + } } diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index f636276f11b8..b51ba31b4eed 100644 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -780,6 +780,7 @@ public class SmsMessage extends SmsMessageBase { mUserData = mBearerData.userData.payload; mUserDataHeader = mBearerData.userData.userDataHeader; mMessageBody = mBearerData.userData.payloadStr; + mReceivedEncodingType = mBearerData.userData.msgEncoding; } if (mOriginatingAddress != null) { @@ -860,6 +861,9 @@ public class SmsMessage extends SmsMessageBase { Rlog.w(LOG_TAG, "BearerData.decode() returned null"); return null; } + if (bData.userData != null) { + mReceivedEncodingType = bData.userData.msgEncoding; + } if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { Rlog.d(LOG_TAG, "MT raw BearerData = " + HexDump.toHexString(mEnvelope.bearerData)); diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java index b51e8d3d3c5d..a5556505edef 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java @@ -1396,28 +1396,28 @@ public class SmsMessage extends SmsMessageBase { } else { switch ((mDataCodingScheme >> 2) & 0x3) { case 0: // GSM 7 bit default alphabet - encodingType = ENCODING_7BIT; - break; + encodingType = ENCODING_7BIT; + break; case 2: // UCS 2 (16bit) - encodingType = ENCODING_16BIT; - break; + encodingType = ENCODING_16BIT; + break; case 1: // 8 bit data - //Support decoding the user data payload as pack GSM 8-bit (a GSM alphabet string - //that's stored in 8-bit unpacked format) characters. - if (r.getBoolean(com.android.internal. - R.bool.config_sms_decode_gsm_8bit_data)) { - encodingType = ENCODING_8BIT; - break; - } + // Support decoding the user data payload as pack GSM 8-bit (a GSM alphabet + // string that's stored in 8-bit unpacked format) characters. + if (r.getBoolean(com.android.internal + .R.bool.config_sms_decode_gsm_8bit_data)) { + encodingType = ENCODING_8BIT; + break; + } case 3: // reserved - Rlog.w(LOG_TAG, "1 - Unsupported SMS data coding scheme " - + (mDataCodingScheme & 0xff)); - encodingType = r.getInteger( - com.android.internal.R.integer.default_reserved_data_coding_scheme); - break; + Rlog.w(LOG_TAG, "1 - Unsupported SMS data coding scheme " + + (mDataCodingScheme & 0xff)); + encodingType = r.getInteger( + com.android.internal.R.integer.default_reserved_data_coding_scheme); + break; } } } else if ((mDataCodingScheme & 0xf0) == 0xf0) { @@ -1492,6 +1492,7 @@ public class SmsMessage extends SmsMessageBase { encodingType == ENCODING_7BIT); this.mUserData = p.getUserData(); this.mUserDataHeader = p.getUserDataHeader(); + this.mReceivedEncodingType = encodingType; /* * Look for voice mail indication in TP_UDH TS23.040 9.2.3.24 |