packages/apps/Settings
Revision | caca20d4eb172986c350a13dac4f2f9e9b94a9a0 (tree) |
---|---|
Zeit | 2021-07-01 20:04:01 |
Autor | Android Build Coastguard Worker <android-build-coastguard-worker@goog...> |
Commiter | Android Build Coastguard Worker |
Merge cherrypicks of [15172584, 15172286, 15172594, 15172385, 15172631, 15172632, 15172633, 15172634, 15171221, 15171222, 15171223, 15171541, 15171542, 15171668, 15172342, 15170823, 15170824, 15170825, 15170826, 15170827, 15170828, 15170829, 15172650, 15172651, 15172652, 15172653, 15172654, 15172655, 15172656, 15172657, 15172658, 15172659, 15172660, 15172661, 15172386, 15172387, 15172388, 15172389, 15172670, 15172553, 15172589, 15172343, 15172617, 15172618, 15172619, 15172620, 15172690, 15172691, 15172692, 15172693, 15172694, 15172695, 15172696, 15172697, 15171708, 15171709, 15172554, 15172555, 15172710, 15172621, 15172635, 15172636, 15172698, 15172699, 15172700, 15171543, 15172701, 15172702, 15172703, 15172704, 15171669, 15172622] into rvc-d2-release
Change-Id: Ic3c06db90ac9c1a0656cc3d3b225dcc6a0787150
@@ -0,0 +1,18 @@ | ||
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<!-- Copyright (C) 2021 The Android Open Source Project | |
3 | + | |
4 | + Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + you may not use this file except in compliance with the License. | |
6 | + You may obtain a copy of the License at | |
7 | + | |
8 | + http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + | |
10 | + Unless required by applicable law or agreed to in writing, software | |
11 | + distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + See the License for the specific language governing permissions and | |
14 | + limitations under the License. | |
15 | +--> | |
16 | +<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> | |
17 | + <string name="cell_broadcast_settings">Emergency alerts</string> | |
18 | +</resources> | |
\ No newline at end of file |
@@ -12198,15 +12198,39 @@ | ||
12198 | 12198 | <string name="aware_summary_when_bedtime_on">Unavailable because bedtime mode is on</string> |
12199 | 12199 | |
12200 | 12200 | <!-- Bluetooth message permission alert for notification content [CHAR LIMIT=none] --> |
12201 | - <string name="bluetooth_message_access_notification_content">Untrusted device wants to access your messages. Tap for details.</string> | |
12201 | + <string name="bluetooth_message_access_notification_content">A device wants to access your messages. Tap for details.</string> | |
12202 | 12202 | <!-- Bluetooth message permission alert for dialog title [CHAR LIMIT=none] --> |
12203 | 12203 | <string name="bluetooth_message_access_dialog_title">Allow access to messages?</string> |
12204 | 12204 | <!-- Bluetooth message permission alert for dialog content [CHAR LIMIT=none] --> |
12205 | - <string name="bluetooth_message_access_dialog_content">An untrusted Bluetooth device, <xliff:g id="device_name" example="My device">%1$s</xliff:g>, wants to access your messages.\n\nYou haven\u2019t connected to <xliff:g id="device_name" example="My device">%2$s</xliff:g> before.</string> | |
12205 | + <string name="bluetooth_message_access_dialog_content">A Bluetooth device, <xliff:g id="device_name" example="My device">%1$s</xliff:g>, wants to access your messages.\n\nYou haven\u2019t connected to <xliff:g id="device_name" example="My device">%2$s</xliff:g> before.</string> | |
12206 | 12206 | <!-- Bluetooth phonebook permission alert for notification content [CHAR LIMIT=none] --> |
12207 | - <string name="bluetooth_phonebook_access_notification_content">Untrusted device wants to access your contacts and call log. Tap for details.</string> | |
12207 | + <string name="bluetooth_phonebook_access_notification_content">A device wants to access your contacts and call log. Tap for details.</string> | |
12208 | 12208 | <!-- Bluetooth phonebook permission alert for dialog title [CHAR LIMIT=none] --> |
12209 | 12209 | <string name="bluetooth_phonebook_access_dialog_title">Allow access to contacts and call log?</string> |
12210 | 12210 | <!-- Bluetooth phonebook permission alert for dialog content [CHAR LIMIT=none] --> |
12211 | - <string name="bluetooth_phonebook_access_dialog_content">An untrusted Bluetooth device, <xliff:g id="device_name" example="My device">%1$s</xliff:g>, wants to access your contacts and call log. This includes data about incoming and outgoing calls.\n\nYou haven\u2019t connected to <xliff:g id="device_name" example="My device">%2$s</xliff:g> before.</string> | |
12211 | + <string name="bluetooth_phonebook_access_dialog_content">A Bluetooth device, <xliff:g id="device_name" example="My device">%1$s</xliff:g>, wants to access your contacts and call log. This includes data about incoming and outgoing calls.\n\nYou haven\u2019t connected to <xliff:g id="device_name" example="My device">%2$s</xliff:g> before.</string> | |
12212 | + | |
12213 | + <!-- Label for button to not allow grant the permission for remote devices. [CHAR_LIMIT=50] --> | |
12214 | + <string name="request_manage_bluetooth_permission_dont_allow">Don\u2019t allow</string> | |
12215 | + | |
12216 | + <!-- Bluetooth sim card permission alert for notification title [CHAR LIMIT=none] --> | |
12217 | + <string name="bluetooth_sim_card_access_notification_title">SIM card access request</string> | |
12218 | + <!-- Bluetooth sim card permission alert for notification content [CHAR LIMIT=none] --> | |
12219 | + <string name="bluetooth_sim_card_access_notification_content">A device wants to access your SIM card. Tap for details.</string> | |
12220 | + <!-- Bluetooth sim card permission alert for dialog title [CHAR LIMIT=none] --> | |
12221 | + <string name="bluetooth_sim_card_access_dialog_title">Allow access to SIM card?</string> | |
12222 | + <!-- Bluetooth sim card permission alert for dialog content [CHAR LIMIT=none] --> | |
12223 | + <string name="bluetooth_sim_card_access_dialog_content">A Bluetooth device, <xliff:g id="device_name" example="My device">%1$s</xliff:g>, wants to access data on your SIM card. This includes your contacts.\n\nWhile connected, <xliff:g id="device_name" example="My device">%2$s</xliff:g> will receive all calls made to <xliff:g id="phone_number" example="0912345678">%3$s</xliff:g>.</string> | |
12224 | + <!-- Bluetooth connect permission alert for notification title [CHAR LIMIT=none] --> | |
12225 | + <string name="bluetooth_connect_access_notification_title">Bluetooth device available</string> | |
12226 | + <!-- Bluetooth connect permission alert for notification content [CHAR LIMIT=none] --> | |
12227 | + <string name="bluetooth_connect_access_notification_content">A device wants to connect. Tap for details.</string> | |
12228 | + <!-- Bluetooth connect permission alert for dialog title [CHAR LIMIT=none] --> | |
12229 | + <string name="bluetooth_connect_access_dialog_title">Connect to Bluetooth device?</string> | |
12230 | + <!-- Bluetooth connect permission alert for dialog content [CHAR LIMIT=none] --> | |
12231 | + <string name="bluetooth_connect_access_dialog_content"><xliff:g id="device_name" example="My device">%1$s</xliff:g> wants to connect to this phone.\n\nYou haven\u2019t connected to <xliff:g id="device_name" example="My device">%2$s</xliff:g> before.</string> | |
12232 | + <!-- Strings for Dialog don't connect button --> | |
12233 | + <string name="bluetooth_connect_access_dialog_negative">Don\u2019t connect</string> | |
12234 | + <!-- Strings for Dialog connect button --> | |
12235 | + <string name="bluetooth_connect_access_dialog_positive">Connect</string> | |
12212 | 12236 | </resources> |
@@ -102,7 +102,7 @@ public class DeviceAdminAdd extends Activity { | ||
102 | 102 | DevicePolicyManager mDPM; |
103 | 103 | AppOpsManager mAppOps; |
104 | 104 | DeviceAdminInfo mDeviceAdmin; |
105 | - CharSequence mAddMsgText; | |
105 | + String mAddMsgText; | |
106 | 106 | String mProfileOwnerName; |
107 | 107 | |
108 | 108 | ImageView mAdminIcon; |
@@ -274,7 +274,11 @@ public class DeviceAdminAdd extends Activity { | ||
274 | 274 | } |
275 | 275 | } |
276 | 276 | |
277 | - mAddMsgText = getIntent().getCharSequenceExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION); | |
277 | + final CharSequence addMsgCharSequence = getIntent().getCharSequenceExtra( | |
278 | + DevicePolicyManager.EXTRA_ADD_EXPLANATION); | |
279 | + if (addMsgCharSequence != null) { | |
280 | + mAddMsgText = addMsgCharSequence.toString(); | |
281 | + } | |
278 | 282 | |
279 | 283 | if (mAddingProfileOwner) { |
280 | 284 | // If we're trying to add a profile owner and user setup hasn't completed yet, no |
@@ -628,7 +632,7 @@ public class DeviceAdminAdd extends Activity { | ||
628 | 632 | } catch (Resources.NotFoundException e) { |
629 | 633 | mAdminDescription.setVisibility(View.GONE); |
630 | 634 | } |
631 | - if (mAddMsgText != null) { | |
635 | + if (!TextUtils.isEmpty(mAddMsgText)) { | |
632 | 636 | mAddMsg.setText(mAddMsgText); |
633 | 637 | mAddMsg.setVisibility(View.VISIBLE); |
634 | 638 | } else { |
@@ -16,6 +16,8 @@ | ||
16 | 16 | |
17 | 17 | package com.android.settings.bluetooth; |
18 | 18 | |
19 | +import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; | |
20 | + | |
19 | 21 | import android.bluetooth.BluetoothDevice; |
20 | 22 | import android.content.BroadcastReceiver; |
21 | 23 | import android.content.Context; |
@@ -23,6 +25,7 @@ import android.content.DialogInterface; | ||
23 | 25 | import android.content.Intent; |
24 | 26 | import android.content.IntentFilter; |
25 | 27 | import android.os.Bundle; |
28 | +import android.telephony.TelephonyManager; | |
26 | 29 | import android.util.Log; |
27 | 30 | import android.view.View; |
28 | 31 | import android.widget.Button; |
@@ -30,12 +33,11 @@ import android.widget.TextView; | ||
30 | 33 | |
31 | 34 | import androidx.preference.Preference; |
32 | 35 | |
36 | +import com.android.internal.annotations.VisibleForTesting; | |
33 | 37 | import com.android.internal.app.AlertActivity; |
34 | 38 | import com.android.internal.app.AlertController; |
35 | 39 | import com.android.settings.R; |
36 | 40 | |
37 | -import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; | |
38 | - | |
39 | 41 | /** |
40 | 42 | * BluetoothPermissionActivity shows a dialog for accepting incoming |
41 | 43 | * profile connection request from untrusted devices. |
@@ -51,8 +53,6 @@ public class BluetoothPermissionActivity extends AlertActivity implements | ||
51 | 53 | private TextView messageView; |
52 | 54 | private Button mOkButton; |
53 | 55 | private BluetoothDevice mDevice; |
54 | - private String mReturnPackage = null; | |
55 | - private String mReturnClass = null; | |
56 | 56 | |
57 | 57 | private int mRequestType = 0; |
58 | 58 | private BroadcastReceiver mReceiver = new BroadcastReceiver() { |
@@ -89,21 +89,19 @@ public class BluetoothPermissionActivity extends AlertActivity implements | ||
89 | 89 | } |
90 | 90 | |
91 | 91 | mDevice = i.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); |
92 | - mReturnPackage = i.getStringExtra(BluetoothDevice.EXTRA_PACKAGE_NAME); | |
93 | - mReturnClass = i.getStringExtra(BluetoothDevice.EXTRA_CLASS_NAME); | |
94 | 92 | mRequestType = i.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, |
95 | 93 | BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); |
96 | 94 | |
97 | 95 | if(DEBUG) Log.i(TAG, "onCreate() Request type: " + mRequestType); |
98 | 96 | |
99 | 97 | if (mRequestType == BluetoothDevice.REQUEST_TYPE_PROFILE_CONNECTION) { |
100 | - showDialog(getString(R.string.bluetooth_connection_permission_request), mRequestType); | |
98 | + showDialog(getString(R.string.bluetooth_connect_access_dialog_title), mRequestType); | |
101 | 99 | } else if (mRequestType == BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS) { |
102 | 100 | showDialog(getString(R.string.bluetooth_phonebook_access_dialog_title), mRequestType); |
103 | 101 | } else if (mRequestType == BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS) { |
104 | 102 | showDialog(getString(R.string.bluetooth_message_access_dialog_title), mRequestType); |
105 | 103 | } else if (mRequestType == BluetoothDevice.REQUEST_TYPE_SIM_ACCESS) { |
106 | - showDialog(getString(R.string.bluetooth_sap_request), mRequestType); | |
104 | + showDialog(getString(R.string.bluetooth_sim_card_access_dialog_title), mRequestType); | |
107 | 105 | } |
108 | 106 | else { |
109 | 107 | Log.e(TAG, "Error: bad request type: " + mRequestType); |
@@ -136,9 +134,14 @@ public class BluetoothPermissionActivity extends AlertActivity implements | ||
136 | 134 | p.mView = createSapDialogView(); |
137 | 135 | break; |
138 | 136 | } |
139 | - p.mPositiveButtonText = getString(R.string.allow); | |
137 | + p.mPositiveButtonText = getString( | |
138 | + requestType == BluetoothDevice.REQUEST_TYPE_PROFILE_CONNECTION | |
139 | + ? R.string.bluetooth_connect_access_dialog_positive : R.string.allow); | |
140 | 140 | p.mPositiveButtonListener = this; |
141 | - p.mNegativeButtonText = getString(R.string.deny); | |
141 | + p.mNegativeButtonText = getString( | |
142 | + requestType == BluetoothDevice.REQUEST_TYPE_PROFILE_CONNECTION | |
143 | + ? R.string.bluetooth_connect_access_dialog_negative | |
144 | + : R.string.request_manage_bluetooth_permission_dont_allow); | |
142 | 145 | p.mNegativeButtonListener = this; |
143 | 146 | mOkButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE); |
144 | 147 | setupAlert(); |
@@ -159,8 +162,8 @@ public class BluetoothPermissionActivity extends AlertActivity implements | ||
159 | 162 | String mRemoteName = Utils.createRemoteName(this, mDevice); |
160 | 163 | mView = getLayoutInflater().inflate(R.layout.bluetooth_access, null); |
161 | 164 | messageView = (TextView)mView.findViewById(R.id.message); |
162 | - messageView.setText(getString(R.string.bluetooth_connection_dialog_text, | |
163 | - mRemoteName)); | |
165 | + messageView.setText(getString(R.string.bluetooth_connect_access_dialog_content, | |
166 | + mRemoteName, mRemoteName)); | |
164 | 167 | return mView; |
165 | 168 | } |
166 | 169 |
@@ -184,10 +187,11 @@ public class BluetoothPermissionActivity extends AlertActivity implements | ||
184 | 187 | |
185 | 188 | private View createSapDialogView() { |
186 | 189 | String mRemoteName = Utils.createRemoteName(this, mDevice); |
190 | + TelephonyManager tm = getSystemService(TelephonyManager.class); | |
187 | 191 | mView = getLayoutInflater().inflate(R.layout.bluetooth_access, null); |
188 | 192 | messageView = (TextView)mView.findViewById(R.id.message); |
189 | - messageView.setText(getString(R.string.bluetooth_sap_acceptance_dialog_text, | |
190 | - mRemoteName, mRemoteName)); | |
193 | + messageView.setText(getString(R.string.bluetooth_sim_card_access_dialog_content, | |
194 | + mRemoteName, mRemoteName, tm.getLine1Number())); | |
191 | 195 | return mView; |
192 | 196 | } |
193 | 197 |
@@ -202,14 +206,14 @@ public class BluetoothPermissionActivity extends AlertActivity implements | ||
202 | 206 | sendReplyIntentToReceiver(false, true); |
203 | 207 | } |
204 | 208 | |
205 | - private void sendReplyIntentToReceiver(final boolean allowed, final boolean always) { | |
209 | + @VisibleForTesting | |
210 | + void sendReplyIntentToReceiver(final boolean allowed, final boolean always) { | |
206 | 211 | Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY); |
207 | 212 | |
208 | - if (mReturnPackage != null && mReturnClass != null) { | |
209 | - intent.setClassName(mReturnPackage, mReturnClass); | |
213 | + if (DEBUG) { | |
214 | + Log.i(TAG, "sendReplyIntentToReceiver() Request type: " + mRequestType | |
215 | + + " mReturnPackage"); | |
210 | 216 | } |
211 | - if (DEBUG) Log.i(TAG, "sendReplyIntentToReceiver() Request type: " + mRequestType + | |
212 | - " mReturnPackage" + mReturnPackage + " mReturnClass" + mReturnClass); | |
213 | 217 | |
214 | 218 | intent.putExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, |
215 | 219 | allowed ? BluetoothDevice.CONNECTION_ACCESS_YES |
@@ -56,8 +56,6 @@ public final class BluetoothPermissionRequest extends BroadcastReceiver { | ||
56 | 56 | Context mContext; |
57 | 57 | int mRequestType; |
58 | 58 | BluetoothDevice mDevice; |
59 | - String mReturnPackage = null; | |
60 | - String mReturnClass = null; | |
61 | 59 | |
62 | 60 | @Override |
63 | 61 | public void onReceive(Context context, Intent intent) { |
@@ -77,11 +75,10 @@ public final class BluetoothPermissionRequest extends BroadcastReceiver { | ||
77 | 75 | mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); |
78 | 76 | mRequestType = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, |
79 | 77 | BluetoothDevice.REQUEST_TYPE_PROFILE_CONNECTION); |
80 | - mReturnPackage = intent.getStringExtra(BluetoothDevice.EXTRA_PACKAGE_NAME); | |
81 | - mReturnClass = intent.getStringExtra(BluetoothDevice.EXTRA_CLASS_NAME); | |
82 | 78 | |
83 | - if (DEBUG) Log.d(TAG, "onReceive request type: " + mRequestType + " return " | |
84 | - + mReturnPackage + "," + mReturnClass); | |
79 | + if (DEBUG) { | |
80 | + Log.d(TAG, "onReceive request type: " + mRequestType); | |
81 | + } | |
85 | 82 | |
86 | 83 | // Even if the user has already made the choice, Bluetooth still may not know that if |
87 | 84 | // the user preference data have not been migrated from Settings app's shared |
@@ -110,8 +107,6 @@ public final class BluetoothPermissionRequest extends BroadcastReceiver { | ||
110 | 107 | connectionAccessIntent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, |
111 | 108 | mRequestType); |
112 | 109 | connectionAccessIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); |
113 | - connectionAccessIntent.putExtra(BluetoothDevice.EXTRA_PACKAGE_NAME, mReturnPackage); | |
114 | - connectionAccessIntent.putExtra(BluetoothDevice.EXTRA_CLASS_NAME, mReturnClass); | |
115 | 110 | |
116 | 111 | String deviceAddress = mDevice != null ? mDevice.getAddress() : null; |
117 | 112 | String deviceName = mDevice != null ? mDevice.getName() : null; |
@@ -149,13 +144,17 @@ public final class BluetoothPermissionRequest extends BroadcastReceiver { | ||
149 | 144 | R.string.bluetooth_message_access_notification_content); |
150 | 145 | break; |
151 | 146 | case BluetoothDevice.REQUEST_TYPE_SIM_ACCESS: |
152 | - title = context.getString(R.string.bluetooth_sap_request); | |
153 | - message = context.getString(R.string.bluetooth_sap_acceptance_dialog_text, | |
147 | + title = context.getString( | |
148 | + R.string.bluetooth_sim_card_access_notification_title); | |
149 | + message = context.getString( | |
150 | + R.string.bluetooth_sim_card_access_notification_content, | |
154 | 151 | deviceAlias, deviceAlias); |
155 | 152 | break; |
156 | 153 | default: |
157 | - title = context.getString(R.string.bluetooth_connection_permission_request); | |
158 | - message = context.getString(R.string.bluetooth_connection_dialog_text, | |
154 | + title = context.getString( | |
155 | + R.string.bluetooth_connect_access_notification_title); | |
156 | + message = context.getString( | |
157 | + R.string.bluetooth_connect_access_notification_content, | |
159 | 158 | deviceAlias, deviceAlias); |
160 | 159 | break; |
161 | 160 | } |
@@ -230,7 +229,7 @@ public final class BluetoothPermissionRequest extends BroadcastReceiver { | ||
230 | 229 | |
231 | 230 | LocalBluetoothManager bluetoothManager = Utils.getLocalBtManager(mContext); |
232 | 231 | CachedBluetoothDeviceManager cachedDeviceManager = |
233 | - bluetoothManager.getCachedDeviceManager(); | |
232 | + bluetoothManager.getCachedDeviceManager(); | |
234 | 233 | CachedBluetoothDevice cachedDevice = cachedDeviceManager.findDevice(mDevice); |
235 | 234 | if (cachedDevice == null) { |
236 | 235 | cachedDevice = cachedDeviceManager.addDevice(mDevice); |
@@ -288,13 +287,9 @@ public final class BluetoothPermissionRequest extends BroadcastReceiver { | ||
288 | 287 | private void sendReplyIntentToReceiver(final boolean allowed) { |
289 | 288 | Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY); |
290 | 289 | |
291 | - if (mReturnPackage != null && mReturnClass != null) { | |
292 | - intent.setClassName(mReturnPackage, mReturnClass); | |
293 | - } | |
294 | - | |
295 | 290 | intent.putExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, |
296 | - allowed ? BluetoothDevice.CONNECTION_ACCESS_YES | |
297 | - : BluetoothDevice.CONNECTION_ACCESS_NO); | |
291 | + allowed ? BluetoothDevice.CONNECTION_ACCESS_YES | |
292 | + : BluetoothDevice.CONNECTION_ACCESS_NO); | |
298 | 293 | intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); |
299 | 294 | intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, mRequestType); |
300 | 295 | mContext.sendBroadcast(intent, android.Manifest.permission.BLUETOOTH_ADMIN); |
@@ -16,6 +16,8 @@ | ||
16 | 16 | |
17 | 17 | package com.android.settings.bluetooth; |
18 | 18 | |
19 | +import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; | |
20 | + | |
19 | 21 | import android.os.Bundle; |
20 | 22 | |
21 | 23 | import androidx.fragment.app.FragmentActivity; |
@@ -31,6 +33,7 @@ public final class DevicePickerActivity extends FragmentActivity { | ||
31 | 33 | @Override |
32 | 34 | protected void onCreate(Bundle savedInstanceState) { |
33 | 35 | super.onCreate(savedInstanceState); |
36 | + getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); | |
34 | 37 | setContentView(R.layout.bluetooth_device_picker); |
35 | 38 | } |
36 | 39 | } |
@@ -27,12 +27,15 @@ import android.content.Context; | ||
27 | 27 | import android.content.Intent; |
28 | 28 | import android.os.Bundle; |
29 | 29 | import android.os.UserManager; |
30 | +import android.util.Log; | |
31 | +import android.text.TextUtils; | |
30 | 32 | import android.view.Menu; |
31 | 33 | import android.view.MenuInflater; |
32 | 34 | |
33 | 35 | import androidx.annotation.VisibleForTesting; |
34 | 36 | |
35 | 37 | import com.android.settings.R; |
38 | +import com.android.settings.password.PasswordUtils; | |
36 | 39 | import com.android.settingslib.bluetooth.CachedBluetoothDevice; |
37 | 40 | import com.android.settingslib.core.AbstractPreferenceController; |
38 | 41 |
@@ -48,10 +51,16 @@ public final class DevicePickerFragment extends DeviceListPreferenceFragment { | ||
48 | 51 | |
49 | 52 | @VisibleForTesting |
50 | 53 | BluetoothProgressCategory mAvailableDevicesCategory; |
54 | + @VisibleForTesting | |
55 | + Context mContext; | |
56 | + @VisibleForTesting | |
57 | + String mLaunchPackage; | |
58 | + @VisibleForTesting | |
59 | + String mLaunchClass; | |
60 | + @VisibleForTesting | |
61 | + String mCallingAppPackageName; | |
51 | 62 | |
52 | 63 | private boolean mNeedAuth; |
53 | - private String mLaunchPackage; | |
54 | - private String mLaunchClass; | |
55 | 64 | private boolean mScanAllowed; |
56 | 65 | |
57 | 66 | public DevicePickerFragment() { |
@@ -85,6 +94,13 @@ public final class DevicePickerFragment extends DeviceListPreferenceFragment { | ||
85 | 94 | getActivity().setTitle(getString(R.string.device_picker)); |
86 | 95 | UserManager um = (UserManager) getSystemService(Context.USER_SERVICE); |
87 | 96 | mScanAllowed = !um.hasUserRestriction(DISALLOW_CONFIG_BLUETOOTH); |
97 | + mCallingAppPackageName = PasswordUtils.getCallingAppPackageName( | |
98 | + getActivity().getActivityToken()); | |
99 | + if (!TextUtils.equals(mCallingAppPackageName, mLaunchPackage)) { | |
100 | + Log.w(TAG, "sendDevicePickedIntent() launch package name is not equivalent to" | |
101 | + + " calling package name!"); | |
102 | + } | |
103 | + mContext = getContext(); | |
88 | 104 | setHasOptionsMenu(true); |
89 | 105 | } |
90 | 106 |
@@ -191,8 +207,11 @@ public final class DevicePickerFragment extends DeviceListPreferenceFragment { | ||
191 | 207 | Intent intent = new Intent(BluetoothDevicePicker.ACTION_DEVICE_SELECTED); |
192 | 208 | intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); |
193 | 209 | if (mLaunchPackage != null && mLaunchClass != null) { |
194 | - intent.setClassName(mLaunchPackage, mLaunchClass); | |
210 | + if (TextUtils.equals(mCallingAppPackageName, mLaunchPackage)) { | |
211 | + intent.setClassName(mLaunchPackage, mLaunchClass); | |
212 | + } | |
195 | 213 | } |
196 | - getActivity().sendBroadcast(intent, Manifest.permission.BLUETOOTH_ADMIN); | |
214 | + | |
215 | + mContext.sendBroadcast(intent, Manifest.permission.BLUETOOTH_ADMIN); | |
197 | 216 | } |
198 | 217 | } |
@@ -25,12 +25,15 @@ import android.net.wifi.WifiManager; | ||
25 | 25 | import android.os.Bundle; |
26 | 26 | import android.os.Handler; |
27 | 27 | import android.os.Looper; |
28 | +import android.os.UserManager; | |
28 | 29 | import android.view.Menu; |
29 | 30 | import android.view.MenuInflater; |
30 | 31 | import android.view.MenuItem; |
31 | 32 | |
33 | +import androidx.annotation.VisibleForTesting; | |
34 | + | |
32 | 35 | import com.android.settings.R; |
33 | -import com.android.settings.dashboard.DashboardFragment; | |
36 | +import com.android.settings.dashboard.RestrictedDashboardFragment; | |
34 | 37 | import com.android.settings.wifi.WifiConfigUiBase; |
35 | 38 | import com.android.settings.wifi.WifiDialog; |
36 | 39 | import com.android.settingslib.RestrictedLockUtils; |
@@ -51,15 +54,45 @@ import java.util.List; | ||
51 | 54 | * future, please develop in |
52 | 55 | * {@link com.android.settings.wifi.details2.WifiNetworkDetailsFragment2}. |
53 | 56 | */ |
54 | -public class WifiNetworkDetailsFragment extends DashboardFragment implements | |
57 | +public class WifiNetworkDetailsFragment extends RestrictedDashboardFragment implements | |
55 | 58 | WifiDialog.WifiDialogListener { |
56 | 59 | |
57 | 60 | private static final String TAG = "WifiNetworkDetailsFrg"; |
58 | 61 | |
62 | + @VisibleForTesting | |
63 | + boolean mIsUiRestricted; | |
64 | + | |
59 | 65 | private AccessPoint mAccessPoint; |
60 | 66 | private WifiDetailPreferenceController mWifiDetailPreferenceController; |
61 | 67 | private List<WifiDialog.WifiDialogListener> mWifiDialogListeners = new ArrayList<>(); |
62 | 68 | |
69 | + public WifiNetworkDetailsFragment() { | |
70 | + super(UserManager.DISALLOW_CONFIG_WIFI); | |
71 | + } | |
72 | + | |
73 | + @Override | |
74 | + public void onCreate(Bundle icicle) { | |
75 | + super.onCreate(icicle); | |
76 | + setIfOnlyAvailableForAdmins(true); | |
77 | + mIsUiRestricted = isUiRestricted(); | |
78 | + } | |
79 | + | |
80 | + @Override | |
81 | + public void onStart() { | |
82 | + super.onStart(); | |
83 | + if (mIsUiRestricted) { | |
84 | + restrictUi(); | |
85 | + } | |
86 | + } | |
87 | + | |
88 | + @VisibleForTesting | |
89 | + void restrictUi() { | |
90 | + if (!isUiRestrictedByOnlyAdmin()) { | |
91 | + getEmptyTextView().setText(R.string.wifi_empty_list_user_restricted); | |
92 | + } | |
93 | + getPreferenceScreen().removeAll(); | |
94 | + } | |
95 | + | |
63 | 96 | @Override |
64 | 97 | public void onAttach(Context context) { |
65 | 98 | mAccessPoint = new AccessPoint(context, getArguments()); |
@@ -102,9 +135,11 @@ public class WifiNetworkDetailsFragment extends DashboardFragment implements | ||
102 | 135 | |
103 | 136 | @Override |
104 | 137 | public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { |
105 | - MenuItem item = menu.add(0, Menu.FIRST, 0, R.string.wifi_modify); | |
106 | - item.setIcon(com.android.internal.R.drawable.ic_mode_edit); | |
107 | - item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); | |
138 | + if (!mIsUiRestricted) { | |
139 | + MenuItem item = menu.add(0, Menu.FIRST, 0, R.string.wifi_modify); | |
140 | + item.setIcon(com.android.internal.R.drawable.ic_mode_edit); | |
141 | + item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); | |
142 | + } | |
108 | 143 | super.onCreateOptionsMenu(menu, inflater); |
109 | 144 | } |
110 | 145 |
@@ -0,0 +1,58 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2021 The Android Open Source Project | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | + | |
17 | +package com.android.settings.bluetooth; | |
18 | + | |
19 | +import static org.mockito.ArgumentMatchers.eq; | |
20 | +import static org.mockito.Mockito.spy; | |
21 | +import static org.mockito.Mockito.verify; | |
22 | + | |
23 | +import android.content.Context; | |
24 | +import android.content.Intent; | |
25 | + | |
26 | +import org.junit.Before; | |
27 | +import org.junit.Test; | |
28 | +import org.junit.runner.RunWith; | |
29 | +import org.mockito.ArgumentCaptor; | |
30 | +import org.mockito.MockitoAnnotations; | |
31 | +import org.robolectric.RobolectricTestRunner; | |
32 | +import org.robolectric.RuntimeEnvironment; | |
33 | +import org.robolectric.util.ReflectionHelpers; | |
34 | + | |
35 | +@RunWith(RobolectricTestRunner.class) | |
36 | +public class BluetoothPermissionActivityTest { | |
37 | + | |
38 | + private BluetoothPermissionActivity mActivity; | |
39 | + private Context mContext; | |
40 | + | |
41 | + @Before | |
42 | + public void setUp() { | |
43 | + MockitoAnnotations.initMocks(this); | |
44 | + mContext = spy(RuntimeEnvironment.application); | |
45 | + mActivity = new BluetoothPermissionActivity(); | |
46 | + } | |
47 | + | |
48 | + @Test | |
49 | + public void sendBroadcastWithPermission() { | |
50 | + final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); | |
51 | + ReflectionHelpers.setField(mActivity, "mBase", mContext); | |
52 | + | |
53 | + mActivity.sendReplyIntentToReceiver(true, true); | |
54 | + | |
55 | + verify(mContext).sendBroadcast(intentCaptor.capture(), | |
56 | + eq("android.permission.BLUETOOTH_ADMIN")); | |
57 | + } | |
58 | +} |
@@ -16,28 +16,46 @@ | ||
16 | 16 | |
17 | 17 | package com.android.settings.bluetooth; |
18 | 18 | |
19 | +import static com.google.common.truth.Truth.assertThat; | |
20 | + | |
21 | +import static org.mockito.ArgumentMatchers.eq; | |
22 | +import static org.mockito.Mockito.mock; | |
23 | +import static org.mockito.Mockito.never; | |
24 | +import static org.mockito.Mockito.spy; | |
19 | 25 | import static org.mockito.Mockito.verify; |
26 | +import static org.mockito.Mockito.when; | |
27 | + | |
28 | +import android.bluetooth.BluetoothDevice; | |
29 | +import android.content.Context; | |
30 | +import android.content.Intent; | |
31 | + | |
32 | +import com.android.settingslib.bluetooth.CachedBluetoothDevice; | |
20 | 33 | |
21 | 34 | import org.junit.Before; |
22 | 35 | import org.junit.Test; |
23 | 36 | import org.junit.runner.RunWith; |
37 | +import org.mockito.ArgumentCaptor; | |
24 | 38 | import org.mockito.Mock; |
25 | 39 | import org.mockito.MockitoAnnotations; |
26 | 40 | import org.robolectric.RobolectricTestRunner; |
41 | +import org.robolectric.RuntimeEnvironment; | |
27 | 42 | |
28 | 43 | @RunWith(RobolectricTestRunner.class) |
29 | 44 | public class DevicePickerFragmentTest { |
30 | 45 | |
31 | 46 | @Mock |
32 | 47 | private BluetoothProgressCategory mAvailableDevicesCategory; |
48 | + | |
33 | 49 | private DevicePickerFragment mFragment; |
50 | + private Context mContext; | |
34 | 51 | |
35 | 52 | @Before |
36 | 53 | public void setUp() { |
37 | 54 | MockitoAnnotations.initMocks(this); |
38 | 55 | |
39 | 56 | mFragment = new DevicePickerFragment(); |
40 | - | |
57 | + mContext = spy(RuntimeEnvironment.application); | |
58 | + mFragment.mContext = mContext; | |
41 | 59 | mFragment.mAvailableDevicesCategory = mAvailableDevicesCategory; |
42 | 60 | } |
43 | 61 |
@@ -49,4 +67,39 @@ public class DevicePickerFragmentTest { | ||
49 | 67 | |
50 | 68 | verify(mAvailableDevicesCategory).setProgress(true); |
51 | 69 | } |
70 | + | |
71 | + @Test | |
72 | + public void callingPackageIsEqualToLaunchPackage_sendBroadcastToLaunchPackage() { | |
73 | + final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class); | |
74 | + final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class); | |
75 | + final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); | |
76 | + when(cachedDevice.getDevice()).thenReturn(bluetoothDevice); | |
77 | + mFragment.mSelectedDevice = bluetoothDevice; | |
78 | + mFragment.mLaunchPackage = "com.android.settings"; | |
79 | + mFragment.mLaunchClass = "com.android.settings.bluetooth.BluetoothPermissionActivity"; | |
80 | + mFragment.mCallingAppPackageName = "com.android.settings"; | |
81 | + | |
82 | + mFragment.onDeviceBondStateChanged(cachedDevice, BluetoothDevice.BOND_BONDED); | |
83 | + | |
84 | + verify(mContext).sendBroadcast(intentCaptor.capture(), | |
85 | + eq("android.permission.BLUETOOTH_ADMIN")); | |
86 | + assertThat(intentCaptor.getValue().getComponent().getPackageName()) | |
87 | + .isEqualTo(mFragment.mLaunchPackage); | |
88 | + } | |
89 | + | |
90 | + @Test | |
91 | + public void callingPackageIsNotEqualToLaunchPackage_broadcastNotSend() { | |
92 | + final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class); | |
93 | + final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class); | |
94 | + final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); | |
95 | + when(cachedDevice.getDevice()).thenReturn(bluetoothDevice); | |
96 | + mFragment.mSelectedDevice = bluetoothDevice; | |
97 | + mFragment.mLaunchPackage = "com.fake.settings"; | |
98 | + mFragment.mLaunchClass = "com.android.settings.bluetooth.BluetoothPermissionActivity"; | |
99 | + mFragment.mCallingAppPackageName = "com.android.settings"; | |
100 | + | |
101 | + mFragment.onDeviceBondStateChanged(cachedDevice, BluetoothDevice.BOND_BONDED); | |
102 | + | |
103 | + verify(mContext, never()).sendBroadcast(intentCaptor.capture()); | |
104 | + } | |
52 | 105 | } |
@@ -0,0 +1,99 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2021 The Android Open Source Project | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | + | |
17 | +package com.android.settings.wifi.details; | |
18 | + | |
19 | +import static org.mockito.ArgumentMatchers.anyInt; | |
20 | +import static org.mockito.ArgumentMatchers.eq; | |
21 | +import static org.mockito.Mockito.doReturn; | |
22 | +import static org.mockito.Mockito.mock; | |
23 | +import static org.mockito.Mockito.never; | |
24 | +import static org.mockito.Mockito.spy; | |
25 | +import static org.mockito.Mockito.verify; | |
26 | + | |
27 | +import android.view.Menu; | |
28 | +import android.view.MenuInflater; | |
29 | +import android.widget.TextView; | |
30 | + | |
31 | +import androidx.preference.PreferenceScreen; | |
32 | + | |
33 | +import com.android.settings.R; | |
34 | + | |
35 | +import org.junit.Before; | |
36 | +import org.junit.Test; | |
37 | +import org.junit.runner.RunWith; | |
38 | +import org.mockito.Mock; | |
39 | +import org.mockito.MockitoAnnotations; | |
40 | +import org.robolectric.RobolectricTestRunner; | |
41 | + | |
42 | +@RunWith(RobolectricTestRunner.class) | |
43 | +public class WifiNetworkDetailsFragmentTest { | |
44 | + | |
45 | + @Mock | |
46 | + Menu mMenu; | |
47 | + private WifiNetworkDetailsFragment mFragment; | |
48 | + | |
49 | + @Before | |
50 | + public void setUp() { | |
51 | + MockitoAnnotations.initMocks(this); | |
52 | + mFragment = new WifiNetworkDetailsFragment(); | |
53 | + } | |
54 | + | |
55 | + @Test | |
56 | + public void onCreateOptionsMenu_uiRestricted_shouldNotAddEditMenu() { | |
57 | + mFragment.mIsUiRestricted = true; | |
58 | + | |
59 | + mFragment.onCreateOptionsMenu(mMenu, mock(MenuInflater.class)); | |
60 | + | |
61 | + verify(mMenu, never()).add(anyInt(), anyInt(), anyInt(), eq(R.string.wifi_modify)); | |
62 | + } | |
63 | + | |
64 | + @Test | |
65 | + public void restrictUi_shouldShowRestrictedText() { | |
66 | + final WifiNetworkDetailsFragmentTest.FakeFragment | |
67 | + fragment = spy(new WifiNetworkDetailsFragmentTest.FakeFragment()); | |
68 | + final PreferenceScreen screen = mock(PreferenceScreen.class); | |
69 | + final TextView restrictedText = mock(TextView.class); | |
70 | + doReturn(screen).when(fragment).getPreferenceScreen(); | |
71 | + doReturn(false).when(fragment).isUiRestrictedByOnlyAdmin(); | |
72 | + doReturn(restrictedText).when(fragment).getEmptyTextView(); | |
73 | + | |
74 | + fragment.restrictUi(); | |
75 | + | |
76 | + verify(restrictedText).setText(anyInt()); | |
77 | + } | |
78 | + | |
79 | + @Test | |
80 | + public void restrictUi_shouldRemoveAllPreferences() { | |
81 | + final WifiNetworkDetailsFragmentTest.FakeFragment | |
82 | + fragment = spy(new WifiNetworkDetailsFragmentTest.FakeFragment()); | |
83 | + final PreferenceScreen screen = mock(PreferenceScreen.class); | |
84 | + doReturn(screen).when(fragment).getPreferenceScreen(); | |
85 | + doReturn(true).when(fragment).isUiRestrictedByOnlyAdmin(); | |
86 | + | |
87 | + fragment.restrictUi(); | |
88 | + | |
89 | + verify(screen).removeAll(); | |
90 | + } | |
91 | + | |
92 | + // Fake WifiNetworkDetailsFragment to override the protected method as public. | |
93 | + public class FakeFragment extends WifiNetworkDetailsFragment { | |
94 | + @Override | |
95 | + public boolean isUiRestrictedByOnlyAdmin() { | |
96 | + return super.isUiRestrictedByOnlyAdmin(); | |
97 | + } | |
98 | + } | |
99 | +} | |
\ No newline at end of file |