/* * Copyright (C) 2022 github.com/REAndroid * * 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.reandroid.arsc.chunk; import com.reandroid.arsc.base.Block; import com.reandroid.arsc.header.OverlayablePolicyHeader; import com.reandroid.arsc.io.BlockLoad; import com.reandroid.arsc.io.BlockReader; import com.reandroid.arsc.item.IntegerArray; import com.reandroid.arsc.item.IntegerItem; import com.reandroid.json.JSONArray; import com.reandroid.json.JSONConvert; import com.reandroid.json.JSONObject; import java.io.IOException; import java.util.Collection; /** * Replica of struct "ResTable_overlayable_policy_header" as on AOSP androidfw/ResourceTypes.h * We didn't test this class with resource table, if someone found a resource/apk please * create issue on https://github.com/REAndroid/ARSCLib * */ public class OverlayablePolicy extends Chunk implements BlockLoad, JSONConvert { private final IntegerArray tableRefArray; public OverlayablePolicy(){ super(new OverlayablePolicyHeader(), 1); this.tableRefArray = new IntegerArray(); addChild(this.tableRefArray); getHeaderBlock().getEntryCount().setBlockLoad(this); } @Override public boolean isNull() { return getTableReferenceCount()==0; } public int getTableReferenceCount(){ return getTableRefArray().size(); } public Collection listTableReferences(){ return getTableRefArray().toList(); } public IntegerArray getTableRefArray() { return tableRefArray; } public int getFlags() { return getHeaderBlock().getFlags().get(); } public void setFlags(int flags){ getHeaderBlock().getFlags().set(flags); } public void setFlags(PolicyFlag[] policyFlags){ setFlags(PolicyFlag.sum(policyFlags)); } public void addFlag(PolicyFlag policyFlag){ int i = policyFlag==null? 0 : policyFlag.getFlagValue(); setFlags(getFlags() | i); } public PolicyFlag[] getPolicyFlags(){ return PolicyFlag.valuesOf(getFlags()); } @Override protected void onChunkRefreshed() { getHeaderBlock().getEntryCount().set(getTableRefArray().size()); } @Override public void onBlockLoaded(BlockReader reader, Block sender) throws IOException { IntegerItem entryCount = getHeaderBlock().getEntryCount(); if(sender==entryCount){ this.tableRefArray.setSize(entryCount.get()); } } @Override public JSONObject toJson() { JSONObject jsonObject = new JSONObject(); jsonObject.put(NAME_flags, getFlags()); JSONArray jsonArray = new JSONArray(); for(Integer reference:listTableReferences()){ jsonArray.put(reference); } jsonObject.put(NAME_references, jsonArray); return jsonObject; } @Override public void fromJson(JSONObject json) { setFlags(json.getInt(NAME_flags)); JSONArray jsonArray = json.getJSONArray(NAME_references); IntegerArray integerArray = getTableRefArray(); int length = jsonArray.length(); integerArray.setSize(length); for(int i=0;i