use of org.robolectric.res.android.Ref in project robolectric by robolectric.
the class ShadowArscAssetManager9 method nativeGetResourceArray.
// static jint NativeGetResourceArray(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint resid,
// jintArray out_data) {
@Implementation(minSdk = P)
protected static int nativeGetResourceArray(long ptr, @ArrayRes int resid, @NonNull int[] out_data) {
CppAssetManager2 assetmanager = AssetManagerFromLong(ptr);
ResolvedBag bag = assetmanager.GetBag(resid);
if (bag == null) {
return -1;
}
int out_data_length = out_data.length;
if ((int) (bag.entry_count) > out_data_length * STYLE_NUM_ENTRIES) {
throw new IllegalArgumentException("Input array is not large enough");
}
int[] buffer = // reinterpret_cast<int*>(env.GetPrimitiveArrayCritical(out_data, null));
out_data;
if (buffer == null) {
return -1;
}
int[] cursor = buffer;
for (int i = 0; i < bag.entry_count; i++) {
ResolvedBag.Entry entry = bag.entries[i];
final Ref<Res_value> value = new Ref<>(entry.value);
final Ref<ResTable_config> selected_config = new Ref<>(new ResTable_config());
selected_config.get().density = 0;
final Ref<Integer> flags = new Ref<>(bag.type_spec_flags);
final Ref<Integer> ref = new Ref<>(0);
ApkAssetsCookie cookie = assetmanager.ResolveReference(entry.cookie, value, selected_config, flags, ref);
if (cookie.intValue() == kInvalidCookie) {
// env.ReleasePrimitiveArrayCritical(out_data, buffer, JNI_ABORT);
return -1;
}
// Deal with the special @null value -- it turns back to TYPE_NULL.
if (value.get().dataType == Res_value.TYPE_REFERENCE && value.get().data == 0) {
value.set(Res_value.NULL_VALUE);
}
int offset = i * STYLE_NUM_ENTRIES;
cursor[offset + STYLE_TYPE] = (int) (value.get().dataType);
cursor[offset + STYLE_DATA] = (int) (value.get().data);
cursor[offset + STYLE_ASSET_COOKIE] = ApkAssetsCookieToJavaCookie(cookie);
cursor[offset + STYLE_RESOURCE_ID] = (int) (ref.get());
cursor[offset + STYLE_CHANGING_CONFIGURATIONS] = (int) (flags.get());
cursor[offset + STYLE_DENSITY] = (int) (selected_config.get().density);
// cursor += STYLE_NUM_ENTRIES;
}
// env.ReleasePrimitiveArrayCritical(out_data, buffer, 0);
return (int) (bag.entry_count);
}
use of org.robolectric.res.android.Ref in project robolectric by robolectric.
the class ShadowArscAssetManager method getArrayStringResource.
@HiddenApi
@Implementation
protected final String[] getArrayStringResource(int arrayResId) {
CppAssetManager am = assetManagerForJavaObject();
if (am == null) {
return null;
}
final ResTable res = am.getResources();
final Ref<bag_entry[]> startOfBag = new Ref<>(null);
final int N = res.lockBag(arrayResId, startOfBag);
if (N < 0) {
return null;
}
String[] array = new String[N];
final Ref<Res_value> valueRef = new Ref<>(null);
final bag_entry[] bag = startOfBag.get();
int strLen = 0;
for (int i = 0; ((int) i) < N; i++) {
valueRef.set(bag[i].map.value);
String str = null;
// Take care of resolving the found resource to its final value.
int block = res.resolveReference(valueRef, bag[i].stringBlock, null);
if (kThrowOnBadId) {
if (block == BAD_INDEX) {
throw new IllegalStateException("Bad resource!");
}
}
if (valueRef.get().dataType == DataType.STRING.code()) {
final ResStringPool pool = res.getTableStringBlock(block);
str = pool.stringAt(valueRef.get().data);
// }
if (str == null) {
res.unlockBag(startOfBag);
return null;
}
array[i] = str;
// str is not NULL at that point, otherwise ExceptionCheck would have been true.
// If we have a large amount of strings in our array, we might
// overflow the local reference table of the VM.
// env.DeleteLocalRef(str);
}
}
res.unlockBag(startOfBag);
return array;
}
use of org.robolectric.res.android.Ref in project robolectric by robolectric.
the class ShadowPausedLooperTest method runOneTask_backgroundLooperExecuteInBackgroundThread.
@Test
public void runOneTask_backgroundLooperExecuteInBackgroundThread() {
shadowOf(handlerThread.getLooper()).pause();
Ref<Thread> threadRef = new Ref<>(null);
new Handler(handlerThread.getLooper()).post(() -> threadRef.set(Thread.currentThread()));
shadowOf(handlerThread.getLooper()).runOneTask();
assertThat(handlerThread.getLooper().getThread()).isEqualTo(threadRef.get());
assertThat(getMainLooper().getThread()).isNotEqualTo(threadRef.get());
}
use of org.robolectric.res.android.Ref in project robolectric by robolectric.
the class ShadowArscAssetManager method getResourceBagValues.
public static Map<String, Integer> getResourceBagValues(int ident, ResTable res) {
// Now lock down the resource object and start pulling stuff from it.
res.lock();
HashMap<String, Integer> map;
try {
final Ref<bag_entry[]> entryRef = new Ref<>(null);
final Ref<Integer> typeSpecFlags = new Ref<>(0);
int entryCount = res.getBagLocked(ident, entryRef, typeSpecFlags);
map = new HashMap<>();
bag_entry[] bag_entries = entryRef.get();
for (int i = 0; i < entryCount; i++) {
bag_entry entry = bag_entries[i];
ResourceName resourceName = new ResourceName();
if (res.getResourceName(entry.map.name.ident, true, resourceName)) {
map.put(resourceName.name, entry.map.value.data);
}
}
} finally {
res.unlock();
}
return map;
}
use of org.robolectric.res.android.Ref in project robolectric by robolectric.
the class ShadowArscAssetManager method getArrayStringInfo.
@HiddenApi
@Implementation
protected final int[] getArrayStringInfo(int arrayResId) {
CppAssetManager am = assetManagerForJavaObject();
ResTable res = am.getResources();
final Ref<bag_entry[]> startOfBag = new Ref<>(null);
final int N = res.lockBag(arrayResId, startOfBag);
if (N < 0) {
return null;
}
int[] array = new int[N * 2];
final Ref<Res_value> value = new Ref<>(null);
bag_entry[] bag = startOfBag.get();
for (int i = 0, j = 0; i < N; i++) {
int stringIndex = -1;
int stringBlock = 0;
value.set(bag[i].map.value);
// Take care of resolving the found resource to its final value.
stringBlock = res.resolveReference(value, bag[i].stringBlock, null);
if (value.get().dataType == DataType.STRING.code()) {
stringIndex = value.get().data;
}
if (kThrowOnBadId) {
if (stringBlock == BAD_INDEX) {
throw new IllegalStateException("Bad resource!");
}
}
// todo: It might be faster to allocate a C array to contain
// the blocknums and indices, put them in there and then
// do just one SetIntArrayRegion()
// env->SetIntArrayRegion(array, j, 1, &stringBlock);
array[j] = stringBlock;
// env->SetIntArrayRegion(array, j + 1, 1, &stringIndex);
array[j + 1] = stringIndex;
j += 2;
}
res.unlockBag(startOfBag);
return array;
}
Aggregations