From 2dd9f7b64d8f2c03fd7354d916d77a7129861a4a Mon Sep 17 00:00:00 2001 From: arangelov Date: Thu, 27 Feb 2020 10:54:24 +0000 Subject: [PATCH] Show a spinner when waiting for the work profile to turn on. This covers the usecase when we show the share sheet or intent resolver on a device with a work profile, and the work profile is turned off. In that case, when sharing from the personal profile, we show an empty state screen with the option to turn on the work profile. When we tap that button, we now show a spinner, as there is a delay until the profile is actually enabled. Fixes: 149821684 Test: manual Change-Id: Id90b21a61b10ecce8172bddc42fdeec5fb61c5fe --- .../app/AbstractMultiProfilePagerAdapter.java | 44 +++++++++++++++++-- .../internal/app/ResolverActivity.java | 20 ++++++++- core/res/res/layout/resolver_empty_states.xml | 31 ++++++++++--- core/res/res/values/symbols.xml | 1 + 4 files changed, 84 insertions(+), 12 deletions(-) diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java index b4a0208ccc914..353522e125842 100644 --- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java @@ -64,6 +64,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { private final UserHandle mPersonalProfileUserHandle; private final UserHandle mWorkProfileUserHandle; private Injector mInjector; + private boolean mIsWaitingToEnableWorkProfile; AbstractMultiProfilePagerAdapter(Context context, int currentPage, UserHandle personalProfileUserHandle, @@ -90,10 +91,19 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { @Override public void requestQuietModeEnabled(boolean enabled, UserHandle workProfileUserHandle) { userManager.requestQuietModeEnabled(enabled, workProfileUserHandle); + mIsWaitingToEnableWorkProfile = true; } }; } + protected void markWorkProfileEnabledBroadcastReceived() { + mIsWaitingToEnableWorkProfile = false; + } + + protected boolean isWaitingToEnableWorkProfile() { + return mIsWaitingToEnableWorkProfile; + } + /** * Overrides the default {@link Injector} for testing purposes. */ @@ -294,8 +304,12 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { R.drawable.ic_work_apps_off, R.string.resolver_turn_on_work_apps, R.string.resolver_turn_on_work_apps_explanation, - (View.OnClickListener) v -> - mInjector.requestQuietModeEnabled(false, mWorkProfileUserHandle)); + (View.OnClickListener) v -> { + ProfileDescriptor descriptor = getItem( + userHandleToPageIndex(activeListAdapter.getUserHandle())); + showSpinner(descriptor.getEmptyStateView()); + mInjector.requestQuietModeEnabled(false, mWorkProfileUserHandle); + }); return false; } if (UserHandle.myUserId() != listUserHandle.getIdentifier()) { @@ -355,7 +369,8 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { ProfileDescriptor descriptor = getItem( userHandleToPageIndex(activeListAdapter.getUserHandle())); descriptor.rootView.findViewById(R.id.resolver_list).setVisibility(View.GONE); - View emptyStateView = descriptor.rootView.findViewById(R.id.resolver_empty_state); + View emptyStateView = descriptor.getEmptyStateView(); + resetViewVisibilities(emptyStateView); emptyStateView.setVisibility(View.VISIBLE); ImageView icon = emptyStateView.findViewById(R.id.resolver_empty_state_icon); @@ -372,6 +387,23 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { button.setOnClickListener(buttonOnClick); } + private void showSpinner(View emptyStateView) { + emptyStateView.findViewById(R.id.resolver_empty_state_icon).setVisibility(View.INVISIBLE); + emptyStateView.findViewById(R.id.resolver_empty_state_title).setVisibility(View.INVISIBLE); + emptyStateView.findViewById(R.id.resolver_empty_state_subtitle) + .setVisibility(View.INVISIBLE); + emptyStateView.findViewById(R.id.resolver_empty_state_button).setVisibility(View.INVISIBLE); + emptyStateView.findViewById(R.id.resolver_empty_state_progress).setVisibility(View.VISIBLE); + } + + private void resetViewVisibilities(View emptyStateView) { + emptyStateView.findViewById(R.id.resolver_empty_state_icon).setVisibility(View.VISIBLE); + 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); + emptyStateView.findViewById(R.id.resolver_empty_state_progress).setVisibility(View.GONE); + } + private void showListView(ResolverListAdapter activeListAdapter) { ProfileDescriptor descriptor = getItem( userHandleToPageIndex(activeListAdapter.getUserHandle())); @@ -409,8 +441,14 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { protected class ProfileDescriptor { final ViewGroup rootView; + private final ViewGroup mEmptyStateView; ProfileDescriptor(ViewGroup rootView) { this.rootView = rootView; + mEmptyStateView = rootView.findViewById(R.id.resolver_empty_state); + } + + private ViewGroup getEmptyStateView() { + return mEmptyStateView; } } diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index ed1b6a3485a14..0790f21f30e12 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -756,7 +756,7 @@ public class ResolverActivity extends Activity implements private void registerWorkProfileStateReceiver() { IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); + filter.addAction(Intent.ACTION_USER_UNLOCKED); filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); registerReceiverAsUser(mWorkProfileStateReceiver, UserHandle.ALL, filter, null, null); } @@ -1729,6 +1729,14 @@ public class ResolverActivity extends Activity implements @Override // ResolverListCommunicator public void onHandlePackagesChanged(ResolverListAdapter listAdapter) { if (listAdapter == mMultiProfilePagerAdapter.getActiveListAdapter()) { + if (listAdapter.getUserHandle() == getWorkProfileUserHandle() + && mMultiProfilePagerAdapter.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 + // turning on. + return; + } boolean listRebuilt = mMultiProfilePagerAdapter.rebuildActiveTab(true); if (listRebuilt) { ResolverListAdapter activeListAdapter = @@ -1749,10 +1757,18 @@ public class ResolverActivity extends Activity implements @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - if (!TextUtils.equals(action, Intent.ACTION_MANAGED_PROFILE_AVAILABLE) + if (!TextUtils.equals(action, Intent.ACTION_USER_UNLOCKED) && !TextUtils.equals(action, Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)) { return; } + int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); + if (TextUtils.equals(action, Intent.ACTION_USER_UNLOCKED) + && userHandle != getWorkProfileUserHandle().getIdentifier()) { + return; + } + if (TextUtils.equals(action, Intent.ACTION_USER_UNLOCKED)) { + mMultiProfilePagerAdapter.markWorkProfileEnabledBroadcastReceived(); + } if (mMultiProfilePagerAdapter.getCurrentUserHandle() == getWorkProfileUserHandle()) { mMultiProfilePagerAdapter.rebuildActiveTab(true); diff --git a/core/res/res/layout/resolver_empty_states.xml b/core/res/res/layout/resolver_empty_states.xml index 3cfa826aa70fa..619b3927e8d5f 100644 --- a/core/res/res/layout/resolver_empty_states.xml +++ b/core/res/res/layout/resolver_empty_states.xml @@ -14,7 +14,7 @@ ~ limitations under the License. --> - + android:layout_height="24dp" + android:layout_centerHorizontal="true" /> + android:textSize="18sp" + android:layout_centerHorizontal="true" /> + android:textSize="14sp" + android:gravity="center_horizontal" + android:layout_centerHorizontal="true" />