Merge "Resolver - Improve flow for Intent URL handling" into qt-dev
am: d73543b588
Change-Id: I158e33705154e00fae20c29ebb7177877beae655
This commit is contained in:
@@ -29,7 +29,6 @@ import android.app.ActivityThread;
|
||||
import android.app.VoiceInteractor.PickOptionRequest;
|
||||
import android.app.VoiceInteractor.PickOptionRequest.Option;
|
||||
import android.app.VoiceInteractor.Prompt;
|
||||
import android.app.role.RoleManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -111,7 +110,6 @@ public class ResolverActivity extends Activity {
|
||||
protected AbsListView mAdapterView;
|
||||
private Button mAlwaysButton;
|
||||
private Button mOnceButton;
|
||||
private Button mSettingsButton;
|
||||
protected View mProfileView;
|
||||
private int mIconDpi;
|
||||
private int mLastSelected = AbsListView.INVALID_POSITION;
|
||||
@@ -146,6 +144,10 @@ public class ResolverActivity extends Activity {
|
||||
/** See {@link #setRetainInOnStop}. */
|
||||
private boolean mRetainInOnStop;
|
||||
|
||||
private static final String EXTRA_SHOW_FRAGMENT_ARGS = ":settings:show_fragment_args";
|
||||
private static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
|
||||
private static final String OPEN_LINKS_COMPONENT_KEY = "app_link_state";
|
||||
|
||||
private final PackageMonitor mPackageMonitor = createPackageMonitor();
|
||||
|
||||
/**
|
||||
@@ -196,9 +198,13 @@ public class ResolverActivity extends Activity {
|
||||
|
||||
// titles for layout that deals with http(s) intents
|
||||
public static final int BROWSABLE_TITLE_RES =
|
||||
com.android.internal.R.string.whichGiveAccessToApplication;
|
||||
public static final int BROWSABLE_NAMED_TITLE_RES =
|
||||
com.android.internal.R.string.whichGiveAccessToApplicationNamed;
|
||||
com.android.internal.R.string.whichOpenLinksWith;
|
||||
public static final int BROWSABLE_HOST_TITLE_RES =
|
||||
com.android.internal.R.string.whichOpenHostLinksWith;
|
||||
public static final int BROWSABLE_HOST_APP_TITLE_RES =
|
||||
com.android.internal.R.string.whichOpenHostLinksWithApp;
|
||||
public static final int BROWSABLE_APP_TITLE_RES =
|
||||
com.android.internal.R.string.whichOpenLinksWithApp;
|
||||
|
||||
public final String action;
|
||||
public final int titleRes;
|
||||
@@ -322,9 +328,7 @@ public class ResolverActivity extends Activity {
|
||||
? false
|
||||
: isHttpSchemeAndViewAction(getTargetIntent());
|
||||
|
||||
// We don't want to support Always Use if browsable layout is being used,
|
||||
// as to mitigate Intent Capturing vulnerability
|
||||
mSupportsAlwaysUseOption = supportsAlwaysUseOption && !mUseLayoutForBrowsables;
|
||||
mSupportsAlwaysUseOption = supportsAlwaysUseOption;
|
||||
|
||||
if (configureContentView(mIntents, initialIntents, rList)) {
|
||||
return;
|
||||
@@ -554,10 +558,21 @@ public class ResolverActivity extends Activity {
|
||||
} else if (isHttpSchemeAndViewAction(intent)) {
|
||||
// If the Intent's scheme is http(s) then we need to warn the user that
|
||||
// they're giving access for the activity to open URLs from this specific host
|
||||
return named
|
||||
? getString(ActionTitle.BROWSABLE_NAMED_TITLE_RES, intent.getData().getHost(),
|
||||
mAdapter.getFilteredItem().getDisplayLabel())
|
||||
: getString(ActionTitle.BROWSABLE_TITLE_RES, intent.getData().getHost());
|
||||
String dialogTitle = null;
|
||||
if (named && !mUseLayoutForBrowsables) {
|
||||
dialogTitle = getString(ActionTitle.BROWSABLE_APP_TITLE_RES,
|
||||
mAdapter.getFilteredItem().getDisplayLabel());
|
||||
} else if (named && mUseLayoutForBrowsables) {
|
||||
dialogTitle = getString(ActionTitle.BROWSABLE_HOST_APP_TITLE_RES,
|
||||
intent.getData().getHost(),
|
||||
mAdapter.getFilteredItem().getDisplayLabel());
|
||||
} else if (mAdapter.areAllTargetsBrowsers()) {
|
||||
dialogTitle = getString(ActionTitle.BROWSABLE_TITLE_RES);
|
||||
} else {
|
||||
dialogTitle = getString(ActionTitle.BROWSABLE_HOST_TITLE_RES,
|
||||
intent.getData().getHost());
|
||||
}
|
||||
return dialogTitle;
|
||||
} else {
|
||||
return named
|
||||
? getString(title.namedTitleRes, mAdapter.getFilteredItem().getDisplayLabel())
|
||||
@@ -856,6 +871,13 @@ public class ResolverActivity extends Activity {
|
||||
} else {
|
||||
enabled = true;
|
||||
}
|
||||
if (mUseLayoutForBrowsables && !ri.handleAllWebDataURI) {
|
||||
mAlwaysButton.setText(getResources()
|
||||
.getString(R.string.activity_resolver_set_always));
|
||||
} else {
|
||||
mAlwaysButton.setText(getResources()
|
||||
.getString(R.string.activity_resolver_use_always));
|
||||
}
|
||||
}
|
||||
mAlwaysButton.setEnabled(enabled);
|
||||
}
|
||||
@@ -866,26 +888,29 @@ public class ResolverActivity extends Activity {
|
||||
? mAdapter.getFilteredPosition()
|
||||
: mAdapterView.getCheckedItemPosition();
|
||||
boolean hasIndexBeenFiltered = !mAdapter.hasFilteredItem();
|
||||
if (id == R.id.button_app_settings) {
|
||||
showSettingsForSelected(which, hasIndexBeenFiltered);
|
||||
ResolveInfo ri = mAdapter.resolveInfoForPosition(which, hasIndexBeenFiltered);
|
||||
if (!ri.handleAllWebDataURI && id == R.id.button_always) {
|
||||
showSettingsForSelected(ri);
|
||||
} else {
|
||||
startSelected(which, id == R.id.button_always, hasIndexBeenFiltered);
|
||||
}
|
||||
}
|
||||
|
||||
private void showSettingsForSelected(int which, boolean hasIndexBeenFiltered) {
|
||||
ResolveInfo ri = mAdapter.resolveInfoForPosition(which, hasIndexBeenFiltered);
|
||||
private void showSettingsForSelected(ResolveInfo ri) {
|
||||
Intent intent = new Intent();
|
||||
// For browsers, we open the Default Browser page
|
||||
|
||||
final String packageName = ri.activityInfo.packageName;
|
||||
Bundle showFragmentArgs = new Bundle();
|
||||
showFragmentArgs.putString(EXTRA_FRAGMENT_ARG_KEY, OPEN_LINKS_COMPONENT_KEY);
|
||||
showFragmentArgs.putString("package", packageName);
|
||||
|
||||
// For regular apps, we open the Open by Default page
|
||||
if (ri.handleAllWebDataURI) {
|
||||
intent.setAction(Intent.ACTION_MANAGE_DEFAULT_APP)
|
||||
.putExtra(Intent.EXTRA_ROLE_NAME, RoleManager.ROLE_BROWSER);
|
||||
} else {
|
||||
intent.setAction(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS)
|
||||
.setData(Uri.fromParts("package", ri.activityInfo.packageName, null))
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
|
||||
}
|
||||
intent.setAction(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS)
|
||||
.setData(Uri.fromParts("package", packageName, null))
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
|
||||
.putExtra(EXTRA_FRAGMENT_ARG_KEY, OPEN_LINKS_COMPONENT_KEY)
|
||||
.putExtra(EXTRA_SHOW_FRAGMENT_ARGS, showFragmentArgs);
|
||||
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@@ -1332,41 +1357,15 @@ public class ResolverActivity extends Activity {
|
||||
R.dimen.resolver_button_bar_spacing) + inset);
|
||||
|
||||
mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once);
|
||||
mSettingsButton = (Button) buttonLayout.findViewById(R.id.button_app_settings);
|
||||
mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always);
|
||||
|
||||
if (mUseLayoutForBrowsables) {
|
||||
resetSettingsOrOnceButtonBar();
|
||||
} else {
|
||||
resetAlwaysOrOnceButtonBar();
|
||||
}
|
||||
resetAlwaysOrOnceButtonBar();
|
||||
} else {
|
||||
Log.e(TAG, "Layout unexpectedly does not have a button bar");
|
||||
}
|
||||
}
|
||||
|
||||
private void resetSettingsOrOnceButtonBar() {
|
||||
//unsetting always button
|
||||
mAlwaysButton.setVisibility(View.GONE);
|
||||
|
||||
// When the items load in, if an item was already selected,
|
||||
// enable the buttons
|
||||
if (mAdapterView != null
|
||||
&& mAdapterView.getCheckedItemPosition() != ListView.INVALID_POSITION) {
|
||||
mSettingsButton.setEnabled(true);
|
||||
mOnceButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void resetAlwaysOrOnceButtonBar() {
|
||||
// This check needs to be made because layout with default
|
||||
// doesn't have a settings button
|
||||
if (mSettingsButton != null) {
|
||||
//unsetting always button
|
||||
mSettingsButton.setVisibility(View.GONE);
|
||||
mSettingsButton = null;
|
||||
}
|
||||
|
||||
if (useLayoutWithDefault()
|
||||
&& mAdapter.getFilteredPosition() != ListView.INVALID_POSITION) {
|
||||
setAlwaysButtonEnabled(true, mAdapter.getFilteredPosition(), false);
|
||||
@@ -1626,6 +1625,7 @@ public class ResolverActivity extends Activity {
|
||||
private DisplayResolveInfo mOtherProfile;
|
||||
private ResolverListController mResolverListController;
|
||||
private int mPlaceholderCount;
|
||||
private boolean mAllTargetsAreBrowsers = false;
|
||||
|
||||
protected final LayoutInflater mInflater;
|
||||
|
||||
@@ -1700,6 +1700,14 @@ public class ResolverActivity extends Activity {
|
||||
mResolverListController.updateChooserCounts(packageName, userId, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if all items in the display list are defined as browsers by
|
||||
* ResolveInfo.handleAllWebDataURI
|
||||
*/
|
||||
public boolean areAllTargetsBrowsers() {
|
||||
return mAllTargetsAreBrowsers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild the list of resolvers. In some cases some parts will need some asynchronous work
|
||||
* to complete.
|
||||
@@ -1712,6 +1720,7 @@ public class ResolverActivity extends Activity {
|
||||
mOtherProfile = null;
|
||||
mLastChosen = null;
|
||||
mLastChosenPosition = -1;
|
||||
mAllTargetsAreBrowsers = false;
|
||||
mDisplayList.clear();
|
||||
if (mBaseResolveList != null) {
|
||||
currentResolveList = mUnfilteredResolveList = new ArrayList<>();
|
||||
@@ -1812,6 +1821,8 @@ public class ResolverActivity extends Activity {
|
||||
private void processSortedList(List<ResolvedComponentInfo> sortedComponents) {
|
||||
int N;
|
||||
if (sortedComponents != null && (N = sortedComponents.size()) != 0) {
|
||||
mAllTargetsAreBrowsers = mUseLayoutForBrowsables;
|
||||
|
||||
// First put the initial items at the top.
|
||||
if (mInitialIntents != null) {
|
||||
for (int i = 0; i < mInitialIntents.length; i++) {
|
||||
@@ -1841,6 +1852,8 @@ public class ResolverActivity extends Activity {
|
||||
ri.noResourceId = true;
|
||||
ri.icon = 0;
|
||||
}
|
||||
mAllTargetsAreBrowsers &= ri.handleAllWebDataURI;
|
||||
|
||||
addResolveInfo(new DisplayResolveInfo(ii, ri,
|
||||
ri.loadLabel(getPackageManager()), null, ii));
|
||||
}
|
||||
@@ -1850,6 +1863,8 @@ public class ResolverActivity extends Activity {
|
||||
for (ResolvedComponentInfo rci : sortedComponents) {
|
||||
final ResolveInfo ri = rci.getResolveInfoAt(0);
|
||||
if (ri != null) {
|
||||
mAllTargetsAreBrowsers &= ri.handleAllWebDataURI;
|
||||
|
||||
ResolveInfoPresentationGetter pg = makePresentationGetter(ri);
|
||||
addResolveInfoWithAlternates(rci, pg.getSubLabel(), pg.getLabel());
|
||||
}
|
||||
@@ -2152,14 +2167,8 @@ public class ResolverActivity extends Activity {
|
||||
final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION;
|
||||
if (!useLayoutWithDefault()
|
||||
&& (!hasValidSelection || mLastSelected != checkedPos)
|
||||
&& (mAlwaysButton != null || mSettingsButton != null)) {
|
||||
if (mSettingsButton != null) {
|
||||
// this implies that the layout for browsables is being used
|
||||
mSettingsButton.setEnabled(true);
|
||||
} else {
|
||||
// this implies that mAlwaysButton != null
|
||||
setAlwaysButtonEnabled(hasValidSelection, checkedPos, true);
|
||||
}
|
||||
&& mAlwaysButton != null) {
|
||||
setAlwaysButtonEnabled(hasValidSelection, checkedPos, true);
|
||||
mOnceButton.setEnabled(hasValidSelection);
|
||||
if (hasValidSelection) {
|
||||
mAdapterView.smoothScrollToPosition(checkedPos);
|
||||
|
||||
@@ -129,18 +129,6 @@
|
||||
android:enabled="false"
|
||||
android:text="@string/activity_resolver_use_always"
|
||||
android:onClick="onButtonClick" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_app_settings"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:maxLines="2"
|
||||
android:minHeight="@dimen/alert_dialog_button_bar_height"
|
||||
style="?attr/buttonBarPositiveButtonStyle"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
android:text="@string/activity_resolver_app_settings"
|
||||
android:onClick="onButtonClick" />
|
||||
</LinearLayout>
|
||||
|
||||
</com.android.internal.widget.ResolverDrawerLayout>
|
||||
|
||||
@@ -3074,12 +3074,20 @@
|
||||
<string name="whichViewApplicationNamed">Open with %1$s</string>
|
||||
<!-- Label for a link to a intent resolver dialog to view something -->
|
||||
<string name="whichViewApplicationLabel">Open</string>
|
||||
<!-- Title of intent resolver dialog when selecting a viewer application that opens URI
|
||||
<!-- Title of intent resolver dialog when selecting a browser/application that opens specific URIs
|
||||
[CHAR LIMIT=128]. -->
|
||||
<string name="whichGiveAccessToApplication">Give access to open <xliff:g id="host" example="mail.google.com">%1$s</xliff:g> links with</string>
|
||||
<string name="whichOpenHostLinksWith">Open <xliff:g id="host" example="mail.google.com">%1$s</xliff:g> links with</string>
|
||||
<!-- Title of intent resolver dialog when selecting a browser that opens URI
|
||||
[CHAR LIMIT=128]. -->
|
||||
<string name="whichOpenLinksWith">Open links with</string>
|
||||
<!-- Title of intent resolver dialog when defaulting to a specific browser that opens URI
|
||||
[CHAR LIMIT=128]. -->
|
||||
<string name="whichOpenLinksWithApp">Open links with <xliff:g id="application" example="Chrome">%1$s</xliff:g></string>
|
||||
<!-- Title of intent resolver dialog when defaulting to a specific browser that opens URI
|
||||
[CHAR LIMIT=128]. -->
|
||||
<string name="whichOpenHostLinksWithApp">Open <xliff:g id="host" example="mail.google.com">%1$s</xliff:g> links with <xliff:g id="application" example="Chrome">%2$s</xliff:g></string>
|
||||
<!-- Title of intent resolver dialog when selecting a viewer application that opens URI
|
||||
and a previously used application is known [CHAR LIMIT=128]. -->
|
||||
<string name="whichGiveAccessToApplicationNamed">Give access to open <xliff:g id="host" example="mail.google.com">%1$s</xliff:g> links with <xliff:g id="application" example="Gmail">%2$s</xliff:g></string>
|
||||
<!-- Label for a link to an intent resolver dialog to open URI [CHAR LIMIT=18] -->
|
||||
<string name="whichGiveAccessToApplicationLabel">Give access</string>
|
||||
<!-- Title of intent resolver dialog when selecting an editor application to run. -->
|
||||
@@ -4211,6 +4219,10 @@
|
||||
as the default in the activity resolver. [CHAR LIMIT=25] -->
|
||||
<string name="activity_resolver_use_always">Always</string>
|
||||
|
||||
<!-- Title for a button to choose the currently selected activity
|
||||
as the default in the activity resolver. [CHAR LIMIT=50] -->
|
||||
<string name="activity_resolver_set_always">Set to always open</string>
|
||||
|
||||
<!-- Title for a button to choose the currently selected activity
|
||||
from the activity resolver to use just this once. [CHAR LIMIT=25] -->
|
||||
<string name="activity_resolver_use_once">Just once</string>
|
||||
|
||||
@@ -2243,7 +2243,6 @@
|
||||
<java-symbol type="id" name="resolver_list" />
|
||||
<java-symbol type="id" name="button_once" />
|
||||
<java-symbol type="id" name="button_always" />
|
||||
<java-symbol type="id" name="button_app_settings" />
|
||||
<java-symbol type="integer" name="config_globalActionsKeyTimeout" />
|
||||
<java-symbol type="integer" name="config_screenshotChordKeyTimeout" />
|
||||
<java-symbol type="integer" name="config_maxResolverActivityColumns" />
|
||||
@@ -2628,14 +2627,17 @@
|
||||
<java-symbol type="bool" name="config_use_voip_mode_for_ims" />
|
||||
<java-symbol type="attr" name="touchscreenBlocksFocus" />
|
||||
<java-symbol type="layout" name="resolver_list_with_default" />
|
||||
<java-symbol type="string" name="activity_resolver_app_settings" />
|
||||
<java-symbol type="string" name="activity_resolver_set_always" />
|
||||
<java-symbol type="string" name="activity_resolver_use_always" />
|
||||
<java-symbol type="string" name="whichApplicationNamed" />
|
||||
<java-symbol type="string" name="whichApplicationLabel" />
|
||||
<java-symbol type="string" name="whichViewApplication" />
|
||||
<java-symbol type="string" name="whichViewApplicationNamed" />
|
||||
<java-symbol type="string" name="whichViewApplicationLabel" />
|
||||
<java-symbol type="string" name="whichGiveAccessToApplication" />
|
||||
<java-symbol type="string" name="whichGiveAccessToApplicationNamed" />
|
||||
<java-symbol type="string" name="whichOpenHostLinksWith" />
|
||||
<java-symbol type="string" name="whichOpenHostLinksWithApp" />
|
||||
<java-symbol type="string" name="whichOpenLinksWith" />
|
||||
<java-symbol type="string" name="whichOpenLinksWithApp" />
|
||||
<java-symbol type="string" name="whichGiveAccessToApplicationLabel" />
|
||||
<java-symbol type="string" name="whichEditApplication" />
|
||||
<java-symbol type="string" name="whichEditApplicationNamed" />
|
||||
|
||||
Reference in New Issue
Block a user