Merge tag 'android-security-11.0.0_r54' into int/11/fp3

Android security 11.0.0 release 54

* tag 'android-security-11.0.0_r54':
  Do not write past end of inotify event structure.

Change-Id: Ib4ba1194f4948e13e0e6f89f4c5488ccc3960d52
diff --git a/NOTICE b/NOTICE
index c5b1efa..8874ff1 100644
--- a/NOTICE
+++ b/NOTICE
@@ -9,7 +9,32 @@
    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.
+________________________________________________________________________________
 
+  DRM based mode setting test program
+  Copyright 2008 Tungsten Graphics
+    Jakob Bornecrantz <jakob@tungstengraphics.com>
+  Copyright 2008 Intel Corporation
+    Jesse Barnes <jesse.barnes@intel.com>
+
+  Permission is hereby granted, free of charge, to any person obtaining a
+  copy of this software and associated documentation files (the "Software"),
+  to deal in the Software without restriction, including without limitation
+  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+  and/or sell copies of the Software, and to permit persons to whom the
+  Software is furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+  IN THE SOFTWARE.
+________________________________________________________________________________
 
                                  Apache License
                            Version 2.0, January 2004
diff --git a/install/Android.bp b/install/Android.bp
index bed3bc5..f927088 100644
--- a/install/Android.bp
+++ b/install/Android.bp
@@ -23,6 +23,7 @@
         "libbase",
         "libbootloader_message",
         "libcrypto",
+        "libcutils",
         "libext4_utils",
         "libfs_mgr",
         "libfusesideload",
diff --git a/install/fuse_install.cpp b/install/fuse_install.cpp
index 143b5d3..91d5d1b 100644
--- a/install/fuse_install.cpp
+++ b/install/fuse_install.cpp
@@ -30,8 +30,10 @@
 #include <string>
 #include <vector>
 
+#include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/strings.h>
+#include <cutils/properties.h>
 
 #include "bootloader_message/bootloader_message.h"
 #include "fuse_provider.h"
@@ -39,6 +41,11 @@
 #include "install/install.h"
 #include "recovery_utils/roots.h"
 
+#define MMC_0_TYPE_PATH "/sys/block/mmcblk0/device/type"
+#define SDCARD_BLK_0_PATH "/dev/block/mmcblk0p1"
+#define MMC_1_TYPE_PATH "/sys/block/mmcblk1/device/type"
+#define SDCARD_BLK_1_PATH "/dev/block/mmcblk1p1"
+
 static constexpr const char* SDCARD_ROOT = "/sdcard";
 // How long (in seconds) we wait for the fuse-provided package file to
 // appear, before timing out.
@@ -204,10 +211,79 @@
   return result;
 }
 
+// Check whether the mmc type of provided path (/sys/block/mmcblk*/device/type)
+// is SD (sdcard) or not.
+static int check_mmc_is_sdcard (const char* mmc_type_path)
+{
+  std::string mmc_type;
+
+  LOG(INFO) << "Checking mmc type for path : " << mmc_type_path;
+
+  if (!android::base::ReadFileToString(mmc_type_path, &mmc_type)) {
+    LOG(ERROR) << "Failed to read mmc type : " << strerror(errno);
+    return -1;
+  }
+  LOG(INFO) << "MMC type is : " << mmc_type.c_str();
+  if (!strncmp(mmc_type.c_str(), "SD", strlen("SD")))
+    return 0;
+  else
+    return -1;
+}
+
+// Gather mount point and other info from fstab, find the right block
+// path where sdcard is mounted, and try mounting it.
+static int do_sdcard_mount() {
+  int rc = 0;
+
+  Volume *v = volume_for_mount_point("/sdcard");
+  if (v == nullptr) {
+    LOG(ERROR) << "Unknown volume for /sdcard. Check fstab\n";
+    goto error;
+  }
+  if (strncmp(v->fs_type.c_str(), "vfat", sizeof("vfat"))) {
+    LOG(ERROR) << "Unsupported format on the sdcard: "
+               << v->fs_type.c_str() << "\n";
+    goto error;
+  }
+
+  if (check_mmc_is_sdcard(MMC_0_TYPE_PATH) == 0) {
+    LOG(INFO) << "Mounting sdcard on " << SDCARD_BLK_0_PATH;
+    rc = mount(SDCARD_BLK_0_PATH,
+               v->mount_point.c_str(),
+               v->fs_type.c_str(),
+               v->flags,
+               v->fs_options.c_str());
+  }
+  else if (check_mmc_is_sdcard(MMC_1_TYPE_PATH) == 0) {
+    LOG(INFO) << "Mounting sdcard on " << SDCARD_BLK_1_PATH;
+    rc = mount(SDCARD_BLK_1_PATH,
+               v->mount_point.c_str(),
+               v->fs_type.c_str(),
+               v->flags,
+               v->fs_options.c_str());
+  }
+  else {
+    LOG(ERROR) << "Unable to get the block path for sdcard.";
+    goto error;
+  }
+
+  if (rc) {
+    LOG(ERROR) << "Failed to mount sdcard: " << strerror(errno) << "\n";
+    goto error;
+  }
+  LOG(INFO) << "Done mounting sdcard\n";
+  return 0;
+
+error:
+  return -1;
+}
+
 InstallResult ApplyFromSdcard(Device* device) {
   auto ui = device->GetUI();
-  if (ensure_path_mounted(SDCARD_ROOT) != 0) {
-    LOG(ERROR) << "\n-- Couldn't mount " << SDCARD_ROOT << ".\n";
+  ui->Print("Update via sdcard. Mounting sdcard\n");
+
+  if (do_sdcard_mount() != 0) {
+    LOG(ERROR) << "\nFailed to mount sdcard\n";
     return INSTALL_ERROR;
   }
 
diff --git a/install/install.cpp b/install/install.cpp
index d404997..5829c11 100644
--- a/install/install.cpp
+++ b/install/install.cpp
@@ -694,7 +694,9 @@
   }
 
   constexpr const char* CACHE_ROOT = "/cache";
-  if (android::base::StartsWith(package_path, CACHE_ROOT)) {
+  constexpr const char* DATA_ROOT = "/data";
+  if (android::base::StartsWith(package_path, CACHE_ROOT) ||
+      android::base::StartsWith(package_path, DATA_ROOT)) {
     *should_use_fuse = false;
   }
   return true;
diff --git a/minadbd/Android.bp b/minadbd/Android.bp
index 4cdcac6..b6ca59e 100644
--- a/minadbd/Android.bp
+++ b/minadbd/Android.bp
@@ -135,4 +135,5 @@
     test_suites: [
         "device-tests",
     ],
+    require_root: true,
 }
diff --git a/minadbd/AndroidTest.xml b/minadbd/AndroidTest.xml
index 7ea235b..dbcbac2 100644
--- a/minadbd/AndroidTest.xml
+++ b/minadbd/AndroidTest.xml
@@ -18,9 +18,10 @@
         <option name="cleanup" value="true" />
         <option name="push" value="minadbd_test->/data/local/tmp/minadbd_test" />
     </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
     <option name="test-suite-tag" value="apct" />
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="minadbd_test" />
     </test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/minui/graphics_drm.cpp b/minui/graphics_drm.cpp
index 95759e3..17ab00a 100644
--- a/minui/graphics_drm.cpp
+++ b/minui/graphics_drm.cpp
@@ -14,8 +14,35 @@
  * limitations under the License.
  */
 
+/*
+ * DRM based mode setting test program
+ * Copyright 2008 Tungsten Graphics
+ *   Jakob Bornecrantz <jakob@tungstengraphics.com>
+ * Copyright 2008 Intel Corporation
+ *   Jesse Barnes <jesse.barnes@intel.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
 #include "graphics_drm.h"
 
+#include <errno.h>
 #include <fcntl.h>
 #include <poll.h>
 #include <stdio.h>
@@ -29,12 +56,256 @@
 #include <android-base/macros.h>
 #include <android-base/stringprintf.h>
 #include <android-base/unique_fd.h>
+#include <string>
 #include <drm_fourcc.h>
 #include <xf86drm.h>
 #include <xf86drmMode.h>
+#include <sstream>
 
 #include "minui/minui.h"
 
+#define find_prop_id(_res, type, Type, obj_id, prop_name, prop_id)    \
+  do {                                                                \
+    int j = 0;                                                        \
+    int prop_count = 0;                                               \
+    struct Type *obj = NULL;                                          \
+    obj = (_res);                                                     \
+    if (!obj || main_monitor_##type->type##_id != (obj_id)){          \
+      prop_id = 0;                                                    \
+      break;                                                          \
+    }                                                                 \
+    prop_count = (int)obj->props->count_props;                        \
+    for (j = 0; j < prop_count; ++j)                                  \
+      if (!strcmp(obj->props_info[j]->name, (prop_name)))             \
+        break;                                                        \
+    (prop_id) = (j == prop_count)?                                    \
+      0 : obj->props_info[j]->prop_id;                                \
+  } while (0)
+
+#define add_prop(res, type, Type, id, id_name, id_val) \
+  find_prop_id(res, type, Type, id, id_name, prop_id); \
+  if (prop_id)                                         \
+    drmModeAtomicAddProperty(atomic_req, id, prop_id, id_val);
+
+/**
+ * enum sde_rm_topology_name - HW resource use case in use by connector
+ * @SDE_RM_TOPOLOGY_NONE:                 No topology in use currently
+ * @SDE_RM_TOPOLOGY_SINGLEPIPE:           1 LM, 1 PP, 1 INTF/WB
+ * @SDE_RM_TOPOLOGY_SINGLEPIPE_DSC:       1 LM, 1 DSC, 1 PP, 1 INTF/WB
+ * @SDE_RM_TOPOLOGY_SINGLEPIPE_VDC:       1 LM, 1 VDC, 1 PP, 1 INTF/WB
+ * @SDE_RM_TOPOLOGY_DUALPIPE:             2 LM, 2 PP, 2 INTF/WB
+ * @SDE_RM_TOPOLOGY_DUALPIPE_DSC:         2 LM, 2 DSC, 2 PP, 2 INTF/WB
+ * @SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE:     2 LM, 2 PP, 3DMux, 1 INTF/WB
+ * @SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC: 2 LM, 2 PP, 3DMux, 1 DSC, 1 INTF/WB
+ * @SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_VDC: 2 LM, 2 PP, 3DMux, 1 VDC, 1 INTF/WB
+ * @SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE:    2 LM, 2 PP, 2 DSC Merge, 1 INTF/WB
+ * @SDE_RM_TOPOLOGY_PPSPLIT:              1 LM, 2 PPs, 2 INTF/WB
+ * @SDE_RM_TOPOLOGY_QUADPIPE_3DMERGE      4 LM, 4 PP, 3DMux, 2 INTF
+ * @SDE_RM_TOPOLOGY_QUADPIPE_3DMERGE_DSC  4 LM, 4 PP, 3DMux, 3 DSC, 2 INTF
+ * @SDE_RM_TOPOLOGY_QUADPIPE_DSCMERE      4 LM, 4 PP, 4 DSC Merge, 2 INTF
+ * @SDE_RM_TOPOLOGY_QUADPIPE_DSC4HSMERGE  4 LM, 4 PP, 4 DSC Merge, 1 INTF
+ */
+
+static uint32_t get_lm_number(const std::string &topology) {
+  if (topology == "sde_singlepipe") return 1;
+  if (topology == "sde_singlepipe_dsc") return 1;
+  if (topology == "sde_singlepipe_vdc") return 1;
+  if (topology == "sde_dualpipe") return 2;
+  if (topology == "sde_dualpipe_dsc") return 2;
+  if (topology == "sde_dualpipe_vdc") return 2;
+  if (topology == "sde_dualpipemerge") return 2;
+  if (topology == "sde_dualpipemerge_dsc") return 2;
+  if (topology == "sde_dualpipemerge_vdc") return 2;
+  if (topology == "sde_dualpipe_dscmerge") return 2;
+  if (topology == "sde_ppsplit") return 1;
+  if (topology == "sde_quadpipemerge") return 4;
+  if (topology == "sde_quadpipe_3dmerge_dsc") return 4;
+  if (topology == "sde_quadpipe_dscmerge") return 4;
+  if (topology == "sde_quadpipe_dsc4hsmerge") return 4;
+  return DEFAULT_NUM_LMS;
+}
+
+static uint32_t get_topology_lm_number(int fd, uint32_t blob_id) {
+  uint32_t num_lm = DEFAULT_NUM_LMS;
+
+  drmModePropertyBlobRes *blob = drmModeGetPropertyBlob(fd, blob_id);
+  if (!blob) {
+    return num_lm;
+  }
+
+  const char *fmt_str = (const char *)(blob->data);
+  std::stringstream stream(fmt_str);
+  std::string line = {};
+  const std::string topology = "topology=";
+
+  while (std::getline(stream, line)) {
+    if (line.find(topology) != std::string::npos) {
+        num_lm = get_lm_number(std::string(line, topology.length()));
+        break;
+    }
+  }
+
+  drmModeFreePropertyBlob(blob);
+  return num_lm;
+}
+
+static int find_plane_prop_id(uint32_t obj_id, const char *prop_name,
+                              Plane *plane_res) {
+  int i, j = 0;
+  int prop_count = 0;
+  struct Plane *obj = NULL;
+
+  for (i = 0; i < NUM_PLANES; ++i) {
+    obj = &plane_res[i];
+    if (!obj || obj->plane->plane_id != obj_id)
+      continue;
+    prop_count = (int)obj->props->count_props;
+    for (j = 0; j < prop_count; ++j)
+      if (!strcmp(obj->props_info[j]->name, prop_name))
+       return obj->props_info[j]->prop_id;
+    break;
+  }
+
+  return 0;
+}
+
+static int atomic_add_prop_to_plane(Plane *plane_res, drmModeAtomicReq *req,
+                                    uint32_t obj_id, const char *prop_name,
+                                    uint64_t value) {
+  uint32_t prop_id;
+
+  prop_id = find_plane_prop_id(obj_id, prop_name, plane_res);
+  if (prop_id == 0) {
+    printf("Could not find obj_id = %d\n", obj_id);
+    return -EINVAL;
+  }
+
+  if (drmModeAtomicAddProperty(req, obj_id, prop_id, value) < 0) {
+    printf("Could not add prop_id = %d for obj_id %d\n",
+            prop_id, obj_id);
+    return -EINVAL;
+  }
+
+  return 0;
+}
+
+int MinuiBackendDrm::AtomicPopulatePlane(int plane, drmModeAtomicReqPtr atomic_req) {
+  uint32_t src_x, src_y, src_w, src_h;
+  uint32_t crtc_x, crtc_y, crtc_w, crtc_h;
+  int width = main_monitor_crtc->mode.hdisplay;
+  int height = main_monitor_crtc->mode.vdisplay;
+  int zpos = 0;
+
+  src_y = 0;
+  src_w = width/number_of_lms;
+  src_h =  height;
+  crtc_y = 0;
+  crtc_w = width/number_of_lms;
+  crtc_h = height;
+  src_x = (width/number_of_lms) * plane;
+  crtc_x = (width/number_of_lms) * plane;
+
+  /* populate z-order property required for 4 layer mixer */
+  if (number_of_lms == 4)
+    zpos = plane >> 1;
+
+  atomic_add_prop_to_plane(plane_res, atomic_req,
+                           plane_res[plane].plane->plane_id, "zpos", zpos);
+
+  if (atomic_add_prop_to_plane(plane_res, atomic_req,
+                               plane_res[plane].plane->plane_id, "FB_ID",
+                               GRSurfaceDrms[current_buffer]->fb_id))
+    return -EINVAL;
+
+  if (atomic_add_prop_to_plane(plane_res, atomic_req,
+                               plane_res[plane].plane->plane_id, "SRC_X", src_x << 16))
+    return -EINVAL;
+
+  if (atomic_add_prop_to_plane(plane_res, atomic_req,
+                               plane_res[plane].plane->plane_id, "SRC_Y", src_y << 16))
+    return -EINVAL;
+
+  if (atomic_add_prop_to_plane(plane_res, atomic_req,
+                               plane_res[plane].plane->plane_id, "SRC_W", src_w << 16))
+    return -EINVAL;
+
+  if (atomic_add_prop_to_plane(plane_res, atomic_req,
+                               plane_res[plane].plane->plane_id, "SRC_H", src_h << 16))
+    return -EINVAL;
+
+  if (atomic_add_prop_to_plane(plane_res, atomic_req,
+                               plane_res[plane].plane->plane_id, "CRTC_X", crtc_x))
+    return -EINVAL;
+
+  if (atomic_add_prop_to_plane(plane_res, atomic_req,
+                               plane_res[plane].plane->plane_id, "CRTC_Y", crtc_y))
+    return -EINVAL;
+
+  if (atomic_add_prop_to_plane(plane_res, atomic_req,
+                               plane_res[plane].plane->plane_id, "CRTC_W", crtc_w))
+    return -EINVAL;
+
+  if (atomic_add_prop_to_plane(plane_res, atomic_req,
+                               plane_res[plane].plane->plane_id, "CRTC_H", crtc_h))
+    return -EINVAL;
+
+  if (atomic_add_prop_to_plane(plane_res, atomic_req,
+                               plane_res[plane].plane->plane_id, "CRTC_ID",
+                               main_monitor_crtc->crtc_id))
+    return -EINVAL;
+
+  return 0;
+}
+
+int MinuiBackendDrm::TeardownPipeline(drmModeAtomicReqPtr atomic_req) {
+  uint32_t i, prop_id;
+  int ret;
+
+  /* During suspend, tear down pipeline */
+  add_prop(&conn_res, connector, Connector, main_monitor_connector->connector_id, "CRTC_ID", 0);
+  add_prop(&crtc_res, crtc, Crtc, main_monitor_crtc->crtc_id, "MODE_ID", 0);
+  add_prop(&crtc_res, crtc, Crtc, main_monitor_crtc->crtc_id, "ACTIVE", 0);
+
+  for(i = 0; i < number_of_lms; i++) {
+    ret = atomic_add_prop_to_plane(plane_res, atomic_req,
+                                   plane_res[i].plane->plane_id, "CRTC_ID", 0);
+    if (ret < 0) {
+      printf("Failed to tear down plane %d\n", i);
+      return ret;
+    }
+
+    if (drmModeAtomicAddProperty(atomic_req, plane_res[i].plane->plane_id, fb_prop_id, 0) < 0) {
+      printf("Failed to add property for plane_id=%d\n", plane_res[i].plane->plane_id);
+      return -EINVAL;
+    }
+  }
+
+  return 0;
+}
+
+int MinuiBackendDrm::SetupPipeline(drmModeAtomicReqPtr atomic_req) {
+  uint32_t i, prop_id;
+  int ret;
+
+  for(i = 0; i < number_of_lms; i++) {
+    add_prop(&conn_res, connector, Connector, main_monitor_connector->connector_id,
+         "CRTC_ID", main_monitor_crtc->crtc_id);
+    add_prop(&crtc_res, crtc, Crtc, main_monitor_crtc->crtc_id, "MODE_ID", crtc_res.mode_blob_id);
+    add_prop(&crtc_res, crtc, Crtc, main_monitor_crtc->crtc_id, "ACTIVE", 1);
+  }
+
+  /* Setup planes */
+  for(i = 0; i < number_of_lms; i++) {
+    ret = AtomicPopulatePlane(i, atomic_req);
+    if (ret < 0) {
+      printf("Error populating plane_id = %d\n", plane_res[i].plane->plane_id);
+      return ret;
+    }
+  }
+
+  return 0;
+}
+
 GRSurfaceDrm::~GRSurfaceDrm() {
   if (mmapped_buffer_) {
     munmap(mmapped_buffer_, row_bytes * height);
@@ -138,35 +409,40 @@
   return surface;
 }
 
-void MinuiBackendDrm::DrmDisableCrtc(int drm_fd, drmModeCrtc* crtc) {
-  if (crtc) {
-    drmModeSetCrtc(drm_fd, crtc->crtc_id,
-                   0,         // fb_id
-                   0, 0,      // x,y
-                   nullptr,   // connectors
-                   0,         // connector_count
-                   nullptr);  // mode
-  }
+int MinuiBackendDrm::DrmDisableCrtc(drmModeAtomicReqPtr atomic_req) {
+  return TeardownPipeline(atomic_req);
 }
 
-bool MinuiBackendDrm::DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc,
-                                    const std::unique_ptr<GRSurfaceDrm>& surface) {
-  if (drmModeSetCrtc(drm_fd, crtc->crtc_id, surface->fb_id, 0, 0,  // x,y
-                     &main_monitor_connector->connector_id,
-                     1,  // connector_count
-                     &main_monitor_crtc->mode) != 0) {
-    perror("Failed to drmModeSetCrtc");
-    return false;
-  }
-  return true;
+int MinuiBackendDrm::DrmEnableCrtc(drmModeAtomicReqPtr atomic_req){
+  return SetupPipeline(atomic_req);
 }
 
 void MinuiBackendDrm::Blank(bool blank) {
-  if (blank) {
-    DrmDisableCrtc(drm_fd, main_monitor_crtc);
-  } else {
-    DrmEnableCrtc(drm_fd, main_monitor_crtc, GRSurfaceDrms[current_buffer]);
+  int ret = 0;
+
+  if (blank == current_blank_state)
+    return;
+
+  drmModeAtomicReqPtr atomic_req = drmModeAtomicAlloc();
+  if (!atomic_req) {
+     printf("Atomic Alloc failed\n");
+     return;
   }
+
+  if (blank)
+    ret = DrmDisableCrtc(atomic_req);
+  else
+    ret = DrmEnableCrtc(atomic_req);
+
+  if (!ret)
+    ret = drmModeAtomicCommit(drm_fd, atomic_req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+  if (!ret) {
+    printf("Atomic Commit failed, rc = %d\n", ret);
+    current_blank_state = blank;
+  }
+
+  drmModeAtomicFree(atomic_req);
 }
 
 static drmModeCrtc* find_crtc_for_connector(int fd, drmModeRes* resources,
@@ -272,20 +548,68 @@
 }
 
 void MinuiBackendDrm::DisableNonMainCrtcs(int fd, drmModeRes* resources, drmModeCrtc* main_crtc) {
+  uint32_t prop_id;
+  drmModeAtomicReqPtr atomic_req = drmModeAtomicAlloc();
+
   for (int i = 0; i < resources->count_connectors; i++) {
     drmModeConnector* connector = drmModeGetConnector(fd, resources->connectors[i]);
     drmModeCrtc* crtc = find_crtc_for_connector(fd, resources, connector);
     if (crtc->crtc_id != main_crtc->crtc_id) {
-      DrmDisableCrtc(fd, crtc);
+      // Switching to atomic commit. Given only crtc, we can only set ACTIVE = 0
+      // to disable any Nonmain CRTCs
+      find_prop_id(&crtc_res, crtc, Crtc, crtc->crtc_id, "ACTIVE", prop_id);
+      if (prop_id == 0)
+        return;
+
+      if (drmModeAtomicAddProperty(atomic_req, main_monitor_crtc->crtc_id, prop_id, 0) < 0)
+        return;
     }
     drmModeFreeCrtc(crtc);
   }
+
+  if (!drmModeAtomicCommit(drm_fd, atomic_req,DRM_MODE_ATOMIC_ALLOW_MODESET, NULL))
+    printf("Atomic Commit failed in DisableNonMainCrtcs\n");
+
+  drmModeAtomicFree(atomic_req);
+}
+
+void MinuiBackendDrm::UpdatePlaneFB() {
+  uint32_t i, prop_id;
+
+  /* Set atomic req */
+  drmModeAtomicReqPtr atomic_req = drmModeAtomicAlloc();
+  if (!atomic_req) {
+     printf("Atomic Alloc failed. Could not update fb_id\n");
+     return;
+  }
+
+  /* Add conn-crtc association property required
+   * for driver to recognize quadpipe topology.
+   */
+  add_prop(&conn_res, connector, Connector, main_monitor_connector->connector_id,
+           "CRTC_ID", main_monitor_crtc->crtc_id);
+
+  /* Add property */
+  for(i = 0; i < number_of_lms; i++)
+    drmModeAtomicAddProperty(atomic_req, plane_res[i].plane->plane_id,
+                             fb_prop_id, GRSurfaceDrms[current_buffer]->fb_id);
+
+  /* Commit changes */
+  int32_t ret;
+  ret = drmModeAtomicCommit(drm_fd, atomic_req,
+                 DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+  drmModeAtomicFree(atomic_req);
+
+  if (ret)
+    printf("Atomic commit failed ret=%d\n", ret);
 }
 
 GRSurface* MinuiBackendDrm::Init() {
   drmModeRes* res = nullptr;
   drm_fd = -1;
 
+  number_of_lms = DEFAULT_NUM_LMS;
   /* Consider DRM devices in order. */
   for (int i = 0; i < DRM_MAX_MINOR; i++) {
     auto dev_name = android::base::StringPrintf(DRM_DEV_NAME, DRM_DIR_NAME, i);
@@ -353,58 +677,111 @@
 
   current_buffer = 0;
 
-  // We will likely encounter errors in the backend functions (i.e. Flip) if EnableCrtc fails.
-  if (!DrmEnableCrtc(drm_fd, main_monitor_crtc, GRSurfaceDrms[1])) {
-    return nullptr;
+  drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+  drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1);
+
+  /* Get possible plane_ids */
+  drmModePlaneRes *plane_options = drmModeGetPlaneResources(drm_fd);
+  if (!plane_options || !plane_options->planes || (plane_options->count_planes < number_of_lms))
+    return NULL;
+
+  /* Set crtc resources */
+  crtc_res.props = drmModeObjectGetProperties(drm_fd,
+                      main_monitor_crtc->crtc_id,
+                      DRM_MODE_OBJECT_CRTC);
+  if (!crtc_res.props)
+    return NULL;
+
+  crtc_res.props_info = static_cast<drmModePropertyRes **>
+                           (calloc(crtc_res.props->count_props,
+                           sizeof(crtc_res.props_info)));
+  if (!crtc_res.props_info)
+    return NULL;
+  else
+    for (int j = 0; j < (int)crtc_res.props->count_props; ++j)
+      crtc_res.props_info[j] = drmModeGetProperty(drm_fd,
+                                   crtc_res.props->props[j]);
+
+  /* Set connector resources */
+  conn_res.props = drmModeObjectGetProperties(drm_fd,
+                     main_monitor_connector->connector_id,
+                     DRM_MODE_OBJECT_CONNECTOR);
+  if (!conn_res.props)
+    return NULL;
+
+  conn_res.props_info = static_cast<drmModePropertyRes **>
+                         (calloc(conn_res.props->count_props,
+                         sizeof(conn_res.props_info)));
+  if (!conn_res.props_info)
+    return NULL;
+  else {
+    for (int j = 0; j < (int)conn_res.props->count_props; ++j) {
+
+      conn_res.props_info[j] = drmModeGetProperty(drm_fd,
+                                 conn_res.props->props[j]);
+
+      /* Get preferred mode information and extract the
+       * number of layer mixers needed from the topology name.
+       */
+      if (!strcmp(conn_res.props_info[j]->name, "mode_properties")) {
+        number_of_lms = get_topology_lm_number(drm_fd, conn_res.props->prop_values[j]);
+        printf("number of lms in topology %d\n", number_of_lms);
+      }
+    }
   }
 
+  /* Set plane resources */
+  for(uint32_t i = 0; i < number_of_lms; ++i) {
+    plane_res[i].plane = drmModeGetPlane(drm_fd, plane_options->planes[i]);
+    if (!plane_res[i].plane)
+      return NULL;
+  }
+
+  for (uint32_t i = 0; i < number_of_lms; ++i) {
+    struct Plane *obj = &plane_res[i];
+    unsigned int j;
+    obj->props = drmModeObjectGetProperties(drm_fd, obj->plane->plane_id,
+                    DRM_MODE_OBJECT_PLANE);
+    if (!obj->props)
+      continue;
+    obj->props_info = static_cast<drmModePropertyRes **>
+                         (calloc(obj->props->count_props, sizeof(*obj->props_info)));
+    if (!obj->props_info)
+      continue;
+    for (j = 0; j < obj->props->count_props; ++j)
+      obj->props_info[j] = drmModeGetProperty(drm_fd, obj->props->props[j]);
+  }
+
+  drmModeFreePlaneResources(plane_options);
+  plane_options = NULL;
+
+  /* Setup pipe and blob_id */
+  if (drmModeCreatePropertyBlob(drm_fd, &main_monitor_crtc->mode, sizeof(drmModeModeInfo),
+      &crtc_res.mode_blob_id)) {
+    printf("failed to create mode blob\n");
+    return NULL;
+  }
+
+  /* Save fb_prop_id*/
+  uint32_t prop_id;
+  prop_id = find_plane_prop_id(plane_res[0].plane->plane_id, "FB_ID", plane_res);
+  fb_prop_id = prop_id;
+
+  Blank(false);
+
   return GRSurfaceDrms[0].get();
 }
 
-static void page_flip_complete(__unused int fd,
-                               __unused unsigned int sequence,
-                               __unused unsigned int tv_sec,
-                               __unused unsigned int tv_usec,
-                               void *user_data) {
-  *static_cast<bool*>(user_data) = false;
-}
-
 GRSurface* MinuiBackendDrm::Flip() {
-  bool ongoing_flip = true;
-  if (drmModePageFlip(drm_fd, main_monitor_crtc->crtc_id, GRSurfaceDrms[current_buffer]->fb_id,
-                      DRM_MODE_PAGE_FLIP_EVENT, &ongoing_flip) != 0) {
-    perror("Failed to drmModePageFlip");
-    return nullptr;
-  }
-
-  while (ongoing_flip) {
-    struct pollfd fds = {
-      .fd = drm_fd,
-      .events = POLLIN
-    };
-
-    if (poll(&fds, 1, -1) == -1 || !(fds.revents & POLLIN)) {
-      perror("Failed to poll() on drm fd");
-      break;
-    }
-
-    drmEventContext evctx = {
-      .version = DRM_EVENT_CONTEXT_VERSION,
-      .page_flip_handler = page_flip_complete
-    };
-
-    if (drmHandleEvent(drm_fd, &evctx) != 0) {
-      perror("Failed to drmHandleEvent");
-      break;
-    }
-  }
+  UpdatePlaneFB();
 
   current_buffer = 1 - current_buffer;
   return GRSurfaceDrms[current_buffer].get();
 }
 
 MinuiBackendDrm::~MinuiBackendDrm() {
-  DrmDisableCrtc(drm_fd, main_monitor_crtc);
+  Blank(true);
+  drmModeDestroyPropertyBlob(drm_fd, crtc_res.mode_blob_id);
   drmModeFreeCrtc(main_monitor_crtc);
   drmModeFreeConnector(main_monitor_connector);
   close(drm_fd);
diff --git a/minui/graphics_drm.h b/minui/graphics_drm.h
index 57ba39b..d048283 100644
--- a/minui/graphics_drm.h
+++ b/minui/graphics_drm.h
@@ -26,6 +26,27 @@
 #include "graphics.h"
 #include "minui/minui.h"
 
+#define NUM_MAIN 1
+#define NUM_PLANES 4
+#define DEFAULT_NUM_LMS 2
+
+struct Crtc {
+  drmModeObjectProperties *props;
+  drmModePropertyRes **props_info;
+  uint32_t mode_blob_id;
+};
+
+struct Connector {
+  drmModeObjectProperties *props;
+  drmModePropertyRes **props_info;
+};
+
+struct Plane {
+  drmModePlane *plane;
+  drmModeObjectProperties *props;
+  drmModePropertyRes ** props_info;
+};
+
 class GRSurfaceDrm : public GRSurface {
  public:
   ~GRSurfaceDrm() override;
@@ -61,14 +82,24 @@
   void Blank(bool) override;
 
  private:
-  void DrmDisableCrtc(int drm_fd, drmModeCrtc* crtc);
-  bool DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc, const std::unique_ptr<GRSurfaceDrm>& surface);
+  int DrmDisableCrtc(drmModeAtomicReqPtr atomic_req);
+  int DrmEnableCrtc(drmModeAtomicReqPtr atomic_req);
   void DisableNonMainCrtcs(int fd, drmModeRes* resources, drmModeCrtc* main_crtc);
   drmModeConnector* FindMainMonitor(int fd, drmModeRes* resources, uint32_t* mode_index);
+  int SetupPipeline(drmModeAtomicReqPtr atomic_req);
+  int TeardownPipeline(drmModeAtomicReqPtr atomic_req);
+  void UpdatePlaneFB();
+  int AtomicPopulatePlane(int plane, drmModeAtomicReqPtr atomic_req);
 
   std::unique_ptr<GRSurfaceDrm> GRSurfaceDrms[2];
   int current_buffer{ 0 };
   drmModeCrtc* main_monitor_crtc{ nullptr };
   drmModeConnector* main_monitor_connector{ nullptr };
   int drm_fd{ -1 };
+  bool current_blank_state = true;
+  int fb_prop_id;
+  struct Crtc crtc_res;
+  struct Connector conn_res;
+  struct Plane plane_res[NUM_PLANES];
+  uint32_t number_of_lms;
 };
diff --git a/recovery.cpp b/recovery.cpp
index 7675121..ed2d5d4 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -26,6 +26,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
+#include <sys/mount.h>
+#include <fs_mgr.h>
+#include <time.h>
 #include <unistd.h>
 
 #include <functional>
@@ -53,6 +56,7 @@
 #include "install/wipe_data.h"
 #include "install/wipe_device.h"
 #include "otautil/boot_state.h"
+#include "otautil/dirutil.h"
 #include "otautil/error_code.h"
 #include "otautil/paths.h"
 #include "otautil/sysutil.h"
@@ -62,13 +66,18 @@
 #include "recovery_utils/logging.h"
 #include "recovery_utils/roots.h"
 
+static constexpr const char* CACHE_LOG_DIR = "/cache/recovery";
 static constexpr const char* COMMAND_FILE = "/cache/recovery/command";
 static constexpr const char* LAST_KMSG_FILE = "/cache/recovery/last_kmsg";
 static constexpr const char* LAST_LOG_FILE = "/cache/recovery/last_log";
 static constexpr const char* LOCALE_FILE = "/cache/recovery/last_locale";
-
 static constexpr const char* CACHE_ROOT = "/cache";
 
+#define MMC_0_TYPE_PATH "/sys/block/mmcblk0/device/type"
+#define SDCARD_BLK_0_PATH "/dev/block/mmcblk0p1"
+#define MMC_1_TYPE_PATH "/sys/block/mmcblk1/device/type"
+#define SDCARD_BLK_1_PATH "/dev/block/mmcblk1p1"
+
 static bool save_current_log = false;
 
 /*
@@ -310,6 +319,75 @@
   ui->ShowText(true);
 }
 
+// Check whether the mmc type of provided path (/sys/block/mmcblk*/device/type)
+// is SD (sdcard) or not.
+static int check_mmc_is_sdcard (const char* mmc_type_path)
+{
+  std::string mmc_type;
+
+  LOG(INFO) << "Checking mmc type for path : " << mmc_type_path;
+
+  if (!android::base::ReadFileToString(mmc_type_path, &mmc_type)) {
+    LOG(ERROR) << "Failed to read mmc type : " << strerror(errno);
+    return -1;
+  }
+  LOG(INFO) << "MMC type is : " << mmc_type.c_str();
+  if (!strncmp(mmc_type.c_str(), "SD", strlen("SD")))
+    return 0;
+  else
+    return -1;
+}
+
+// Gather mount point and other info from fstab, find the right block
+// path where sdcard is mounted, and try mounting it.
+static int do_sdcard_mount(RecoveryUI* ui)
+{
+  int rc = 0;
+  ui->Print("Update via sdcard. Mounting sdcard\n");
+  Volume *v = volume_for_mount_point("/sdcard");
+  if (v == nullptr) {
+          ui->Print("Unknown volume for /sdcard. Check fstab\n");
+          goto error;
+  }
+  if (strncmp(v->fs_type.c_str(), "vfat", sizeof("vfat"))) {
+          ui->Print("Unsupported format on the sdcard: %s\n",
+                          v->fs_type.c_str());
+          goto error;
+  }
+
+  if (check_mmc_is_sdcard(MMC_0_TYPE_PATH) == 0) {
+    LOG(INFO) << "Mounting sdcard on " << SDCARD_BLK_0_PATH;
+    rc = mount(SDCARD_BLK_0_PATH,
+               v->mount_point.c_str(),
+               v->fs_type.c_str(),
+               v->flags,
+               v->fs_options.c_str());
+  }
+  else if (check_mmc_is_sdcard(MMC_1_TYPE_PATH) == 0) {
+    LOG(INFO) << "Mounting sdcard on " << SDCARD_BLK_1_PATH;
+    rc = mount(SDCARD_BLK_1_PATH,
+               v->mount_point.c_str(),
+               v->fs_type.c_str(),
+               v->flags,
+               v->fs_options.c_str());
+  }
+  else {
+    LOG(ERROR) << "Unable to get the block path for sdcard.";
+    goto error;
+  }
+
+  if (rc) {
+          ui->Print("Failed to mount sdcard : %s\n",
+                          strerror(errno));
+          goto error;
+  }
+  ui->Print("Done mounting sdcard\n");
+  return 0;
+
+error:
+  return -1;
+}
+
 static void WriteUpdateInProgress() {
   std::string err;
   if (!update_bootloader_message({ "--reason=update_in_progress" }, &err)) {
@@ -630,6 +708,16 @@
   std::string locale;
 
   auto args_to_parse = StringVectorToNullTerminatedArray(args);
+  InstallResult status = INSTALL_SUCCESS;
+
+
+  if (HasCache() && ensure_path_mounted(CACHE_ROOT) == 0) {
+  //Create /cache/recovery specifically if it is not created
+  //As in cases where device is booted into recovery directly after
+  //flashing recovery folder is not created in init
+    // TODO(b/140199946) Check what to pass for selabel_handle argument.
+    mkdir_recursively(CACHE_LOG_DIR, 0777, false, nullptr);
+  }
 
   int arg;
   int option_index;
@@ -686,6 +774,10 @@
   }
   optind = 1;
 
+  // next_action indicates the next target to reboot into upon finishing the install. It could be
+  // overridden to a different reboot target per user request.
+  Device::BuiltinAction next_action = shutdown_after ? Device::SHUTDOWN : Device::REBOOT;
+
   printf("stage is [%s]\n", device->GetStage().value_or("").c_str());
   printf("reason is [%s]\n", device->GetReason().value_or("").c_str());
 
@@ -715,14 +807,18 @@
   }
   printf("\n\n");
 
+   if (update_package) {
+        if (!strncmp("/sdcard", update_package, 7)) {
+            if(do_sdcard_mount(ui) != 0) {
+                status = INSTALL_ERROR;
+                goto error;
+            }
+        }
+    }
+
   property_list(print_property, nullptr);
   printf("\n");
 
-  InstallResult status = INSTALL_SUCCESS;
-  // next_action indicates the next target to reboot into upon finishing the install. It could be
-  // overridden to a different reboot target per user request.
-  Device::BuiltinAction next_action = shutdown_after ? Device::SHUTDOWN : Device::REBOOT;
-
   if (update_package != nullptr) {
     // It's not entirely true that we will modify the flash. But we want
     // to log the update attempt since update_package is non-NULL.
@@ -847,6 +943,7 @@
     ui->SetBackground(RecoveryUI::NO_COMMAND);
   }
 
+error:
   if (status == INSTALL_ERROR || status == INSTALL_CORRUPT) {
     ui->SetBackground(RecoveryUI::ERROR);
     if (!ui->IsTextVisible()) {
diff --git a/recovery_main.cpp b/recovery_main.cpp
index 80cba61..ad87b7e 100644
--- a/recovery_main.cpp
+++ b/recovery_main.cpp
@@ -375,8 +375,7 @@
           locale = optarg;
         } else if (option == "reason") {
           reason = optarg;
-        } else if (option == "fastboot" &&
-                   android::base::GetBoolProperty("ro.boot.dynamic_partitions", false)) {
+        } else if (option == "fastboot") {
           fastboot = true;
         }
         break;
@@ -440,10 +439,6 @@
     device->RemoveMenuItemForAction(Device::WIPE_CACHE);
   }
 
-  if (!android::base::GetBoolProperty("ro.boot.dynamic_partitions", false)) {
-    device->RemoveMenuItemForAction(Device::ENTER_FASTBOOT);
-  }
-
   if (!IsRoDebuggable()) {
     device->RemoveMenuItemForAction(Device::ENTER_RESCUE);
   }
diff --git a/recovery_ui/screen_ui.cpp b/recovery_ui/screen_ui.cpp
index 087fc0e..7ce83f4 100644
--- a/recovery_ui/screen_ui.cpp
+++ b/recovery_ui/screen_ui.cpp
@@ -914,9 +914,7 @@
   no_command_text_ = LoadLocalizedBitmap("no_command_text");
   error_text_ = LoadLocalizedBitmap("error_text");
 
-  if (android::base::GetBoolProperty("ro.boot.dynamic_partitions", false)) {
-    fastbootd_logo_ = LoadBitmap("fastbootd");
-  }
+  fastbootd_logo_ = LoadBitmap("fastbootd");
 
   // Background text for "installing_update" could be "installing update" or
   // "installing security update". It will be set after Init() according to the commands in BCB.
diff --git a/recovery_utils/roots.cpp b/recovery_utils/roots.cpp
index 99f3c5d..ee5cb86 100644
--- a/recovery_utils/roots.cpp
+++ b/recovery_utils/roots.cpp
@@ -291,7 +291,8 @@
   }
   for (const FstabEntry& entry : fstab) {
     // We don't want to do anything with "/".
-    if (entry.mount_point == "/") {
+    if (entry.mount_point == "/" || entry.mount_point == "/sdcard" ||
+        entry.mount_point == "/data") {
       continue;
     }
 
diff --git a/tools/recovery_l10n/res/values-ca/strings.xml b/tools/recovery_l10n/res/values-ca/strings.xml
index 6b7bec0..b14a76f 100644
--- a/tools/recovery_l10n/res/values-ca/strings.xml
+++ b/tools/recovery_l10n/res/values-ca/strings.xml
@@ -9,6 +9,6 @@
     <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"No s\'ha pogut carregar el sistema Android. És possible que les teves dades estiguin malmeses. Si continues veient aquest missatge, pot ser que hagis de restablir les dades de fàbrica i esborrar totes les dades d\'usuari emmagatzemades en aquest dispositiu."</string>
     <string name="recovery_try_again" msgid="7168248750158873496">"Torna-ho a provar"</string>
     <string name="recovery_factory_data_reset" msgid="7321351565602894783">"Restableix les dades de fàbrica"</string>
-    <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"Vols eliminar totes les dades d\'usuari?\n\n AQUESTA ACCIÓ NO ES POT DESFER."</string>
+    <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"Vols netejar totes les dades d\'usuari?\n\n AQUESTA ACCIÓ NO ES POT DESFER."</string>
     <string name="recovery_cancel_wipe_data" msgid="66987687653647384">"Cancel·la"</string>
 </resources>
diff --git a/tools/recovery_l10n/res/values-iw/strings.xml b/tools/recovery_l10n/res/values-iw/strings.xml
index 8ca3bdf..0b81d05 100644
--- a/tools/recovery_l10n/res/values-iw/strings.xml
+++ b/tools/recovery_l10n/res/values-iw/strings.xml
@@ -2,10 +2,10 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recovery_installing" msgid="2013591905463558223">"מתקין עדכון מערכת"</string>
-    <string name="recovery_erasing" msgid="7334826894904037088">"מוחק"</string>
+    <string name="recovery_erasing" msgid="7334826894904037088">"מתבצעת מחיקה"</string>
     <string name="recovery_no_command" msgid="4465476568623024327">"אין פקודה"</string>
     <string name="recovery_error" msgid="5748178989622716736">"שגיאה!"</string>
-    <string name="recovery_installing_security" msgid="9184031299717114342">"מתקין עדכון אבטחה"</string>
+    <string name="recovery_installing_security" msgid="9184031299717114342">"התקנת עדכון אבטחה מתבצעת"</string>
     <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"‏לא ניתן לטעון את מערכת Android. ייתכן שהנתונים שלך פגומים. אם הודעה זו תופיע שוב, ייתכן שיהיה עליך לבצע איפוס לנתוני היצרן ולמחוק את כל נתוני המשתמש ששמורים במכשיר זה."</string>
     <string name="recovery_try_again" msgid="7168248750158873496">"ניסיון נוסף"</string>
     <string name="recovery_factory_data_reset" msgid="7321351565602894783">"איפוס לנתוני היצרן"</string>
diff --git a/tools/recovery_l10n/res/values-ky/strings.xml b/tools/recovery_l10n/res/values-ky/strings.xml
index 837cf7d..45fcd15 100644
--- a/tools/recovery_l10n/res/values-ky/strings.xml
+++ b/tools/recovery_l10n/res/values-ky/strings.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recovery_installing" msgid="2013591905463558223">"Тутум жаңыртуусу орнотулууда"</string>
+    <string name="recovery_installing" msgid="2013591905463558223">"Тутум жаңырууда"</string>
     <string name="recovery_erasing" msgid="7334826894904037088">"Тазаланууда"</string>
     <string name="recovery_no_command" msgid="4465476568623024327">"Буйрук берилген жок"</string>
     <string name="recovery_error" msgid="5748178989622716736">"Ката!"</string>
-    <string name="recovery_installing_security" msgid="9184031299717114342">"Коопсуздук жаңыртуусу орнотулууда"</string>
-    <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Android тутуму жүктөлбөй жатат. Дайын-даректериңиз бузук болушу мүмкүн. Бул билдирүү дагы деле келе берсе, түзмөктү кайра башынан жөндөп, анда сакталган бардык колдонуучу дайындарын тазалашыңыз керек."</string>
+    <string name="recovery_installing_security" msgid="9184031299717114342">"Коопсуздук жаңырууда"</string>
+    <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Android системасы жүктөлбөй жатат. Дайын-даректериңиз бузук болушу мүмкүн. Бул билдирүү дагы деле келе берсе, түзмөктү кайра башынан жөндөп, анда сакталган бардык колдонуучу дайындарын тазалашыңыз керек."</string>
     <string name="recovery_try_again" msgid="7168248750158873496">"Кайталоо"</string>
     <string name="recovery_factory_data_reset" msgid="7321351565602894783">"Кайра башынан жөндөө"</string>
     <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"Колдонуучу дайындарынын баары жашырылсынбы?\n\n МУНУ АРТКА КАЙТАРУУ МҮМКҮН ЭМЕС!"</string>