Add PhoneCapabilityChanged in phone state listener

Add a new hidden event PhoneCapabilityChanged that can be
listned to know phone capability has changed.

Bug: 92796390
Test: build
Change-Id: I12ccde1a1c4257ac50c2cfa73d2d5b58dd7e1518
This commit is contained in:
Malcolm Chen
2018-08-08 20:27:45 -07:00
parent e6bb077804
commit e1623652a4
9 changed files with 329 additions and 3 deletions

View File

@@ -36,6 +36,7 @@ import android.telephony.CellInfo;
import android.telephony.CellLocation;
import android.telephony.DisconnectCause;
import android.telephony.LocationAccessPolicy;
import android.telephony.PhoneCapability;
import android.telephony.PhoneStateListener;
import android.telephony.PhysicalChannelConfig;
import android.telephony.PreciseCallState;
@@ -47,7 +48,6 @@ import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.VoLteServiceState;
import android.text.TextUtils;
import android.util.LocalLog;
import com.android.internal.app.IBatteryStats;
@@ -200,6 +200,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private boolean mCarrierNetworkChangeState = false;
private PhoneCapability mPhoneCapability = null;
private final LocalLog mLocalLog = new LocalLog(100);
private PreciseDataConnectionState mPreciseDataConnectionState =
@@ -658,6 +660,13 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE) != 0) {
try {
r.callback.onPhoneCapabilityChanged(mPhoneCapability);
} catch (RemoteException ex) {
remove(r.binder);
}
}
}
}
} else {
@@ -1453,6 +1462,33 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
}
public void notifyPhoneCapabilityChanged(PhoneCapability capability) {
if (!checkNotifyPermission("notifyPhoneCapabilityChanged()")) {
return;
}
if (VDBG) {
log("notifyPhoneCapabilityChanged: capability=" + capability);
}
synchronized (mRecords) {
mPhoneCapability = capability;
for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(
PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE)) {
try {
r.callback.onPhoneCapabilityChanged(capability);
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
}
}
handleRemoveListLocked();
}
}
@Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
@@ -1488,6 +1524,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
pw.println("mForegroundCallState=" + mForegroundCallState);
pw.println("mBackgroundCallState=" + mBackgroundCallState);
pw.println("mVoLteServiceState=" + mVoLteServiceState);
pw.println("mPhoneCapability=" + mPhoneCapability);
pw.decreaseIndent();

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* 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 android.telephony;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Objects;
/**
* Information of a single logical modem indicating
* its id, supported rats and whether it supports voice or data, etc.
* @hide
*/
public class ModemInfo implements Parcelable {
public final int modemId;
public final int rat; /* bitset */
public final boolean isVoiceSupported;
public final boolean isDataSupported;
public ModemInfo(int modemId, int rat, boolean isVoiceSupported, boolean isDataSupported) {
this.modemId = modemId;
this.rat = rat;
this.isVoiceSupported = isVoiceSupported;
this.isDataSupported = isDataSupported;
}
public ModemInfo(Parcel in) {
modemId = in.readInt();
rat = in.readInt();
isVoiceSupported = in.readBoolean();
isDataSupported = in.readBoolean();
}
@Override
public String toString() {
return "modemId=" + modemId + " rat=" + rat + " isVoiceSupported:" + isVoiceSupported
+ " isDataSupported:" + isDataSupported;
}
@Override
public int hashCode() {
return Objects.hash(modemId, rat, isVoiceSupported, isDataSupported);
}
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof ModemInfo) || hashCode() != o.hashCode()) {
return false;
}
if (this == o) {
return true;
}
ModemInfo s = (ModemInfo) o;
return (modemId == s.modemId
&& rat == s.rat
&& isVoiceSupported == s.isVoiceSupported
&& isDataSupported == s.isDataSupported);
}
/**
* {@link Parcelable#describeContents}
*/
public @ContentsFlags int describeContents() {
return 0;
}
/**
* {@link Parcelable#writeToParcel}
*/
public void writeToParcel(Parcel dest, @WriteFlags int flags) {
dest.writeInt(modemId);
dest.writeInt(rat);
dest.writeBoolean(isVoiceSupported);
dest.writeBoolean(isDataSupported);
}
public static final Parcelable.Creator<ModemInfo> CREATOR = new Parcelable.Creator() {
public ModemInfo createFromParcel(Parcel in) {
return new ModemInfo(in);
}
public ModemInfo[] newArray(int size) {
return new ModemInfo[size];
}
};
}

View File

@@ -0,0 +1,20 @@
/*
**
** Copyright 2018, The Android Open Source Project
**
** 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 android.telephony;
parcelable PhoneCapability;

View File

@@ -0,0 +1,111 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* 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 android.telephony;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* Define capability of a modem group. That is, the capabilities
* are shared between those modems defined by list of modem IDs.
* @hide
*/
public class PhoneCapability implements Parcelable {
public final int maxActiveVoiceCalls;
public final int maxActiveData;
public final int max5G;
public final List<ModemInfo> logicalModemList;
public PhoneCapability(int maxActiveVoiceCalls, int maxActiveData, int max5G,
List<ModemInfo> logicalModemList) {
this.maxActiveVoiceCalls = maxActiveVoiceCalls;
this.maxActiveData = maxActiveData;
this.max5G = max5G;
// Make sure it's not null.
this.logicalModemList = logicalModemList == null ? new ArrayList<>() : logicalModemList;
}
@Override
public String toString() {
return "maxActiveVoiceCalls=" + maxActiveVoiceCalls + " maxActiveData=" + maxActiveData
+ " max5G=" + max5G + "logicalModemList:"
+ Arrays.toString(logicalModemList.toArray());
}
private PhoneCapability(Parcel in) {
maxActiveVoiceCalls = in.readInt();
maxActiveData = in.readInt();
max5G = in.readInt();
logicalModemList = new ArrayList<>();
in.readList(logicalModemList, ModemInfo.class.getClassLoader());
}
@Override
public int hashCode() {
return Objects.hash(maxActiveVoiceCalls, maxActiveData, max5G, logicalModemList);
}
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof PhoneCapability) || hashCode() != o.hashCode()) {
return false;
}
if (this == o) {
return true;
}
PhoneCapability s = (PhoneCapability) o;
return (maxActiveVoiceCalls == s.maxActiveVoiceCalls
&& maxActiveData == s.maxActiveData
&& max5G == s.max5G
&& logicalModemList.equals(s.logicalModemList));
}
/**
* {@link Parcelable#describeContents}
*/
public @Parcelable.ContentsFlags int describeContents() {
return 0;
}
/**
* {@link Parcelable#writeToParcel}
*/
public void writeToParcel(Parcel dest, @Parcelable.WriteFlags int flags) {
dest.writeInt(maxActiveVoiceCalls);
dest.writeInt(maxActiveData);
dest.writeInt(max5G);
dest.writeList(logicalModemList);
}
public static final Parcelable.Creator<PhoneCapability> CREATOR = new Parcelable.Creator() {
public PhoneCapability createFromParcel(Parcel in) {
return new PhoneCapability(in);
}
public PhoneCapability[] newArray(int size) {
return new PhoneCapability[size];
}
};
}

View File

@@ -21,12 +21,11 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.telecom.TelecomManager;
import com.android.internal.telephony.IPhoneStateListener;
import java.util.List;
import java.lang.ref.WeakReference;
import java.util.List;
/**
* A listener class for monitoring changes in specific telephony states
@@ -271,6 +270,14 @@ public class PhoneStateListener {
*/
public static final int LISTEN_PHYSICAL_CHANNEL_CONFIGURATION = 0x00100000;
/**
* Listen for changes to the phone capability.
*
* @see #onPhoneCapabilityChanged
* @hide
*/
public static final int LISTEN_PHONE_CAPABILITY_CHANGE = 0x00200000;
/*
* Subscription used to listen to the phone state changes
* @hide
@@ -389,6 +396,10 @@ public class PhoneStateListener {
PhoneStateListener.this.onPhysicalChannelConfigurationChanged(
(List<PhysicalChannelConfig>)msg.obj);
break;
case LISTEN_PHONE_CAPABILITY_CHANGE:
PhoneStateListener.this.onPhoneCapabilityChanged(
(PhoneCapability) msg.obj);
break;
}
}
};
@@ -612,6 +623,16 @@ public class PhoneStateListener {
// default implementation empty
}
/**
* Callback invoked when phone capability changes. Requires
* the READ_PRIVILEGED_PHONE_STATE permission.
* @param capability the new phone capability
* @hide
*/
public void onPhoneCapabilityChanged(PhoneCapability capability) {
// default implementation empty
}
/**
* Callback invoked when telephony has received notice from a carrier
* app that a network action that could result in connectivity loss
@@ -739,6 +760,10 @@ public class PhoneStateListener {
public void onPhysicalChannelConfigurationChanged(List<PhysicalChannelConfig> configs) {
send(LISTEN_PHYSICAL_CHANNEL_CONFIGURATION, 0, 0, configs);
}
public void onPhoneCapabilityChanged(PhoneCapability capability) {
send(LISTEN_PHONE_CAPABILITY_CHANGE, 0, 0, capability);
}
}
IPhoneStateListener callback = new IPhoneStateListenerStub(this);

View File

@@ -7973,4 +7973,23 @@ public class TelephonyManager {
}
return UNKNOWN_CARRIER_ID_LIST_VERSION;
}
/**
* How many modems can have simultaneous data connections.
* @hide
*/
@RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
public int getNumberOfModemsWithSimultaneousDataConnections() {
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
return telephony.getNumberOfModemsWithSimultaneousDataConnections(
getSubId(), mContext.getOpPackageName());
}
} catch (RemoteException ex) {
// This could happen if binder process crashes.
}
return 0;
}
}

View File

@@ -21,6 +21,7 @@ import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.CellInfo;
import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.PhoneCapability;
import android.telephony.PhysicalChannelConfig;
import android.telephony.PreciseCallState;
import android.telephony.PreciseDataConnectionState;
@@ -50,5 +51,6 @@ oneway interface IPhoneStateListener {
void onOemHookRawEvent(in byte[] rawData);
void onCarrierNetworkChange(in boolean active);
void onUserMobileDataStateChanged(in boolean enabled);
void onPhoneCapabilityChanged(in PhoneCapability capability);
}

View File

@@ -1531,4 +1531,10 @@ interface ITelephony {
* @hide
*/
void refreshUiccProfile(int subId);
/**
* How many modems can have simultaneous data connections.
* @hide
*/
int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage);
}

View File

@@ -21,6 +21,7 @@ import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.os.Bundle;
import android.telephony.CellInfo;
import android.telephony.PhoneCapability;
import android.telephony.PhysicalChannelConfig;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
@@ -74,4 +75,5 @@ interface ITelephonyRegistry {
void notifySubscriptionInfoChanged();
void notifyCarrierNetworkChange(in boolean active);
void notifyUserMobileDataStateChangedForPhoneId(in int phoneId, in int subId, in boolean state);
void notifyPhoneCapabilityChanged(in PhoneCapability capability);
}