diff options
author | Ram Peri <ramperi@google.com> | 2023-06-22 23:47:59 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-06-22 23:47:59 +0000 |
commit | 4d2e52ae14b12dd6c7e297dff31c12eaefb4c2da (patch) | |
tree | 8f3c9632d1843a9eb8348b164a952bd80b80f286 | |
parent | 25f2c34c4800cc0770faea9d7187fd4fa81a5209 (diff) | |
parent | 010ed742ac377b0d9b9146bb640ebcc6f045ff68 (diff) | |
download | robolectric-4d2e52ae14b12dd6c7e297dff31c12eaefb4c2da.tar.gz |
Merge branch 'upstream-google' into rng_import am: 010ed742ac
Original change: https://googleplex-android-review.googlesource.com/c/platform/external/robolectric/+/23782705
Change-Id: I651915ea845f1cab07021f08517477d32fcb5902
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
5 files changed, 135 insertions, 13 deletions
diff --git a/integration_tests/ctesque/src/sharedTest/java/android/content/res/ResourcesTest.java b/integration_tests/ctesque/src/sharedTest/java/android/content/res/ResourcesTest.java index c1922b60d..5e4de013c 100644 --- a/integration_tests/ctesque/src/sharedTest/java/android/content/res/ResourcesTest.java +++ b/integration_tests/ctesque/src/sharedTest/java/android/content/res/ResourcesTest.java @@ -503,6 +503,14 @@ public class ResourcesTest { assertThat(id).isEqualTo(0); } + @Test + @SdkSuppress(minSdkVersion = LOLLIPOP) + @Config(minSdk = LOLLIPOP) + public void getIdentifier_material() { + int id = Resources.getSystem().getIdentifier("btn_check_material_anim", "drawable", "android"); + assertThat(id).isGreaterThan(0); + } + /** * Public framework symbols are defined here: * https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/values/public.xml diff --git a/resources/src/main/java/org/robolectric/res/android/LoadedArsc.java b/resources/src/main/java/org/robolectric/res/android/LoadedArsc.java index 0de3390e7..8b8165bd1 100644 --- a/resources/src/main/java/org/robolectric/res/android/LoadedArsc.java +++ b/resources/src/main/java/org/robolectric/res/android/LoadedArsc.java @@ -526,32 +526,79 @@ public class LoadedArsc { return 0; } + // for (const auto& type_entry : type_spec->type_entries) { for (ResTable_type iter : type_spec.types) { + // const incfs::verified_map_ptr<ResTable_type>& type = type_entry.type; ResTable_type type = iter; + // const size_t entry_count = dtohl(type->entryCount); int entry_count = type.entryCount; + // const auto entry_offsets = type.offset(dtohs(type->header.headerSize)); + // for (size_t entry_idx = 0; entry_idx < entry_count; entry_idx++) { for (int entry_idx = 0; entry_idx < entry_count; entry_idx++) { - // const uint32_t* entry_offsets = reinterpret_cast<const uint32_t*>( - // reinterpret_cast<const uint8_t*>(type.type) + dtohs(type.type.header.headerSize)); - // ResTable_type entry_offsets = new ResTable_type(type.myBuf(), - // type.myOffset() + type.header.headerSize); - // int offset = dtohl(entry_offsets[entry_idx]); - int offset = dtohl(type.entryOffset(entry_idx)); + // uint32_t offset; + int offset; + // uint16_t res_idx; + short res_idx; + // if (type->flags & ResTable_type::FLAG_SPARSE) { + if (isTruthy(type.flags & ResTable_type.FLAG_SPARSE)) { + // auto sparse_entry = entry_offsets.convert<ResTable_sparseTypeEntry>() + entry_idx; + + ResTable_sparseTypeEntry sparse_entry = + new ResTable_sparseTypeEntry( + type.myBuf(), type.myOffset() + entry_idx * ResTable_sparseTypeEntry.SIZEOF); + // if (!sparse_entry) { + // return base::unexpected(IOError::PAGES_MISSING); + // } + // TODO: implement above + // offset = dtohs(sparse_entry->offset) * 4u; + offset = dtohs(sparse_entry.offset) * 4; + // res_idx = dtohs(sparse_entry->idx); + res_idx = dtohs(sparse_entry.idx); + // } else if (type->flags & ResTable_type::FLAG_OFFSET16) { + } else if (isTruthy(type.flags & ResTable_type.FLAG_OFFSET16)) { + // auto entry = entry_offsets.convert<uint16_t>() + entry_idx; + int entry = type.entryOffset(entry_idx); + // if (!entry) { + // return base::unexpected(IOError::PAGES_MISSING); + // } + // offset = offset_from16(entry.value()); + offset = entry; + // res_idx = entry_idx; + res_idx = (short) entry_idx; + } else { + // auto entry = entry_offsets.convert<uint32_t>() + entry_idx; + int entry = type.entryOffset(entry_idx); + // if (!entry) { + // return base::unexpected(IOError::PAGES_MISSING); + // } + // offset = dtohl(entry.value()); + offset = dtohl(entry); + res_idx = (short) entry_idx; + } + if (offset != ResTable_type.NO_ENTRY) { - // const ResTable_entry* entry = - // reinterpret_cast<const ResTable_entry*>(reinterpret_cast<const uint8_t*>(type.type) + - // dtohl(type.type.entriesStart) + offset); + // auto entry = type.offset(dtohl(type->entriesStart) + + // offset).convert<ResTable_entry>(); ResTable_entry entry = - new ResTable_entry(type.myBuf(), type.myOffset() + - dtohl(type.entriesStart) + offset); + new ResTable_entry( + type.myBuf(), type.myOffset() + dtohl(type.entriesStart) + offset); + // if (!entry) { + // return base::unexpected(IOError::PAGES_MISSING); + // } + // TODO implement above + // if (entry->key() == static_cast<uint32_t>(*key_idx)) { if (dtohl(entry.getKeyIndex()) == key_idx) { - // The package ID will be overridden by the caller (due to runtime assignment of package + // The package ID will be overridden by the caller (due to runtime assignment of + // package // IDs for shared libraries). - return make_resid((byte) 0x00, (byte) (type_idx + type_id_offset_ + 1), (short) entry_idx); + // return make_resid(0x00, *type_idx + type_id_offset_ + 1, res_idx); + return make_resid((byte) 0x00, (byte) (type_idx + type_id_offset_ + 1), res_idx); } } } } + // return base::unexpected(std::nullopt); return 0; } diff --git a/robolectric/src/main/java/org/robolectric/Robolectric.java b/robolectric/src/main/java/org/robolectric/Robolectric.java index 47a52c54e..3ce637e76 100644 --- a/robolectric/src/main/java/org/robolectric/Robolectric.java +++ b/robolectric/src/main/java/org/robolectric/Robolectric.java @@ -1,5 +1,6 @@ package org.robolectric; +import static com.google.common.base.Preconditions.checkState; import static org.robolectric.shadows.ShadowAssetManager.useLegacy; import android.annotation.IdRes; @@ -11,6 +12,7 @@ import android.app.backup.BackupAgent; import android.content.ContentProvider; import android.content.Intent; import android.os.Bundle; +import android.os.Looper; import android.util.AttributeSet; import android.view.View; import javax.annotation.Nullable; @@ -104,6 +106,9 @@ public class Robolectric { */ public static <T extends Activity> ActivityController<T> buildActivity( Class<T> activityClass, Intent intent, @Nullable Bundle activityOptions) { + checkState( + Thread.currentThread() == Looper.getMainLooper().getThread(), + "buildActivity must be called on main Looper thread"); return ActivityController.of( ReflectionHelpers.callConstructor(activityClass), intent, activityOptions); } diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSubscriptionManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSubscriptionManagerTest.java index e3b48f0f1..a527ec98f 100644 --- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSubscriptionManagerTest.java +++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSubscriptionManagerTest.java @@ -10,6 +10,8 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import static org.robolectric.Shadows.shadowOf; +import android.os.Handler; +import android.os.Looper; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -90,6 +92,29 @@ public class ShadowSubscriptionManagerTest { } @Test + public void + addOnSubscriptionsChangedListener_whenHasExecutorParameter_shouldCallbackImmediately() { + DummySubscriptionsChangedListener listener = new DummySubscriptionsChangedListener(); + shadowOf(subscriptionManager) + .addOnSubscriptionsChangedListener(new Handler(Looper.getMainLooper())::post, listener); + + assertThat(listener.subscriptionChangedCount).isEqualTo(1); + } + + @Test + public void addOnSubscriptionsChangedListener_whenHasExecutorParameter_shouldAddListener() { + DummySubscriptionsChangedListener listener = new DummySubscriptionsChangedListener(); + shadowOf(subscriptionManager) + .addOnSubscriptionsChangedListener(new Handler(Looper.getMainLooper())::post, listener); + + shadowOf(subscriptionManager) + .setActiveSubscriptionInfos( + SubscriptionInfoBuilder.newBuilder().setId(123).buildSubscriptionInfo()); + + assertThat(listener.subscriptionChangedCount).isEqualTo(2); + } + + @Test public void removeOnSubscriptionsChangedListener_shouldRemoveListener() { DummySubscriptionsChangedListener listener = new DummySubscriptionsChangedListener(); DummySubscriptionsChangedListener listener2 = new DummySubscriptionsChangedListener(); @@ -106,6 +131,21 @@ public class ShadowSubscriptionManagerTest { } @Test + public void hasOnSubscriptionsChangedListener_whenListenerNotExist_shouldReturnFalse() { + DummySubscriptionsChangedListener listener = new DummySubscriptionsChangedListener(); + + assertThat(shadowOf(subscriptionManager).hasOnSubscriptionsChangedListener(listener)).isFalse(); + } + + @Test + public void hasOnSubscriptionsChangedListener_whenListenerExist_shouldReturnTrue() { + DummySubscriptionsChangedListener listener = new DummySubscriptionsChangedListener(); + shadowOf(subscriptionManager).addOnSubscriptionsChangedListener(listener); + + assertThat(shadowOf(subscriptionManager).hasOnSubscriptionsChangedListener(listener)).isTrue(); + } + + @Test public void getActiveSubscriptionInfo_shouldReturnInfoWithSubId() { SubscriptionInfo expectedSubscriptionInfo = SubscriptionInfoBuilder.newBuilder().setId(123).buildSubscriptionInfo(); diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSubscriptionManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSubscriptionManager.java index fb5c1c295..1b239d188 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSubscriptionManager.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSubscriptionManager.java @@ -21,6 +21,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.Executor; import org.robolectric.annotation.HiddenApi; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -282,6 +283,17 @@ public class ShadowSubscriptionManager { } /** + * Adds a listener to a local list of listeners. Will be triggered by {@link + * #setActiveSubscriptionInfoList} when the local list of {@link SubscriptionInfo} is updated. + */ + @Implementation(minSdk = R) + protected void addOnSubscriptionsChangedListener( + Executor executor, OnSubscriptionsChangedListener listener) { + listeners.add(listener); + listener.onSubscriptionsChanged(); + } + + /** * Removes a listener from a local list of listeners. Will be triggered by {@link * #setActiveSubscriptionInfoList} when the local list of {@link SubscriptionInfo} is updated. */ @@ -290,6 +302,16 @@ public class ShadowSubscriptionManager { listeners.remove(listener); } + /** + * Check if a listener exists in the {@link ShadowSubscriptionManager.listeners}. + * + * @param listener The listener to check. + * @return boolean True if the listener already added, otherwise false. + */ + public boolean hasOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { + return listeners.contains(listener); + } + /** Returns subscription Ids that were set via {@link #setActiveSubscriptionInfoList}. */ @Implementation(minSdk = LOLLIPOP_MR1) @HiddenApi |