AssetManager LoadedArsc ResStringPool

class LoadedArsc

class ApkAssets

android.content.res.ApkAssets#ApkAssets()

private static final String FRAMEWORK_APK_PATH = “/system/framework/framework-res.apk”;

ResStringPool

what is RES_XML_TYPE

Res_value:

    // The 'data' holds an index into the containing resource table's
    // global value string pool.
    TYPE_STRING = 0x03,

    // The 'data' is a raw integer value of the form n..n.
    TYPE_INT_DEC = 0x10,

    // The 'data' is a raw integer value of the form #rrggbb.
    TYPE_INT_COLOR_RGB8 = 0x1d,

#define Res_GETPACKAGE(id) ((id>>24)-1)
#define Res_GETTYPE(id) (((id>>16)&0xFF)-1)
#define Res_GETENTRY(id) (id&0xFFFF)

#define APP_PACKAGE_ID 0x7f
#define SYS_PACKAGE_ID 0x01

string id: 7f0e0024: 2131623972

package_id: 0x7f
type_idx: 0x0e 13
entry_index: 36

Step to get resource:

1 nativeGetResourceValue

2 AssetManager2::GetResource()

3 AssetManager2::FindEntry() :

first find PackageGroup by package_id , then call FindEntryInternal().

4 AssetManager2::FindEntryInternal()

get TypeSpec :

   const TypeSpec* type_spec = loaded_package->GetTypeSpecByTypeIndex(type_idx);

struct ResTable_type

struct ResTable_entry

struct Res_value

What is std::unordered_map<uint8_t, TypeSpec> type_specs_;

ResTable::collectString

when to init package_ids_ ?

String type_idx: 13 :

const TypeSpec* type_spec = loaded_package->GetTypeSpecByTypeIndex(type_idx);

ResChunk_header type is : RES_TABLE_TYPE_TYPE = 0x0201,

Res_value data type is 3 : String

ResTable_entry and Res_value :

This is the beginning of information about an entry in the resource
table. It holds the reference to the name of this entry, and is
immediately followed by one of:
A Res_value structure, if FLAG_COMPLEX is -not- set.
An array of ResTable_map structures, if FLAG_COMPLEX is set.
These supply a set of name/value mappings of data.

const TypeSpec* type_spec = loaded_package->GetTypeSpecByTypeIndex(type_idx);

load apk step :

nativeLoad

STEP 1:

android_content_res_ApkAssets.cpp:

case FORMAT_APK: {
        auto assets = MultiAssetsProvider::Create(std::move(loader_assets),
                                                  ZipAssetsProvider::Create(path.c_str(),
                                                                            property_flags));
        apk_assets = ApkAssets::Load(std::move(assets), property_flags);
        break;
    }

AssetsProvider open

finally to this function:

STEP 2:

resources_asset is the stream to read from .

std::unique_ptr<ApkAssets> ApkAssets::LoadImpl(std::unique_ptr<Asset> resources_asset,
                                               std::unique_ptr<AssetsProvider> assets,
                                               package_property_t property_flags,
                                               std::unique_ptr<Asset> idmap_asset,
                                               std::unique_ptr<LoadedIdmap> loaded_idmap) {
  if (assets == nullptr ) {
    return {};
  }

  std::unique_ptr<LoadedArsc> loaded_arsc;
  if (resources_asset != nullptr) {
    const auto data = resources_asset->getIncFsBuffer(true /* aligned */);
    const size_t length = resources_asset->getLength();
    if (!data || length == 0) {
      LOG(ERROR) << "Failed to read resources table in APK '" << assets->GetDebugName() << "'.";
      return {};
    }
    loaded_arsc = LoadedArsc::Load(data, length, loaded_idmap.get(), property_flags);
  } else {
    loaded_arsc = LoadedArsc::CreateEmpty();
  }

  if (loaded_arsc == nullptr) {
    LOG(ERROR) << "Failed to load resources table in APK '" << assets->GetDebugName() << "'.";
    return {};
  }

  return std::unique_ptr<ApkAssets>(new ApkAssets(std::move(resources_asset),
                                                  std::move(loaded_arsc), std::move(assets),
                                                  property_flags, std::move(idmap_asset),
                                                  std::move(loaded_idmap)));
}

call :

 loaded_arsc = LoadedArsc::Load(data, length, loaded_idmap.get(), property_flags);  

read into LoadedArsc.

STEP 3:

LoadedArsc::Load

the top Chunk type is : RES_TABLE_TYPE = 0x0002,

then call LoadedArsc::LoadTable
child chunk type is : RES_STRING_POOL_TYPE and RES_TABLE_PACKAGE_TYPE .

  ChunkIterator iter(chunk.data_ptr(), chunk.data_size());
  while (iter.HasNext()) {
    const Chunk child_chunk = iter.Next();
    switch (child_chunk.type()) {
      case RES_STRING_POOL_TYPE:
        // Only use the first string pool. Ignore others.
        if (global_string_pool_->getError() == NO_INIT) {
          status_t err = global_string_pool_->setTo(child_chunk.header<ResStringPool_header>(),
                                                    child_chunk.size());
          if (err != NO_ERROR) {
            LOG(ERROR) << "RES_STRING_POOL_TYPE corrupt.";
            return false;
          }
        } else {
          LOG(WARNING) << "Multiple RES_STRING_POOL_TYPEs found in RES_TABLE_TYPE.";
        }
        break;

      case RES_TABLE_PACKAGE_TYPE: {
        if (packages_seen + 1 > package_count) {
          LOG(ERROR) << "More package chunks were found than the " << package_count
                     << " declared in the header.";
          return false;
        }
        packages_seen++;

        std::unique_ptr<const LoadedPackage> loaded_package =
            LoadedPackage::Load(child_chunk, property_flags);
        if (!loaded_package) {
          return false;
        }
        packages_.push_back(std::move(loaded_package));
      } break;

      default:
        LOG(WARNING) << StringPrintf("Unknown chunk type '%02x'.", chunk.type());
        break;
    }
  }

RES_STRING_POOL_TYPE call global_string_pool_->setTo ();

RES_TABLE_PACKAGE_TYPE create LoadedPackage and then put into packages_ .

STEP 4: LoadedArsc.cpp LoadedPackage

call static function LoadedPackage::Load()
type_string_pool_
key_string_pool_

loaded_package->type_specs_[type_id]

loaded_package->resource_ids_.set(type_spec->id, entry_count);

Type :

string: 0x0e;
drawable: 0x08;
integer:0x0a;
color:0x06;

todo:
/home/andy/aosp13/system/incremental_delivery/incfs/util/include/util/map_ptr.h

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值