aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRam Peri <ramperi@google.com>2023-06-22 23:47:59 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-06-22 23:47:59 +0000
commit4d2e52ae14b12dd6c7e297dff31c12eaefb4c2da (patch)
tree8f3c9632d1843a9eb8348b164a952bd80b80f286
parent25f2c34c4800cc0770faea9d7187fd4fa81a5209 (diff)
parent010ed742ac377b0d9b9146bb640ebcc6f045ff68 (diff)
downloadrobolectric-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>
-rw-r--r--integration_tests/ctesque/src/sharedTest/java/android/content/res/ResourcesTest.java8
-rw-r--r--resources/src/main/java/org/robolectric/res/android/LoadedArsc.java73
-rw-r--r--robolectric/src/main/java/org/robolectric/Robolectric.java5
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSubscriptionManagerTest.java40
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSubscriptionManager.java22
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