diff --git a/res/drawable/security_dialog_corners.xml b/res/drawable/security_dialog_corners.xml new file mode 100644 index 00000000000..648d1658fce --- /dev/null +++ b/res/drawable/security_dialog_corners.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/res/layout/security_dialog_layout.xml b/res/layout/security_dialog_layout.xml new file mode 100644 index 00000000000..db08f824426 --- /dev/null +++ b/res/layout/security_dialog_layout.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values/du_strings.xml b/res/values/du_strings.xml index 65445b47b1c..12ce82fa488 100644 --- a/res/values/du_strings.xml +++ b/res/values/du_strings.xml @@ -15,6 +15,15 @@ --> + + https://source.android.com/security/bulletin/2018-04-01 + Security updates + AOSP Security Bulletins + AOSP security patch level + Android security updates are a collection of patches to the Android platform and the vendor binaries that help it run. Since these binaries are closed source, we have to rely on the vendors to supply them to the OEMs and the OEMs to ship them to users so we can add them to our builds. As we cannot control this process at all, we want to make it clear that we only update the security patch level in the repos that come from the Android Open Source Project. Generally, the vendor security patch level will be whatever patch level the latest stock ROM is on. + Functional updates + In addition to AOSP security updates, we include Google\'s functional updates. These are patches that Google push in addition to security updates for Pixel devices to address functionality issues such as connectivity, stability, and performance. Since we support more than just Pixel devices, they are included for all our devices. + It\u2019s on the back of your phone. Use any finger. diff --git a/res/values/du_styles.xml b/res/values/du_styles.xml index 5733da64f2b..e2c47780b03 100644 --- a/res/values/du_styles.xml +++ b/res/values/du_styles.xml @@ -17,4 +17,9 @@ + diff --git a/res/xml/device_info_settings.xml b/res/xml/device_info_settings.xml index 7a79f5bc645..e22574a1a12 100644 --- a/res/xml/device_info_settings.xml +++ b/res/xml/device_info_settings.xml @@ -82,13 +82,19 @@ android:title="@string/firmware_version" android:summary="@string/summary_placeholder"/> + + + - - + buildPreferenceControllers(Con controllers.add(new FirmwareVersionPreferenceController(context, lifecycle)); //controllers.add(new RegulatoryInfoPreferenceController(context)); controllers.add(new DeviceModelPreferenceController(context, fragment)); + controllers.add(new SecurityDialogPreferenceController(context, fragment)); controllers.add(new SecurityPatchPreferenceController(context)); controllers.add(new FccEquipmentIdPreferenceController(context)); controllers.add(new SELinuxStatusPreferenceController(context)); diff --git a/src/com/android/settings/deviceinfo/SecurityDialogFragment.java b/src/com/android/settings/deviceinfo/SecurityDialogFragment.java new file mode 100644 index 00000000000..2dfc1d5842d --- /dev/null +++ b/src/com/android/settings/deviceinfo/SecurityDialogFragment.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.deviceinfo; + +import android.annotation.SuppressLint; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.ActivityNotFoundException; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.net.Uri; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.DialogFragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.Window; +import android.widget.TextView; + +import com.android.internal.logging.nano.MetricsProto; +import com.android.settings.R; +import com.android.settings.core.instrumentation.InstrumentedDialogFragment; +import com.android.settingslib.DeviceInfoUtils; + +public class SecurityDialogFragment extends InstrumentedDialogFragment { + + public static final String TAG = "SecurityDialogTag"; + + public static SecurityDialogFragment newInstance() { + return new SecurityDialogFragment(); + } + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), + R.style.SecurityDialog); + + @SuppressLint("InflateParams") final View content = LayoutInflater.from(builder.getContext()) + .inflate(R.layout.security_dialog_layout, null /* parent */); + + TextView mSecurityPatch = content.findViewById(R.id.security_patch_level_text); + mSecurityPatch.setText(DeviceInfoUtils.getSecurityPatch()); + + builder.setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + builder.setNeutralButton(getString(R.string.security_dialog_neutral_button), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + try { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.aosp_security_bulletin_url))); + startActivity(intent); + } catch (ActivityNotFoundException e) { + e.printStackTrace(); + } + } + }); + if (getDialog() != null && getDialog().getWindow() != null) { + getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); + } + return builder.setView(content).create(); + } + + @Override + public int getMetricsCategory() { + return MetricsProto.MetricsEvent.DIRTYTWEAKS; + } +} diff --git a/src/com/android/settings/deviceinfo/SecurityDialogPreferenceController.java b/src/com/android/settings/deviceinfo/SecurityDialogPreferenceController.java new file mode 100644 index 00000000000..0b6002efb42 --- /dev/null +++ b/src/com/android/settings/deviceinfo/SecurityDialogPreferenceController.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.deviceinfo; + +import android.app.Fragment; +import android.content.Context; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.text.TextUtils; + +import com.android.settings.R; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settings.deviceinfo.SecurityDialogFragment; +import com.android.settingslib.DeviceInfoUtils; +import com.android.settingslib.core.AbstractPreferenceController; + +public class SecurityDialogPreferenceController extends AbstractPreferenceController implements + PreferenceControllerMixin { + + private static final String TAG = "SecurityDialogTag"; + private static final String KEY_SECURITY_DIALOG = "security_dialog"; + + private final Fragment mHost; + + public SecurityDialogPreferenceController(Context context, Fragment host) { + super(context); + mHost = host; + } + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public String getPreferenceKey() { + return KEY_SECURITY_DIALOG; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + final Preference pref = screen.findPreference(KEY_SECURITY_DIALOG); + if (pref == null) return; + pref.setSummary(DeviceInfoUtils.getSecurityPatch()); + } + + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + if (TextUtils.equals(preference.getKey(), KEY_SECURITY_DIALOG)) { + SecurityDialogFragment fragment = SecurityDialogFragment.newInstance(); + fragment.show(mHost.getFragmentManager(), SecurityDialogFragment.TAG); + return true; + } + return false; + } +}