From 89403529adf7584ded2bdadf985fde12a346ec3b Mon Sep 17 00:00:00 2001 From: Zoltan Szatmary-Ban Date: Wed, 15 Apr 2015 13:42:13 +0100 Subject: [PATCH] Show dialog when user tries to edit a locked down WiFi config Also, 'FORGET' button is not shown on WifiDialogs of locked down configs. Context menu only shows 'Connect' for them. Bug: 20117316 Change-Id: I3fa986c10b6ff47d1a897794213c225c8c6f579b --- res/values/strings.xml | 2 + .../wifi/SavedAccessPointsWifiSettings.java | 7 +- .../settings/wifi/WifiConfigController.java | 7 ++ src/com/android/settings/wifi/WifiDialog.java | 10 ++- .../android/settings/wifi/WifiSettings.java | 70 ++++++++++++++++++- 5 files changed, 93 insertions(+), 3 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 86eae3a8a55..430b7706526 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1333,6 +1333,8 @@ 5GHz + + %1$s manages your device and has disabled modifying and deleting this Wi-Fi network. For more information, contact your administrator. diff --git a/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java b/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java index 2627bc413e6..e9fbe87a209 100644 --- a/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java +++ b/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java @@ -128,8 +128,13 @@ public class SavedAccessPointsWifiSettings extends SettingsPreferenceFragment mAccessPointSavedState = null; } mSelectedAccessPoint = mDlgAccessPoint; + + // Hide forget button if config editing is locked down + final boolean hideForgetButton = WifiSettings.isCreatorDeviceOwner(getActivity(), + mDlgAccessPoint.getConfig()); mDialog = new WifiDialog(getActivity(), this, mDlgAccessPoint, - false /* not editting */, true /* hide the submit button */); + false /* not editting */, true /* hide the submit button */, + hideForgetButton); return mDialog; } diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java index 1503c63730c..ee538877fc7 100644 --- a/src/com/android/settings/wifi/WifiConfigController.java +++ b/src/com/android/settings/wifi/WifiConfigController.java @@ -315,6 +315,13 @@ public class WifiConfigController implements TextWatcher, return (level > -1 && level < mLevels.length) ? mLevels[level] : null; } + void hideForgetButton() { + Button forget = mConfigUi.getForgetButton(); + if (forget == null) return; + + forget.setVisibility(View.GONE); + } + void hideSubmitButton() { Button submit = mConfigUi.getSubmitButton(); if (submit == null) return; diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java index 1e8a981abbc..c18baf5e207 100644 --- a/src/com/android/settings/wifi/WifiDialog.java +++ b/src/com/android/settings/wifi/WifiDialog.java @@ -37,11 +37,14 @@ class WifiDialog extends AlertDialog implements WifiConfigUiBase { private View mView; private WifiConfigController mController; private boolean mHideSubmitButton; + private boolean mHideForgetButton; public WifiDialog(Context context, DialogInterface.OnClickListener listener, - AccessPoint accessPoint, boolean edit, boolean hideSubmitButton) { + AccessPoint accessPoint, boolean edit, boolean hideSubmitButton, + boolean hideForgetButton) { this(context, listener, accessPoint, edit); mHideSubmitButton = hideSubmitButton; + mHideForgetButton = hideForgetButton; } public WifiDialog(Context context, DialogInterface.OnClickListener listener, @@ -51,6 +54,7 @@ class WifiDialog extends AlertDialog implements WifiConfigUiBase { mListener = listener; mAccessPoint = accessPoint; mHideSubmitButton = false; + mHideForgetButton = false; } @Override @@ -73,6 +77,10 @@ class WifiDialog extends AlertDialog implements WifiConfigUiBase { * visibility. Right after creation, update button visibility */ mController.enableSubmitIfAppropriate(); } + + if (mHideForgetButton) { + mController.hideForgetButton(); + } } public void onRestoreInstanceState(Bundle savedInstanceState) { diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index cb6be536afe..60fd497c0e3 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -20,10 +20,17 @@ import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID; import static android.os.UserManager.DISALLOW_CONFIG_WIFI; import android.app.Activity; +import android.app.AlertDialog; +import android.app.AppGlobals; import android.app.Dialog; +import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.IPackageManager; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; @@ -35,6 +42,8 @@ import android.net.wifi.WifiManager; import android.net.wifi.WpsInfo; import android.nfc.NfcAdapter; import android.os.Bundle; +import android.os.RemoteException; +import android.os.UserHandle; import android.preference.Preference; import android.preference.PreferenceScreen; import android.text.Spannable; @@ -433,6 +442,12 @@ public class WifiSettings extends RestrictedSettingsFragment menu.add(Menu.NONE, MENU_ID_CONNECT, 0, R.string.wifi_menu_connect); } + WifiConfiguration config = mSelectedAccessPoint.getConfig(); + // Device Owner created configs are uneditable + if (isCreatorDeviceOwner(getActivity(), config)) { + return; + } + if (mSelectedAccessPoint.isSaved() || mSelectedAccessPoint.isEphemeral()) { // Allow forgetting a network if either the network is saved or ephemerally // connected. (In the latter case, "forget" blacklists the network so it won't @@ -509,6 +524,31 @@ public class WifiSettings extends RestrictedSettingsFragment } private void showDialog(AccessPoint accessPoint, boolean edit) { + WifiConfiguration config = accessPoint.getConfig(); + if (isCreatorDeviceOwner(getActivity(), config) && accessPoint.isActive()) { + final int userId = UserHandle.getUserId(config.creatorUid); + final PackageManager pm = getActivity().getPackageManager(); + final IPackageManager ipm = AppGlobals.getPackageManager(); + String appName = pm.getNameForUid(config.creatorUid); + try { + final ApplicationInfo appInfo = ipm.getApplicationInfo(appName, /* flags */ 0, + userId); + final CharSequence label = pm.getApplicationLabel(appInfo); + if (label != null) { + appName = label.toString(); + } + } catch (RemoteException e) { + // leave appName as packageName + } + final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(accessPoint.getSsid()) + .setMessage(getString(R.string.wifi_alert_lockdown_by_device_owner, + appName)) + .setPositiveButton(android.R.string.ok, null) + .show(); + return; + } + if (mDialog != null) { removeDialog(WIFI_DIALOG_ID); mDialog = null; @@ -537,7 +577,10 @@ public class WifiSettings extends RestrictedSettingsFragment } // If it's null, fine, it's for Add Network mSelectedAccessPoint = ap; - mDialog = new WifiDialog(getActivity(), this, ap, mDlgEdit); + mDialog = new WifiDialog(getActivity(), this, ap, mDlgEdit, + /* no hide submit/connect */ false, + /* hide forget if config locked down */ isCreatorDeviceOwner(getActivity(), + ap.getConfig())); return mDialog; case WPS_PBC_DIALOG_ID: return new WpsDialog(getActivity(), WpsInfo.PBC); @@ -845,4 +888,29 @@ public class WifiSettings extends RestrictedSettingsFragment return result; } }; + + /** + * Returns the true if the app that created this config is the device owner of the device. + * @param config The WiFi config. + * @return creator package name or null if creator package is not device owner. + */ + static boolean isCreatorDeviceOwner(Context context, WifiConfiguration config) { + if (config == null) { + return false; + } + final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( + Context.DEVICE_POLICY_SERVICE); + final String deviceOwnerPackageName = dpm.getDeviceOwner(); + if (deviceOwnerPackageName == null) { + return false; + } + final PackageManager pm = context.getPackageManager(); + try { + final int deviceOwnerUid = pm.getPackageUid(deviceOwnerPackageName, + UserHandle.getUserId(config.creatorUid)); + return deviceOwnerUid == config.creatorUid; + } catch (NameNotFoundException e) { + return false; + } + } }