From 9260c67352e9d7ef85617bddcd6f572210ed040f Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Fri, 19 May 2023 23:17:47 +0000 Subject: [PATCH 1/3] DO NOT MERGE: Prevent non-system IME from becoming device admin Currently selected IME can inject KeyEvent on DeviceAdminAdd screen to activate itself as device admin and cause various DoS attacks. This CL ensures KeyEvent on "Activate" button can only come from system apps. Bug: 280793427 Test: atest DeviceAdminActivationTest Change-Id: I6470d1684d707f4b1e86f8b456be0b4e0af5f188 (cherry picked from commit 70a501d02e0a6aefd874767a15378ba998759373) --- .../deviceadmin/DeviceAdminAdd.java | 131 +++++++++--------- 1 file changed, 69 insertions(+), 62 deletions(-) diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java index 1d45c518a6f..c43bde64a35 100644 --- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java +++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java @@ -66,6 +66,7 @@ import android.text.TextUtils.TruncateAt; import android.util.EventLog; import android.util.Log; import android.view.Display; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -155,12 +156,12 @@ public class DeviceAdminAdd extends CollapsingToolbarBaseActivity { mHandler = new Handler(getMainLooper()); - mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE); - mAppOps = (AppOpsManager)getSystemService(Context.APP_OPS_SERVICE); + mDPM = getSystemService(DevicePolicyManager.class); + mAppOps = getSystemService(AppOpsManager.class); mLayoutInflaternflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); PackageManager packageManager = getPackageManager(); - if ((getIntent().getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { + if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { Log.w(TAG, "Cannot start ADD_DEVICE_ADMIN as a new task"); finish(); return; @@ -170,7 +171,7 @@ public class DeviceAdminAdd extends CollapsingToolbarBaseActivity { EXTRA_CALLED_FROM_SUPPORT_DIALOG, false); String action = getIntent().getAction(); - ComponentName who = (ComponentName)getIntent().getParcelableExtra( + ComponentName who = (ComponentName) getIntent().getParcelableExtra( DevicePolicyManager.EXTRA_DEVICE_ADMIN); if (who == null) { String packageName = getIntent().getStringExtra(EXTRA_DEVICE_ADMIN_PACKAGE_NAME); @@ -226,7 +227,7 @@ public class DeviceAdminAdd extends CollapsingToolbarBaseActivity { PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS); int count = avail == null ? 0 : avail.size(); boolean found = false; - for (int i=0; i getString(R.string.device_admin_warning_simplified, - profileOwnerName), profileOwnerName)); + profileOwnerName), profileOwnerName)); return; } setContentView(R.layout.device_admin_add); - mAdminIcon = (ImageView)findViewById(R.id.admin_icon); - mAdminName = (TextView)findViewById(R.id.admin_name); - mAdminDescription = (TextView)findViewById(R.id.admin_description); + mAdminIcon = (ImageView) findViewById(R.id.admin_icon); + mAdminName = (TextView) findViewById(R.id.admin_name); + mAdminDescription = (TextView) findViewById(R.id.admin_description); mProfileOwnerWarning = (TextView) findViewById(R.id.profile_owner_warning); mProfileOwnerWarning.setText( mDPM.getResources().getString(SET_PROFILE_OWNER_POSTSETUP_WARNING, () -> getString(R.string.adding_profile_owner_warning))); - mAddMsg = (TextView)findViewById(R.id.add_msg); + mAddMsg = (TextView) findViewById(R.id.add_msg); mAddMsgExpander = (ImageView) findViewById(R.id.add_msg_expander); final View.OnClickListener onClickListener = new View.OnClickListener() { @Override @@ -380,7 +381,7 @@ public class DeviceAdminAdd extends CollapsingToolbarBaseActivity { boolean hideMsgExpander = mAddMsg.getLineCount() <= maxLines; mAddMsgExpander.setVisibility(hideMsgExpander ? View.GONE : View.VISIBLE); if (hideMsgExpander) { - ((View)mAddMsgExpander.getParent()).invalidate(); + ((View) mAddMsgExpander.getParent()).invalidate(); } mAddMsg.getViewTreeObserver().removeOnGlobalLayoutListener(this); } @@ -398,7 +399,7 @@ public class DeviceAdminAdd extends CollapsingToolbarBaseActivity { mCancelButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { EventLog.writeEvent(EventLogTags.EXP_DET_DEVICE_ADMIN_DECLINED_BY_USER, - mDeviceAdmin.getActivityInfo().applicationInfo.uid); + mDeviceAdmin.getActivityInfo().applicationInfo.uid); finish(); } }); @@ -420,58 +421,64 @@ public class DeviceAdminAdd extends CollapsingToolbarBaseActivity { final View restrictedAction = findViewById(R.id.restricted_action); restrictedAction.setFilterTouchesWhenObscured(true); - restrictedAction.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - if (!mActionButton.isEnabled()) { - showPolicyTransparencyDialogIfRequired(); - return; - } - if (mAdding) { - addAndFinish(); - } else if (isManagedProfile(mDeviceAdmin) - && mDeviceAdmin.getComponent().equals(mDPM.getProfileOwner())) { - final int userId = UserHandle.myUserId(); - UserDialogs.createRemoveDialog(DeviceAdminAdd.this, userId, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - UserManager um = UserManager.get(DeviceAdminAdd.this); - um.removeUser(userId); - finish(); - } - } - ).show(); - } else if (mUninstalling) { - mDPM.uninstallPackageWithActiveAdmins(mDeviceAdmin.getPackageName()); - finish(); - } else if (!mWaitingForRemoveMsg) { - try { - // Don't allow the admin to put a dialog up in front - // of us while we interact with the user. - ActivityManager.getService().stopAppSwitches(); - } catch (RemoteException e) { - } - mWaitingForRemoveMsg = true; - mDPM.getRemoveWarning(mDeviceAdmin.getComponent(), - new RemoteCallback(new RemoteCallback.OnResultListener() { - @Override - public void onResult(Bundle result) { - CharSequence msg = result != null - ? result.getCharSequence( - DeviceAdminReceiver.EXTRA_DISABLE_WARNING) - : null; - continueRemoveAction(msg); - } - }, mHandler)); - // Don't want to wait too long. - getWindow().getDecorView().getHandler().postDelayed(new Runnable() { - @Override public void run() { - continueRemoveAction(null); - } - }, 2*1000); - } + + final View.OnClickListener restrictedActionClickListener = v -> { + if (!mActionButton.isEnabled()) { + showPolicyTransparencyDialogIfRequired(); + return; } + if (mAdding) { + addAndFinish(); + } else if (isManagedProfile(mDeviceAdmin) + && mDeviceAdmin.getComponent().equals(mDPM.getProfileOwner())) { + final int userId = UserHandle.myUserId(); + UserDialogs.createRemoveDialog(DeviceAdminAdd.this, userId, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + UserManager um = UserManager.get(DeviceAdminAdd.this); + um.removeUser(userId); + finish(); + } + } + ).show(); + } else if (mUninstalling) { + mDPM.uninstallPackageWithActiveAdmins(mDeviceAdmin.getPackageName()); + finish(); + } else if (!mWaitingForRemoveMsg) { + try { + // Don't allow the admin to put a dialog up in front + // of us while we interact with the user. + ActivityManager.getService().stopAppSwitches(); + } catch (RemoteException e) { + } + mWaitingForRemoveMsg = true; + mDPM.getRemoveWarning(mDeviceAdmin.getComponent(), + new RemoteCallback(new RemoteCallback.OnResultListener() { + @Override + public void onResult(Bundle result) { + CharSequence msg = result != null + ? result.getCharSequence( + DeviceAdminReceiver.EXTRA_DISABLE_WARNING) + : null; + continueRemoveAction(msg); + } + }, mHandler)); + // Don't want to wait too long. + getWindow().getDecorView().getHandler().postDelayed( + () -> continueRemoveAction(null), 2 * 1000); + } + }; + restrictedAction.setOnKeyListener((view, keyCode, keyEvent) -> { + if ((keyEvent.getFlags() & KeyEvent.FLAG_FROM_SYSTEM) == 0) { + Log.e(TAG, "Can not activate device-admin with KeyEvent from non-system app."); + // Consume event to suppress click. + return true; + } + // Fallback to view click handler. + return false; }); + restrictedAction.setOnClickListener(restrictedActionClickListener); } /** From ac04ce9091230921a93807089e550ed50178ee15 Mon Sep 17 00:00:00 2001 From: jasonwshsu Date: Mon, 5 Jun 2023 17:01:03 +0800 Subject: [PATCH 2/3] Change the summary string to exclude 'Audio output' feature 'Audio output' plan to punt into U-QPR or V. Change the summary to not mention it. Bug: 286174797 Test: flash rom and check UI not exist Change-Id: I66ffb26c9b9ed612f41be7025a474cc63f256d87 --- res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index a72794dc4b5..66518049439 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -131,7 +131,7 @@ Hearing device settings - Audio output, shortcut, hearing aid compatibility + Shortcut, hearing aid compatibility For this device From b452bc9f9d9a23b8f3402326aa05fbd101930ab1 Mon Sep 17 00:00:00 2001 From: Han Xu Date: Fri, 9 Jun 2023 15:36:00 +0800 Subject: [PATCH 3/3] Add manufactured year into hardware info page Bug: 285471557 Test: manual visually Change-Id: Iaab254ac6ee77217e29d89524d782577f44119cb --- res/values/strings.xml | 2 ++ res/xml/hardware_info.xml | 9 ++++++ .../HardwareInfoFeatureProvider.kt | 26 +++++++++++++++ .../HardwareInfoFeatureProviderImpl.kt | 24 ++++++++++++++ .../ManufacturedYearPreferenceController.kt | 32 +++++++++++++++++++ .../settings/overlay/FeatureFactory.java | 6 ++++ .../settings/overlay/FeatureFactoryImpl.java | 7 ++++ .../testutils/FakeFeatureFactory.java | 7 ++++ .../settings/testutils/FakeFeatureFactory.kt | 5 +++ .../testutils/FakeFeatureFactory.java | 7 ++++ 10 files changed, 125 insertions(+) create mode 100644 src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFeatureProvider.kt create mode 100644 src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFeatureProviderImpl.kt create mode 100644 src/com/android/settings/deviceinfo/hardwareinfo/ManufacturedYearPreferenceController.kt diff --git a/res/values/strings.xml b/res/values/strings.xml index 1ba43d261f6..45b60265548 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2642,6 +2642,8 @@ Model Hardware version + + Manufactured year Equipment ID diff --git a/res/xml/hardware_info.xml b/res/xml/hardware_info.xml index 641f707a65e..e086a486ee0 100644 --- a/res/xml/hardware_info.xml +++ b/res/xml/hardware_info.xml @@ -48,4 +48,13 @@ settings:controller="com.android.settings.deviceinfo.hardwareinfo.HardwareRevisionPreferenceController" settings:enableCopying="true"/> + + + diff --git a/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFeatureProvider.kt b/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFeatureProvider.kt new file mode 100644 index 00000000000..400ece9a217 --- /dev/null +++ b/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFeatureProvider.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2023 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.deviceinfo.hardwareinfo + +/** + * Feature provider for hardware info + */ +interface HardwareInfoFeatureProvider { + /** + * Returns the manufactured year + */ + val manufacturedYear: String? +} \ No newline at end of file diff --git a/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFeatureProviderImpl.kt b/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFeatureProviderImpl.kt new file mode 100644 index 00000000000..54a112bec35 --- /dev/null +++ b/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFeatureProviderImpl.kt @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2023 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.deviceinfo.hardwareinfo + +/** + * Feature provider for hardware info + */ +object HardwareInfoFeatureProviderImpl : HardwareInfoFeatureProvider { + override val manufacturedYear: String? + get() = null +} \ No newline at end of file diff --git a/src/com/android/settings/deviceinfo/hardwareinfo/ManufacturedYearPreferenceController.kt b/src/com/android/settings/deviceinfo/hardwareinfo/ManufacturedYearPreferenceController.kt new file mode 100644 index 00000000000..0b0eeb750ec --- /dev/null +++ b/src/com/android/settings/deviceinfo/hardwareinfo/ManufacturedYearPreferenceController.kt @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 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.deviceinfo.hardwareinfo + +import android.content.Context +import com.android.settings.core.BasePreferenceController +import com.android.settings.overlay.FeatureFactory + +/** Preference controller for Manufactured Year. */ +class ManufacturedYearPreferenceController(context: Context, preferenceKey: String) : + BasePreferenceController(context, preferenceKey) { + private val year: String? = + FeatureFactory.getFactory(context).hardwareInfoFeatureProvider.manufacturedYear + + override fun getAvailabilityStatus(): Int = + if (!year.isNullOrEmpty()) AVAILABLE else UNSUPPORTED_ON_DEVICE + + override fun getSummary(): CharSequence = year ?: "" +} \ No newline at end of file diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java index a6d595810b3..c536a382b55 100644 --- a/src/com/android/settings/overlay/FeatureFactory.java +++ b/src/com/android/settings/overlay/FeatureFactory.java @@ -33,6 +33,7 @@ import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider; import com.android.settings.bluetooth.BluetoothFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; +import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider; import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider; import com.android.settings.fuelgauge.BatterySettingsFeatureProvider; import com.android.settings.fuelgauge.BatteryStatusFeatureProvider; @@ -109,6 +110,11 @@ public abstract class FeatureFactory { */ public abstract SuggestionFeatureProvider getSuggestionFeatureProvider(); + /** + * Retrieves implementation for Hardware Info feature. + */ + public abstract HardwareInfoFeatureProvider getHardwareInfoFeatureProvider(); + public abstract SupportFeatureProvider getSupportFeatureProvider(Context context); public abstract MetricsFeatureProvider getMetricsFeatureProvider(); diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java index 584e72a08c5..3ddda474b08 100644 --- a/src/com/android/settings/overlay/FeatureFactoryImpl.java +++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java @@ -47,6 +47,8 @@ import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProviderImpl; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl; +import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider; +import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProviderImpl; import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider; import com.android.settings.enterprise.EnterprisePrivacyFeatureProviderImpl; import com.android.settings.fuelgauge.BatterySettingsFeatureProvider; @@ -115,6 +117,11 @@ public class FeatureFactoryImpl extends FeatureFactory { private AdvancedVpnFeatureProvider mAdvancedVpnFeatureProvider; private WifiFeatureProvider mWifiFeatureProvider; + @Override + public HardwareInfoFeatureProvider getHardwareInfoFeatureProvider() { + return HardwareInfoFeatureProviderImpl.INSTANCE; + } + @Override public SupportFeatureProvider getSupportFeatureProvider(Context context) { return null; diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java index a17ce4f8608..29a6da372a2 100644 --- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java +++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java @@ -31,6 +31,8 @@ import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider; import com.android.settings.bluetooth.BluetoothFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; +import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider; +import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProviderImpl; import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider; import com.android.settings.fuelgauge.BatterySettingsFeatureProvider; import com.android.settings.fuelgauge.BatteryStatusFeatureProvider; @@ -287,6 +289,11 @@ public class FakeFeatureFactory extends FeatureFactory { return mAccessibilityMetricsFeatureProvider; } + @Override + public HardwareInfoFeatureProvider getHardwareInfoFeatureProvider() { + return HardwareInfoFeatureProviderImpl.INSTANCE; + } + @Override public AdvancedVpnFeatureProvider getAdvancedVpnFeatureProvider() { return mAdvancedVpnFeatureProvider; diff --git a/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt b/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt index da6e8231536..99d4f32b253 100644 --- a/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt +++ b/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt @@ -27,6 +27,7 @@ import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider import com.android.settings.bluetooth.BluetoothFeatureProvider import com.android.settings.dashboard.DashboardFeatureProvider import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider +import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider import com.android.settings.fuelgauge.BatterySettingsFeatureProvider import com.android.settings.fuelgauge.BatteryStatusFeatureProvider @@ -175,6 +176,10 @@ class FakeFeatureFactory : FeatureFactory() { TODO("Not yet implemented") } + override fun getHardwareInfoFeatureProvider(): HardwareInfoFeatureProvider { + TODO("Not yet implemented") + } + override fun getAdvancedVpnFeatureProvider(): AdvancedVpnFeatureProvider { TODO("Not yet implemented") } diff --git a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java index 0150b726544..697217bd332 100644 --- a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java +++ b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java @@ -29,6 +29,8 @@ import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider; import com.android.settings.bluetooth.BluetoothFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; +import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider; +import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProviderImpl; import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider; import com.android.settings.fuelgauge.BatterySettingsFeatureProvider; import com.android.settings.fuelgauge.BatteryStatusFeatureProvider; @@ -273,6 +275,11 @@ public class FakeFeatureFactory extends FeatureFactory { return mAccessibilityMetricsFeatureProvider; } + @Override + public HardwareInfoFeatureProvider getHardwareInfoFeatureProvider() { + return HardwareInfoFeatureProviderImpl.INSTANCE; + } + @Override public AdvancedVpnFeatureProvider getAdvancedVpnFeatureProvider() { return mAdvancedVpnFeatureProvider;