Settings: Add Leaf entries

Change-Id: I776d7c55802466c6a3d4cbdb2955d233d1d73246
diff --git a/res/drawable/leaf_logo.xml b/res/drawable/leaf_logo.xml
new file mode 100644
index 0000000..14088d7
--- /dev/null
+++ b/res/drawable/leaf_logo.xml
@@ -0,0 +1,3 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt" android:viewportWidth="140.2" android:viewportHeight="76.8" android:width="140.2dp" android:height="76.8dp">
+    <path android:pathData="M28.88 31.84C35.54 40 45.19 48.78 51 58.5c5.14 10.73 14.22 25.34 -3.33 13.65 -13.43 -6.58 -29.21 -10 -38.22 -22.22C0.3 42.26 -2.77 -3.82 2.74 0.25 24.46 11 48 9.35 60.23 23.48a40.75 40.75 0 0 1 8.15 14.85c2.81 7.88 5.2 -7.21 7.53 -9.22C79.66 22.69 85.58 18 92.06 14.8c14.06 -5.15 29.14 -7 42.88 -13.31 2.26 -1 4.25 -1.55 4.8 -0.43 1.28 18.32 0.77 39.76 -12.86 53.37C114.91 65.51 98 67.91 84.12 76.7c-3.83 1 -0.62 -5.45 0.17 -8 5.56 -16 17.39 -24.86 29.34 -37.27C85.69 39.75 77.73 81 73.41 67.29c-1.25 -2 -0.53 -7.12 -3.5 -7.3 -3.17 0.58 -2.27 13.27 -8.27 7.83C53.88 54 43.86 37.9 28.88 31.84Z" android:fillColor="?android:attr/colorAccent"/>
+</vector>
diff --git a/res/layout/leaf_logo_header.xml b/res/layout/leaf_logo_header.xml
new file mode 100644
index 0000000..4a88bbb
--- /dev/null
+++ b/res/layout/leaf_logo_header.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The LeafOS 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingLeft="16dp">
+
+    <ImageView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:layout_marginEnd="16dp"
+        android:src="@drawable/leaf_logo" />
+
+</LinearLayout>
diff --git a/res/values/leaf_strings.xml b/res/values/leaf_strings.xml
new file mode 100644
index 0000000..a0e370d
--- /dev/null
+++ b/res/values/leaf_strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2022 The LeafOS 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- About device -->
+    <string name="build_date">Build date</string>
+    <string name="leaf_version">LeafOS version</string>
+    <string name="leaf_vendor_security_patch">Vendor security patch level</string>
+</resources>
diff --git a/res/xml/firmware_version.xml b/res/xml/firmware_version.xml
index 41f7733..a095b14 100644
--- a/res/xml/firmware_version.xml
+++ b/res/xml/firmware_version.xml
@@ -21,6 +21,11 @@
     android:title="@string/firmware_version"
     settings:keywords="@string/keywords_android_version">
 
+    <com.android.settingslib.widget.LayoutPreference
+        android:key="pref_app_header"
+        android:layout="@layout/leaf_logo_header"
+        settings:allowDividerBelow="true"/>
+
     <!-- Android version -->
     <Preference
         android:key="os_firmware_version"
@@ -30,6 +35,14 @@
         settings:searchable="false"
         settings:controller="com.android.settings.deviceinfo.firmwareversion.FirmwareVersionDetailPreferenceController"/>
 
+    <!-- Leaf version -->
+    <Preference
+        android:key="leaf_version"
+        android:title="@string/leaf_version"
+        android:summary="@string/summary_placeholder"
+        settings:enableCopying="true"
+        settings:controller="com.android.settings.deviceinfo.firmwareversion.LeafVersionDetailPreferenceController"/>
+
     <!-- Security patch -->
     <Preference
         android:key="security_key"
@@ -37,6 +50,14 @@
         settings:enableCopying="true"
         settings:controller="com.android.settings.deviceinfo.firmwareversion.SecurityPatchLevelPreferenceController"/>
 
+    <!-- Vendor security patch -->
+    <Preference
+        android:key="vendor_security_key"
+        android:title="@string/leaf_vendor_security_patch"
+        android:selectable="false"
+        settings:enableCopying="true"
+        settings:controller="com.android.settings.deviceinfo.firmwareversion.LeafVendorSecurityPatchLevelPreferenceController"/>
+
     <!-- Mainline module version -->
     <Preference
         android:key="module_version"
@@ -63,6 +84,14 @@
         settings:enableCopying="true"
         settings:controller="com.android.settings.deviceinfo.firmwareversion.KernelVersionPreferenceController"/>
 
+    <!-- Build date -->
+    <Preference
+        android:key="os_build_date"
+        android:title="@string/build_date"
+        android:summary="@string/summary_placeholder"
+        settings:enableCopying="true"
+        settings:controller="com.android.settings.deviceinfo.firmwareversion.LeafBuildDatePreferenceController"/>
+
     <!-- Build -->
     <Preference
         android:key="os_build_number"
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/LeafBuildDatePreferenceController.java b/src/com/android/settings/deviceinfo/firmwareversion/LeafBuildDatePreferenceController.java
new file mode 100644
index 0000000..b448e32
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/LeafBuildDatePreferenceController.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 The LineageOS Project
+ * Copyright (C) 2022 The LeafOS 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.firmwareversion;
+
+import android.content.Context;
+import android.os.SystemProperties;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+
+public class LeafBuildDatePreferenceController extends BasePreferenceController {
+
+    private static final String TAG = "LeafBuildDateCtrl";
+
+    private static final String KEY_BUILD_DATE_PROP = "ro.build.date";
+
+    public LeafBuildDatePreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        return SystemProperties.get(KEY_BUILD_DATE_PROP,
+                mContext.getString(R.string.unknown));
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/LeafVendorSecurityPatchLevelPreferenceController.java b/src/com/android/settings/deviceinfo/firmwareversion/LeafVendorSecurityPatchLevelPreferenceController.java
new file mode 100644
index 0000000..0775817
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/LeafVendorSecurityPatchLevelPreferenceController.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 The LineageOS Project
+ * Copyright (C) 2022 The LeafOS 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.firmwareversion;
+
+import android.content.Context;
+import android.os.SystemProperties;
+import android.text.format.DateFormat;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+public class LeafVendorSecurityPatchLevelPreferenceController extends BasePreferenceController {
+
+    private static final String TAG = "LeafVendorSecurityPatchCtrl";
+
+    private static final String KEY_AOSP_VENDOR_SECURITY_PATCH =
+            "ro.vendor.build.security_patch";
+
+    public LeafVendorSecurityPatchLevelPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        String patchLevel = SystemProperties.get(KEY_AOSP_VENDOR_SECURITY_PATCH);
+
+        if (!patchLevel.isEmpty()) {
+            try {
+                SimpleDateFormat template = new SimpleDateFormat("yyyy-MM-dd");
+                Date patchLevelDate = template.parse(patchLevel);
+                String format = DateFormat.getBestDateTimePattern(Locale.getDefault(), "dMMMMyyyy");
+                patchLevel = DateFormat.format(format, patchLevelDate).toString();
+            } catch (ParseException e) {
+                // parsing failed, use raw string
+            }
+        } else {
+            patchLevel = mContext.getString(R.string.unknown);
+        }
+
+        return patchLevel;
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/LeafVersionDetailPreferenceController.java b/src/com/android/settings/deviceinfo/firmwareversion/LeafVersionDetailPreferenceController.java
new file mode 100644
index 0000000..9b9f7bb
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/LeafVersionDetailPreferenceController.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2019 The LineageOS Project
+ * Copyright (C) 2022 The LeafOS 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.firmwareversion;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.slices.Sliceable;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
+
+public class LeafVersionDetailPreferenceController extends BasePreferenceController {
+
+    private static final String TAG = "LeafVersionDialogCtrl";
+    private static final int DELAY_TIMER_MILLIS = 500;
+    private static final int ACTIVITY_TRIGGER_COUNT = 3;
+
+    private static final String KEY_LEAF_VERSION_PROP = "ro.leaf.display.version";
+
+    private static final String PLATLOGO_PACKAGE_NAME = "org.leafos.leafparts";
+    private static final String PLATLOGO_ACTIVITY_CLASS =
+            PLATLOGO_PACKAGE_NAME + ".logo.PlatLogoActivity";
+
+    private final UserManager mUserManager;
+    private final long[] mHits = new long[ACTIVITY_TRIGGER_COUNT];
+
+    private RestrictedLockUtils.EnforcedAdmin mFunDisallowedAdmin;
+    private boolean mFunDisallowedBySystem;
+
+    public LeafVersionDetailPreferenceController(Context context, String key) {
+        super(context, key);
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        initializeAdminPermissions();
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public boolean useDynamicSliceSummary() {
+        return true;
+    }
+
+    @Override
+    public boolean isSliceable() {
+        return true;
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        return SystemProperties.get(KEY_LEAF_VERSION_PROP,
+                mContext.getString(R.string.unknown));
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
+            return false;
+        }
+        if (Utils.isMonkeyRunning()) {
+            return false;
+        }
+        arrayCopy();
+        mHits[mHits.length - 1] = SystemClock.uptimeMillis();
+        if (mHits[0] >= (SystemClock.uptimeMillis() - DELAY_TIMER_MILLIS)) {
+            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_FUN)) {
+                if (mFunDisallowedAdmin != null && !mFunDisallowedBySystem) {
+                    RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext,
+                            mFunDisallowedAdmin);
+                }
+                Log.d(TAG, "Sorry, no fun for you!");
+                return true;
+            }
+
+            final Intent intent = new Intent(Intent.ACTION_MAIN)
+                     .setClassName(PLATLOGO_PACKAGE_NAME, PLATLOGO_ACTIVITY_CLASS);
+            try {
+                mContext.startActivity(intent);
+            } catch (Exception e) {
+                Log.e(TAG, "Unable to start activity " + intent.toString());
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Copies the array onto itself to remove the oldest hit.
+     */
+    @VisibleForTesting
+    void arrayCopy() {
+        System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);
+    }
+
+    @VisibleForTesting
+    void initializeAdminPermissions() {
+        mFunDisallowedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
+                mContext, UserManager.DISALLOW_FUN, UserHandle.myUserId());
+        mFunDisallowedBySystem = RestrictedLockUtilsInternal.hasBaseUserRestriction(
+                mContext, UserManager.DISALLOW_FUN, UserHandle.myUserId());
+    }
+}