Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd38c8ce authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 6378851 from 164a1d8b to rvc-release

Change-Id: I04cc179c6be163f20fd2f5999ea1ffe2aebe67ab
parents 1a39352a 164a1d8b
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
@@ -75,6 +76,7 @@
#define LOG_TAG "installd"
#endif

using android::base::ParseUint;
using android::base::StringPrintf;
using std::endl;

@@ -1101,6 +1103,43 @@ binder::Status InstalldNativeService::destroyAppDataSnapshot(
    return ok();
}

binder::Status InstalldNativeService::destroyCeSnapshotsNotSpecified(
        const std::unique_ptr<std::string> &volumeUuid, const int32_t userId,
        const std::vector<int32_t>& retainSnapshotIds) {
    ENFORCE_UID(AID_SYSTEM);
    CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid);
    std::lock_guard<std::recursive_mutex> lock(mLock);

    const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr;

    auto base_path = create_data_misc_ce_rollback_base_path(volume_uuid, userId);

    std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(base_path.c_str()), closedir);
    if (!dir) {
        return error(-1, "Failed to open rollback base dir " + base_path);
    }

    struct dirent* ent;
    while ((ent = readdir(dir.get()))) {
        if (ent->d_type != DT_DIR) {
            continue;
        }

        uint snapshot_id;
        bool parse_ok = ParseUint(ent->d_name, &snapshot_id);
        if (parse_ok &&
                std::find(retainSnapshotIds.begin(), retainSnapshotIds.end(),
                          snapshot_id) == retainSnapshotIds.end()) {
            auto rollback_path = create_data_misc_ce_rollback_path(
                volume_uuid, userId, snapshot_id);
            int res = delete_dir_contents_and_dir(rollback_path, true /* ignore_if_missing */);
            if (res != 0) {
                return error(res, "Failed clearing snapshot " + rollback_path);
            }
        }
    }
    return ok();
}

binder::Status InstalldNativeService::moveCompleteApp(const std::unique_ptr<std::string>& fromUuid,
        const std::unique_ptr<std::string>& toUuid, const std::string& packageName,
+2 −0
Original line number Diff line number Diff line
@@ -69,6 +69,8 @@ public:
    binder::Status destroyAppDataSnapshot(const std::unique_ptr<std::string> &volumeUuid,
            const std::string& packageName, const int32_t user, const int64_t ceSnapshotInode,
            const int32_t snapshotId, int32_t storageFlags);
    binder::Status destroyCeSnapshotsNotSpecified(const std::unique_ptr<std::string> &volumeUuid,
            const int32_t userId, const std::vector<int32_t>& retainSnapshotIds);

    binder::Status getAppSize(const std::unique_ptr<std::string>& uuid,
            const std::vector<std::string>& packageNames, int32_t userId, int32_t flags,
+3 −0
Original line number Diff line number Diff line
@@ -116,6 +116,9 @@ interface IInstalld {
            int appId, @utf8InCpp String seInfo, int user, int snapshotId, int storageflags);
    void destroyAppDataSnapshot(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName,
            int userId, long ceSnapshotInode, int snapshotId, int storageFlags);
    void destroyCeSnapshotsNotSpecified(@nullable @utf8InCpp String uuid, int userId,
            in int[] retainSnapshotIds);

    void tryMountDataMirror(@nullable @utf8InCpp String volumeUuid);
    void onPrivateVolumeRemoved(@nullable @utf8InCpp String volumeUuid);

+40 −0
Original line number Diff line number Diff line
@@ -641,6 +641,46 @@ TEST_F(AppDataSnapshotTest, DestroyAppDataSnapshot_WrongVolumeUuid) {
          "com.foo", 0, 0, 43, FLAG_STORAGE_DE).isOk());
}

TEST_F(AppDataSnapshotTest, DestroyCeSnapshotsNotSpecified) {
  auto rollback_ce_dir_in_1 = create_data_misc_ce_rollback_path("TEST", 0, 1543);
  auto rollback_ce_dir_in_2 = create_data_misc_ce_rollback_path("TEST", 0, 77);
  auto rollback_ce_dir_out_1 = create_data_misc_ce_rollback_path("TEST", 0, 1500);
  auto rollback_ce_dir_out_2 = create_data_misc_ce_rollback_path("TEST", 0, 2);

  // Create snapshots
  ASSERT_TRUE(mkdirs(rollback_ce_dir_in_1 + "/com.foo/", 0700));
  ASSERT_TRUE(android::base::WriteStringToFile(
          "CE_RESTORE_CONTENT", rollback_ce_dir_in_1 + "/com.foo/file1",
          0700, 10000, 20000, false /* follow_symlinks */));

  ASSERT_TRUE(mkdirs(rollback_ce_dir_in_2 + "/com.foo/", 0700));
  ASSERT_TRUE(android::base::WriteStringToFile(
          "CE_RESTORE_CONTENT", rollback_ce_dir_in_2 + "/com.foo/file1",
          0700, 10000, 20000, false /* follow_symlinks */));

  ASSERT_TRUE(mkdirs(rollback_ce_dir_out_1 + "/com.foo/", 0700));
  ASSERT_TRUE(android::base::WriteStringToFile(
          "CE_RESTORE_CONTENT", rollback_ce_dir_out_1 + "/com.foo/file1",
          0700, 10000, 20000, false /* follow_symlinks */));

  ASSERT_TRUE(mkdirs(rollback_ce_dir_out_2 + "/com.foo/", 0700));
  ASSERT_TRUE(android::base::WriteStringToFile(
          "CE_RESTORE_CONTENT", rollback_ce_dir_out_2 + "/com.foo/file1",
          0700, 10000, 20000, false /* follow_symlinks */));

  ASSERT_TRUE(service->destroyCeSnapshotsNotSpecified(
          std::make_unique<std::string>("TEST"), 0, { 1543, 77 }).isOk());

  // Check only snapshots not specified are deleted.
  struct stat sb;
  ASSERT_EQ(0, stat((rollback_ce_dir_in_1 + "/com.foo").c_str(), &sb));
  ASSERT_EQ(0, stat((rollback_ce_dir_in_2 + "/com.foo").c_str(), &sb));
  ASSERT_EQ(-1, stat((rollback_ce_dir_out_1 + "/com.foo").c_str(), &sb));
  ASSERT_EQ(ENOENT, errno);
  ASSERT_EQ(-1, stat((rollback_ce_dir_out_2 + "/com.foo").c_str(), &sb));
  ASSERT_EQ(ENOENT, errno);
}

TEST_F(AppDataSnapshotTest, RestoreAppDataSnapshot_WrongVolumeUuid) {
  // Setup rollback data to make sure that fails due to wrong volumeUuid being
  // passed, not because of some other reason.
+19 −1
Original line number Diff line number Diff line
@@ -430,6 +430,19 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel
}

status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const {
    // If we write the Transaction to a parcel, we want to ensure the Buffers are cached
    // before crossing the IPC boundary. Otherwise the receiving party will cache the buffers
    // but is unlikely to use them again as they are owned by the other process.
    // You may be asking yourself, is this const cast safe? Const cast is safe up
    // until the point where you try and write to an object that was originally const at which
    // point we enter undefined behavior. In this case we are safe though, because there are
    // two possibilities:
    //    1. The SurfaceComposerClient::Transaction was originally non-const. Safe.
    //    2. It was originall const! In this case not only was it useless, but it by definition
    //       contains no composer states and so cacheBuffers will not perform any writes.

    const_cast<SurfaceComposerClient::Transaction*>(this)->cacheBuffers();

    parcel->writeUint32(mForceSynchronous);
    parcel->writeUint32(mTransactionNestCount);
    parcel->writeBool(mAnimation);
@@ -507,7 +520,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr

    mInputWindowCommands.merge(other.mInputWindowCommands);

    mContainsBuffer = other.mContainsBuffer;
    mContainsBuffer |= other.mContainsBuffer;
    mEarlyWakeup = mEarlyWakeup || other.mEarlyWakeup;
    other.clear();
    return *this;
@@ -547,6 +560,11 @@ void SurfaceComposerClient::Transaction::cacheBuffers() {
        layer_state_t* s = getLayerState(handle);
        if (!(s->what & layer_state_t::eBufferChanged)) {
            continue;
        } else if (s->what & layer_state_t::eCachedBufferChanged) {
            // If eBufferChanged and eCachedBufferChanged are both trued then that means
            // we already cached the buffer in a previous call to cacheBuffers, perhaps
            // from writeToParcel on a Transaction that was merged in to this one.
            continue;
        }

        // Don't try to cache a null buffer. Sending null buffers is cheap so we shouldn't waste
Loading