Loading res/layout/wifi_dpp_qrcode_generator_fragment.xml +1 −0 Original line number Original line Diff line number Diff line Loading @@ -42,6 +42,7 @@ android:layout_width="match_parent" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_height="match_parent" android:gravity="center" android:gravity="center" android:id="@+id/wifi_dpp_layout" android:orientation="vertical"> android:orientation="vertical"> <ImageView <ImageView Loading src/com/android/settings/wifi/WifiSettings.java +24 −1 Original line number Original line Diff line number Diff line Loading @@ -106,6 +106,7 @@ public class WifiSettings extends RestrictedSettingsFragment @VisibleForTesting @VisibleForTesting static final int MENU_ID_FORGET = Menu.FIRST + 3; static final int MENU_ID_FORGET = Menu.FIRST + 3; static final int MENU_ID_MODIFY = Menu.FIRST + 4; static final int MENU_ID_MODIFY = Menu.FIRST + 4; static final int MENU_ID_SHARE = Menu.FIRST + 5; // Max age of tracked WifiEntries // Max age of tracked WifiEntries private static final long MAX_SCAN_AGE_MILLIS = 15_000; private static final long MAX_SCAN_AGE_MILLIS = 15_000; Loading Loading @@ -499,7 +500,8 @@ public class WifiSettings extends RestrictedSettingsFragment } } if (mSelectedWifiEntry.canDisconnect()) { if (mSelectedWifiEntry.canDisconnect()) { menu.add(Menu.NONE, MENU_ID_DISCONNECT, 0 /* order */, menu.add(Menu.NONE, MENU_ID_SHARE, 0 /* order */, R.string.share); menu.add(Menu.NONE, MENU_ID_DISCONNECT, 1 /* order */, R.string.wifi_disconnect_button_text); R.string.wifi_disconnect_button_text); } } Loading Loading @@ -538,6 +540,10 @@ public class WifiSettings extends RestrictedSettingsFragment case MENU_ID_FORGET: case MENU_ID_FORGET: forget(mSelectedWifiEntry); forget(mSelectedWifiEntry); return true; return true; case MENU_ID_SHARE: WifiDppUtils.showLockScreen(getContext(), () -> launchWifiDppConfiguratorActivity(mSelectedWifiEntry)); return true; case MENU_ID_MODIFY: case MENU_ID_MODIFY: showDialog(mSelectedWifiEntry, WifiConfigUiBase2.MODE_MODIFY); showDialog(mSelectedWifiEntry, WifiConfigUiBase2.MODE_MODIFY); return true; return true; Loading Loading @@ -1115,6 +1121,23 @@ public class WifiSettings extends RestrictedSettingsFragment .launch(); .launch(); } } private void launchWifiDppConfiguratorActivity(WifiEntry wifiEntry) { final Intent intent = WifiDppUtils.getConfiguratorQrCodeGeneratorIntentOrNull(getContext(), mWifiManager, wifiEntry); if (intent == null) { Log.e(TAG, "Launch Wi-Fi DPP QR code generator with a wrong Wi-Fi network!"); } else { mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN, SettingsEnums.ACTION_SETTINGS_SHARE_WIFI_QR_CODE, SettingsEnums.SETTINGS_WIFI_DPP_CONFIGURATOR, /* key */ null, /* value */ Integer.MIN_VALUE); startActivity(intent); } } /** Helper method to return whether a WifiEntry is disabled due to a wrong password */ /** Helper method to return whether a WifiEntry is disabled due to a wrong password */ private static boolean isDisabledByWrongPassword(WifiEntry wifiEntry) { private static boolean isDisabledByWrongPassword(WifiEntry wifiEntry) { WifiConfiguration config = wifiEntry.getWifiConfiguration(); WifiConfiguration config = wifiEntry.getWifiConfiguration(); Loading src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java +144 −4 Original line number Original line Diff line number Diff line Loading @@ -16,9 +16,17 @@ package com.android.settings.wifi.dpp; package com.android.settings.wifi.dpp; import android.annotation.Nullable; import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums; import android.content.ComponentName; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Bundle; import android.provider.Settings; import android.text.TextUtils; import android.text.TextUtils; import android.util.Log; import android.util.Log; import android.view.LayoutInflater; import android.view.LayoutInflater; Loading @@ -27,9 +35,13 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.MenuItem; import android.view.View; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; import android.widget.ImageView; import android.widget.TextView; import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.chooser.DisplayResolveInfo; import com.android.internal.app.chooser.TargetInfo; import com.android.settings.R; import com.android.settings.R; import com.android.settings.wifi.qrcode.QrCodeGenerator; import com.android.settings.wifi.qrcode.QrCodeGenerator; Loading @@ -45,6 +57,15 @@ public class WifiDppQrCodeGeneratorFragment extends WifiDppQrCodeBaseFragment { private ImageView mQrCodeView; private ImageView mQrCodeView; private String mQrCode; private String mQrCode; private static final String CHIP_LABEL_METADATA_KEY = "android.service.chooser.chip_label"; private static final String CHIP_ICON_METADATA_KEY = "android.service.chooser.chip_icon"; private static final String EXTRA_WIFI_CREDENTIALS_BUNDLE = "android.intent.extra.WIFI_CREDENTIALS_BUNDLE"; private static final String EXTRA_SSID = "android.intent.extra.SSID"; private static final String EXTRA_PASSWORD = "android.intent.extra.PASSWORD"; private static final String EXTRA_SECURITY_TYPE = "android.intent.extra.SECURITY_TYPE"; private static final String EXTRA_HIDDEN_SSID = "android.intent.extra.HIDDEN_SSID"; @Override @Override public int getMetricsCategory() { public int getMetricsCategory() { return SettingsEnums.SETTINGS_WIFI_DPP_CONFIGURATOR; return SettingsEnums.SETTINGS_WIFI_DPP_CONFIGURATOR; Loading @@ -56,12 +77,14 @@ public class WifiDppQrCodeGeneratorFragment extends WifiDppQrCodeBaseFragment { // setTitle for TalkBack // setTitle for TalkBack final WifiNetworkConfig wifiNetworkConfig = getWifiNetworkConfigFromHostActivity(); final WifiNetworkConfig wifiNetworkConfig = getWifiNetworkConfigFromHostActivity(); if (getActivity() != null) { if (wifiNetworkConfig.isHotspot()) { if (wifiNetworkConfig.isHotspot()) { getActivity().setTitle(R.string.wifi_dpp_share_hotspot); getActivity().setTitle(R.string.wifi_dpp_share_hotspot); } else { } else { getActivity().setTitle(R.string.wifi_dpp_share_wifi); getActivity().setTitle(R.string.wifi_dpp_share_wifi); } } } } } @Override @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { Loading Loading @@ -112,10 +135,127 @@ public class WifiDppQrCodeGeneratorFragment extends WifiDppQrCodeBaseFragment { } } } } final Intent intent = new Intent().setComponent(getNearbySharingComponent()); addActionButton(view.findViewById(R.id.wifi_dpp_layout), createNearbyButton(intent, v -> { intent.setAction(Intent.ACTION_SEND); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); Bundle wifiCredentialBundle = new Bundle(); String ssid = WifiDppUtils.removeFirstAndLastDoubleQuotes(wifiNetworkConfig.getSsid()); String passwordExtra = wifiNetworkConfig.getPreSharedKey(); String securityType = wifiNetworkConfig.getSecurity(); boolean hiddenSsid = wifiNetworkConfig.getHiddenSsid(); wifiCredentialBundle.putString(EXTRA_SSID, ssid); wifiCredentialBundle.putString(EXTRA_PASSWORD, passwordExtra); wifiCredentialBundle.putString(EXTRA_SECURITY_TYPE, securityType); wifiCredentialBundle.putBoolean(EXTRA_HIDDEN_SSID, hiddenSsid); intent.putExtra(EXTRA_WIFI_CREDENTIALS_BUNDLE, wifiCredentialBundle); startActivity(intent); })); mQrCode = wifiNetworkConfig.getQrCode(); mQrCode = wifiNetworkConfig.getQrCode(); setQrCode(); setQrCode(); } } @VisibleForTesting ComponentName getNearbySharingComponent() { String nearbyComponent = Settings.Secure.getString( getContext().getContentResolver(), Settings.Secure.NEARBY_SHARING_COMPONENT); if (TextUtils.isEmpty(nearbyComponent)) { nearbyComponent = getString( com.android.internal.R.string.config_defaultNearbySharingComponent); } if (TextUtils.isEmpty(nearbyComponent)) { return null; } return ComponentName.unflattenFromString(nearbyComponent); } private TargetInfo getNearbySharingTarget(Intent originalIntent) { final ComponentName cn = getNearbySharingComponent(); if (cn == null) return null; final Intent resolveIntent = new Intent(originalIntent); resolveIntent.setComponent(cn); PackageManager pm = getContext().getPackageManager(); final ResolveInfo resolveInfo = pm.resolveActivity( resolveIntent, PackageManager.GET_META_DATA); if (resolveInfo == null || resolveInfo.activityInfo == null) { Log.e(TAG, "Device-specified nearby sharing component (" + cn + ") not available"); return null; } // Allow the nearby sharing component to provide a more appropriate icon and label // for the chip. CharSequence name = null; Drawable icon = null; final Bundle metaData = resolveInfo.activityInfo.metaData; if (metaData != null) { try { final Resources pkgRes = pm.getResourcesForActivity(cn); final int nameResId = metaData.getInt(CHIP_LABEL_METADATA_KEY); name = pkgRes.getString(nameResId); final int resId = metaData.getInt(CHIP_ICON_METADATA_KEY); icon = pkgRes.getDrawable(resId); } catch (Resources.NotFoundException ex) { } catch (PackageManager.NameNotFoundException ex) { } } if (TextUtils.isEmpty(name)) { name = resolveInfo.loadLabel(pm); } if (icon == null) { icon = resolveInfo.loadIcon(pm); } final DisplayResolveInfo dri = new DisplayResolveInfo( originalIntent, resolveInfo, name, "", resolveIntent, null); dri.setDisplayIcon(icon); return dri; } private Button createActionButton(Drawable icon, CharSequence title, View.OnClickListener r) { Button b = (Button) LayoutInflater.from(getContext()).inflate( com.android.internal.R.layout.chooser_action_button, null); if (icon != null) { final int size = getResources() .getDimensionPixelSize( com.android.internal.R.dimen.chooser_action_button_icon_size); icon.setBounds(0, 0, size, size); b.setCompoundDrawablesRelative(icon, null, null, null); } b.setText(title); b.setOnClickListener(r); return b; } private void addActionButton(ViewGroup parent, Button b) { if (b == null) return; final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT ); final int gap = getResources().getDimensionPixelSize( com.android.internal.R.dimen.resolver_icon_margin) / 2; lp.setMarginsRelative(gap, 0, gap, 0); parent.addView(b, lp); } @VisibleForTesting @Nullable Button createNearbyButton(Intent originalIntent, View.OnClickListener r) { final TargetInfo ti = getNearbySharingTarget(originalIntent); if (ti == null) return null; return createActionButton(ti.getDisplayIcon(getContext()), ti.getDisplayLabel(), r); } private void setQrCode() { private void setQrCode() { try { try { final int qrcodeSize = getContext().getResources().getDimensionPixelSize( final int qrcodeSize = getContext().getResources().getDimensionPixelSize( Loading src/com/android/settings/wifi/dpp/WifiDppUtils.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -145,7 +145,7 @@ public class WifiDppUtils { return wifiConfiguration.preSharedKey; return wifiConfiguration.preSharedKey; } } private static String removeFirstAndLastDoubleQuotes(String str) { static String removeFirstAndLastDoubleQuotes(String str) { if (TextUtils.isEmpty(str)) { if (TextUtils.isEmpty(str)) { return str; return str; } } Loading tests/robotests/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragmentTest.java 0 → 100644 +161 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2018 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.wifi.dpp; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Bundle; import androidx.fragment.app.FragmentTransaction; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; import org.robolectric.Robolectric; @RunWith(AndroidJUnit4.class) public class WifiDppQrCodeGeneratorFragmentTest { private WifiDppConfiguratorActivity mActivity; private WifiDppQrCodeGeneratorFragment mFragment; private Context mContext; @Before public void setUp() { Intent intent = new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR); intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest"); intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WPA"); intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "\\012345678,"); MockitoAnnotations.initMocks(this); mActivity = Robolectric.setupActivity(WifiDppConfiguratorActivity.class); mActivity.setWifiNetworkConfig(WifiNetworkConfig.getValidConfigOrNull(intent)); mActivity.startActivity(intent); mFragment = spy(new WifiDppQrCodeGeneratorFragment()); FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction(); ft.add(mFragment, null); ft.commit(); mContext = spy(InstrumentationRegistry.getTargetContext()); when(mFragment.getContext()).thenReturn(mContext); } @Test public void rotateScreen_shouldNotCrash() { mActivity.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); mActivity.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } @Test public void createNearbyButton_returnsNull() { assertThat(mFragment.createNearbyButton(new Intent(), v -> { })).isNull(); } private static ResolveInfo createResolveInfo(int userId) { final ResolveInfo resolveInfo = new ResolveInfo(); resolveInfo.activityInfo = createActivityInfo(); resolveInfo.targetUserId = userId; return resolveInfo; } private static ActivityInfo createActivityInfo() { ActivityInfo ai = new ActivityInfo(); ai.name = "activity_name"; ai.packageName = "foo_bar"; ai.enabled = true; ai.exported = true; ai.permission = null; ai.applicationInfo = new ApplicationInfo(); ai.applicationInfo.packageName = "com.google.android.gms"; Bundle metadata = mock(Bundle.class); when(metadata.getInt(anyString())).thenReturn(1); ai.metaData = metadata; return ai; } @Test public void createNearbyButtonFromSetting_notNull() throws PackageManager.NameNotFoundException { doReturn(ComponentName.unflattenFromString( "com.google.android.gms/com.google.android.gms.nearby.sharing.ShareSheetActivity")) .when(mFragment).getNearbySharingComponent(); PackageManager packageManager = mock(PackageManager.class); doReturn(createResolveInfo(0)).when(packageManager).resolveActivity(any(), anyInt()); Resources resources = mock(Resources.class); when(resources.getString(anyInt())).thenReturn("Nearby"); Drawable drawable = mock(Drawable.class); when(resources.getDrawable(anyInt())).thenReturn(drawable); when(packageManager.getResourcesForActivity(any())).thenReturn(resources); when(mContext.getPackageManager()).thenReturn(packageManager); assertThat(mFragment.createNearbyButton(new Intent(), v -> { })).isNotNull(); } @Test public void createNearbyButtonFromConfig_notNull() throws PackageManager.NameNotFoundException { doReturn( "com.google.android.gms/com.google.android.gms.nearby.sharing.ShareSheetActivity") .when(mFragment).getString(anyInt()); PackageManager packageManager = mock(PackageManager.class); doReturn(createResolveInfo(0)).when(packageManager).resolveActivity(any(), anyInt()); Resources resources = mock(Resources.class); when(resources.getString(anyInt())).thenReturn("Nearby"); Drawable drawable = mock(Drawable.class); when(resources.getDrawable(anyInt())).thenReturn(drawable); when(packageManager.getResourcesForActivity(any())).thenReturn(resources); when(mContext.getPackageManager()).thenReturn(packageManager); assertThat(mFragment.createNearbyButton(new Intent(), v -> { })).isNotNull(); } } Loading
res/layout/wifi_dpp_qrcode_generator_fragment.xml +1 −0 Original line number Original line Diff line number Diff line Loading @@ -42,6 +42,7 @@ android:layout_width="match_parent" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_height="match_parent" android:gravity="center" android:gravity="center" android:id="@+id/wifi_dpp_layout" android:orientation="vertical"> android:orientation="vertical"> <ImageView <ImageView Loading
src/com/android/settings/wifi/WifiSettings.java +24 −1 Original line number Original line Diff line number Diff line Loading @@ -106,6 +106,7 @@ public class WifiSettings extends RestrictedSettingsFragment @VisibleForTesting @VisibleForTesting static final int MENU_ID_FORGET = Menu.FIRST + 3; static final int MENU_ID_FORGET = Menu.FIRST + 3; static final int MENU_ID_MODIFY = Menu.FIRST + 4; static final int MENU_ID_MODIFY = Menu.FIRST + 4; static final int MENU_ID_SHARE = Menu.FIRST + 5; // Max age of tracked WifiEntries // Max age of tracked WifiEntries private static final long MAX_SCAN_AGE_MILLIS = 15_000; private static final long MAX_SCAN_AGE_MILLIS = 15_000; Loading Loading @@ -499,7 +500,8 @@ public class WifiSettings extends RestrictedSettingsFragment } } if (mSelectedWifiEntry.canDisconnect()) { if (mSelectedWifiEntry.canDisconnect()) { menu.add(Menu.NONE, MENU_ID_DISCONNECT, 0 /* order */, menu.add(Menu.NONE, MENU_ID_SHARE, 0 /* order */, R.string.share); menu.add(Menu.NONE, MENU_ID_DISCONNECT, 1 /* order */, R.string.wifi_disconnect_button_text); R.string.wifi_disconnect_button_text); } } Loading Loading @@ -538,6 +540,10 @@ public class WifiSettings extends RestrictedSettingsFragment case MENU_ID_FORGET: case MENU_ID_FORGET: forget(mSelectedWifiEntry); forget(mSelectedWifiEntry); return true; return true; case MENU_ID_SHARE: WifiDppUtils.showLockScreen(getContext(), () -> launchWifiDppConfiguratorActivity(mSelectedWifiEntry)); return true; case MENU_ID_MODIFY: case MENU_ID_MODIFY: showDialog(mSelectedWifiEntry, WifiConfigUiBase2.MODE_MODIFY); showDialog(mSelectedWifiEntry, WifiConfigUiBase2.MODE_MODIFY); return true; return true; Loading Loading @@ -1115,6 +1121,23 @@ public class WifiSettings extends RestrictedSettingsFragment .launch(); .launch(); } } private void launchWifiDppConfiguratorActivity(WifiEntry wifiEntry) { final Intent intent = WifiDppUtils.getConfiguratorQrCodeGeneratorIntentOrNull(getContext(), mWifiManager, wifiEntry); if (intent == null) { Log.e(TAG, "Launch Wi-Fi DPP QR code generator with a wrong Wi-Fi network!"); } else { mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN, SettingsEnums.ACTION_SETTINGS_SHARE_WIFI_QR_CODE, SettingsEnums.SETTINGS_WIFI_DPP_CONFIGURATOR, /* key */ null, /* value */ Integer.MIN_VALUE); startActivity(intent); } } /** Helper method to return whether a WifiEntry is disabled due to a wrong password */ /** Helper method to return whether a WifiEntry is disabled due to a wrong password */ private static boolean isDisabledByWrongPassword(WifiEntry wifiEntry) { private static boolean isDisabledByWrongPassword(WifiEntry wifiEntry) { WifiConfiguration config = wifiEntry.getWifiConfiguration(); WifiConfiguration config = wifiEntry.getWifiConfiguration(); Loading
src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java +144 −4 Original line number Original line Diff line number Diff line Loading @@ -16,9 +16,17 @@ package com.android.settings.wifi.dpp; package com.android.settings.wifi.dpp; import android.annotation.Nullable; import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums; import android.content.ComponentName; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Bundle; import android.provider.Settings; import android.text.TextUtils; import android.text.TextUtils; import android.util.Log; import android.util.Log; import android.view.LayoutInflater; import android.view.LayoutInflater; Loading @@ -27,9 +35,13 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.MenuItem; import android.view.View; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; import android.widget.ImageView; import android.widget.TextView; import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.chooser.DisplayResolveInfo; import com.android.internal.app.chooser.TargetInfo; import com.android.settings.R; import com.android.settings.R; import com.android.settings.wifi.qrcode.QrCodeGenerator; import com.android.settings.wifi.qrcode.QrCodeGenerator; Loading @@ -45,6 +57,15 @@ public class WifiDppQrCodeGeneratorFragment extends WifiDppQrCodeBaseFragment { private ImageView mQrCodeView; private ImageView mQrCodeView; private String mQrCode; private String mQrCode; private static final String CHIP_LABEL_METADATA_KEY = "android.service.chooser.chip_label"; private static final String CHIP_ICON_METADATA_KEY = "android.service.chooser.chip_icon"; private static final String EXTRA_WIFI_CREDENTIALS_BUNDLE = "android.intent.extra.WIFI_CREDENTIALS_BUNDLE"; private static final String EXTRA_SSID = "android.intent.extra.SSID"; private static final String EXTRA_PASSWORD = "android.intent.extra.PASSWORD"; private static final String EXTRA_SECURITY_TYPE = "android.intent.extra.SECURITY_TYPE"; private static final String EXTRA_HIDDEN_SSID = "android.intent.extra.HIDDEN_SSID"; @Override @Override public int getMetricsCategory() { public int getMetricsCategory() { return SettingsEnums.SETTINGS_WIFI_DPP_CONFIGURATOR; return SettingsEnums.SETTINGS_WIFI_DPP_CONFIGURATOR; Loading @@ -56,12 +77,14 @@ public class WifiDppQrCodeGeneratorFragment extends WifiDppQrCodeBaseFragment { // setTitle for TalkBack // setTitle for TalkBack final WifiNetworkConfig wifiNetworkConfig = getWifiNetworkConfigFromHostActivity(); final WifiNetworkConfig wifiNetworkConfig = getWifiNetworkConfigFromHostActivity(); if (getActivity() != null) { if (wifiNetworkConfig.isHotspot()) { if (wifiNetworkConfig.isHotspot()) { getActivity().setTitle(R.string.wifi_dpp_share_hotspot); getActivity().setTitle(R.string.wifi_dpp_share_hotspot); } else { } else { getActivity().setTitle(R.string.wifi_dpp_share_wifi); getActivity().setTitle(R.string.wifi_dpp_share_wifi); } } } } } @Override @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { Loading Loading @@ -112,10 +135,127 @@ public class WifiDppQrCodeGeneratorFragment extends WifiDppQrCodeBaseFragment { } } } } final Intent intent = new Intent().setComponent(getNearbySharingComponent()); addActionButton(view.findViewById(R.id.wifi_dpp_layout), createNearbyButton(intent, v -> { intent.setAction(Intent.ACTION_SEND); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); Bundle wifiCredentialBundle = new Bundle(); String ssid = WifiDppUtils.removeFirstAndLastDoubleQuotes(wifiNetworkConfig.getSsid()); String passwordExtra = wifiNetworkConfig.getPreSharedKey(); String securityType = wifiNetworkConfig.getSecurity(); boolean hiddenSsid = wifiNetworkConfig.getHiddenSsid(); wifiCredentialBundle.putString(EXTRA_SSID, ssid); wifiCredentialBundle.putString(EXTRA_PASSWORD, passwordExtra); wifiCredentialBundle.putString(EXTRA_SECURITY_TYPE, securityType); wifiCredentialBundle.putBoolean(EXTRA_HIDDEN_SSID, hiddenSsid); intent.putExtra(EXTRA_WIFI_CREDENTIALS_BUNDLE, wifiCredentialBundle); startActivity(intent); })); mQrCode = wifiNetworkConfig.getQrCode(); mQrCode = wifiNetworkConfig.getQrCode(); setQrCode(); setQrCode(); } } @VisibleForTesting ComponentName getNearbySharingComponent() { String nearbyComponent = Settings.Secure.getString( getContext().getContentResolver(), Settings.Secure.NEARBY_SHARING_COMPONENT); if (TextUtils.isEmpty(nearbyComponent)) { nearbyComponent = getString( com.android.internal.R.string.config_defaultNearbySharingComponent); } if (TextUtils.isEmpty(nearbyComponent)) { return null; } return ComponentName.unflattenFromString(nearbyComponent); } private TargetInfo getNearbySharingTarget(Intent originalIntent) { final ComponentName cn = getNearbySharingComponent(); if (cn == null) return null; final Intent resolveIntent = new Intent(originalIntent); resolveIntent.setComponent(cn); PackageManager pm = getContext().getPackageManager(); final ResolveInfo resolveInfo = pm.resolveActivity( resolveIntent, PackageManager.GET_META_DATA); if (resolveInfo == null || resolveInfo.activityInfo == null) { Log.e(TAG, "Device-specified nearby sharing component (" + cn + ") not available"); return null; } // Allow the nearby sharing component to provide a more appropriate icon and label // for the chip. CharSequence name = null; Drawable icon = null; final Bundle metaData = resolveInfo.activityInfo.metaData; if (metaData != null) { try { final Resources pkgRes = pm.getResourcesForActivity(cn); final int nameResId = metaData.getInt(CHIP_LABEL_METADATA_KEY); name = pkgRes.getString(nameResId); final int resId = metaData.getInt(CHIP_ICON_METADATA_KEY); icon = pkgRes.getDrawable(resId); } catch (Resources.NotFoundException ex) { } catch (PackageManager.NameNotFoundException ex) { } } if (TextUtils.isEmpty(name)) { name = resolveInfo.loadLabel(pm); } if (icon == null) { icon = resolveInfo.loadIcon(pm); } final DisplayResolveInfo dri = new DisplayResolveInfo( originalIntent, resolveInfo, name, "", resolveIntent, null); dri.setDisplayIcon(icon); return dri; } private Button createActionButton(Drawable icon, CharSequence title, View.OnClickListener r) { Button b = (Button) LayoutInflater.from(getContext()).inflate( com.android.internal.R.layout.chooser_action_button, null); if (icon != null) { final int size = getResources() .getDimensionPixelSize( com.android.internal.R.dimen.chooser_action_button_icon_size); icon.setBounds(0, 0, size, size); b.setCompoundDrawablesRelative(icon, null, null, null); } b.setText(title); b.setOnClickListener(r); return b; } private void addActionButton(ViewGroup parent, Button b) { if (b == null) return; final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT ); final int gap = getResources().getDimensionPixelSize( com.android.internal.R.dimen.resolver_icon_margin) / 2; lp.setMarginsRelative(gap, 0, gap, 0); parent.addView(b, lp); } @VisibleForTesting @Nullable Button createNearbyButton(Intent originalIntent, View.OnClickListener r) { final TargetInfo ti = getNearbySharingTarget(originalIntent); if (ti == null) return null; return createActionButton(ti.getDisplayIcon(getContext()), ti.getDisplayLabel(), r); } private void setQrCode() { private void setQrCode() { try { try { final int qrcodeSize = getContext().getResources().getDimensionPixelSize( final int qrcodeSize = getContext().getResources().getDimensionPixelSize( Loading
src/com/android/settings/wifi/dpp/WifiDppUtils.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -145,7 +145,7 @@ public class WifiDppUtils { return wifiConfiguration.preSharedKey; return wifiConfiguration.preSharedKey; } } private static String removeFirstAndLastDoubleQuotes(String str) { static String removeFirstAndLastDoubleQuotes(String str) { if (TextUtils.isEmpty(str)) { if (TextUtils.isEmpty(str)) { return str; return str; } } Loading
tests/robotests/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragmentTest.java 0 → 100644 +161 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2018 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.wifi.dpp; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Bundle; import androidx.fragment.app.FragmentTransaction; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; import org.robolectric.Robolectric; @RunWith(AndroidJUnit4.class) public class WifiDppQrCodeGeneratorFragmentTest { private WifiDppConfiguratorActivity mActivity; private WifiDppQrCodeGeneratorFragment mFragment; private Context mContext; @Before public void setUp() { Intent intent = new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR); intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest"); intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WPA"); intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "\\012345678,"); MockitoAnnotations.initMocks(this); mActivity = Robolectric.setupActivity(WifiDppConfiguratorActivity.class); mActivity.setWifiNetworkConfig(WifiNetworkConfig.getValidConfigOrNull(intent)); mActivity.startActivity(intent); mFragment = spy(new WifiDppQrCodeGeneratorFragment()); FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction(); ft.add(mFragment, null); ft.commit(); mContext = spy(InstrumentationRegistry.getTargetContext()); when(mFragment.getContext()).thenReturn(mContext); } @Test public void rotateScreen_shouldNotCrash() { mActivity.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); mActivity.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } @Test public void createNearbyButton_returnsNull() { assertThat(mFragment.createNearbyButton(new Intent(), v -> { })).isNull(); } private static ResolveInfo createResolveInfo(int userId) { final ResolveInfo resolveInfo = new ResolveInfo(); resolveInfo.activityInfo = createActivityInfo(); resolveInfo.targetUserId = userId; return resolveInfo; } private static ActivityInfo createActivityInfo() { ActivityInfo ai = new ActivityInfo(); ai.name = "activity_name"; ai.packageName = "foo_bar"; ai.enabled = true; ai.exported = true; ai.permission = null; ai.applicationInfo = new ApplicationInfo(); ai.applicationInfo.packageName = "com.google.android.gms"; Bundle metadata = mock(Bundle.class); when(metadata.getInt(anyString())).thenReturn(1); ai.metaData = metadata; return ai; } @Test public void createNearbyButtonFromSetting_notNull() throws PackageManager.NameNotFoundException { doReturn(ComponentName.unflattenFromString( "com.google.android.gms/com.google.android.gms.nearby.sharing.ShareSheetActivity")) .when(mFragment).getNearbySharingComponent(); PackageManager packageManager = mock(PackageManager.class); doReturn(createResolveInfo(0)).when(packageManager).resolveActivity(any(), anyInt()); Resources resources = mock(Resources.class); when(resources.getString(anyInt())).thenReturn("Nearby"); Drawable drawable = mock(Drawable.class); when(resources.getDrawable(anyInt())).thenReturn(drawable); when(packageManager.getResourcesForActivity(any())).thenReturn(resources); when(mContext.getPackageManager()).thenReturn(packageManager); assertThat(mFragment.createNearbyButton(new Intent(), v -> { })).isNotNull(); } @Test public void createNearbyButtonFromConfig_notNull() throws PackageManager.NameNotFoundException { doReturn( "com.google.android.gms/com.google.android.gms.nearby.sharing.ShareSheetActivity") .when(mFragment).getString(anyInt()); PackageManager packageManager = mock(PackageManager.class); doReturn(createResolveInfo(0)).when(packageManager).resolveActivity(any(), anyInt()); Resources resources = mock(Resources.class); when(resources.getString(anyInt())).thenReturn("Nearby"); Drawable drawable = mock(Drawable.class); when(resources.getDrawable(anyInt())).thenReturn(drawable); when(packageManager.getResourcesForActivity(any())).thenReturn(resources); when(mContext.getPackageManager()).thenReturn(packageManager); assertThat(mFragment.createNearbyButton(new Intent(), v -> { })).isNotNull(); } }