summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java42
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java65
-rw-r--r--core/java/com/android/internal/app/ChooserListAdapter.java5
-rw-r--r--core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java15
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java156
-rw-r--r--core/java/com/android/internal/app/ResolverListAdapter.java7
-rw-r--r--core/java/com/android/internal/app/ResolverListController.java3
-rw-r--r--core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java15
-rw-r--r--core/java/com/android/internal/app/ResolverViewPager.java (renamed from core/java/com/android/internal/app/WrapHeightViewPager.java)29
-rw-r--r--core/res/res/layout/chooser_grid.xml29
-rw-r--r--core/res/res/layout/resolver_list.xml42
-rw-r--r--core/res/res/layout/resolver_list_per_profile.xml4
-rw-r--r--core/res/res/layout/resolver_list_with_default.xml44
-rw-r--r--core/res/res/values/colors.xml2
-rw-r--r--core/res/res/values/strings.xml4
-rw-r--r--core/res/res/values/symbols.xml11
16 files changed, 358 insertions, 115 deletions
diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
index 08022e983892..b2aa0431251d 100644
--- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
@@ -26,7 +26,9 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.PagerAdapter;
import com.android.internal.widget.ViewPager;
+import java.util.HashSet;
import java.util.Objects;
+import java.util.Set;
/**
* Skeletal {@link PagerAdapter} implementation of a work or personal profile page for
@@ -34,6 +36,7 @@ import java.util.Objects;
*/
public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
+ private static final String TAG = "AbstractMultiProfilePagerAdapter";
static final int PROFILE_PERSONAL = 0;
static final int PROFILE_WORK = 1;
@IntDef({PROFILE_PERSONAL, PROFILE_WORK})
@@ -41,10 +44,17 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
private final Context mContext;
private int mCurrentPage;
+ private OnProfileSelectedListener mOnProfileSelectedListener;
+ private Set<Integer> mLoadedPages;
AbstractMultiProfilePagerAdapter(Context context, int currentPage) {
mContext = Objects.requireNonNull(context);
mCurrentPage = currentPage;
+ mLoadedPages = new HashSet<>();
+ }
+
+ void setOnProfileSelectedListener(OnProfileSelectedListener listener) {
+ mOnProfileSelectedListener = listener;
}
Context getContext() {
@@ -57,15 +67,22 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
* page and rebuilds the list.
*/
void setupViewPager(ViewPager viewPager) {
- viewPager.setCurrentItem(mCurrentPage);
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
mCurrentPage = position;
- getActiveListAdapter().rebuildList();
+ if (!mLoadedPages.contains(position)) {
+ getActiveListAdapter().rebuildList();
+ mLoadedPages.add(position);
+ }
+ if (mOnProfileSelectedListener != null) {
+ mOnProfileSelectedListener.onProfileSelected(position);
+ }
}
});
viewPager.setAdapter(this);
+ viewPager.setCurrentItem(mCurrentPage);
+ mLoadedPages.add(mCurrentPage);
}
@Override
@@ -90,7 +107,8 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
return mCurrentPage;
}
- UserHandle getCurrentUserHandle() {
+ @VisibleForTesting
+ public UserHandle getCurrentUserHandle() {
return getActiveListAdapter().mResolverListController.getUserHandle();
}
@@ -135,7 +153,8 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
* <p>This method is meant to be implemented with an implementation-specific return type
* depending on the adapter type.
*/
- abstract Object getAdapterForIndex(int pageIndex);
+ @VisibleForTesting
+ public abstract Object getAdapterForIndex(int pageIndex);
@VisibleForTesting
public abstract ResolverListAdapter getActiveListAdapter();
@@ -152,7 +171,9 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
abstract Object getCurrentRootAdapter();
- abstract ViewGroup getCurrentAdapterView();
+ abstract ViewGroup getActiveAdapterView();
+
+ abstract @Nullable ViewGroup getInactiveAdapterView();
protected class ProfileDescriptor {
final ViewGroup rootView;
@@ -160,4 +181,15 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
this.rootView = rootView;
}
}
+
+ public interface OnProfileSelectedListener {
+ /**
+ * Callback for when the user changes the active tab from personal to work or vice versa.
+ * <p>This callback is only called when the intent resolver or share sheet shows
+ * the work and personal profiles.
+ * @param profileIndex {@link #PROFILE_PERSONAL} if the personal profile was selected or
+ * {@link #PROFILE_WORK} if the work profile was selected.
+ */
+ void onProfileSelected(int profileIndex);
+ }
} \ 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 9532faecb4df..8bbc343fa4ca 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -508,7 +508,6 @@ public class ChooserActivity extends ResolverActivity implements
protected void onCreate(Bundle savedInstanceState) {
final long intentReceivedTime = System.currentTimeMillis();
// This is the only place this value is being set. Effectively final.
- //TODO(arangelov) - should there be a mIsAppPredictorComponentAvailable flag for work tab?
mIsAppPredictorComponentAvailable = isAppPredictionServiceAvailable();
mIsSuccessfullySelected = false;
@@ -689,29 +688,6 @@ public class ChooserActivity extends ResolverActivity implements
mResolverDrawerLayout.setOnScrollChangeListener(this::handleScroll);
}
- final View chooserHeader = mResolverDrawerLayout.findViewById(R.id.chooser_header);
- final float defaultElevation = chooserHeader.getElevation();
- final float chooserHeaderScrollElevation =
- getResources().getDimensionPixelSize(R.dimen.chooser_header_scroll_elevation);
-
- mChooserMultiProfilePagerAdapter.getCurrentAdapterView().addOnScrollListener(
- new RecyclerView.OnScrollListener() {
- public void onScrollStateChanged(RecyclerView view, int scrollState) {
- }
-
- public void onScrolled(RecyclerView view, int dx, int dy) {
- if (view.getChildCount() > 0) {
- View child = view.getLayoutManager().findViewByPosition(0);
- if (child == null || child.getTop() < 0) {
- chooserHeader.setElevation(chooserHeaderScrollElevation);
- return;
- }
- }
-
- chooserHeader.setElevation(defaultElevation);
- }
- });
-
mResolverDrawerLayout.setOnCollapsedChangedListener(
new ResolverDrawerLayout.OnCollapsedChangedListener() {
@@ -1330,8 +1306,8 @@ public class ChooserActivity extends ResolverActivity implements
}
@Override
- public void onPrepareAdapterView(ResolverListAdapter adapter) {
- mChooserMultiProfilePagerAdapter.getCurrentAdapterView().setVisibility(View.VISIBLE);
+ public void addUseDifferentAppLabelIfNecessary(ResolverListAdapter adapter) {
+ mChooserMultiProfilePagerAdapter.getActiveAdapterView().setVisibility(View.VISIBLE);
if (mCallerChooserTargets != null && mCallerChooserTargets.length > 0) {
mChooserMultiProfilePagerAdapter.getActiveListAdapter().addServiceResults(
/* origTarget */ null,
@@ -2202,7 +2178,7 @@ public class ChooserActivity extends ResolverActivity implements
if (mChooserMultiProfilePagerAdapter == null) {
return;
}
- RecyclerView recyclerView = mChooserMultiProfilePagerAdapter.getCurrentAdapterView();
+ RecyclerView recyclerView = mChooserMultiProfilePagerAdapter.getActiveAdapterView();
ChooserGridAdapter gridAdapter = mChooserMultiProfilePagerAdapter.getCurrentRootAdapter();
if (gridAdapter == null || recyclerView == null) {
return;
@@ -2328,6 +2304,8 @@ public class ChooserActivity extends ResolverActivity implements
@Override
public void onListRebuilt(ResolverListAdapter listAdapter) {
+ setupScrollListener();
+
ChooserListAdapter chooserListAdapter = (ChooserListAdapter) listAdapter;
if (chooserListAdapter.mDisplayList == null
|| chooserListAdapter.mDisplayList.isEmpty()) {
@@ -2368,6 +2346,34 @@ public class ChooserActivity extends ResolverActivity implements
}
}
+ private void setupScrollListener() {
+ if (mResolverDrawerLayout == null) {
+ return;
+ }
+ final View chooserHeader = mResolverDrawerLayout.findViewById(R.id.chooser_header);
+ final float defaultElevation = chooserHeader.getElevation();
+ final float chooserHeaderScrollElevation =
+ getResources().getDimensionPixelSize(R.dimen.chooser_header_scroll_elevation);
+
+ mChooserMultiProfilePagerAdapter.getActiveAdapterView().addOnScrollListener(
+ new RecyclerView.OnScrollListener() {
+ public void onScrollStateChanged(RecyclerView view, int scrollState) {
+ }
+
+ public void onScrolled(RecyclerView view, int dx, int dy) {
+ if (view.getChildCount() > 0) {
+ View child = view.getLayoutManager().findViewByPosition(0);
+ if (child == null || child.getTop() < 0) {
+ chooserHeader.setElevation(chooserHeaderScrollElevation);
+ return;
+ }
+ }
+
+ chooserHeader.setElevation(defaultElevation);
+ }
+ });
+ }
+
@Override // ChooserListCommunicator
public boolean isSendAction(Intent targetIntent) {
if (targetIntent == null) {
@@ -2475,7 +2481,8 @@ public class ChooserActivity extends ResolverActivity implements
* row level by this adapter but not on the item level. Individual targets within the row are
* handled by {@link ChooserListAdapter}
*/
- final class ChooserGridAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+ @VisibleForTesting
+ public final class ChooserGridAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ChooserListAdapter mChooserListAdapter;
private final LayoutInflater mLayoutInflater;
@@ -2905,7 +2912,7 @@ public class ChooserActivity extends ResolverActivity implements
if (mDirectShareViewHolder != null && canExpandDirectShare) {
mDirectShareViewHolder.handleScroll(
- mChooserMultiProfilePagerAdapter.getCurrentAdapterView(), y, oldy,
+ mChooserMultiProfilePagerAdapter.getActiveAdapterView(), y, oldy,
getMaxTargetsPerRow());
}
}
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index a8a676d03971..6ff844a2eaae 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -246,11 +246,6 @@ public class ChooserListAdapter extends ResolverListAdapter {
}
@Override
- public boolean shouldGetResolvedFilter() {
- return true;
- }
-
- @Override
public int getCount() {
return getRankedTargetCount() + getAlphaTargetCount()
+ getSelectableServiceTargetCount() + getCallerTargetCount();
diff --git a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
index 7d856e1b945d..1c52d0e8f9f1 100644
--- a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
@@ -16,6 +16,7 @@
package com.android.internal.app;
+import android.annotation.Nullable;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.ViewGroup;
@@ -77,7 +78,8 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd
}
@Override
- ChooserActivity.ChooserGridAdapter getAdapterForIndex(int pageIndex) {
+ @VisibleForTesting
+ public ChooserActivity.ChooserGridAdapter getAdapterForIndex(int pageIndex) {
return mItems[pageIndex].chooserGridAdapter;
}
@@ -121,10 +123,19 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd
}
@Override
- RecyclerView getCurrentAdapterView() {
+ RecyclerView getActiveAdapterView() {
return getListViewForIndex(getCurrentPage());
}
+ @Override
+ @Nullable
+ RecyclerView getInactiveAdapterView() {
+ if (getCount() == 1) {
+ return null;
+ }
+ return getListViewForIndex(1 - getCurrentPage());
+ }
+
class ChooserProfileDescriptor extends ProfileDescriptor {
private ChooserActivity.ChooserGridAdapter chooserGridAdapter;
private RecyclerView recyclerView;
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index b2417b2e79cc..68d6e03f654c 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -59,6 +59,7 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -67,9 +68,12 @@ import android.view.WindowInsets;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.Button;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Space;
+import android.widget.TabHost;
+import android.widget.TabWidget;
import android.widget.TextView;
import android.widget.Toast;
@@ -82,6 +86,7 @@ import com.android.internal.content.PackageMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.widget.ResolverDrawerLayout;
+import com.android.internal.widget.ViewPager;
import java.util.ArrayList;
import java.util.Arrays;
@@ -147,7 +152,10 @@ public class ResolverActivity extends Activity implements
/**
* TODO(arangelov): Remove a couple of weeks after work/personal tabs are finalized.
*/
- static final boolean ENABLE_TABBED_VIEW = false;
+ @VisibleForTesting
+ public static boolean ENABLE_TABBED_VIEW = false;
+ private static final String TAB_TAG_PERSONAL = "personal";
+ private static final String TAB_TAG_WORK = "work";
private final PackageMonitor mPackageMonitor = createPackageMonitor();
@@ -418,12 +426,16 @@ public class ResolverActivity extends Activity implements
Intent[] initialIntents,
List<ResolveInfo> rList,
boolean filterLastUsed) {
+ // We only show the default app for the profile of the current user. The filterLastUsed
+ // flag determines whether to show a default app and that app is not shown in the
+ // resolver list. So filterLastUsed should be false for the other profile.
ResolverListAdapter personalAdapter = createResolverListAdapter(
/* context */ this,
/* payloadIntents */ mIntents,
initialIntents,
rList,
- filterLastUsed,
+ (filterLastUsed && UserHandle.myUserId()
+ == getPersonalProfileUserHandle().getIdentifier()),
mUseLayoutForBrowsables,
/* userHandle */ getPersonalProfileUserHandle());
ResolverListAdapter workAdapter = createResolverListAdapter(
@@ -431,7 +443,8 @@ public class ResolverActivity extends Activity implements
/* payloadIntents */ mIntents,
initialIntents,
rList,
- filterLastUsed,
+ (filterLastUsed && UserHandle.myUserId()
+ == getWorkProfileUserHandle().getIdentifier()),
mUseLayoutForBrowsables,
/* userHandle */ getWorkProfileUserHandle());
return new ResolverMultiProfilePagerAdapter(
@@ -495,12 +508,12 @@ public class ResolverActivity extends Activity implements
mFooterSpacer = new Space(getApplicationContext());
} else {
((ResolverMultiProfilePagerAdapter) mMultiProfilePagerAdapter)
- .getCurrentAdapterView().removeFooterView(mFooterSpacer);
+ .getActiveAdapterView().removeFooterView(mFooterSpacer);
}
mFooterSpacer.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT,
mSystemWindowInsets.bottom));
((ResolverMultiProfilePagerAdapter) mMultiProfilePagerAdapter)
- .getCurrentAdapterView().addFooterView(mFooterSpacer);
+ .getActiveAdapterView().addFooterView(mFooterSpacer);
}
protected WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
@@ -817,7 +830,7 @@ public class ResolverActivity extends Activity implements
public void onButtonClick(View v) {
final int id = v.getId();
- ListView listView = (ListView) mMultiProfilePagerAdapter.getCurrentAdapterView();
+ ListView listView = (ListView) mMultiProfilePagerAdapter.getActiveAdapterView();
ResolverListAdapter currentListAdapter = mMultiProfilePagerAdapter.getActiveListAdapter();
int which = currentListAdapter.hasFilteredItem()
? currentListAdapter.getFilteredPosition()
@@ -898,7 +911,10 @@ public class ResolverActivity extends Activity implements
@Override // ResolverListCommunicator
public void onPostListReady(ResolverListAdapter listAdapter) {
- setHeader();
+ if (mMultiProfilePagerAdapter.getCurrentUserHandle().getIdentifier()
+ == UserHandle.myUserId()) {
+ setHeader();
+ }
resetButtonBar();
onListRebuilt(listAdapter);
}
@@ -913,6 +929,9 @@ public class ResolverActivity extends Activity implements
finish();
}
}
+
+ final ItemClickListener listener = new ItemClickListener();
+ setupAdapterListView((ListView) mMultiProfilePagerAdapter.getActiveAdapterView(), listener);
}
protected boolean onTargetSelected(TargetInfo target, boolean alwaysCheck) {
@@ -1094,6 +1113,7 @@ public class ResolverActivity extends Activity implements
return true;
}
+ @VisibleForTesting
public void safelyStartActivity(TargetInfo cti) {
// We're dispatching intents that might be coming from legacy apps, so
// don't kill ourselves.
@@ -1222,9 +1242,6 @@ public class ResolverActivity extends Activity implements
+ "cannot be null.");
}
boolean rebuildCompleted = mMultiProfilePagerAdapter.getActiveListAdapter().rebuildList();
- if (mMultiProfilePagerAdapter.getInactiveListAdapter() != null) {
- mMultiProfilePagerAdapter.getInactiveListAdapter().rebuildList();
- }
if (useLayoutWithDefault()) {
mLayoutId = R.layout.resolver_list_with_default;
} else {
@@ -1272,45 +1289,99 @@ public class ResolverActivity extends Activity implements
}
}
- setupViewVisibilities(count);
+ setupViewVisibilities();
+
+ if (hasWorkProfile() && ENABLE_TABBED_VIEW) {
+ setupProfileTabs();
+ }
+
return false;
}
- private void setupViewVisibilities(int count) {
- if (count == 0
- && mMultiProfilePagerAdapter.getActiveListAdapter().getPlaceholderCount() == 0) {
- final TextView emptyView = findViewById(R.id.empty);
- emptyView.setVisibility(View.VISIBLE);
- findViewById(R.id.profile_pager).setVisibility(View.GONE);
- } else {
- onPrepareAdapterView(mMultiProfilePagerAdapter.getActiveListAdapter());
+ private void setupProfileTabs() {
+ TabHost tabHost = findViewById(R.id.profile_tabhost);
+ tabHost.setup();
+ ViewPager viewPager = findViewById(R.id.profile_pager);
+ TabHost.TabSpec tabSpec = tabHost.newTabSpec(TAB_TAG_PERSONAL)
+ .setContent(R.id.profile_pager)
+ .setIndicator(getString(R.string.resolver_personal_tab));
+ tabHost.addTab(tabSpec);
+
+ tabSpec = tabHost.newTabSpec(TAB_TAG_WORK)
+ .setContent(R.id.profile_pager)
+ .setIndicator(getString(R.string.resolver_work_tab));
+ tabHost.addTab(tabSpec);
+
+ TabWidget tabWidget = tabHost.getTabWidget();
+ tabWidget.setVisibility(View.VISIBLE);
+ resetTabsHeaderStyle(tabWidget);
+ updateActiveTabStyle(tabHost);
+
+ tabHost.setOnTabChangedListener(tabId -> {
+ resetTabsHeaderStyle(tabWidget);
+ updateActiveTabStyle(tabHost);
+ if (TAB_TAG_PERSONAL.equals(tabId)) {
+ viewPager.setCurrentItem(0);
+ } else {
+ viewPager.setCurrentItem(1);
+ }
+ setupViewVisibilities();
+ });
+
+ viewPager.setVisibility(View.VISIBLE);
+ tabHost.setCurrentTab(mMultiProfilePagerAdapter.getCurrentPage());
+ mMultiProfilePagerAdapter.setOnProfileSelectedListener(tabHost::setCurrentTab);
+ }
+
+ private void resetTabsHeaderStyle(TabWidget tabWidget) {
+ for (int i = 0; i < tabWidget.getChildCount(); i++) {
+ TextView title = tabWidget.getChildAt(i).findViewById(android.R.id.title);
+ title.setTextColor(getColor(R.color.resolver_tabs_inactive_color));
+ title.setAllCaps(false);
+ }
+ }
+
+ private void updateActiveTabStyle(TabHost tabHost) {
+ TextView title = tabHost.getTabWidget().getChildAt(tabHost.getCurrentTab())
+ .findViewById(android.R.id.title);
+ title.setTextColor(getColor(R.color.resolver_tabs_active_color));
+ }
+
+ private void setupViewVisibilities() {
+ int count = mMultiProfilePagerAdapter.getActiveListAdapter().getUnfilteredCount();
+ boolean shouldShowEmptyState = count == 0
+ && mMultiProfilePagerAdapter.getActiveListAdapter().getPlaceholderCount() == 0;
+ //TODO(arangelov): Handle empty state
+ if (!shouldShowEmptyState) {
+ addUseDifferentAppLabelIfNecessary(mMultiProfilePagerAdapter.getActiveListAdapter());
}
}
/**
- * Prepare the scrollable view which consumes data in the list adapter.
+ * Add a label to signify that the user can pick a different app.
* @param adapter The adapter used to provide data to item views.
*/
- public void onPrepareAdapterView(ResolverListAdapter adapter) {
- mMultiProfilePagerAdapter.getCurrentAdapterView().setVisibility(View.VISIBLE);
+ public void addUseDifferentAppLabelIfNecessary(ResolverListAdapter adapter) {
final boolean useHeader = adapter.hasFilteredItem();
- final ListView listView = (ListView) mMultiProfilePagerAdapter.getCurrentAdapterView();
- final ItemClickListener listener = new ItemClickListener();
+ if (useHeader) {
+ FrameLayout stub = findViewById(R.id.stub);
+ stub.setVisibility(View.VISIBLE);
+ TextView textView = (TextView) LayoutInflater.from(this).inflate(
+ R.layout.resolver_different_item_header, null, false);
+ if (ENABLE_TABBED_VIEW) {
+ textView.setGravity(Gravity.CENTER);
+ }
+ stub.addView(textView);
+ }
+ }
+
+ private void setupAdapterListView(ListView listView, ItemClickListener listener) {
listView.setOnItemClickListener(listener);
listView.setOnItemLongClickListener(listener);
if (mSupportsAlwaysUseOption || mUseLayoutForBrowsables) {
listView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
}
-
- // In case this method is called again (due to activity recreation), avoid adding a new
- // header if one is already present.
- if (useHeader && listView.getHeaderViewsCount() == 0) {
- listView.setHeaderDividersEnabled(true);
- listView.addHeaderView(LayoutInflater.from(this).inflate(
- R.layout.resolver_different_item_header, listView, false),
- null, false);
- }
}
/**
@@ -1378,7 +1449,7 @@ public class ResolverActivity extends Activity implements
}
// When the items load in, if an item was already selected, enable the buttons
- ListView currentAdapterView = (ListView) mMultiProfilePagerAdapter.getCurrentAdapterView();
+ ListView currentAdapterView = (ListView) mMultiProfilePagerAdapter.getActiveAdapterView();
if (currentAdapterView != null
&& currentAdapterView.getCheckedItemPosition() != ListView.INVALID_POSITION) {
setAlwaysButtonEnabled(true, currentAdapterView.getCheckedItemPosition(), true);
@@ -1388,8 +1459,18 @@ public class ResolverActivity extends Activity implements
@Override // ResolverListCommunicator
public boolean useLayoutWithDefault() {
- return mSupportsAlwaysUseOption
- && mMultiProfilePagerAdapter.getActiveListAdapter().hasFilteredItem();
+ // We only use the default app layout when the profile of the active user has a
+ // filtered item. We always show the same default app even in the inactive user profile.
+ boolean currentUserAdapterHasFilteredItem;
+ if (mMultiProfilePagerAdapter.getCurrentUserHandle().getIdentifier()
+ == UserHandle.myUserId()) {
+ currentUserAdapterHasFilteredItem =
+ mMultiProfilePagerAdapter.getActiveListAdapter().hasFilteredItem();
+ } else {
+ currentUserAdapterHasFilteredItem =
+ mMultiProfilePagerAdapter.getInactiveListAdapter().hasFilteredItem();
+ }
+ return mSupportsAlwaysUseOption && currentUserAdapterHasFilteredItem;
}
/**
@@ -1494,9 +1575,8 @@ public class ResolverActivity extends Activity implements
.resolveInfoForPosition(position, true) == null) {
return;
}
-
ListView currentAdapterView =
- (ListView) mMultiProfilePagerAdapter.getCurrentAdapterView();
+ (ListView) mMultiProfilePagerAdapter.getActiveAdapterView();
final int checkedPos = currentAdapterView.getCheckedItemPosition();
final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION;
if (!useLayoutWithDefault()
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index ef7a347cf7be..d227ec5c1b38 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -193,7 +193,8 @@ public class ResolverListAdapter extends BaseAdapter {
mBaseResolveList);
} else {
currentResolveList = mUnfilteredResolveList =
- mResolverListController.getResolversForIntent(shouldGetResolvedFilter(),
+ mResolverListController.getResolversForIntent(
+ /* shouldGetResolvedFilter= */ true,
mResolverListCommunicator.shouldGetActivityMetadata(),
mIntents);
if (currentResolveList == null) {
@@ -363,10 +364,6 @@ public class ResolverListAdapter extends BaseAdapter {
}
}
- public boolean shouldGetResolvedFilter() {
- return mFilterLastUsed;
- }
-
private void addResolveInfoWithAlternates(ResolvedComponentInfo rci) {
final int count = rci.getCount();
final Intent intent = rci.getIntentAt(0);
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index abd3eb2453df..0bfe9eb04d28 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -133,7 +133,8 @@ public class ResolverListController {
return resolvedComponents;
}
- UserHandle getUserHandle() {
+ @VisibleForTesting
+ public UserHandle getUserHandle() {
return mUserHandle;
}
diff --git a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
index d72c52bfe6b6..567ed74670bf 100644
--- a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
@@ -16,6 +16,7 @@
package com.android.internal.app;
+import android.annotation.Nullable;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.ViewGroup;
@@ -81,7 +82,8 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA
}
@Override
- ResolverListAdapter getAdapterForIndex(int pageIndex) {
+ @VisibleForTesting
+ public ResolverListAdapter getAdapterForIndex(int pageIndex) {
return mItems[pageIndex].resolverListAdapter;
}
@@ -106,10 +108,19 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA
}
@Override
- ListView getCurrentAdapterView() {
+ ListView getActiveAdapterView() {
return getListViewForIndex(getCurrentPage());
}
+ @Override
+ @Nullable
+ ViewGroup getInactiveAdapterView() {
+ if (getCount() == 1) {
+ return null;
+ }
+ return getListViewForIndex(1 - getCurrentPage());
+ }
+
class ResolverProfileDescriptor extends ProfileDescriptor {
private ResolverListAdapter resolverListAdapter;
final ListView listView;
diff --git a/core/java/com/android/internal/app/WrapHeightViewPager.java b/core/java/com/android/internal/app/ResolverViewPager.java
index b017bb44d751..8ec94f159725 100644
--- a/core/java/com/android/internal/app/WrapHeightViewPager.java
+++ b/core/java/com/android/internal/app/ResolverViewPager.java
@@ -18,39 +18,36 @@ package com.android.internal.app;
import android.content.Context;
import android.util.AttributeSet;
+import android.view.MotionEvent;
import android.view.View;
import com.android.internal.widget.ViewPager;
/**
- * A {@link ViewPager} which wraps around its first child's height.
+ * A {@link ViewPager} which wraps around its first child's height and has swiping disabled.
* <p>Normally {@link ViewPager} instances expand their height to cover all remaining space in
* the layout.
- * <p>This class is used for the intent resolver picker's tabbed view to maintain
- * consistency with the previous behavior.
+ * <p>This class is used for the intent resolver and share sheet's tabbed view.
*/
-public class WrapHeightViewPager extends ViewPager {
+public class ResolverViewPager extends ViewPager {
- public WrapHeightViewPager(Context context) {
+ public ResolverViewPager(Context context) {
super(context);
}
- public WrapHeightViewPager(Context context, AttributeSet attrs) {
+ public ResolverViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
- public WrapHeightViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
+ public ResolverViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
- public WrapHeightViewPager(Context context, AttributeSet attrs,
+ public ResolverViewPager(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
- // TODO(arangelov): When we have multiple pages, the height should wrap to the currently
- // displayed page. Investigate whether onMeasure is called when changing a page, and instead
- // of getChildAt(0), use the currently displayed one.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -68,4 +65,14 @@ public class WrapHeightViewPager extends ViewPager {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ return false;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ return false;
+ }
}
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
index 0c45e45e7980..4e8a41f81c48 100644
--- a/core/res/res/layout/chooser_grid.xml
+++ b/core/res/res/layout/chooser_grid.xml
@@ -61,10 +61,33 @@
android:layout_height="wrap_content"
android:visibility="gone" />
- <com.android.internal.widget.ViewPager
- android:id="@+id/profile_pager"
+ <TabHost
+ android:id="@+id/profile_tabhost"
android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true"
+ android:background="?attr/colorBackgroundFloating">
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <TabWidget
+ android:id="@android:id/tabs"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ </TabWidget>
+ <FrameLayout
+ android:id="@android:id/tabcontent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <com.android.internal.app.ResolverViewPager
+ android:id="@+id/profile_pager"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ </FrameLayout>
+ </LinearLayout>
+ </TabHost>
<TextView android:id="@+id/empty"
android:layout_width="match_parent"
diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml
index c5d891254227..757cd539152d 100644
--- a/core/res/res/layout/resolver_list.xml
+++ b/core/res/res/layout/resolver_list.xml
@@ -70,14 +70,44 @@
android:background="?attr/colorBackgroundFloating"
android:foreground="?attr/dividerVertical" />
- <com.android.internal.app.WrapHeightViewPager
- android:id="@+id/profile_pager"
+ <FrameLayout
+ android:id="@+id/stub"
+ android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:divider="?attr/dividerVertical"
- android:footerDividersEnabled="false"
- android:headerDividersEnabled="false"
- android:dividerHeight="1dp"/>
+ android:background="?attr/colorBackgroundFloating"/>
+
+ <TabHost
+ android:id="@+id/profile_tabhost"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true"
+ android:background="?attr/colorBackgroundFloating">
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <TabWidget
+ android:id="@android:id/tabs"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ </TabWidget>
+ <FrameLayout
+ android:id="@android:id/tabcontent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <com.android.internal.app.ResolverViewPager
+ android:id="@+id/profile_pager"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:divider="?attr/dividerVertical"
+ android:footerDividersEnabled="false"
+ android:headerDividersEnabled="false"
+ android:dividerHeight="1dp"/>
+ </FrameLayout>
+ </LinearLayout>
+ </TabHost>
<View
android:layout_alwaysShow="true"
diff --git a/core/res/res/layout/resolver_list_per_profile.xml b/core/res/res/layout/resolver_list_per_profile.xml
index 68b991755e73..6d8d3480dc8c 100644
--- a/core/res/res/layout/resolver_list_per_profile.xml
+++ b/core/res/res/layout/resolver_list_per_profile.xml
@@ -25,7 +25,7 @@
android:nestedScrollingEnabled="true"
android:scrollbarStyle="outsideOverlay"
android:scrollIndicators="top|bottom"
- android:divider="?attr/dividerVertical"
+ android:divider="@null"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false"
- android:dividerHeight="1dp" /> \ No newline at end of file
+ android:dividerHeight="0dp" /> \ No newline at end of file
diff --git a/core/res/res/layout/resolver_list_with_default.xml b/core/res/res/layout/resolver_list_with_default.xml
index 5b3d929d23a5..b54673834ea9 100644
--- a/core/res/res/layout/resolver_list_with_default.xml
+++ b/core/res/res/layout/resolver_list_with_default.xml
@@ -151,14 +151,46 @@
android:background="?attr/colorBackgroundFloating"
android:foreground="?attr/dividerVertical" />
- <com.android.internal.app.WrapHeightViewPager
- android:id="@+id/profile_pager"
+ <FrameLayout
+ android:id="@+id/stub"
+ android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:dividerHeight="1dp"
- android:divider="?attr/dividerVertical"
- android:footerDividersEnabled="false"
- android:headerDividersEnabled="false"/>
+ android:background="?attr/colorBackgroundFloating"/>
+
+ <TabHost
+ android:id="@+id/profile_tabhost"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true"
+ android:background="?attr/colorBackgroundFloating">
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <TabWidget
+ android:id="@android:id/tabs"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone">
+ </TabWidget>
+ <FrameLayout
+ android:id="@android:id/tabcontent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <com.android.internal.app.ResolverViewPager
+ android:id="@+id/profile_pager"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:dividerHeight="1dp"
+ android:divider="?attr/dividerVertical"
+ android:footerDividersEnabled="false"
+ android:headerDividersEnabled="false"/>
+ </FrameLayout>
+ </LinearLayout>
+ </TabHost>
+
<View
android:layout_alwaysShow="true"
android:layout_width="match_parent"
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 1dcd389d9d8f..731e2ec95f9e 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -224,4 +224,6 @@
<!-- Resolver/Chooser -->
<color name="resolver_text_color_secondary_dark">#ffC4C6C6</color>
+ <color name="resolver_tabs_active_color">#FF1A73E8</color>
+ <color name="resolver_tabs_inactive_color">#FF80868B</color>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index bed418dc4c2d..cea6a1524d09 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5319,4 +5319,8 @@
<!-- Text to tell the user that a package has been forced by themselves in the RESTRICTED bucket. [CHAR LIMIT=NONE] -->
<string name="as_app_forced_to_restricted_bucket">
<xliff:g id="package_name" example="com.android.example">%1$s</xliff:g> has been put into the RESTRICTED bucket</string>
+
+ <!-- ResolverActivity - profile tabs -->
+ <string name="resolver_personal_tab">Personal</string>
+ <string name="resolver_work_tab">Work</string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 357b1f069107..6e67080d3651 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -249,6 +249,9 @@
<java-symbol type="id" name="app_ops" />
<java-symbol type="id" name="profile_pager" />
<java-symbol type="id" name="content_preview_container" />
+ <java-symbol type="id" name="profile_tabhost" />
+ <java-symbol type="id" name="tabs" />
+ <java-symbol type="id" name="tabcontent" />
<java-symbol type="attr" name="actionModeShareDrawable" />
<java-symbol type="attr" name="alertDialogCenterButtons" />
@@ -3833,4 +3836,12 @@
<java-symbol type="array" name="config_defaultImperceptibleKillingExemptionPkgs" />
<java-symbol type="array" name="config_defaultImperceptibleKillingExemptionProcStates" />
+
+ <!-- Intent resolver and share sheet -->
+ <java-symbol type="color" name="resolver_tabs_active_color" />
+ <java-symbol type="color" name="resolver_tabs_inactive_color" />
+ <java-symbol type="string" name="resolver_personal_tab" />
+ <java-symbol type="string" name="resolver_work_tab" />
+ <java-symbol type="id" name="stub" />
+
</resources>