Merge "Add tests for property reads from unset properties"
diff --git a/api/system-current.txt b/api/system-current.txt
index 0b8cdf2..a135f55 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1371,6 +1371,10 @@
package android.content {
+ public abstract class BroadcastReceiver {
+ method @NonNull public final android.os.UserHandle getSendingUser();
+ }
+
public class ContentProviderClient implements java.lang.AutoCloseable {
method @RequiresPermission(android.Manifest.permission.REMOVE_TASKS) public void setDetectNotResponding(long);
}
@@ -1387,6 +1391,7 @@
method @NonNull public android.content.Context createPackageContextAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
method @Nullable public abstract java.io.File getPreloadsFileCache();
method public abstract boolean isCredentialProtectedStorage();
+ method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public android.content.Intent registerReceiverForAllUsers(@Nullable android.content.BroadcastReceiver, @NonNull android.content.IntentFilter, @Nullable String, @Nullable android.os.Handler);
method public abstract void sendBroadcast(android.content.Intent, @Nullable String, @Nullable android.os.Bundle);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String, @Nullable android.os.Bundle);
method public abstract void sendOrderedBroadcast(@NonNull android.content.Intent, @Nullable String, @Nullable android.os.Bundle, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
@@ -8632,6 +8637,7 @@
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled();
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle();
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isInEmergencySmsMode();
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String);
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRadioOn();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 794ffcb..0e0e7f7 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -127,6 +127,13 @@
}
@Override
+ public Intent registerReceiverForAllUsers(BroadcastReceiver receiver, IntentFilter filter,
+ String broadcastPermission, Handler scheduler) {
+ return registerReceiverAsUser(
+ receiver, UserHandle.ALL, filter, broadcastPermission, scheduler);
+ }
+
+ @Override
public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
IntentFilter filter, String broadcastPermission, Handler scheduler) {
if (receiver == null) {
@@ -1520,6 +1527,13 @@
}
@Override
+ public Intent registerReceiverForAllUsers(BroadcastReceiver receiver,
+ IntentFilter filter, String broadcastPermission, Handler scheduler) {
+ return registerReceiverAsUser(receiver, UserHandle.ALL,
+ filter, broadcastPermission, scheduler);
+ }
+
+ @Override
public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
IntentFilter filter, String broadcastPermission, Handler scheduler) {
return registerReceiverInternal(receiver, user.getIdentifier(),
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index 8691ed4..f73a376 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -16,6 +16,8 @@
package android.content;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager;
import android.app.ActivityThread;
@@ -25,6 +27,7 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
@@ -623,6 +626,20 @@
return mPendingResult;
}
+ /**
+ * Returns the user that the broadcast was sent to.
+ *
+ * <p>It can be used in a receiver registered by
+ * {@link Context#registerReceiverForAllUsers Context.registerReceiverForAllUsers()}
+ * to determine on which user the broadcast was sent.
+ *
+ * @hide
+ */
+ @SystemApi
+ public final @NonNull UserHandle getSendingUser() {
+ return UserHandle.of(getSendingUserId());
+ }
+
/** @hide */
public int getSendingUserId() {
return mPendingResult.mSendingUser;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 4b22166..507d1d8 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2795,6 +2795,37 @@
@Nullable Handler scheduler, @RegisterReceiverFlags int flags);
/**
+ * Same as {@link #registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)}
+ * but this receiver will receive broadcasts that are sent to all users. The receiver can
+ * use {@link BroadcastReceiver#getSendingUser} to determine on which user the broadcast
+ * was sent.
+ *
+ * @param receiver The BroadcastReceiver to handle the broadcast.
+ * @param filter Selects the Intent broadcasts to be received.
+ * @param broadcastPermission String naming a permissions that a
+ * broadcaster must hold in order to send an Intent to you. If {@code null},
+ * no permission is required.
+ * @param scheduler Handler identifying the thread that will receive
+ * the Intent. If {@code null}, the main thread of the process will be used.
+ *
+ * @return The first sticky intent found that matches <var>filter</var>,
+ * or {@code null} if there are none.
+ *
+ * @see #registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)
+ * @see #sendBroadcast
+ * @see #unregisterReceiver
+ * @hide
+ */
+ @Nullable
+ @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+ @SystemApi
+ public Intent registerReceiverForAllUsers(@Nullable BroadcastReceiver receiver,
+ @NonNull IntentFilter filter, @Nullable String broadcastPermission,
+ @Nullable Handler scheduler) {
+ throw new RuntimeException("Not implemented. Must override in a subclass.");
+ }
+
+ /**
* @hide
* Same as {@link #registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)
* but for a specific user. This receiver will receiver broadcasts that
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 428aadb..497e2fd 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -664,6 +664,17 @@
/** @hide */
@Override
+ @Nullable
+ @SystemApi
+ public Intent registerReceiverForAllUsers(@Nullable BroadcastReceiver receiver,
+ @NonNull IntentFilter filter, @Nullable String broadcastPermission,
+ @Nullable Handler scheduler) {
+ return mBase.registerReceiverForAllUsers(receiver, filter, broadcastPermission,
+ scheduler);
+ }
+
+ /** @hide */
+ @Override
@UnsupportedAppUsage
public Intent registerReceiverAsUser(
BroadcastReceiver receiver, UserHandle user, IntentFilter filter,
diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java
index 64effb8..210f5d7 100644
--- a/core/java/android/os/SystemClock.java
+++ b/core/java/android/os/SystemClock.java
@@ -154,6 +154,7 @@
final IAlarmManager mgr = IAlarmManager.Stub
.asInterface(ServiceManager.getService(Context.ALARM_SERVICE));
if (mgr == null) {
+ Slog.e(TAG, "Unable to set RTC: mgr == null");
return false;
}
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 3d91c37..00ab45e 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -891,9 +891,9 @@
}
}
- private static void callPostForkSystemServerHooks() {
+ private static void callPostForkSystemServerHooks(int runtimeFlags) {
// SystemServer specific post fork hooks run before child post fork hooks.
- ZygoteHooks.postForkSystemServer();
+ ZygoteHooks.postForkSystemServer(runtimeFlags);
}
private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemServer,
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 1a81e3d..a3f5311 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -1108,7 +1108,7 @@
UnsetChldSignalHandler();
if (is_system_server) {
- env->CallStaticVoidMethod(gZygoteClass, gCallPostForkSystemServerHooks);
+ env->CallStaticVoidMethod(gZygoteClass, gCallPostForkSystemServerHooks, runtime_flags);
if (env->ExceptionCheck()) {
fail_fn("Error calling post fork system server hooks.");
}
@@ -1741,7 +1741,7 @@
gZygoteClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteClassName));
gCallPostForkSystemServerHooks = GetStaticMethodIDOrDie(env, gZygoteClass,
"callPostForkSystemServerHooks",
- "()V");
+ "(I)V");
gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkChildHooks",
"(IZZLjava/lang/String;)V");
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index 0efc5bf..2f4406b 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -171,14 +171,17 @@
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
mSeparator = separator;
mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
- mSimSlotsNumber = ((TelephonyManager) context.getSystemService(
- Context.TELEPHONY_SERVICE)).getSupportedModemCount();
+ mSimSlotsNumber = getTelephonyManager().getSupportedModemCount();
mSimErrorState = new boolean[mSimSlotsNumber];
updateDisplayOpportunisticSubscriptionCarrierText(SystemProperties.getBoolean(
TelephonyProperties.DISPLAY_OPPORTUNISTIC_SUBSCRIPTION_CARRIER_TEXT_PROPERTY_NAME,
false));
}
+ private TelephonyManager getTelephonyManager() {
+ return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ }
+
/**
* Checks if there are faulty cards. Adds the text depending on the slot of the card
*
@@ -194,7 +197,7 @@
CharSequence carrierTextForSimIOError = getCarrierTextForSimState(
IccCardConstants.State.CARD_IO_ERROR, carrier);
// mSimErrorState has the state of each sim indexed by slotID.
- for (int index = 0; index < mSimErrorState.length; index++) {
+ for (int index = 0; index < getTelephonyManager().getActiveModemCount(); index++) {
if (!mSimErrorState[index]) {
continue;
}
@@ -227,8 +230,7 @@
* @param callback Callback to provide text updates
*/
public void setListening(CarrierTextCallback callback) {
- TelephonyManager telephonyManager = ((TelephonyManager) mContext
- .getSystemService(Context.TELEPHONY_SERVICE));
+ TelephonyManager telephonyManager = getTelephonyManager();
if (callback != null) {
mCarrierTextCallback = callback;
if (ConnectivityManager.from(mContext).isNetworkSupported(
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
index 528625e..e74cc8e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
@@ -120,6 +120,7 @@
mCarrierTextCallbackInfo = new CarrierTextController.CarrierTextCallbackInfo("",
new CharSequence[]{}, false, new int[]{});
when(mTelephonyManager.getSupportedModemCount()).thenReturn(3);
+ when(mTelephonyManager.getActiveModemCount()).thenReturn(3);
mCarrierTextController = new TestCarrierTextController(mContext, SEPARATOR, true, true,
mKeyguardUpdateMonitor);
@@ -173,6 +174,15 @@
// There's only one subscription in the list
assertEquals(1, captor.getValue().listOfCarriers.length);
assertEquals(TEST_CARRIER, captor.getValue().listOfCarriers[0]);
+
+ // Now it becomes single SIM active mode.
+ reset(mCarrierTextCallback);
+ when(mTelephonyManager.getActiveModemCount()).thenReturn(1);
+ // Update carrier text. It should ignore error state of subId 3 in inactive slotId.
+ mCarrierTextController.updateCarrierText();
+ mTestableLooper.processAllMessages();
+ verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+ assertEquals("TEST_CARRIER", captor.getValue().carrierText);
}
@Test
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 447ed59..f8b0072 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -16,6 +16,10 @@
package com.android.server;
+import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED;
+
+import static java.util.Arrays.copyOf;
+
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.BroadcastReceiver;
@@ -286,7 +290,7 @@
switch (msg.what) {
case MSG_USER_SWITCHED: {
if (VDBG) log("MSG_USER_SWITCHED userId=" + msg.arg1);
- int numPhones = TelephonyManager.getDefault().getPhoneCount();
+ int numPhones = getTelephonyManager().getPhoneCount();
for (int sub = 0; sub < numPhones; sub++) {
TelephonyRegistry.this.notifyCellLocationForSubscriber(sub,
mCellLocation[sub]);
@@ -367,10 +371,111 @@
mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_DEFAULT_SUB,
newDefaultPhoneId, newDefaultSubId));
}
+ } else if (action.equals(ACTION_MULTI_SIM_CONFIG_CHANGED)) {
+ onMultiSimConfigChanged();
}
}
};
+ private TelephonyManager getTelephonyManager() {
+ return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ }
+
+ private void onMultiSimConfigChanged() {
+ int oldNumPhones = mNumPhones;
+ mNumPhones = getTelephonyManager().getActiveModemCount();
+ if (oldNumPhones == mNumPhones) return;
+
+ if (DBG) {
+ log("TelephonyRegistry: activeModemCount changed from " + oldNumPhones
+ + " to " + mNumPhones);
+ }
+ mCallState = copyOf(mCallState, mNumPhones);
+ mDataActivity = copyOf(mCallState, mNumPhones);
+ mDataConnectionState = copyOf(mCallState, mNumPhones);
+ mDataConnectionNetworkType = copyOf(mCallState, mNumPhones);
+ mCallIncomingNumber = copyOf(mCallIncomingNumber, mNumPhones);
+ mServiceState = copyOf(mServiceState, mNumPhones);
+ mVoiceActivationState = copyOf(mVoiceActivationState, mNumPhones);
+ mDataActivationState = copyOf(mDataActivationState, mNumPhones);
+ mUserMobileDataState = copyOf(mUserMobileDataState, mNumPhones);
+ mSignalStrength = copyOf(mSignalStrength, mNumPhones);
+ mMessageWaiting = copyOf(mMessageWaiting, mNumPhones);
+ mCallForwarding = copyOf(mCallForwarding, mNumPhones);
+ mCellLocation = copyOf(mCellLocation, mNumPhones);
+ mSrvccState = copyOf(mSrvccState, mNumPhones);
+ mOtaspMode = copyOf(mOtaspMode, mNumPhones);
+ mPreciseCallState = copyOf(mPreciseCallState, mNumPhones);
+ mForegroundCallState = copyOf(mForegroundCallState, mNumPhones);
+ mBackgroundCallState = copyOf(mBackgroundCallState, mNumPhones);
+ mRingingCallState = copyOf(mRingingCallState, mNumPhones);
+ mCallDisconnectCause = copyOf(mCallDisconnectCause, mNumPhones);
+ mCallPreciseDisconnectCause = copyOf(mCallPreciseDisconnectCause, mNumPhones);
+ mCallQuality = copyOf(mCallQuality, mNumPhones);
+ mCallNetworkType = copyOf(mCallNetworkType, mNumPhones);
+ mCallAttributes = copyOf(mCallAttributes, mNumPhones);
+ mPreciseDataConnectionState = copyOf(mPreciseDataConnectionState, mNumPhones);
+ mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones);
+ mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones);
+
+ // ds -> ss switch.
+ if (mNumPhones < oldNumPhones) {
+ cutListToSize(mCellInfo, mNumPhones);
+ cutListToSize(mImsReasonInfo, mNumPhones);
+ cutListToSize(mPhysicalChannelConfigs, mNumPhones);
+ return;
+ }
+
+ // mNumPhones > oldNumPhones: ss -> ds switch
+ for (int i = oldNumPhones; i < mNumPhones; i++) {
+ mCallState[i] = TelephonyManager.CALL_STATE_IDLE;
+ mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
+ mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN;
+ mVoiceActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
+ mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
+ mCallIncomingNumber[i] = "";
+ mServiceState[i] = new ServiceState();
+ mSignalStrength[i] = new SignalStrength();
+ mUserMobileDataState[i] = false;
+ mMessageWaiting[i] = false;
+ mCallForwarding[i] = false;
+ mCellLocation[i] = new Bundle();
+ mCellInfo.add(i, null);
+ mImsReasonInfo.add(i, null);
+ mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE;
+ mPhysicalChannelConfigs.add(i, new ArrayList<>());
+ mOtaspMode[i] = TelephonyManager.OTASP_UNKNOWN;
+ mCallDisconnectCause[i] = DisconnectCause.NOT_VALID;
+ mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID;
+ mCallQuality[i] = new CallQuality();
+ mCallAttributes[i] = new CallAttributes(new PreciseCallState(),
+ TelephonyManager.NETWORK_TYPE_UNKNOWN, new CallQuality());
+ mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+ mPreciseCallState[i] = new PreciseCallState();
+ mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
+ mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
+ mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
+ mPreciseDataConnectionState[i] = new PreciseDataConnectionState();
+ }
+
+ // Note that location can be null for non-phone builds like
+ // like the generic one.
+ CellLocation location = CellLocation.getEmpty();
+ if (location != null) {
+ for (int i = oldNumPhones; i < mNumPhones; i++) {
+ location.fillInNotifierBundle(mCellLocation[i]);
+ }
+ }
+ }
+
+ private void cutListToSize(List list, int size) {
+ if (list == null) return;
+
+ while (list.size() > size) {
+ list.remove(list.size() - 1);
+ }
+ }
+
// we keep a copy of all of the state so we can send it out when folks
// register for it
//
@@ -385,7 +490,7 @@
mContext = context;
mBatteryStats = BatteryStatsService.getService();
- int numPhones = TelephonyManager.getDefault().getSupportedModemCount();
+ int numPhones = getTelephonyManager().getActiveModemCount();
if (DBG) log("TelephonyRegistry: ctor numPhones=" + numPhones);
mNumPhones = numPhones;
mCallState = new int[numPhones];
@@ -467,6 +572,7 @@
filter.addAction(Intent.ACTION_USER_SWITCHED);
filter.addAction(Intent.ACTION_USER_REMOVED);
filter.addAction(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
+ filter.addAction(ACTION_MULTI_SIM_CONFIG_CHANGED);
log("systemRunning register for intents");
mContext.registerReceiver(mBroadcastReceiver, filter);
}
@@ -2014,7 +2120,7 @@
final int recordCount = mRecords.size();
pw.println("last known state:");
pw.increaseIndent();
- for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
+ for (int i = 0; i < getTelephonyManager().getPhoneCount(); i++) {
pw.println("Phone Id=" + i);
pw.increaseIndent();
pw.println("mCallState=" + mCallState[i]);
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index fe18fbf..fdb14be 100644
--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -400,13 +400,9 @@
* Sends a command to the uncrypt service.
*
* @param command command to send to the uncrypt service
- * @throws IOException if the socket is closed or there was an error writing to the socket
+ * @throws IOException if there was an error writing to the socket
*/
public void sendCommand(String command) throws IOException {
- if (mLocalSocket.isClosed()) {
- throw new IOException("socket is closed");
- }
-
byte[] cmdUtf8 = command.getBytes(StandardCharsets.UTF_8);
mOutputStream.writeInt(cmdUtf8.length);
mOutputStream.write(cmdUtf8, 0, cmdUtf8.length);
@@ -415,25 +411,17 @@
/**
* Reads the status from the uncrypt service which is usually represented as a percentage.
* @return an integer representing the percentage completed
- * @throws IOException if the socket was closed or there was an error reading the socket
+ * @throws IOException if there was an error reading the socket
*/
public int getPercentageUncrypted() throws IOException {
- if (mLocalSocket.isClosed()) {
- throw new IOException("socket is closed");
- }
-
return mInputStream.readInt();
}
/**
* Sends a confirmation to the uncrypt service.
- * @throws IOException if the socket was closed or there was an error writing to the socket
+ * @throws IOException if there was an error writing to the socket
*/
public void sendAck() throws IOException {
- if (mLocalSocket.isClosed()) {
- throw new IOException("socket is closed");
- }
-
mOutputStream.writeInt(0);
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 313f884..def61bf 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -384,15 +384,6 @@
EventLog.writeEvent(EventLogTags.SYSTEM_SERVER_START,
mStartCount, mRuntimeStartUptime, mRuntimeStartElapsedTime);
- // If a device's clock is before 1970 (before 0), a lot of
- // APIs crash dealing with negative numbers, notably
- // java.io.File#setLastModified, so instead we fake it and
- // hope that time from cell towers or NTP fixes it shortly.
- if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
- Slog.w(TAG, "System clock is before 1970; setting to 1970.");
- SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
- }
-
//
// Default the timezone property to GMT if not set.
//
diff --git a/telephony/java/com/android/internal/telephony/SmsConstants.java b/telephony/common/com/android/internal/telephony/SmsConstants.java
similarity index 100%
rename from telephony/java/com/android/internal/telephony/SmsConstants.java
rename to telephony/common/com/android/internal/telephony/SmsConstants.java
diff --git a/telephony/common/com/android/internal/telephony/SmsNumberUtils.java b/telephony/common/com/android/internal/telephony/SmsNumberUtils.java
index 0d33af6..367aad1 100644
--- a/telephony/common/com/android/internal/telephony/SmsNumberUtils.java
+++ b/telephony/common/com/android/internal/telephony/SmsNumberUtils.java
@@ -359,15 +359,41 @@
return NP_NONE;
}
+ /**
+ * This function checks if the passed in string conforms to the NANP format
+ * i.e. NXX-NXX-XXXX, N is any digit 2-9 and X is any digit 0-9
+ */
private static boolean isNANP(String number) {
+ boolean retVal = false;
+
if (number.length() == NANP_MEDIUM_LENGTH
|| (number.length() == NANP_LONG_LENGTH && number.startsWith(NANP_NDD))) {
+
if (number.length() == NANP_LONG_LENGTH) {
number = number.substring(1);
}
- return (PhoneNumberUtils.isNanp(number));
+
+ if (isTwoToNine(number.charAt(0)) &&
+ isTwoToNine(number.charAt(3))) {
+ retVal = true;
+ for (int i=1; i<NANP_MEDIUM_LENGTH; i++ ) {
+ char c=number.charAt(i);
+ if (!PhoneNumberUtils.isISODigit(c)) {
+ retVal = false;
+ break;
+ }
+ }
+ }
}
- return false;
+ return retVal;
+ }
+
+ private static boolean isTwoToNine (char c) {
+ if (c >= '2' && c <= '9') {
+ return true;
+ } else {
+ return false;
+ }
}
/**
@@ -573,9 +599,9 @@
int networkType = -1;
int phoneType = telephonyManager.getPhoneType();
- if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+ if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
networkType = GSM_UMTS_NETWORK;
- } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+ } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
if (isInternationalRoaming(telephonyManager)) {
networkType = CDMA_ROAMING_NETWORK;
} else {
diff --git a/telephony/common/com/google/android/mms/pdu/PduPersister.java b/telephony/common/com/google/android/mms/pdu/PduPersister.java
index 95ae409..b237705 100755
--- a/telephony/common/com/google/android/mms/pdu/PduPersister.java
+++ b/telephony/common/com/google/android/mms/pdu/PduPersister.java
@@ -291,15 +291,11 @@
@UnsupportedAppUsage
private final ContentResolver mContentResolver;
private final DrmManagerClient mDrmManagerClient;
- @UnsupportedAppUsage
- private final TelephonyManager mTelephonyManager;
private PduPersister(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
mDrmManagerClient = new DrmManagerClient(context);
- mTelephonyManager = (TelephonyManager)context
- .getSystemService(Context.TELEPHONY_SERVICE);
}
/** Get(or create if not exist) an instance of PduPersister */
@@ -1453,7 +1449,8 @@
if (excludeMyNumber) {
// Build a list of my phone numbers from the various sims.
for (int subid : subscriptionManager.getActiveSubscriptionIdList()) {
- final String myNumber = mTelephonyManager.getLine1Number(subid);
+ final String myNumber = mContext.getSystemService(TelephonyManager.class).
+ createForSubscriptionId(subid).getLine1Number();
if (myNumber != null) {
myPhoneNumbers.add(myNumber);
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 3c890a1..3e51ff6 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -2971,6 +2971,7 @@
* permission or had carrier privilege permission on the subscription.
* {@link TelephonyManager#hasCarrierPrivileges()}
*
+ * @throws IllegalStateException if Telephony service is in bad state.
* @throws SecurityException if the caller doesn't meet the requirements
* outlined above.
*
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e99465d..2925b115 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1692,8 +1692,8 @@
*
* <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
* profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
- * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
- * managed profile on the device; for more details see <a
+ * privileges (see {@link #hasCarrierPrivileges}) on any active subscription. The profile owner
+ * is an app that owns a managed profile on the device; for more details see <a
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release.
*
@@ -1733,8 +1733,8 @@
*
* <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
* profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
- * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
- * managed profile on the device; for more details see <a
+ * privileges (see {@link #hasCarrierPrivileges}) on any active subscription. The profile owner
+ * is an app that owns a managed profile on the device; for more details see <a
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release.
*
@@ -1793,7 +1793,8 @@
* <li>The caller holds the READ_PRIVILEGED_PHONE_STATE permission.</li>
* <li>If the caller is the device or profile owner, the caller holds the
* {@link Manifest.permission#READ_PHONE_STATE} permission.</li>
- * <li>The caller has carrier privileges (see {@link #hasCarrierPrivileges()}.</li>
+ * <li>The caller has carrier privileges (see {@link #hasCarrierPrivileges()} on any
+ * active subscription.</li>
* <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
@@ -1862,8 +1863,8 @@
*
* <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
* profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
- * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
- * managed profile on the device; for more details see <a
+ * privileges (see {@link #hasCarrierPrivileges}) on any active subscription. The profile owner
+ * is an app that owns a managed profile on the device; for more details see <a
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release.
*
@@ -1889,8 +1890,8 @@
*
* <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
* profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
- * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
- * managed profile on the device; for more details see <a
+ * privileges (see {@link #hasCarrierPrivileges}) on any active subscription. The profile owner
+ * is an app that owns a managed profile on the device; for more details see <a
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release.
*
@@ -7593,20 +7594,20 @@
* {@link CarrierConfigManager#KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT}. If
* the carrier does not support this mode, this function will always return false.
*
- * @return true if this device is in emergency SMS mode, false otherwise.
+ * @return {@code true} if this device is in emergency SMS mode, {@code false} otherwise.
*
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public boolean isInEmergencySmsMode() {
-
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
return telephony.isInEmergencySmsMode();
}
} catch (RemoteException ex) {
- Rlog.e(TAG, "getNetworkSelectionMode RemoteException", ex);
+ Rlog.e(TAG, "isInEmergencySmsMode RemoteException", ex);
}
return false;
}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index 67103bf..8a852ee 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -237,9 +237,10 @@
* <ul>
* <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling
* package passes a DevicePolicyManager Device Owner / Profile Owner device identifier
- * access check, or the calling package has carrier privileges.
- * <li>throw SecurityException: if the caller does not meet any of the requirements and is
- * targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission.
+ * access check, or the calling package has carrier privileges on any active subscription.
+ * <li>throw SecurityException: if the caller does not meet any of the requirements and is
+ * targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission
+ * or carrier privileges of any active subscription.
* <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
* permission. In this case the caller would expect to have access to the device
* identifiers so false is returned instead of throwing a SecurityException to indicate
@@ -259,10 +260,10 @@
* <ul>
* <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling
* package passes a DevicePolicyManager Device Owner / Profile Owner device identifier
- * access check, or the calling package has carrier privileges.
+ * access check, or the calling package has carrier privileges on any active subscription.
* <li>throw SecurityException: if the caller does not meet any of the requirements and is
* targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission
- * or carrier privileges.
+ * or carrier privileges of any active subscription.
* <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
* permission or carrier privileges. In this case the caller would expect to have access
* to the device identifiers so false is returned instead of throwing a SecurityException
@@ -271,8 +272,8 @@
*/
public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context, int subId,
String callingPackage, String message) {
- return checkReadDeviceIdentifiers(context, TELEPHONY_SUPPLIER, subId,
- Binder.getCallingPid(), Binder.getCallingUid(), callingPackage, message);
+ return checkPrivilegedReadPermissionOrCarrierPrivilegePermission(
+ context, subId, callingPackage, message, true);
}
/**
@@ -282,7 +283,7 @@
* <ul>
* <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling
* package passes a DevicePolicyManager Device Owner / Profile Owner device identifier
- * access check, or the calling package has carrier privileges.
+ * access check, or the calling package has carrier privileges on specified subscription.
* <li>throw SecurityException: if the caller does not meet any of the requirements and is
* targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission.
* <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
@@ -293,21 +294,33 @@
*/
public static boolean checkCallingOrSelfReadSubscriberIdentifiers(Context context, int subId,
String callingPackage, String message) {
- return checkReadDeviceIdentifiers(context, TELEPHONY_SUPPLIER, subId,
- Binder.getCallingPid(), Binder.getCallingUid(), callingPackage, message);
+ return checkPrivilegedReadPermissionOrCarrierPrivilegePermission(
+ context, subId, callingPackage, message, false);
}
/**
* Checks whether the app with the given pid/uid can read device identifiers.
*
- * @returns true if the caller has the READ_PRIVILEGED_PHONE_STATE permission or the calling
- * package passes a DevicePolicyManager Device Owner / Profile Owner device identifier access
- * check.
+ * <p>This method behaves in one of the following ways:
+ * <ul>
+ * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling
+ * package passes a DevicePolicyManager Device Owner / Profile Owner device identifier
+ * access check; or the calling package has carrier privileges on the specified
+ * subscription; or allowCarrierPrivilegeOnAnySub is true and has carrier privilege on
+ * any active subscription.
+ * <li>throw SecurityException: if the caller does not meet any of the requirements and is
+ * targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission.
+ * <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
+ * permission. In this case the caller would expect to have access to the device
+ * identifiers so false is returned instead of throwing a SecurityException to indicate
+ * the calling function should return dummy data.
+ * </ul>
*/
- @VisibleForTesting
- public static boolean checkReadDeviceIdentifiers(Context context,
- Supplier<ITelephony> telephonySupplier, int subId, int pid, int uid,
- String callingPackage, String message) {
+ private static boolean checkPrivilegedReadPermissionOrCarrierPrivilegePermission(
+ Context context, int subId, String callingPackage, String message,
+ boolean allowCarrierPrivilegeOnAnySub) {
+ int uid = Binder.getCallingUid();
+ int pid = Binder.getCallingPid();
// Allow system and root access to the device identifiers.
final int appId = UserHandle.getAppId(uid);
if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) {
@@ -318,10 +331,17 @@
uid) == PackageManager.PERMISSION_GRANTED) {
return true;
}
- // If the calling package has carrier privileges for any subscription then allow access.
- if (checkCarrierPrivilegeForAnySubId(context, telephonySupplier, uid)) {
+
+ // If the calling package has carrier privileges for specified sub, then allow access.
+ if (checkCarrierPrivilegeForSubId(subId)) return true;
+
+ // If the calling package has carrier privileges for any subscription
+ // and allowCarrierPrivilegeOnAnySub is set true, then allow access.
+ if (allowCarrierPrivilegeOnAnySub && checkCarrierPrivilegeForAnySubId(
+ context, TELEPHONY_SUPPLIER, uid)) {
return true;
}
+
// if the calling package is not null then perform the DevicePolicyManager device /
// profile owner and Appop checks.
if (callingPackage != null) {
@@ -347,7 +367,7 @@
}
}
return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage,
- message);
+ message);
}
/**
diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java
index 1de6260..45b236c 100644
--- a/test-mock/src/android/test/mock/MockContext.java
+++ b/test-mock/src/android/test/mock/MockContext.java
@@ -535,6 +535,14 @@
/** @hide */
@Override
+ @SystemApi
+ public Intent registerReceiverForAllUsers(BroadcastReceiver receiver,
+ IntentFilter filter, String broadcastPermission, Handler scheduler) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** @hide */
+ @Override
public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
IntentFilter filter, String broadcastPermission, Handler scheduler) {
throw new UnsupportedOperationException();