diff options
| author | 2023-02-22 18:15:35 +0000 | |
|---|---|---|
| committer | 2023-02-22 18:15:35 +0000 | |
| commit | 25c119f04c375740903779693520a45b506d35fa (patch) | |
| tree | 5bf6303ba69a5c0cd139dd3165910545300cc832 /java/src | |
| parent | bff86f9daa724d016a4dc93a65f88e2eb1043dfe (diff) | |
| parent | 9c1f0f80ee06bef63ab8a681aae0c1fed60e4d96 (diff) | |
Merge "Extract component for work-profile availability." into tm-qpr-dev
Diffstat (limited to 'java/src')
8 files changed, 222 insertions, 165 deletions
diff --git a/java/src/com/android/intentresolver/AbstractMultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/AbstractMultiProfilePagerAdapter.java index 17dbb8f2..e3f1b233 100644 --- a/java/src/com/android/intentresolver/AbstractMultiProfilePagerAdapter.java +++ b/java/src/com/android/intentresolver/AbstractMultiProfilePagerAdapter.java @@ -40,6 +40,7 @@ import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.function.Supplier; /** * Skeletal {@link PagerAdapter} implementation of a work or personal profile page for @@ -61,22 +62,20 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { private Set<Integer> mLoadedPages; private final EmptyStateProvider mEmptyStateProvider; private final UserHandle mWorkProfileUserHandle; - private final QuietModeManager mQuietModeManager; + private final Supplier<Boolean> mWorkProfileQuietModeChecker; // True when work is quiet. - AbstractMultiProfilePagerAdapter(Context context, int currentPage, + AbstractMultiProfilePagerAdapter( + Context context, + int currentPage, EmptyStateProvider emptyStateProvider, - QuietModeManager quietModeManager, + Supplier<Boolean> workProfileQuietModeChecker, UserHandle workProfileUserHandle) { mContext = Objects.requireNonNull(context); mCurrentPage = currentPage; mLoadedPages = new HashSet<>(); mWorkProfileUserHandle = workProfileUserHandle; mEmptyStateProvider = emptyStateProvider; - mQuietModeManager = quietModeManager; - } - - private boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { - return mQuietModeManager.isQuietModeEnabled(workProfileUserHandle); + mWorkProfileQuietModeChecker = workProfileQuietModeChecker; } void setOnProfileSelectedListener(OnProfileSelectedListener listener) { @@ -433,7 +432,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { int count = listAdapter.getUnfilteredCount(); return (count == 0 && listAdapter.getPlaceholderCount() == 0) || (listAdapter.getUserHandle().equals(mWorkProfileUserHandle) - && isQuietModeEnabled(mWorkProfileUserHandle)); + && mWorkProfileQuietModeChecker.get()); } protected static class ProfileDescriptor { @@ -573,29 +572,4 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { */ void onSwitchOnWorkSelected(); } - - /** - * Describes an injector to be used for cross profile functionality. Overridable for testing. - */ - public interface QuietModeManager { - /** - * Returns whether the given profile is in quiet mode or not. - */ - boolean isQuietModeEnabled(UserHandle workProfileUserHandle); - - /** - * 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(); - } } diff --git a/java/src/com/android/intentresolver/ChooserActivity.java b/java/src/com/android/intentresolver/ChooserActivity.java index 65c72fda..72336e84 100644 --- a/java/src/com/android/intentresolver/ChooserActivity.java +++ b/java/src/com/android/intentresolver/ChooserActivity.java @@ -543,7 +543,7 @@ public class ChooserActivity extends ResolverActivity implements /* context */ this, adapter, createEmptyStateProvider(/* workProfileUserHandle= */ null), - mQuietModeManager, + /* workProfileQuietModeChecker= */ () -> false, /* workProfileUserHandle= */ null, mMaxTargetsPerRow); } @@ -572,7 +572,7 @@ public class ChooserActivity extends ResolverActivity implements personalAdapter, workAdapter, createEmptyStateProvider(/* workProfileUserHandle= */ getWorkProfileUserHandle()), - mQuietModeManager, + () -> mWorkProfileAvailability.isQuietModeEnabled(), selectedProfile, getWorkProfileUserHandle(), mMaxTargetsPerRow); diff --git a/java/src/com/android/intentresolver/ChooserMultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/ChooserMultiProfilePagerAdapter.java index 39d1fab0..3e2ea473 100644 --- a/java/src/com/android/intentresolver/ChooserMultiProfilePagerAdapter.java +++ b/java/src/com/android/intentresolver/ChooserMultiProfilePagerAdapter.java @@ -48,7 +48,7 @@ public class ChooserMultiProfilePagerAdapter extends GenericMultiProfilePagerAda Context context, ChooserGridAdapter adapter, EmptyStateProvider emptyStateProvider, - QuietModeManager quietModeManager, + Supplier<Boolean> workProfileQuietModeChecker, UserHandle workProfileUserHandle, int maxTargetsPerRow) { this( @@ -56,7 +56,7 @@ public class ChooserMultiProfilePagerAdapter extends GenericMultiProfilePagerAda new ChooserProfileAdapterBinder(maxTargetsPerRow), ImmutableList.of(adapter), emptyStateProvider, - quietModeManager, + workProfileQuietModeChecker, /* defaultProfile= */ 0, workProfileUserHandle, new BottomPaddingOverrideSupplier(context)); @@ -67,7 +67,7 @@ public class ChooserMultiProfilePagerAdapter extends GenericMultiProfilePagerAda ChooserGridAdapter personalAdapter, ChooserGridAdapter workAdapter, EmptyStateProvider emptyStateProvider, - QuietModeManager quietModeManager, + Supplier<Boolean> workProfileQuietModeChecker, @Profile int defaultProfile, UserHandle workProfileUserHandle, int maxTargetsPerRow) { @@ -76,7 +76,7 @@ public class ChooserMultiProfilePagerAdapter extends GenericMultiProfilePagerAda new ChooserProfileAdapterBinder(maxTargetsPerRow), ImmutableList.of(personalAdapter, workAdapter), emptyStateProvider, - quietModeManager, + workProfileQuietModeChecker, defaultProfile, workProfileUserHandle, new BottomPaddingOverrideSupplier(context)); @@ -87,7 +87,7 @@ public class ChooserMultiProfilePagerAdapter extends GenericMultiProfilePagerAda ChooserProfileAdapterBinder adapterBinder, ImmutableList<ChooserGridAdapter> gridAdapters, EmptyStateProvider emptyStateProvider, - QuietModeManager quietModeManager, + Supplier<Boolean> workProfileQuietModeChecker, @Profile int defaultProfile, UserHandle workProfileUserHandle, BottomPaddingOverrideSupplier bottomPaddingOverrideSupplier) { @@ -97,7 +97,7 @@ public class ChooserMultiProfilePagerAdapter extends GenericMultiProfilePagerAda adapterBinder, gridAdapters, emptyStateProvider, - quietModeManager, + workProfileQuietModeChecker, defaultProfile, workProfileUserHandle, () -> makeProfileView(context), diff --git a/java/src/com/android/intentresolver/GenericMultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/GenericMultiProfilePagerAdapter.java index 9bbdf7c7..7613f35f 100644 --- a/java/src/com/android/intentresolver/GenericMultiProfilePagerAdapter.java +++ b/java/src/com/android/intentresolver/GenericMultiProfilePagerAdapter.java @@ -81,7 +81,7 @@ class GenericMultiProfilePagerAdapter< AdapterBinder<PageViewT, SinglePageAdapterT> adapterBinder, ImmutableList<SinglePageAdapterT> adapters, EmptyStateProvider emptyStateProvider, - QuietModeManager quietModeManager, + Supplier<Boolean> workProfileQuietModeChecker, @Profile int defaultProfile, UserHandle workProfileUserHandle, Supplier<ViewGroup> pageViewInflater, @@ -90,7 +90,7 @@ class GenericMultiProfilePagerAdapter< context, /* currentPage= */ defaultProfile, emptyStateProvider, - quietModeManager, + workProfileQuietModeChecker, workProfileUserHandle); mListAdapterExtractor = listAdapterExtractor; diff --git a/java/src/com/android/intentresolver/ResolverActivity.java b/java/src/com/android/intentresolver/ResolverActivity.java index ff436ed8..faccbc36 100644 --- a/java/src/com/android/intentresolver/ResolverActivity.java +++ b/java/src/com/android/intentresolver/ResolverActivity.java @@ -44,7 +44,6 @@ import android.app.VoiceInteractor.PickOptionRequest.Option; import android.app.VoiceInteractor.Prompt; import android.app.admin.DevicePolicyEventLogger; import android.app.admin.DevicePolicyManager; -import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -61,7 +60,6 @@ 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; @@ -105,7 +103,6 @@ import com.android.intentresolver.AbstractMultiProfilePagerAdapter.EmptyStatePro import com.android.intentresolver.AbstractMultiProfilePagerAdapter.MyUserIdProvider; import com.android.intentresolver.AbstractMultiProfilePagerAdapter.OnSwitchOnWorkSelectedListener; import com.android.intentresolver.AbstractMultiProfilePagerAdapter.Profile; -import com.android.intentresolver.AbstractMultiProfilePagerAdapter.QuietModeManager; import com.android.intentresolver.NoCrossProfileEmptyStateProvider.DevicePolicyBlockerEmptyState; import com.android.intentresolver.chooser.DisplayResolveInfo; import com.android.intentresolver.chooser.TargetInfo; @@ -191,7 +188,7 @@ public class ResolverActivity extends FragmentActivity implements @VisibleForTesting protected AbstractMultiProfilePagerAdapter mMultiProfilePagerAdapter; - protected QuietModeManager mQuietModeManager; + protected WorkProfileAvailabilityManager mWorkProfileAvailability; // Intent extra for connected audio devices public static final String EXTRA_IS_AUDIO_CAPTURE_DEVICE = "is_audio_capture_device"; @@ -219,7 +216,6 @@ public class ResolverActivity extends FragmentActivity implements protected static final int PROFILE_PERSONAL = AbstractMultiProfilePagerAdapter.PROFILE_PERSONAL; protected static final int PROFILE_WORK = AbstractMultiProfilePagerAdapter.PROFILE_WORK; - private BroadcastReceiver mWorkProfileStateReceiver; private UserHandle mHeaderCreatorUser; // User handle annotations are lazy-initialized to ensure that they're computed exactly once @@ -357,8 +353,6 @@ public class ResolverActivity extends FragmentActivity 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()); @@ -367,6 +361,8 @@ public class ResolverActivity extends FragmentActivity implements // associated TODO comment to explain why this is structured as a lazy computation.) AnnotatedUserHandles unusedReferenceToHandles = mLazyAnnotatedUserHandles.get(); + mWorkProfileAvailability = createWorkProfileAvailabilityManager(); + mPm = getPackageManager(); mReferrerPackage = getReferrerPackageName(); @@ -593,10 +589,8 @@ public class ResolverActivity extends FragmentActivity implements finish(); } } - if (mWorkPackageMonitor != null) { - unregisterReceiver(mWorkProfileStateReceiver); - mWorkPackageMonitor = null; - } + // TODO: should we clean up the work-profile manager before we potentially finish() above? + mWorkProfileAvailability.unregisterWorkProfileStateReceiver(this); } @Override @@ -950,7 +944,7 @@ public class ResolverActivity extends FragmentActivity implements public void onHandlePackagesChanged(ResolverListAdapter listAdapter) { if (listAdapter == mMultiProfilePagerAdapter.getActiveListAdapter()) { if (listAdapter.getUserHandle().equals(getWorkProfileUserHandle()) - && mQuietModeManager.isWaitingToEnableWorkProfile()) { + && mWorkProfileAvailability.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 @@ -988,35 +982,19 @@ public class ResolverActivity extends FragmentActivity implements // @NonFinalForTesting @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); + protected WorkProfileAvailabilityManager createWorkProfileAvailabilityManager() { + final UserHandle workUser = getWorkProfileUserHandle(); + + return new WorkProfileAvailabilityManager( + getSystemService(UserManager.class), + workUser, + () -> { + if (mMultiProfilePagerAdapter.getCurrentUserHandle().equals(workUser)) { + mMultiProfilePagerAdapter.rebuildActiveTab(true); + } else { + mMultiProfilePagerAdapter.clearInactiveProfileCache(); + } }); - mIsWaitingToEnableWorkProfile = true; - } - - @Override - public void markWorkProfileEnabledBroadcastReceived() { - mIsWaitingToEnableWorkProfile = false; - } - - @Override - public boolean isWaitingToEnableWorkProfile() { - return mIsWaitingToEnableWorkProfile; - } - }; } // TODO: have tests override `getAnnotatedUserHandles()`, and make this method `final`. @@ -1083,7 +1061,7 @@ public class ResolverActivity extends FragmentActivity implements final EmptyStateProvider workProfileOffEmptyStateProvider = new WorkProfilePausedEmptyStateProvider(this, workProfileUserHandle, - mQuietModeManager, + mWorkProfileAvailability, /* onSwitchOnWorkSelectedListener= */ () -> { if (mOnSwitchOnWorkSelectedListener != null) { @@ -1141,12 +1119,11 @@ public class ResolverActivity extends FragmentActivity implements rList, filterLastUsed, /* userHandle */ UserHandle.of(UserHandle.myUserId())); - QuietModeManager quietModeManager = createQuietModeManager(); return new ResolverMultiProfilePagerAdapter( /* context */ this, adapter, createEmptyStateProvider(/* workProfileUserHandle= */ null), - quietModeManager, + /* workProfileQuietModeChecker= */ () -> false, /* workProfileUserHandle= */ null); } @@ -1197,13 +1174,12 @@ public class ResolverActivity extends FragmentActivity implements (filterLastUsed && UserHandle.myUserId() == workProfileUserHandle.getIdentifier()), /* userHandle */ workProfileUserHandle); - QuietModeManager quietModeManager = createQuietModeManager(); return new ResolverMultiProfilePagerAdapter( /* context */ this, personalAdapter, workAdapter, createEmptyStateProvider(getWorkProfileUserHandle()), - quietModeManager, + () -> mWorkProfileAvailability.isQuietModeEnabled(), selectedProfile, getWorkProfileUserHandle()); } @@ -1441,9 +1417,9 @@ public class ResolverActivity extends FragmentActivity implements } mRegistered = true; } - if (shouldShowTabs() && mQuietModeManager.isWaitingToEnableWorkProfile()) { - if (mQuietModeManager.isQuietModeEnabled(getWorkProfileUserHandle())) { - mQuietModeManager.markWorkProfileEnabledBroadcastReceived(); + if (shouldShowTabs() && mWorkProfileAvailability.isWaitingToEnableWorkProfile()) { + if (mWorkProfileAvailability.isQuietModeEnabled()) { + mWorkProfileAvailability.markWorkProfileEnabledBroadcastReceived(); } } mMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged(); @@ -1456,29 +1432,10 @@ public class ResolverActivity extends FragmentActivity implements this.getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); if (shouldShowTabs()) { - mWorkProfileStateReceiver = createWorkProfileStateReceiver(); - registerWorkProfileStateReceiver(); - - mWorkProfileHasBeenEnabled = isWorkProfileEnabled(); + mWorkProfileAvailability.registerWorkProfileStateReceiver(this); } } - private boolean isWorkProfileEnabled() { - UserHandle workUserHandle = getWorkProfileUserHandle(); - UserManager userManager = getSystemService(UserManager.class); - - return !userManager.isQuietModeEnabled(workUserHandle) - && userManager.isUserUnlocked(workUserHandle); - } - - private void registerWorkProfileStateReceiver() { - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_USER_UNLOCKED); - filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); - filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); - registerReceiverAsUser(mWorkProfileStateReceiver, UserHandle.ALL, filter, null, null); - } - @Override protected final void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); @@ -2248,45 +2205,6 @@ public class ResolverActivity extends FragmentActivity implements return mMultiProfilePagerAdapter.getInactiveListAdapter().getCount() > 0; } - private BroadcastReceiver createWorkProfileStateReceiver() { - return new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (!TextUtils.equals(action, Intent.ACTION_USER_UNLOCKED) - && !TextUtils.equals(action, Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) - && !TextUtils.equals(action, Intent.ACTION_MANAGED_PROFILE_AVAILABLE)) { - return; - } - - int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); - - if (userId != getWorkProfileUserHandle().getIdentifier()) { - return; - } - - if (isWorkProfileEnabled()) { - if (mWorkProfileHasBeenEnabled) { - return; - } - - mWorkProfileHasBeenEnabled = true; - mQuietModeManager.markWorkProfileEnabledBroadcastReceived(); - } else { - // Must be an UNAVAILABLE broadcast, so we watch for the next availability - mWorkProfileHasBeenEnabled = false; - } - - if (mMultiProfilePagerAdapter.getCurrentUserHandle() - .equals(getWorkProfileUserHandle())) { - mMultiProfilePagerAdapter.rebuildActiveTab(true); - } else { - mMultiProfilePagerAdapter.clearInactiveProfileCache(); - } - } - }; - } - public static final class ResolvedComponentInfo { public final ComponentName name; private final List<Intent> mIntents = new ArrayList<>(); @@ -2439,4 +2357,4 @@ public class ResolverActivity extends FragmentActivity implements } } } -}
\ No newline at end of file +} diff --git a/java/src/com/android/intentresolver/ResolverMultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/ResolverMultiProfilePagerAdapter.java index 65de9409..48e3b62d 100644 --- a/java/src/com/android/intentresolver/ResolverMultiProfilePagerAdapter.java +++ b/java/src/com/android/intentresolver/ResolverMultiProfilePagerAdapter.java @@ -43,13 +43,13 @@ public class ResolverMultiProfilePagerAdapter extends Context context, ResolverListAdapter adapter, EmptyStateProvider emptyStateProvider, - QuietModeManager quietModeManager, + Supplier<Boolean> workProfileQuietModeChecker, UserHandle workProfileUserHandle) { this( context, ImmutableList.of(adapter), emptyStateProvider, - quietModeManager, + workProfileQuietModeChecker, /* defaultProfile= */ 0, workProfileUserHandle, new BottomPaddingOverrideSupplier()); @@ -59,14 +59,14 @@ public class ResolverMultiProfilePagerAdapter extends ResolverListAdapter personalAdapter, ResolverListAdapter workAdapter, EmptyStateProvider emptyStateProvider, - QuietModeManager quietModeManager, + Supplier<Boolean> workProfileQuietModeChecker, @Profile int defaultProfile, UserHandle workProfileUserHandle) { this( context, ImmutableList.of(personalAdapter, workAdapter), emptyStateProvider, - quietModeManager, + workProfileQuietModeChecker, defaultProfile, workProfileUserHandle, new BottomPaddingOverrideSupplier()); @@ -76,7 +76,7 @@ public class ResolverMultiProfilePagerAdapter extends Context context, ImmutableList<ResolverListAdapter> listAdapters, EmptyStateProvider emptyStateProvider, - QuietModeManager quietModeManager, + Supplier<Boolean> workProfileQuietModeChecker, @Profile int defaultProfile, UserHandle workProfileUserHandle, BottomPaddingOverrideSupplier bottomPaddingOverrideSupplier) { @@ -86,7 +86,7 @@ public class ResolverMultiProfilePagerAdapter extends (listView, bindAdapter) -> listView.setAdapter(bindAdapter), listAdapters, emptyStateProvider, - quietModeManager, + workProfileQuietModeChecker, defaultProfile, workProfileUserHandle, () -> (ViewGroup) LayoutInflater.from(context).inflate( diff --git a/java/src/com/android/intentresolver/WorkProfileAvailabilityManager.java b/java/src/com/android/intentresolver/WorkProfileAvailabilityManager.java new file mode 100644 index 00000000..6e51520b --- /dev/null +++ b/java/src/com/android/intentresolver/WorkProfileAvailabilityManager.java @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.intentresolver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.AsyncTask; +import android.os.UserHandle; +import android.os.UserManager; +import android.text.TextUtils; + +import androidx.annotation.VisibleForTesting; + +/** Monitor for runtime conditions that may disable work profile display. */ +public class WorkProfileAvailabilityManager { + private final UserManager mUserManager; + private final UserHandle mWorkProfileUserHandle; + private final Runnable mOnWorkProfileStateUpdated; + + private BroadcastReceiver mWorkProfileStateReceiver; + + private boolean mIsWaitingToEnableWorkProfile; + private boolean mWorkProfileHasBeenEnabled; + + public WorkProfileAvailabilityManager( + UserManager userManager, + UserHandle workProfileUserHandle, + Runnable onWorkProfileStateUpdated) { + mUserManager = userManager; + mWorkProfileUserHandle = workProfileUserHandle; + mWorkProfileHasBeenEnabled = isWorkProfileEnabled(); + mOnWorkProfileStateUpdated = onWorkProfileStateUpdated; + } + + /** + * Register a {@link BroadcastReceiver}, if we haven't already, to be notified about work + * profile availability changes. + * + * TODO: this takes the context for testing, because we don't have a context on hand when we + * set up this component's default "override" in {@link ChooserActivityOverrideData#reset()}. + * The use of these overrides in our testing design is questionable and can hopefully be + * improved someday; then this context should be injected in our constructor & held as `final`. + * + * TODO: consider injecting an optional `Lifecycle` so that this component can automatically + * manage its own registration/unregistration. (This would be optional because registration of + * the receiver is conditional on having `shouldShowTabs()` in our session.) + */ + public void registerWorkProfileStateReceiver(Context context) { + if (mWorkProfileStateReceiver != null) { + return; + } + mWorkProfileStateReceiver = createWorkProfileStateReceiver(); + + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_USER_UNLOCKED); + filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); + filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); + context.registerReceiverAsUser( + mWorkProfileStateReceiver, UserHandle.ALL, filter, null, null); + } + + /** + * Unregister any {@link BroadcastReceiver} currently waiting for a work-enabled broadcast. + * + * TODO: this takes the context for testing, because we don't have a context on hand when we + * set up this component's default "override" in {@link ChooserActivityOverrideData#reset()}. + * The use of these overrides in our testing design is questionable and can hopefully be + * improved someday; then this context should be injected in our constructor & held as `final`. + */ + public void unregisterWorkProfileStateReceiver(Context context) { + if (mWorkProfileStateReceiver == null) { + return; + } + context.unregisterReceiver(mWorkProfileStateReceiver); + mWorkProfileStateReceiver = null; + } + + public boolean isQuietModeEnabled() { + return mUserManager.isQuietModeEnabled(mWorkProfileUserHandle); + } + + // TODO: why do clients only care about the result of `isQuietModeEnabled()`, even though + // internally (in `isWorkProfileEnabled()`) we also check this 'unlocked' condition? + @VisibleForTesting + public boolean isWorkProfileUserUnlocked() { + return mUserManager.isUserUnlocked(mWorkProfileUserHandle); + } + + /** + * Request that quiet mode be enabled (or disabled) for the work profile. + * TODO: this is only used to disable quiet mode; should that be hard-coded? + */ + public void requestQuietModeEnabled(boolean enabled) { + AsyncTask.THREAD_POOL_EXECUTOR.execute( + () -> mUserManager.requestQuietModeEnabled(enabled, mWorkProfileUserHandle)); + mIsWaitingToEnableWorkProfile = true; + } + + /** + * Stop waiting for a work-enabled broadcast. + * TODO: this seems strangely low-level to include as part of the public API. Maybe some + * responsibilities need to be pulled over from the client? + */ + public void markWorkProfileEnabledBroadcastReceived() { + mIsWaitingToEnableWorkProfile = false; + } + + public boolean isWaitingToEnableWorkProfile() { + return mIsWaitingToEnableWorkProfile; + } + + private boolean isWorkProfileEnabled() { + return (mWorkProfileUserHandle != null) + && !isQuietModeEnabled() + && isWorkProfileUserUnlocked(); + } + + private BroadcastReceiver createWorkProfileStateReceiver() { + return new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (!TextUtils.equals(action, Intent.ACTION_USER_UNLOCKED) + && !TextUtils.equals(action, Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) + && !TextUtils.equals(action, Intent.ACTION_MANAGED_PROFILE_AVAILABLE)) { + return; + } + + if (intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1) + != mWorkProfileUserHandle.getIdentifier()) { + return; + } + + if (isWorkProfileEnabled()) { + if (mWorkProfileHasBeenEnabled) { + return; + } + mWorkProfileHasBeenEnabled = true; + mIsWaitingToEnableWorkProfile = false; + } else { + // Must be an UNAVAILABLE broadcast, so we watch for the next availability. + // TODO: confirm the above reasoning (& handling of "UNAVAILABLE" in general). + mWorkProfileHasBeenEnabled = false; + } + + mOnWorkProfileStateUpdated.run(); + } + }; + } +} diff --git a/java/src/com/android/intentresolver/WorkProfilePausedEmptyStateProvider.java b/java/src/com/android/intentresolver/WorkProfilePausedEmptyStateProvider.java index b7c89907..0333039b 100644 --- a/java/src/com/android/intentresolver/WorkProfilePausedEmptyStateProvider.java +++ b/java/src/com/android/intentresolver/WorkProfilePausedEmptyStateProvider.java @@ -26,11 +26,10 @@ import android.content.Context; import android.os.UserHandle; import android.stats.devicepolicy.nano.DevicePolicyEnums; -import com.android.internal.R; import com.android.intentresolver.AbstractMultiProfilePagerAdapter.EmptyState; import com.android.intentresolver.AbstractMultiProfilePagerAdapter.EmptyStateProvider; import com.android.intentresolver.AbstractMultiProfilePagerAdapter.OnSwitchOnWorkSelectedListener; -import com.android.intentresolver.AbstractMultiProfilePagerAdapter.QuietModeManager; +import com.android.internal.R; /** * Chooser/ResolverActivity empty state provider that returns empty state which is shown when @@ -39,19 +38,19 @@ import com.android.intentresolver.AbstractMultiProfilePagerAdapter.QuietModeMana public class WorkProfilePausedEmptyStateProvider implements EmptyStateProvider { private final UserHandle mWorkProfileUserHandle; - private final QuietModeManager mQuietModeManager; + private final WorkProfileAvailabilityManager mWorkProfileAvailability; private final String mMetricsCategory; private final OnSwitchOnWorkSelectedListener mOnSwitchOnWorkSelectedListener; private final Context mContext; public WorkProfilePausedEmptyStateProvider(@NonNull Context context, @Nullable UserHandle workProfileUserHandle, - @NonNull QuietModeManager quietModeManager, + @NonNull WorkProfileAvailabilityManager workProfileAvailability, @Nullable OnSwitchOnWorkSelectedListener onSwitchOnWorkSelectedListener, @NonNull String metricsCategory) { mContext = context; mWorkProfileUserHandle = workProfileUserHandle; - mQuietModeManager = quietModeManager; + mWorkProfileAvailability = workProfileAvailability; mMetricsCategory = metricsCategory; mOnSwitchOnWorkSelectedListener = onSwitchOnWorkSelectedListener; } @@ -60,7 +59,7 @@ public class WorkProfilePausedEmptyStateProvider implements EmptyStateProvider { @Override public EmptyState getEmptyState(ResolverListAdapter resolverListAdapter) { if (!resolverListAdapter.getUserHandle().equals(mWorkProfileUserHandle) - || !mQuietModeManager.isQuietModeEnabled(mWorkProfileUserHandle) + || !mWorkProfileAvailability.isQuietModeEnabled() || resolverListAdapter.getCount() == 0) { return null; } @@ -74,7 +73,7 @@ public class WorkProfilePausedEmptyStateProvider implements EmptyStateProvider { if (mOnSwitchOnWorkSelectedListener != null) { mOnSwitchOnWorkSelectedListener.onSwitchOnWorkSelected(); } - mQuietModeManager.requestQuietModeEnabled(false, mWorkProfileUserHandle); + mWorkProfileAvailability.requestQuietModeEnabled(false); }, mMetricsCategory); } |