Merge "Update WebView implementation Dev Setting - new looks + descriptions."
This commit is contained in:
committed by
Android (Google) Code Review
commit
1c750fb7c0
@@ -2005,6 +2005,9 @@
|
|||||||
<activity android:name=".AppPicker" android:label="@string/select_application"
|
<activity android:name=".AppPicker" android:label="@string/select_application"
|
||||||
android:theme="@android:style/Theme.DeviceDefault.Light.Dialog" />
|
android:theme="@android:style/Theme.DeviceDefault.Light.Dialog" />
|
||||||
|
|
||||||
|
<activity android:name=".webview.WebViewAppPicker" android:label="@string/select_webview_provider_dialog_title"
|
||||||
|
android:theme="@android:style/Theme.DeviceDefault.Light.Dialog" />
|
||||||
|
|
||||||
<!-- Keep compatibility with old shortcuts. -->
|
<!-- Keep compatibility with old shortcuts. -->
|
||||||
<activity-alias android:name="UsbSettings"
|
<activity-alias android:name="UsbSettings"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
@@ -2940,7 +2943,9 @@
|
|||||||
android:value="true" />
|
android:value="true" />
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:name=".WebViewImplementation"
|
<!-- Keep compatibility with old WebView-picker implementation -->
|
||||||
|
<activity-alias android:name=".WebViewImplementation"
|
||||||
|
android:targetActivity=".webview.WebViewAppPicker"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:excludeFromRecents="true"
|
android:excludeFromRecents="true"
|
||||||
android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert">
|
android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert">
|
||||||
@@ -2950,7 +2955,7 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
|
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
|
||||||
android:value="true" />
|
android:value="true" />
|
||||||
</activity>
|
</activity-alias>
|
||||||
|
|
||||||
<!-- activity for gesture settings -->
|
<!-- activity for gesture settings -->
|
||||||
<activity android:name="Settings$GestureSettingsActivity"
|
<activity android:name="Settings$GestureSettingsActivity"
|
||||||
|
@@ -8098,4 +8098,9 @@
|
|||||||
<!-- On status for the automatic storage manager. [CHAR_LIMIT=10] -->
|
<!-- On status for the automatic storage manager. [CHAR_LIMIT=10] -->
|
||||||
<string name="storage_manager_indicator_on">On</string>
|
<string name="storage_manager_indicator_on">On</string>
|
||||||
|
|
||||||
|
<!-- UI webview setting: WebView uninstalled-for-user explanatory text [CHAR LIMIT=30] -->
|
||||||
|
<string name="webview_uninstalled_for_user">Uninstalled for user <xliff:g id="user" example="John Doe">%s</xliff:g>\n</string>
|
||||||
|
<!-- UI webview setting: WebView disabled-for-user explanatory text [CHAR LIMIT=30] -->
|
||||||
|
<string name="webview_disabled_for_user">Disabled for user <xliff:g id="user" example="John Doe">%s</xliff:g>\n</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -74,11 +74,9 @@
|
|||||||
android:title="@string/picture_color_mode"
|
android:title="@string/picture_color_mode"
|
||||||
android:summary="@string/picture_color_mode_desc" />
|
android:summary="@string/picture_color_mode_desc" />
|
||||||
|
|
||||||
<ListPreference
|
<Preference android:key="select_webview_provider"
|
||||||
android:key="select_webview_provider"
|
|
||||||
android:title="@string/select_webview_provider_title"
|
android:title="@string/select_webview_provider_title"
|
||||||
android:dialogTitle="@string/select_webview_provider_dialog_title"
|
android:dialogTitle="@string/select_webview_provider_dialog_title" />
|
||||||
android:summary="%s" />
|
|
||||||
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="enable_webview_multiprocess"
|
android:key="enable_webview_multiprocess"
|
||||||
|
@@ -78,7 +78,7 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.accessibility.AccessibilityManager;
|
import android.view.accessibility.AccessibilityManager;
|
||||||
import android.webkit.IWebViewUpdateService;
|
import android.webkit.IWebViewUpdateService;
|
||||||
import android.webkit.WebViewProviderInfo;
|
import android.webkit.WebViewFactory;
|
||||||
import android.widget.Switch;
|
import android.widget.Switch;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@@ -92,6 +92,7 @@ import com.android.settings.fuelgauge.InactiveApps;
|
|||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settings.search.BaseSearchIndexProvider;
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
import com.android.settings.search.Indexable;
|
import com.android.settings.search.Indexable;
|
||||||
|
import com.android.settings.webview.WebViewAppPreferenceController;
|
||||||
import com.android.settings.widget.SwitchBar;
|
import com.android.settings.widget.SwitchBar;
|
||||||
import com.android.settingslib.RestrictedLockUtils;
|
import com.android.settingslib.RestrictedLockUtils;
|
||||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||||
@@ -126,7 +127,6 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
private static final String ENABLE_TERMINAL = "enable_terminal";
|
private static final String ENABLE_TERMINAL = "enable_terminal";
|
||||||
private static final String KEEP_SCREEN_ON = "keep_screen_on";
|
private static final String KEEP_SCREEN_ON = "keep_screen_on";
|
||||||
private static final String BT_HCI_SNOOP_LOG = "bt_hci_snoop_log";
|
private static final String BT_HCI_SNOOP_LOG = "bt_hci_snoop_log";
|
||||||
private static final String WEBVIEW_PROVIDER_KEY = "select_webview_provider";
|
|
||||||
private static final String WEBVIEW_MULTIPROCESS_KEY = "enable_webview_multiprocess";
|
private static final String WEBVIEW_MULTIPROCESS_KEY = "enable_webview_multiprocess";
|
||||||
private static final String ENABLE_OEM_UNLOCK = "oem_unlock_enable";
|
private static final String ENABLE_OEM_UNLOCK = "oem_unlock_enable";
|
||||||
private static final String HDCP_CHECKING_KEY = "hdcp_checking";
|
private static final String HDCP_CHECKING_KEY = "hdcp_checking";
|
||||||
@@ -230,6 +230,7 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
|
|
||||||
private static final int RESULT_DEBUG_APP = 1000;
|
private static final int RESULT_DEBUG_APP = 1000;
|
||||||
private static final int RESULT_MOCK_LOCATION_APP = 1001;
|
private static final int RESULT_MOCK_LOCATION_APP = 1001;
|
||||||
|
private static final int RESULT_WEBVIEW_APP = 1002;
|
||||||
|
|
||||||
private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
|
private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
|
||||||
private static final String FLASH_LOCKED_PROP = "ro.boot.flash.locked";
|
private static final String FLASH_LOCKED_PROP = "ro.boot.flash.locked";
|
||||||
@@ -310,8 +311,8 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
private ListPreference mAnimatorDurationScale;
|
private ListPreference mAnimatorDurationScale;
|
||||||
private ListPreference mOverlayDisplayDevices;
|
private ListPreference mOverlayDisplayDevices;
|
||||||
|
|
||||||
|
private WebViewAppPreferenceController mWebViewAppPrefController;
|
||||||
private SwitchPreference mWebViewMultiprocess;
|
private SwitchPreference mWebViewMultiprocess;
|
||||||
private ListPreference mWebViewProvider;
|
|
||||||
|
|
||||||
private ListPreference mSimulateColorSpace;
|
private ListPreference mSimulateColorSpace;
|
||||||
|
|
||||||
@@ -371,8 +372,7 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
|
mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
|
||||||
mBackupManager = IBackupManager.Stub.asInterface(
|
mBackupManager = IBackupManager.Stub.asInterface(
|
||||||
ServiceManager.getService(Context.BACKUP_SERVICE));
|
ServiceManager.getService(Context.BACKUP_SERVICE));
|
||||||
mWebViewUpdateService =
|
mWebViewUpdateService = WebViewFactory.getUpdateService();
|
||||||
IWebViewUpdateService.Stub.asInterface(ServiceManager.getService("webviewupdate"));
|
|
||||||
mOemUnlockManager = (PersistentDataBlockManager) getActivity()
|
mOemUnlockManager = (PersistentDataBlockManager) getActivity()
|
||||||
.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
|
.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
|
||||||
mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
|
mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
@@ -384,6 +384,7 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
|
|
||||||
mBugReportController = new BugReportPreferenceController(getActivity());
|
mBugReportController = new BugReportPreferenceController(getActivity());
|
||||||
mBugReportInPowerController = new BugReportInPowerPreferenceController(getActivity());
|
mBugReportInPowerController = new BugReportInPowerPreferenceController(getActivity());
|
||||||
|
mWebViewAppPrefController = new WebViewAppPreferenceController(getActivity());
|
||||||
|
|
||||||
setIfOnlyAvailableForAdmins(true);
|
setIfOnlyAvailableForAdmins(true);
|
||||||
if (isUiRestricted() || !Utils.isDeviceProvisioned(getActivity())) {
|
if (isUiRestricted() || !Utils.isDeviceProvisioned(getActivity())) {
|
||||||
@@ -414,6 +415,7 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
|
|
||||||
mBugReportController.displayPreference(getPreferenceScreen());
|
mBugReportController.displayPreference(getPreferenceScreen());
|
||||||
mBugReportInPowerController.displayPreference(getPreferenceScreen());
|
mBugReportInPowerController.displayPreference(getPreferenceScreen());
|
||||||
|
mWebViewAppPrefController.displayPreference(getPreferenceScreen());
|
||||||
|
|
||||||
mKeepScreenOn = (RestrictedSwitchPreference) findAndInitSwitchPref(KEEP_SCREEN_ON);
|
mKeepScreenOn = (RestrictedSwitchPreference) findAndInitSwitchPref(KEEP_SCREEN_ON);
|
||||||
mBtHciSnoopLog = findAndInitSwitchPref(BT_HCI_SNOOP_LOG);
|
mBtHciSnoopLog = findAndInitSwitchPref(BT_HCI_SNOOP_LOG);
|
||||||
@@ -483,7 +485,6 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
mLogpersist = null;
|
mLogpersist = null;
|
||||||
}
|
}
|
||||||
mUsbConfiguration = addListPreference(USB_CONFIGURATION_KEY);
|
mUsbConfiguration = addListPreference(USB_CONFIGURATION_KEY);
|
||||||
mWebViewProvider = addListPreference(WEBVIEW_PROVIDER_KEY);
|
|
||||||
mWebViewMultiprocess = findAndInitSwitchPref(WEBVIEW_MULTIPROCESS_KEY);
|
mWebViewMultiprocess = findAndInitSwitchPref(WEBVIEW_MULTIPROCESS_KEY);
|
||||||
mBluetoothDisableAbsVolume = findAndInitSwitchPref(BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_KEY);
|
mBluetoothDisableAbsVolume = findAndInitSwitchPref(BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_KEY);
|
||||||
|
|
||||||
@@ -544,7 +545,6 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
removePreference(KEY_COLOR_MODE);
|
removePreference(KEY_COLOR_MODE);
|
||||||
mColorModePreference = null;
|
mColorModePreference = null;
|
||||||
}
|
}
|
||||||
updateWebViewProviderOptions();
|
|
||||||
|
|
||||||
mColorTemperaturePreference = (SwitchPreference) findPreference(COLOR_TEMPERATURE_KEY);
|
mColorTemperaturePreference = (SwitchPreference) findPreference(COLOR_TEMPERATURE_KEY);
|
||||||
if (getResources().getBoolean(R.bool.config_enableColorTemperature)) {
|
if (getResources().getBoolean(R.bool.config_enableColorTemperature)) {
|
||||||
@@ -629,6 +629,7 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
pref.setEnabled(enabled && !mDisabledPrefs.contains(pref));
|
pref.setEnabled(enabled && !mDisabledPrefs.contains(pref));
|
||||||
}
|
}
|
||||||
mBugReportInPowerController.enablePreference(enabled);
|
mBugReportInPowerController.enablePreference(enabled);
|
||||||
|
mWebViewAppPrefController.enablePreference(enabled);
|
||||||
updateAllOptions();
|
updateAllOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -793,8 +794,8 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
updateSimulateColorSpace();
|
updateSimulateColorSpace();
|
||||||
updateUSBAudioOptions();
|
updateUSBAudioOptions();
|
||||||
updateForceResizableOptions();
|
updateForceResizableOptions();
|
||||||
|
mWebViewAppPrefController.updateState(null);
|
||||||
updateWebViewMultiprocessOptions();
|
updateWebViewMultiprocessOptions();
|
||||||
updateWebViewProviderOptions();
|
|
||||||
updateOemUnlockOptions();
|
updateOemUnlockOptions();
|
||||||
if (mColorTemperaturePreference != null) {
|
if (mColorTemperaturePreference != null) {
|
||||||
updateColorTemperature();
|
updateColorTemperature();
|
||||||
@@ -831,39 +832,6 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
pokeSystemProperties();
|
pokeSystemProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateWebViewProviderOptions() {
|
|
||||||
try {
|
|
||||||
WebViewProviderInfo[] providers = mWebViewUpdateService.getValidWebViewPackages();
|
|
||||||
if (providers == null) {
|
|
||||||
Log.e(TAG, "No WebView providers available");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ArrayList<String> options = new ArrayList<String>();
|
|
||||||
ArrayList<String> values = new ArrayList<String>();
|
|
||||||
for (int n = 0; n < providers.length; n++) {
|
|
||||||
if (Utils.isPackageEnabled(getActivity(), providers[n].packageName)) {
|
|
||||||
options.add(providers[n].description);
|
|
||||||
values.add(providers[n].packageName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mWebViewProvider.setEntries(options.toArray(new String[options.size()]));
|
|
||||||
mWebViewProvider.setEntryValues(values.toArray(new String[values.size()]));
|
|
||||||
|
|
||||||
String value = mWebViewUpdateService.getCurrentWebViewPackageName();
|
|
||||||
if (value == null) {
|
|
||||||
value = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < values.size(); i++) {
|
|
||||||
if (value.contentEquals(values.get(i))) {
|
|
||||||
mWebViewProvider.setValueIndex(i);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateWebViewMultiprocessOptions() {
|
private void updateWebViewMultiprocessOptions() {
|
||||||
try {
|
try {
|
||||||
updateSwitchPreference(mWebViewMultiprocess,
|
updateSwitchPreference(mWebViewMultiprocess,
|
||||||
@@ -918,17 +886,6 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
mBtHciSnoopLog.isChecked() ? 1 : 0);
|
mBtHciSnoopLog.isChecked() ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean writeWebViewProviderOptions(Object newValue) {
|
|
||||||
try {
|
|
||||||
String updatedProvider = mWebViewUpdateService.changeProviderAndSetting(
|
|
||||||
newValue == null ? "" : newValue.toString());
|
|
||||||
updateWebViewProviderOptions();
|
|
||||||
return newValue != null && newValue.equals(updatedProvider);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeDebuggerOptions() {
|
private void writeDebuggerOptions() {
|
||||||
try {
|
try {
|
||||||
ActivityManager.getService().setDebugApp(
|
ActivityManager.getService().setDebugApp(
|
||||||
@@ -2327,6 +2284,8 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
writeMockLocation();
|
writeMockLocation();
|
||||||
updateMockLocation();
|
updateMockLocation();
|
||||||
}
|
}
|
||||||
|
} else if (requestCode == RESULT_WEBVIEW_APP) {
|
||||||
|
mWebViewAppPrefController.onActivityResult(resultCode, data);
|
||||||
} else if (requestCode == REQUEST_CODE_ENABLE_OEM_UNLOCK) {
|
} else if (requestCode == REQUEST_CODE_ENABLE_OEM_UNLOCK) {
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
if (mEnableOemUnlock.isChecked()) {
|
if (mEnableOemUnlock.isChecked()) {
|
||||||
@@ -2349,6 +2308,10 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
if (mBugReportInPowerController.handlePreferenceTreeClick(preference)) {
|
if (mBugReportInPowerController.handlePreferenceTreeClick(preference)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (mWebViewAppPrefController.handlePreferenceTreeClick(preference)) {
|
||||||
|
startActivityForResult(
|
||||||
|
mWebViewAppPrefController.getActivityIntent(), RESULT_WEBVIEW_APP);
|
||||||
|
}
|
||||||
|
|
||||||
if (preference == mEnableAdb) {
|
if (preference == mEnableAdb) {
|
||||||
if (mEnableAdb.isChecked()) {
|
if (mEnableAdb.isChecked()) {
|
||||||
@@ -2502,21 +2465,6 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
|
|||||||
updateHdcpValues();
|
updateHdcpValues();
|
||||||
pokeSystemProperties();
|
pokeSystemProperties();
|
||||||
return true;
|
return true;
|
||||||
} else if (preference == mWebViewProvider) {
|
|
||||||
if (newValue == null) {
|
|
||||||
Log.e(TAG, "Tried to set a null WebView provider");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (writeWebViewProviderOptions(newValue)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
// The user chose a package that became invalid since the list was last updated,
|
|
||||||
// show a Toast to explain the situation.
|
|
||||||
Toast toast = Toast.makeText(getActivity(),
|
|
||||||
R.string.select_webview_provider_toast_text, Toast.LENGTH_SHORT);
|
|
||||||
toast.show();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} else if ((preference == mBluetoothSelectA2dpCodec) ||
|
} else if ((preference == mBluetoothSelectA2dpCodec) ||
|
||||||
(preference == mBluetoothSelectA2dpSampleRate) ||
|
(preference == mBluetoothSelectA2dpSampleRate) ||
|
||||||
(preference == mBluetoothSelectA2dpBitsPerSample) ||
|
(preference == mBluetoothSelectA2dpBitsPerSample) ||
|
||||||
|
@@ -44,6 +44,8 @@ public class SettingsInitialize extends BroadcastReceiver {
|
|||||||
private static final String TAG = "Settings";
|
private static final String TAG = "Settings";
|
||||||
private static final String PRIMARY_PROFILE_SETTING =
|
private static final String PRIMARY_PROFILE_SETTING =
|
||||||
"com.android.settings.PRIMARY_PROFILE_CONTROLLED";
|
"com.android.settings.PRIMARY_PROFILE_CONTROLLED";
|
||||||
|
private static final String SETTINGS_PACKAGE = "com.android.settings";
|
||||||
|
private static final String WEBVIEW_IMPLEMENTATION_ACTIVITY = ".WebViewImplementation";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent broadcast) {
|
public void onReceive(Context context, Intent broadcast) {
|
||||||
@@ -100,7 +102,7 @@ public class SettingsInitialize extends BroadcastReceiver {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ComponentName settingsComponentName =
|
ComponentName settingsComponentName =
|
||||||
new ComponentName(context, WebViewImplementation.class);
|
new ComponentName(SETTINGS_PACKAGE, SETTINGS_PACKAGE + WEBVIEW_IMPLEMENTATION_ACTIVITY);
|
||||||
pm.setComponentEnabledSetting(settingsComponentName,
|
pm.setComponentEnabledSetting(settingsComponentName,
|
||||||
userInfo.isAdmin() ?
|
userInfo.isAdmin() ?
|
||||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
|
PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
|
||||||
|
@@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 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.settings;
|
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.DialogInterface.OnCancelListener;
|
|
||||||
import android.content.DialogInterface.OnClickListener;
|
|
||||||
import android.content.DialogInterface.OnDismissListener;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.os.ServiceManager;
|
|
||||||
import android.os.UserManager;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.webkit.IWebViewUpdateService;
|
|
||||||
import android.webkit.WebViewProviderInfo;
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|
||||||
import com.android.settings.core.InstrumentedActivity;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class WebViewImplementation extends InstrumentedActivity implements
|
|
||||||
OnCancelListener, OnDismissListener {
|
|
||||||
|
|
||||||
private static final String TAG = "WebViewImplementation";
|
|
||||||
|
|
||||||
private IWebViewUpdateService mWebViewUpdateService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
if (!UserManager.get(this).isAdminUser()) {
|
|
||||||
finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mWebViewUpdateService =
|
|
||||||
IWebViewUpdateService.Stub.asInterface(ServiceManager.getService("webviewupdate"));
|
|
||||||
try {
|
|
||||||
WebViewProviderInfo[] providers = mWebViewUpdateService.getValidWebViewPackages();
|
|
||||||
if (providers == null) {
|
|
||||||
Log.e(TAG, "No WebView providers available");
|
|
||||||
finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String currentValue = mWebViewUpdateService.getCurrentWebViewPackageName();
|
|
||||||
if (currentValue == null) {
|
|
||||||
currentValue = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
int currentIndex = -1;
|
|
||||||
ArrayList<String> options = new ArrayList<>();
|
|
||||||
final ArrayList<String> values = new ArrayList<>();
|
|
||||||
for (WebViewProviderInfo provider : providers) {
|
|
||||||
if (Utils.isPackageEnabled(this, provider.packageName)) {
|
|
||||||
options.add(provider.description);
|
|
||||||
values.add(provider.packageName);
|
|
||||||
if (currentValue.contentEquals(provider.packageName)) {
|
|
||||||
currentIndex = values.size() - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
new AlertDialog.Builder(this)
|
|
||||||
.setTitle(R.string.select_webview_provider_dialog_title)
|
|
||||||
.setSingleChoiceItems(options.toArray(new String[0]), currentIndex,
|
|
||||||
new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
try {
|
|
||||||
mWebViewUpdateService.changeProviderAndSetting(values.get(which));
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.w(TAG, "Problem reaching webviewupdate service", e);
|
|
||||||
}
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}).setNegativeButton(android.R.string.cancel, null)
|
|
||||||
.setOnCancelListener(this)
|
|
||||||
.setOnDismissListener(this)
|
|
||||||
.show();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.w(TAG, "Problem reaching webviewupdate service", e);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsCategory() {
|
|
||||||
return MetricsEvent.WEBVIEW_IMPLEMENTATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCancel(DialogInterface dialog) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDismiss(DialogInterface dialog) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
33
src/com/android/settings/webview/UserPackageWrapper.java
Normal file
33
src/com/android/settings/webview/UserPackageWrapper.java
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.settings.webview;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.pm.UserInfo;
|
||||||
|
import android.webkit.UserPackage;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper class around android.webkit.UserPackage - to be able to use UserPackage in Robolectric
|
||||||
|
* tests (such tests currently don't support mocking hidden classes).
|
||||||
|
*/
|
||||||
|
interface UserPackageWrapper {
|
||||||
|
UserInfo getUserInfo();
|
||||||
|
PackageInfo getPackageInfo();
|
||||||
|
boolean isEnabledPackage();
|
||||||
|
boolean isInstalledPackage();
|
||||||
|
}
|
50
src/com/android/settings/webview/UserPackageWrapperImpl.java
Normal file
50
src/com/android/settings/webview/UserPackageWrapperImpl.java
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.settings.webview;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.pm.UserInfo;
|
||||||
|
import android.webkit.UserPackage;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default implementation of UserPackageWrapper.
|
||||||
|
*/
|
||||||
|
class UserPackageWrapperImpl implements UserPackageWrapper {
|
||||||
|
private final UserPackage mUserPackage;
|
||||||
|
|
||||||
|
UserPackageWrapperImpl(UserPackage userPackage) {
|
||||||
|
mUserPackage = userPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserInfo getUserInfo() {
|
||||||
|
return mUserPackage.getUserInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PackageInfo getPackageInfo() {
|
||||||
|
return mUserPackage.getPackageInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabledPackage() {
|
||||||
|
return mUserPackage.isEnabledPackage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInstalledPackage() {
|
||||||
|
return mUserPackage.isInstalledPackage();
|
||||||
|
}
|
||||||
|
}
|
126
src/com/android/settings/webview/WebViewAppListAdapter.java
Normal file
126
src/com/android/settings/webview/WebViewAppListAdapter.java
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.settings.webview;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.support.annotation.VisibleForTesting;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
|
||||||
|
import com.android.settings.applications.AppViewHolder;
|
||||||
|
import com.android.settings.R;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom list adapter for Settings to choose WebView package.
|
||||||
|
* Note: parts of this class are copied from AppPicker.java.
|
||||||
|
*/
|
||||||
|
class WebViewAppListAdapter extends ArrayAdapter<WebViewApplicationInfo> {
|
||||||
|
private final LayoutInflater mInflater;
|
||||||
|
|
||||||
|
public WebViewAppListAdapter(Context context,
|
||||||
|
WebViewUpdateServiceWrapper webviewUpdateServiceWrapper) {
|
||||||
|
super(context, 0);
|
||||||
|
mInflater = LayoutInflater.from(context);
|
||||||
|
|
||||||
|
final List<WebViewApplicationInfo> packageInfoList =
|
||||||
|
new ArrayList<WebViewApplicationInfo>();
|
||||||
|
List<ApplicationInfo> pkgs =
|
||||||
|
webviewUpdateServiceWrapper.getValidWebViewApplicationInfos(getContext());
|
||||||
|
for (ApplicationInfo ai : pkgs) {
|
||||||
|
WebViewApplicationInfo info = new WebViewApplicationInfo(ai,
|
||||||
|
ai.loadLabel(context.getPackageManager()).toString(),
|
||||||
|
getDisabledReason(webviewUpdateServiceWrapper, context, ai.packageName));
|
||||||
|
packageInfoList.add(info);
|
||||||
|
}
|
||||||
|
addAll(packageInfoList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
// A ViewHolder keeps references to children views to avoid unnecessary calls
|
||||||
|
// to findViewById() on each row.
|
||||||
|
AppViewHolder holder = AppViewHolder.createOrRecycle(mInflater, convertView);
|
||||||
|
convertView = holder.rootView;
|
||||||
|
WebViewApplicationInfo info = getItem(position);
|
||||||
|
holder.appName.setText(info.label);
|
||||||
|
if (info.info != null) {
|
||||||
|
holder.appIcon.setImageDrawable(info.info.loadIcon(getContext().getPackageManager()));
|
||||||
|
// Allow disable-description to wrap - to be able to show several lines of text in case
|
||||||
|
// a package is disabled/uninstalled for several users.
|
||||||
|
holder.summary.setSingleLine(false);
|
||||||
|
if (!isEnabled(position)) {
|
||||||
|
holder.summary.setText(info.disabledReason);
|
||||||
|
} else {
|
||||||
|
holder.summary.setText("");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
holder.appIcon.setImageDrawable(null);
|
||||||
|
holder.summary.setText("");
|
||||||
|
}
|
||||||
|
holder.disabled.setVisibility(View.GONE);
|
||||||
|
// Only allow a package to be chosen if it is enabled and installed for all users.
|
||||||
|
convertView.setEnabled(isEnabled(position));
|
||||||
|
return convertView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled (int position) {
|
||||||
|
WebViewApplicationInfo info = getItem(position);
|
||||||
|
return info.disabledReason == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areAllItemsEnabled() {
|
||||||
|
int numItems = getCount();
|
||||||
|
for (int n = 0; n < numItems; n++) {
|
||||||
|
if (!isEnabled(n)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the reason why a package cannot be used as WebView implementation.
|
||||||
|
* This is either because of it being disabled, uninstalled, or hidden for any user.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
static String getDisabledReason(WebViewUpdateServiceWrapper webviewUpdateServiceWrapper,
|
||||||
|
Context context, String packageName) {
|
||||||
|
StringBuilder disabledReason = new StringBuilder();
|
||||||
|
List<UserPackageWrapper> userPackages =
|
||||||
|
webviewUpdateServiceWrapper.getPackageInfosAllUsers(context, packageName);
|
||||||
|
for (UserPackageWrapper userPackage : userPackages) {
|
||||||
|
if (!userPackage.isInstalledPackage()) {
|
||||||
|
// Package uninstalled/hidden
|
||||||
|
disabledReason.append(context.getString(
|
||||||
|
R.string.webview_uninstalled_for_user, userPackage.getUserInfo().name));
|
||||||
|
} else if (!userPackage.isEnabledPackage()) {
|
||||||
|
// Package disabled
|
||||||
|
disabledReason.append(context.getString(
|
||||||
|
R.string.webview_disabled_for_user, userPackage.getUserInfo().name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (disabledReason.length() == 0) return null;
|
||||||
|
return disabledReason.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
95
src/com/android/settings/webview/WebViewAppPicker.java
Normal file
95
src/com/android/settings/webview/WebViewAppPicker.java
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.settings.webview;
|
||||||
|
|
||||||
|
import android.app.ListActivity;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.support.annotation.VisibleForTesting;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.webkit.WebViewFactory;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
|
import com.android.settings.core.instrumentation.Instrumentable;
|
||||||
|
import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
|
||||||
|
|
||||||
|
public class WebViewAppPicker extends ListActivity implements Instrumentable {
|
||||||
|
private static final String TAG = WebViewAppPicker.class.getSimpleName();
|
||||||
|
private WebViewAppListAdapter mAdapter;
|
||||||
|
private WebViewUpdateServiceWrapper mWebViewUpdateServiceWrapper;
|
||||||
|
|
||||||
|
private final VisibilityLoggerMixin mVisibilityLoggerMixin =
|
||||||
|
new VisibilityLoggerMixin(getMetricsCategory());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle icicle) {
|
||||||
|
super.onCreate(icicle);
|
||||||
|
|
||||||
|
if (mWebViewUpdateServiceWrapper == null) {
|
||||||
|
setWebViewUpdateServiceWrapper(createDefaultWebViewUpdateServiceWrapper());
|
||||||
|
}
|
||||||
|
mAdapter = new WebViewAppListAdapter(this, mWebViewUpdateServiceWrapper);
|
||||||
|
setListAdapter(mAdapter);
|
||||||
|
|
||||||
|
mVisibilityLoggerMixin.onAttach(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||||
|
WebViewApplicationInfo app = mAdapter.getItem(position);
|
||||||
|
|
||||||
|
if (mWebViewUpdateServiceWrapper.setWebViewProvider(app.info.packageName)) {
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.setAction(app.info.packageName);
|
||||||
|
setResult(RESULT_OK, intent);
|
||||||
|
} else {
|
||||||
|
mWebViewUpdateServiceWrapper.showInvalidChoiceToast(this);
|
||||||
|
}
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private WebViewUpdateServiceWrapper createDefaultWebViewUpdateServiceWrapper() {
|
||||||
|
return new WebViewUpdateServiceWrapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void setWebViewUpdateServiceWrapper(WebViewUpdateServiceWrapper wvusWrapper) {
|
||||||
|
mWebViewUpdateServiceWrapper = wvusWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
mVisibilityLoggerMixin.onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
mVisibilityLoggerMixin.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMetricsCategory() {
|
||||||
|
return MetricsEvent.WEBVIEW_IMPLEMENTATION;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.settings.webview;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.support.annotation.VisibleForTesting;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
|
||||||
|
import com.android.settings.DevelopmentSettings;
|
||||||
|
import com.android.settings.core.PreferenceController;
|
||||||
|
|
||||||
|
public class WebViewAppPreferenceController extends PreferenceController {
|
||||||
|
|
||||||
|
private static final String WEBVIEW_APP_KEY = "select_webview_provider";
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private Preference mPreference;
|
||||||
|
private final WebViewUpdateServiceWrapper mWebViewUpdateServiceWrapper;
|
||||||
|
|
||||||
|
public WebViewAppPreferenceController(Context context) {
|
||||||
|
this(context, new WebViewUpdateServiceWrapper());
|
||||||
|
}
|
||||||
|
|
||||||
|
public WebViewAppPreferenceController(Context context,
|
||||||
|
WebViewUpdateServiceWrapper webviewUpdateServiceWrapper) {
|
||||||
|
super(context);
|
||||||
|
mContext = context;
|
||||||
|
mWebViewUpdateServiceWrapper = webviewUpdateServiceWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||||
|
if (getPreferenceKey().equals(preference.getKey())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Intent getActivityIntent() {
|
||||||
|
return new Intent(mContext, WebViewAppPicker.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateState(Preference preference) {
|
||||||
|
mPreference.setSummary(getCurrentWebViewPackageLabel(mContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayPreference(PreferenceScreen screen) {
|
||||||
|
super.displayPreference(screen);
|
||||||
|
if (isAvailable()) {
|
||||||
|
mPreference = screen.findPreference(WEBVIEW_APP_KEY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the return-value from the WebViewAppPicker Activity.
|
||||||
|
*/
|
||||||
|
public void onActivityResult(int resultCode, Intent data) {
|
||||||
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
|
updateState(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCurrentWebViewPackageLabel(Context context) {
|
||||||
|
PackageInfo webViewPackage = mWebViewUpdateServiceWrapper.getCurrentWebViewPackage();
|
||||||
|
if (webViewPackage == null) return "";
|
||||||
|
return webViewPackage.applicationInfo.loadLabel(context.getPackageManager()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPreferenceKey() {
|
||||||
|
return WEBVIEW_APP_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enablePreference(boolean enabled) {
|
||||||
|
if (isAvailable()) {
|
||||||
|
mPreference.setEnabled(enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
src/com/android/settings/webview/WebViewApplicationInfo.java
Normal file
29
src/com/android/settings/webview/WebViewApplicationInfo.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.settings.webview;
|
||||||
|
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
|
||||||
|
final class WebViewApplicationInfo {
|
||||||
|
final ApplicationInfo info;
|
||||||
|
final String label;
|
||||||
|
final String disabledReason;
|
||||||
|
|
||||||
|
public WebViewApplicationInfo(ApplicationInfo info, String label, String disabledReason) {
|
||||||
|
this.info = info;
|
||||||
|
this.label = label;
|
||||||
|
this.disabledReason = disabledReason;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.settings.webview;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.webkit.UserPackage;
|
||||||
|
import android.webkit.WebViewFactory;
|
||||||
|
import android.webkit.WebViewProviderInfo;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class WebViewUpdateServiceWrapper {
|
||||||
|
private static final String TAG = "WVUSWrapper";
|
||||||
|
|
||||||
|
public WebViewUpdateServiceWrapper() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the package currently used as WebView implementation.
|
||||||
|
*/
|
||||||
|
public PackageInfo getCurrentWebViewPackage() {
|
||||||
|
try {
|
||||||
|
return WebViewFactory.getUpdateService().getCurrentWebViewPackage();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, e.toString());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches ApplicationInfo objects for all currently valid WebView packages.
|
||||||
|
* A WebView package is considered valid if it can be used as a WebView implementation. The
|
||||||
|
* validity of a package is not dependent on whether the package is installed/enabled.
|
||||||
|
*/
|
||||||
|
public List<ApplicationInfo> getValidWebViewApplicationInfos(Context context) {
|
||||||
|
WebViewProviderInfo[] providers = null;
|
||||||
|
try {
|
||||||
|
providers = WebViewFactory.getUpdateService().getValidWebViewPackages();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
}
|
||||||
|
List<ApplicationInfo> pkgs = new ArrayList<>();
|
||||||
|
for (WebViewProviderInfo provider : providers) {
|
||||||
|
try {
|
||||||
|
pkgs.add(context.getPackageManager().getApplicationInfo(
|
||||||
|
provider.packageName, PACKAGE_FLAGS));
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pkgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change WebView provider to {@param packageName}.
|
||||||
|
* @return whether the change succeeded.
|
||||||
|
*/
|
||||||
|
public boolean setWebViewProvider(String packageName) {
|
||||||
|
try {
|
||||||
|
return packageName.equals(
|
||||||
|
WebViewFactory.getUpdateService().changeProviderAndSetting(packageName));
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "RemoteException when trying to change provider to " + packageName, e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch PackageInfos for the package named {@param packageName} for all users on the device.
|
||||||
|
*/
|
||||||
|
public List<UserPackageWrapper> getPackageInfosAllUsers(Context context, String packageName) {
|
||||||
|
List<UserPackageWrapper> userPackageWrappers = new ArrayList<>();
|
||||||
|
List<UserPackage> userPackages =
|
||||||
|
UserPackage.getPackageInfosAllUsers(context, packageName, PACKAGE_FLAGS);
|
||||||
|
for (UserPackage userPackage : userPackages) {
|
||||||
|
userPackageWrappers.add(new UserPackageWrapperImpl(userPackage));
|
||||||
|
}
|
||||||
|
return userPackageWrappers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a toast to explain the chosen package can no longer be chosen.
|
||||||
|
*/
|
||||||
|
public void showInvalidChoiceToast(Context context) {
|
||||||
|
// The user chose a package that became invalid since the list was last updated,
|
||||||
|
// show a Toast to explain the situation.
|
||||||
|
Toast toast = Toast.makeText(context,
|
||||||
|
R.string.select_webview_provider_toast_text, Toast.LENGTH_SHORT);
|
||||||
|
toast.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
static final int PACKAGE_FLAGS = PackageManager.MATCH_ANY_USER;
|
||||||
|
}
|
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.settings.webview;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Matchers.anyInt;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.UserInfo;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.SettingsRobolectricTestRunner;
|
||||||
|
import com.android.settings.TestConfig;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
|
public class WebViewAppListAdapterTest {
|
||||||
|
private Context mContext = RuntimeEnvironment.application;
|
||||||
|
|
||||||
|
private final static UserInfo FIRST_USER = new UserInfo(0, "FIRST_USER", 0);
|
||||||
|
private final static UserInfo SECOND_USER = new UserInfo(0, "SECOND_USER", 0);
|
||||||
|
|
||||||
|
private final static String DEFAULT_PACKAGE_NAME = "DEFAULT_PACKAGE_NAME";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDisabledReasonNullIfPackagesOk() {
|
||||||
|
UserPackageWrapper packageForFirstUser = mock(UserPackageWrapper.class);
|
||||||
|
when(packageForFirstUser.isEnabledPackage()).thenReturn(true);
|
||||||
|
when(packageForFirstUser.isInstalledPackage()).thenReturn(true);
|
||||||
|
|
||||||
|
UserPackageWrapper packageForSecondUser = mock(UserPackageWrapper.class);
|
||||||
|
when(packageForSecondUser.isEnabledPackage()).thenReturn(true);
|
||||||
|
when(packageForSecondUser.isInstalledPackage()).thenReturn(true);
|
||||||
|
|
||||||
|
WebViewUpdateServiceWrapper wvusWrapper = mock(WebViewUpdateServiceWrapper.class);
|
||||||
|
when(wvusWrapper.getPackageInfosAllUsers(
|
||||||
|
any(), eq(DEFAULT_PACKAGE_NAME))).thenReturn(
|
||||||
|
Arrays.asList(packageForFirstUser, packageForSecondUser));
|
||||||
|
|
||||||
|
assertThat(WebViewAppListAdapter.getDisabledReason(
|
||||||
|
wvusWrapper, mContext, DEFAULT_PACKAGE_NAME)).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDisabledReasonForSingleUserDisabledPackage() {
|
||||||
|
UserPackageWrapper packageForFirstUser = mock(UserPackageWrapper.class);
|
||||||
|
when(packageForFirstUser.isEnabledPackage()).thenReturn(false);
|
||||||
|
when(packageForFirstUser.isInstalledPackage()).thenReturn(true);
|
||||||
|
when(packageForFirstUser.getUserInfo()).thenReturn(FIRST_USER);
|
||||||
|
|
||||||
|
WebViewUpdateServiceWrapper wvusWrapper = mock(WebViewUpdateServiceWrapper.class);
|
||||||
|
when(wvusWrapper.getPackageInfosAllUsers(any(), eq(DEFAULT_PACKAGE_NAME)
|
||||||
|
)).thenReturn(Arrays.asList(packageForFirstUser));
|
||||||
|
|
||||||
|
assertThat(WebViewAppListAdapter.getDisabledReason(wvusWrapper, mContext,
|
||||||
|
DEFAULT_PACKAGE_NAME)).isEqualTo("Disabled for user " + FIRST_USER.name + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDisabledReasonForSingleUserUninstalledPackage() {
|
||||||
|
UserPackageWrapper packageForFirstUser = mock(UserPackageWrapper.class);
|
||||||
|
when(packageForFirstUser.isEnabledPackage()).thenReturn(true);
|
||||||
|
when(packageForFirstUser.isInstalledPackage()).thenReturn(false);
|
||||||
|
when(packageForFirstUser.getUserInfo()).thenReturn(FIRST_USER);
|
||||||
|
|
||||||
|
WebViewUpdateServiceWrapper wvusWrapper = mock(WebViewUpdateServiceWrapper.class);
|
||||||
|
when(wvusWrapper.getPackageInfosAllUsers(any(), eq(DEFAULT_PACKAGE_NAME)
|
||||||
|
)).thenReturn(Arrays.asList(packageForFirstUser));
|
||||||
|
|
||||||
|
assertThat(WebViewAppListAdapter.getDisabledReason(wvusWrapper, mContext,
|
||||||
|
DEFAULT_PACKAGE_NAME)).isEqualTo("Uninstalled for user " + FIRST_USER.name + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDisabledReasonSeveralUsers() {
|
||||||
|
UserPackageWrapper packageForFirstUser = mock(UserPackageWrapper.class);
|
||||||
|
when(packageForFirstUser.isEnabledPackage()).thenReturn(false);
|
||||||
|
when(packageForFirstUser.isInstalledPackage()).thenReturn(true);
|
||||||
|
when(packageForFirstUser.getUserInfo()).thenReturn(FIRST_USER);
|
||||||
|
|
||||||
|
UserPackageWrapper packageForSecondUser = mock(UserPackageWrapper.class);
|
||||||
|
when(packageForSecondUser.isEnabledPackage()).thenReturn(true);
|
||||||
|
when(packageForSecondUser.isInstalledPackage()).thenReturn(false);
|
||||||
|
when(packageForSecondUser.getUserInfo()).thenReturn(SECOND_USER);
|
||||||
|
|
||||||
|
WebViewUpdateServiceWrapper wvusWrapper = mock(WebViewUpdateServiceWrapper.class);
|
||||||
|
when(wvusWrapper.getPackageInfosAllUsers(any(), eq(DEFAULT_PACKAGE_NAME)
|
||||||
|
)).thenReturn(Arrays.asList(packageForFirstUser, packageForSecondUser));
|
||||||
|
|
||||||
|
final String EXPECTED_DISABLED_REASON = String.format(
|
||||||
|
"Disabled for user %s\nUninstalled for user %s\n",
|
||||||
|
FIRST_USER.name, SECOND_USER.name);
|
||||||
|
assertThat(WebViewAppListAdapter.getDisabledReason(
|
||||||
|
wvusWrapper, mContext,DEFAULT_PACKAGE_NAME)).isEqualTo(EXPECTED_DISABLED_REASON);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure we only proclaim a package as uninstalled for a certain user if it's both uninstalled
|
||||||
|
* and disabled.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDisabledReasonUninstalledAndDisabled() {
|
||||||
|
UserPackageWrapper packageForFirstUser = mock(UserPackageWrapper.class);
|
||||||
|
when(packageForFirstUser.isEnabledPackage()).thenReturn(false);
|
||||||
|
when(packageForFirstUser.isInstalledPackage()).thenReturn(false);
|
||||||
|
when(packageForFirstUser.getUserInfo()).thenReturn(FIRST_USER);
|
||||||
|
|
||||||
|
UserPackageWrapper packageForSecondUser = mock(UserPackageWrapper.class);
|
||||||
|
when(packageForSecondUser.isEnabledPackage()).thenReturn(true);
|
||||||
|
when(packageForSecondUser.isInstalledPackage()).thenReturn(true);
|
||||||
|
when(packageForSecondUser.getUserInfo()).thenReturn(SECOND_USER);
|
||||||
|
|
||||||
|
WebViewUpdateServiceWrapper wvusWrapper = mock(WebViewUpdateServiceWrapper.class);
|
||||||
|
when(wvusWrapper.getPackageInfosAllUsers(any(), eq(DEFAULT_PACKAGE_NAME)
|
||||||
|
)).thenReturn(Arrays.asList(packageForFirstUser, packageForSecondUser));
|
||||||
|
|
||||||
|
final String EXPECTED_DISABLED_REASON = String.format(
|
||||||
|
"Uninstalled for user %s\n", FIRST_USER.name);
|
||||||
|
assertThat(WebViewAppListAdapter.getDisabledReason(wvusWrapper, mContext,
|
||||||
|
DEFAULT_PACKAGE_NAME)).isEqualTo(EXPECTED_DISABLED_REASON);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.settings.webview;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.robolectric.shadows.ShadowView.clickOn;
|
||||||
|
import static org.robolectric.Shadows.shadowOf;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.android.settings.SettingsRobolectricTestRunner;
|
||||||
|
import com.android.settings.TestConfig;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.Robolectric;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.util.ActivityController;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
|
public class WebViewAppPickerTest {
|
||||||
|
|
||||||
|
private static final String DEFAULT_PACKAGE_NAME = "DEFAULT_PACKAGE_NAME";
|
||||||
|
|
||||||
|
private static ApplicationInfo createApplicationInfo(String packageName) {
|
||||||
|
ApplicationInfo ai = new ApplicationInfo();
|
||||||
|
ai.packageName = packageName;
|
||||||
|
return ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClickingItemChangesProvider() {
|
||||||
|
ActivityController<WebViewAppPicker> controller =
|
||||||
|
Robolectric.buildActivity(WebViewAppPicker.class);
|
||||||
|
WebViewAppPicker webviewAppPicker = controller.get();
|
||||||
|
|
||||||
|
WebViewUpdateServiceWrapper wvusWrapper = mock(WebViewUpdateServiceWrapper.class);
|
||||||
|
when(wvusWrapper.getValidWebViewApplicationInfos(any())).thenReturn(
|
||||||
|
Arrays.asList(createApplicationInfo(DEFAULT_PACKAGE_NAME)));
|
||||||
|
when(wvusWrapper.setWebViewProvider(eq(DEFAULT_PACKAGE_NAME))).thenReturn(true);
|
||||||
|
|
||||||
|
webviewAppPicker.setWebViewUpdateServiceWrapper(wvusWrapper);
|
||||||
|
|
||||||
|
controller.create().start().postCreate(null).resume().visible();
|
||||||
|
WebViewApplicationInfo firstItem =
|
||||||
|
(WebViewApplicationInfo) webviewAppPicker.getListView().getItemAtPosition(0);
|
||||||
|
assertThat(firstItem.info.packageName).isEqualTo(DEFAULT_PACKAGE_NAME);
|
||||||
|
|
||||||
|
webviewAppPicker.onListItemClick(webviewAppPicker.getListView(), null, 0, 0);
|
||||||
|
|
||||||
|
verify(wvusWrapper, times(1)).setWebViewProvider(eq(DEFAULT_PACKAGE_NAME));
|
||||||
|
assertThat(shadowOf(webviewAppPicker).getResultCode()).isEqualTo(Activity.RESULT_OK);
|
||||||
|
verify(wvusWrapper, never()).showInvalidChoiceToast(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFailingPackageChangeReturnsCancelled() {
|
||||||
|
ActivityController<WebViewAppPicker> controller =
|
||||||
|
Robolectric.buildActivity(WebViewAppPicker.class);
|
||||||
|
WebViewAppPicker webviewAppPicker = controller.get();
|
||||||
|
|
||||||
|
WebViewUpdateServiceWrapper wvusWrapper = mock(WebViewUpdateServiceWrapper.class);
|
||||||
|
when(wvusWrapper.getValidWebViewApplicationInfos(any())).thenReturn(
|
||||||
|
Arrays.asList(createApplicationInfo(DEFAULT_PACKAGE_NAME)));
|
||||||
|
when(wvusWrapper.setWebViewProvider(eq(DEFAULT_PACKAGE_NAME))).thenReturn(false);
|
||||||
|
|
||||||
|
webviewAppPicker.setWebViewUpdateServiceWrapper(wvusWrapper);
|
||||||
|
|
||||||
|
controller.create().start().postCreate(null).resume().visible();
|
||||||
|
WebViewApplicationInfo firstItem =
|
||||||
|
(WebViewApplicationInfo) webviewAppPicker.getListView().getItemAtPosition(0);
|
||||||
|
assertThat(firstItem.info.packageName).isEqualTo(DEFAULT_PACKAGE_NAME);
|
||||||
|
|
||||||
|
webviewAppPicker.onListItemClick(webviewAppPicker.getListView(), null, 0, 0);
|
||||||
|
|
||||||
|
verify(wvusWrapper, times(1)).setWebViewProvider(eq(DEFAULT_PACKAGE_NAME));
|
||||||
|
assertThat(shadowOf(webviewAppPicker).getResultCode()).isEqualTo(Activity.RESULT_CANCELED);
|
||||||
|
verify(wvusWrapper, times(1)).showInvalidChoiceToast(any());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.settings.webview;
|
||||||
|
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
|
||||||
|
import com.android.settings.SettingsRobolectricTestRunner;
|
||||||
|
import com.android.settings.TestConfig;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.JUnit4;
|
||||||
|
import org.mockito.Answers;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
|
public class WebViewAppPreferenceControllerTest {
|
||||||
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
|
private Context mContext;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private PreferenceScreen mPreferenceScreen;
|
||||||
|
@Mock
|
||||||
|
private Preference mPreference;
|
||||||
|
|
||||||
|
private static final String DEFAULT_PACKAGE_NAME = "DEFAULT_PACKAGE_NAME";
|
||||||
|
|
||||||
|
@Before public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
when(mPreferenceScreen.findPreference(any())).thenReturn(mPreference);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void testOnActivityResultUpdatesStateOnSuccess() {
|
||||||
|
WebViewUpdateServiceWrapper wvusWrapper = mock(WebViewUpdateServiceWrapper.class);
|
||||||
|
WebViewAppPreferenceController controller =
|
||||||
|
spy(new WebViewAppPreferenceController(mContext, wvusWrapper));
|
||||||
|
|
||||||
|
controller.displayPreference(mPreferenceScreen); // Makes sure Preference is non-null
|
||||||
|
controller.onActivityResult(Activity.RESULT_OK, new Intent(DEFAULT_PACKAGE_NAME));
|
||||||
|
verify(controller, times(1)).updateState(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void testOnActivityResultWithFailureDoesNothing() {
|
||||||
|
WebViewUpdateServiceWrapper wvusWrapper = mock(WebViewUpdateServiceWrapper.class);
|
||||||
|
|
||||||
|
WebViewAppPreferenceController controller =
|
||||||
|
spy(new WebViewAppPreferenceController(mContext, wvusWrapper));
|
||||||
|
|
||||||
|
controller.displayPreference(mPreferenceScreen); // Makes sure Preference is non-null
|
||||||
|
controller.onActivityResult(Activity.RESULT_CANCELED, new Intent(DEFAULT_PACKAGE_NAME));
|
||||||
|
verify(controller, never()).updateState(any());
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user