diff options
39 files changed, 1224 insertions, 363 deletions
diff --git a/Android.bp b/Android.bp index 124f4732f2c5..482b19dbd8d7 100644 --- a/Android.bp +++ b/Android.bp @@ -825,6 +825,7 @@ aidl_interface { local_include_dir: "core/java", srcs: [ "core/java/android/net/INetworkStackConnector.aidl", + "core/java/android/net/dhcp/DhcpServingParamsParcel.aidl", ], api_dir: "aidl/networkstack", } diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt index b8d758da5e21..6025766a80f2 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -2846,94 +2846,6 @@ Lcom/android/internal/telephony/Connection;->mDuration:J Lcom/android/internal/telephony/Connection;->mIsIncoming:Z Lcom/android/internal/telephony/Connection;->mNumberPresentation:I Lcom/android/internal/telephony/Connection;->setVideoState(I)V -Lcom/android/internal/telephony/dataconnection/ApnContext;->getApnType()Ljava/lang/String; -Lcom/android/internal/telephony/dataconnection/ApnContext;->getReason()Ljava/lang/String; -Lcom/android/internal/telephony/dataconnection/ApnContext;->getState()Lcom/android/internal/telephony/DctConstants$State; -Lcom/android/internal/telephony/dataconnection/ApnContext;->isConnectable()Z -Lcom/android/internal/telephony/dataconnection/ApnContext;->isDisconnected()Z -Lcom/android/internal/telephony/dataconnection/ApnContext;->isEnabled()Z -Lcom/android/internal/telephony/dataconnection/ApnContext;->isReady()Z -Lcom/android/internal/telephony/dataconnection/ApnContext;->log(Ljava/lang/String;)V -Lcom/android/internal/telephony/dataconnection/ApnContext;->mApnType:Ljava/lang/String; -Lcom/android/internal/telephony/dataconnection/ApnContext;->mRefCount:I -Lcom/android/internal/telephony/dataconnection/ApnContext;->mRefCountLock:Ljava/lang/Object; -Lcom/android/internal/telephony/dataconnection/ApnContext;->setState(Lcom/android/internal/telephony/DctConstants$State;)V -Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;->mApnContext:Lcom/android/internal/telephony/dataconnection/ApnContext; -Lcom/android/internal/telephony/dataconnection/DataConnection;->clearSettings()V -Lcom/android/internal/telephony/dataconnection/DataConnection;->dumpToLog()V -Lcom/android/internal/telephony/dataconnection/DataConnection;->initConnection(Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;)Z -Lcom/android/internal/telephony/dataconnection/DataConnection;->log(Ljava/lang/String;)V -Lcom/android/internal/telephony/dataconnection/DataConnection;->mActivatingState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcActivatingState; -Lcom/android/internal/telephony/dataconnection/DataConnection;->mActiveState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcActiveState; -Lcom/android/internal/telephony/dataconnection/DataConnection;->mConnectionParams:Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams; -Lcom/android/internal/telephony/dataconnection/DataConnection;->mDataRegState:I -Lcom/android/internal/telephony/dataconnection/DataConnection;->mDct:Lcom/android/internal/telephony/dataconnection/DcTracker; -Lcom/android/internal/telephony/dataconnection/DataConnection;->mDisconnectingErrorCreatingConnection:Lcom/android/internal/telephony/dataconnection/DataConnection$DcDisconnectionErrorCreatingConnection; -Lcom/android/internal/telephony/dataconnection/DataConnection;->mDisconnectingState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcDisconnectingState; -Lcom/android/internal/telephony/dataconnection/DataConnection;->mDisconnectParams:Lcom/android/internal/telephony/dataconnection/DataConnection$DisconnectParams; -Lcom/android/internal/telephony/dataconnection/DataConnection;->mId:I -Lcom/android/internal/telephony/dataconnection/DataConnection;->mInactiveState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcInactiveState; -Lcom/android/internal/telephony/dataconnection/DataConnection;->mLinkProperties:Landroid/net/LinkProperties; -Lcom/android/internal/telephony/dataconnection/DataConnection;->mNetworkInfo:Landroid/net/NetworkInfo; -Lcom/android/internal/telephony/dataconnection/DataConnection;->mPhone:Lcom/android/internal/telephony/Phone; -Lcom/android/internal/telephony/dataconnection/DataConnection;->mRilRat:I -Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllOfConnected(Ljava/lang/String;)V -Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyDisconnectCompleted(Lcom/android/internal/telephony/dataconnection/DataConnection$DisconnectParams;Z)V -Lcom/android/internal/telephony/dataconnection/DataConnection;->onConnect(Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;)V -Lcom/android/internal/telephony/dataconnection/DataConnection;->tearDownData(Ljava/lang/Object;)V -Lcom/android/internal/telephony/dataconnection/DataConnection;->updateTcpBufferSizes(I)V -Lcom/android/internal/telephony/dataconnection/DcController;->lr(Ljava/lang/String;)V -Lcom/android/internal/telephony/dataconnection/DcController;->mDcListActiveByCid:Ljava/util/HashMap; -Lcom/android/internal/telephony/dataconnection/DcController;->mDct:Lcom/android/internal/telephony/dataconnection/DcTracker; -Lcom/android/internal/telephony/dataconnection/DcController;->mDcTesterDeactivateAll:Lcom/android/internal/telephony/dataconnection/DcTesterDeactivateAll; -Lcom/android/internal/telephony/dataconnection/DcTracker$RecoveryAction;->isAggressiveRecovery(I)Z -Lcom/android/internal/telephony/dataconnection/DcTracker;->cancelReconnectAlarm(Lcom/android/internal/telephony/dataconnection/ApnContext;)V -Lcom/android/internal/telephony/dataconnection/DcTracker;->cleanUpAllConnections(Ljava/lang/String;)V -Lcom/android/internal/telephony/dataconnection/DcTracker;->createAllApnList()V -Lcom/android/internal/telephony/dataconnection/DcTracker;->getActiveApnTypes()[Ljava/lang/String; -Lcom/android/internal/telephony/dataconnection/DcTracker;->getOverallState()Lcom/android/internal/telephony/DctConstants$State; -Lcom/android/internal/telephony/dataconnection/DcTracker;->getUiccRecords(I)Lcom/android/internal/telephony/uicc/IccRecords; -Lcom/android/internal/telephony/dataconnection/DcTracker;->isConnected()Z -Lcom/android/internal/telephony/dataconnection/DcTracker;->isDisconnected()Z -Lcom/android/internal/telephony/dataconnection/DcTracker;->isOnlySingleDcAllowed(I)Z -Lcom/android/internal/telephony/dataconnection/DcTracker;->log(Ljava/lang/String;)V -Lcom/android/internal/telephony/dataconnection/DcTracker;->loge(Ljava/lang/String;)V -Lcom/android/internal/telephony/dataconnection/DcTracker;->mAllApnSettings:Ljava/util/ArrayList; -Lcom/android/internal/telephony/dataconnection/DcTracker;->mApnContexts:Ljava/util/concurrent/ConcurrentHashMap; -Lcom/android/internal/telephony/dataconnection/DcTracker;->mAttached:Ljava/util/concurrent/atomic/AtomicBoolean; -Lcom/android/internal/telephony/dataconnection/DcTracker;->mAutoAttachOnCreation:Ljava/util/concurrent/atomic/AtomicBoolean; -Lcom/android/internal/telephony/dataconnection/DcTracker;->mDataConnectionTracker:Landroid/os/Handler; -Lcom/android/internal/telephony/dataconnection/DcTracker;->mDisconnectPendingCount:I -Lcom/android/internal/telephony/dataconnection/DcTracker;->mIccRecords:Ljava/util/concurrent/atomic/AtomicReference; -Lcom/android/internal/telephony/dataconnection/DcTracker;->mIsPsRestricted:Z -Lcom/android/internal/telephony/dataconnection/DcTracker;->mIsScreenOn:Z -Lcom/android/internal/telephony/dataconnection/DcTracker;->mNetStatPollEnabled:Z -Lcom/android/internal/telephony/dataconnection/DcTracker;->mNetStatPollPeriod:I -Lcom/android/internal/telephony/dataconnection/DcTracker;->mPhone:Lcom/android/internal/telephony/Phone; -Lcom/android/internal/telephony/dataconnection/DcTracker;->mPrioritySortedApnContexts:Ljava/util/PriorityQueue; -Lcom/android/internal/telephony/dataconnection/DcTracker;->mProvisioningSpinner:Landroid/app/ProgressDialog; -Lcom/android/internal/telephony/dataconnection/DcTracker;->mResolver:Landroid/content/ContentResolver; -Lcom/android/internal/telephony/dataconnection/DcTracker;->mState:Lcom/android/internal/telephony/DctConstants$State; -Lcom/android/internal/telephony/dataconnection/DcTracker;->mSubscriptionManager:Landroid/telephony/SubscriptionManager; -Lcom/android/internal/telephony/dataconnection/DcTracker;->notifyDataConnection(Ljava/lang/String;)V -Lcom/android/internal/telephony/dataconnection/DcTracker;->notifyOffApnsOfAvailability(Ljava/lang/String;)V -Lcom/android/internal/telephony/dataconnection/DcTracker;->onActionIntentDataStallAlarm(Landroid/content/Intent;)V -Lcom/android/internal/telephony/dataconnection/DcTracker;->onActionIntentProvisioningApnAlarm(Landroid/content/Intent;)V -Lcom/android/internal/telephony/dataconnection/DcTracker;->onRecordsLoadedOrSubIdChanged()V -Lcom/android/internal/telephony/dataconnection/DcTracker;->onTrySetupData(Lcom/android/internal/telephony/dataconnection/ApnContext;)Z -Lcom/android/internal/telephony/dataconnection/DcTracker;->onTrySetupData(Ljava/lang/String;)Z -Lcom/android/internal/telephony/dataconnection/DcTracker;->registerSettingsObserver()V -Lcom/android/internal/telephony/dataconnection/DcTracker;->resetPollStats()V -Lcom/android/internal/telephony/dataconnection/DcTracker;->restartDataStallAlarm()V -Lcom/android/internal/telephony/dataconnection/DcTracker;->setInitialAttachApn()V -Lcom/android/internal/telephony/dataconnection/DcTracker;->setPreferredApn(I)V -Lcom/android/internal/telephony/dataconnection/DcTracker;->setRadio(Z)V -Lcom/android/internal/telephony/dataconnection/DcTracker;->setupDataOnConnectableApns(Ljava/lang/String;)V -Lcom/android/internal/telephony/dataconnection/DcTracker;->startDataStallAlarm(Z)V -Lcom/android/internal/telephony/dataconnection/DcTracker;->startNetStatPoll()V -Lcom/android/internal/telephony/dataconnection/DcTracker;->stopDataStallAlarm()V -Lcom/android/internal/telephony/dataconnection/DcTracker;->stopNetStatPoll()V -Lcom/android/internal/telephony/dataconnection/DcTracker;->unregisterForAllDataDisconnected(Landroid/os/Handler;)V Lcom/android/internal/telephony/DctConstants$Activity;->DATAIN:Lcom/android/internal/telephony/DctConstants$Activity; Lcom/android/internal/telephony/DctConstants$Activity;->DATAINANDOUT:Lcom/android/internal/telephony/DctConstants$Activity; Lcom/android/internal/telephony/DctConstants$Activity;->DATAOUT:Lcom/android/internal/telephony/DctConstants$Activity; @@ -3368,7 +3280,7 @@ Lcom/android/internal/telephony/ITelephonyRegistry$Stub;->asInterface(Landroid/o Lcom/android/internal/telephony/ITelephonyRegistry;->listen(Ljava/lang/String;Lcom/android/internal/telephony/IPhoneStateListener;IZ)V Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCallState(ILjava/lang/String;)V Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCellInfo(Ljava/util/List;)V -Lcom/android/internal/telephony/ITelephonyRegistry;->notifyDataConnectionFailed(Ljava/lang/String;Ljava/lang/String;)V +Lcom/android/internal/telephony/ITelephonyRegistry;->notifyDataConnectionFailed(Ljava/lang/String;)V Lcom/android/internal/telephony/IWapPushManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IWapPushManager; Lcom/android/internal/telephony/IWapPushManager;->addPackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZZ)Z Lcom/android/internal/telephony/IWapPushManager;->deletePackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 61d5a9127743..23e4ec0567f2 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -16,6 +16,7 @@ package android.net; import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; @@ -909,6 +910,7 @@ public class ConnectivityManager { */ @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @Nullable public NetworkInfo getActiveNetworkInfo() { try { return mService.getActiveNetworkInfo(); @@ -928,6 +930,7 @@ public class ConnectivityManager { * {@code null} if no default network is currently active */ @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @Nullable public Network getActiveNetwork() { try { return mService.getActiveNetwork(); @@ -949,6 +952,7 @@ public class ConnectivityManager { * @hide */ @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) + @Nullable public Network getActiveNetworkForUid(int uid) { return getActiveNetworkForUid(uid, false); } @@ -1074,6 +1078,7 @@ public class ConnectivityManager { */ @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @Nullable public NetworkInfo getNetworkInfo(int networkType) { try { return mService.getNetworkInfo(networkType); @@ -1095,7 +1100,8 @@ public class ConnectivityManager { */ @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public NetworkInfo getNetworkInfo(Network network) { + @Nullable + public NetworkInfo getNetworkInfo(@Nullable Network network) { return getNetworkInfoForUid(network, Process.myUid(), false); } @@ -1121,6 +1127,7 @@ public class ConnectivityManager { */ @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @NonNull public NetworkInfo[] getAllNetworkInfo() { try { return mService.getAllNetworkInfo(); @@ -1156,6 +1163,7 @@ public class ConnectivityManager { * @return an array of {@link Network} objects. */ @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @NonNull public Network[] getAllNetworks() { try { return mService.getAllNetworks(); @@ -1230,7 +1238,8 @@ public class ConnectivityManager { * @return The {@link LinkProperties} for the network, or {@code null}. */ @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public LinkProperties getLinkProperties(Network network) { + @Nullable + public LinkProperties getLinkProperties(@Nullable Network network) { try { return mService.getLinkProperties(network); } catch (RemoteException e) { @@ -1246,7 +1255,8 @@ public class ConnectivityManager { * @return The {@link android.net.NetworkCapabilities} for the network, or {@code null}. */ @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public NetworkCapabilities getNetworkCapabilities(Network network) { + @Nullable + public NetworkCapabilities getNetworkCapabilities(@Nullable Network network) { try { return mService.getNetworkCapabilities(network); } catch (RemoteException e) { @@ -2000,7 +2010,7 @@ public class ConnectivityManager { * * @param l Previously registered listener. */ - public void removeDefaultNetworkActiveListener(OnNetworkActiveListener l) { + public void removeDefaultNetworkActiveListener(@NonNull OnNetworkActiveListener l) { INetworkActivityListener rl = mNetworkActivityListeners.get(l); Preconditions.checkArgument(rl != null, "Listener was not registered."); try { @@ -2528,7 +2538,7 @@ public class ConnectivityManager { * working and non-working connectivity. */ @Deprecated - public void reportBadNetwork(Network network) { + public void reportBadNetwork(@Nullable Network network) { printStackTrace(); try { // One of these will be ignored because it matches system's current state. @@ -2551,7 +2561,7 @@ public class ConnectivityManager { * @param hasConnectivity {@code true} if the application was able to successfully access the * Internet using {@code network} or {@code false} if not. */ - public void reportNetworkConnectivity(Network network, boolean hasConnectivity) { + public void reportNetworkConnectivity(@Nullable Network network, boolean hasConnectivity) { printStackTrace(); try { mService.reportNetworkConnectivity(network, hasConnectivity); @@ -2625,6 +2635,7 @@ public class ConnectivityManager { * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no * HTTP proxy is active. */ + @Nullable public ProxyInfo getDefaultProxy() { return getProxyForNetwork(getBoundNetworkForProcess()); } @@ -3156,8 +3167,9 @@ public class ConnectivityManager { * * @hide */ - public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback, - int timeoutMs, int legacyType, Handler handler) { + public void requestNetwork(@NonNull NetworkRequest request, + @NonNull NetworkCallback networkCallback, int timeoutMs, int legacyType, + @NonNull Handler handler) { CallbackHandler cbHandler = new CallbackHandler(handler); NetworkCapabilities nc = request.networkCapabilities; sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, legacyType, cbHandler); @@ -3194,7 +3206,8 @@ public class ConnectivityManager { * @throws IllegalArgumentException if {@code request} specifies any mutable * {@code NetworkCapabilities}. */ - public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback) { + public void requestNetwork(@NonNull NetworkRequest request, + @NonNull NetworkCallback networkCallback) { requestNetwork(request, networkCallback, getDefaultHandler()); } @@ -3229,8 +3242,8 @@ public class ConnectivityManager { * @throws IllegalArgumentException if {@code request} specifies any mutable * {@code NetworkCapabilities}. */ - public void requestNetwork( - NetworkRequest request, NetworkCallback networkCallback, Handler handler) { + public void requestNetwork(@NonNull NetworkRequest request, + @NonNull NetworkCallback networkCallback, @NonNull Handler handler) { int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities); CallbackHandler cbHandler = new CallbackHandler(handler); requestNetwork(request, networkCallback, 0, legacyType, cbHandler); @@ -3264,8 +3277,8 @@ public class ConnectivityManager { * before {@link NetworkCallback#onUnavailable()} is called. The timeout must * be a positive value (i.e. >0). */ - public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback, - int timeoutMs) { + public void requestNetwork(@NonNull NetworkRequest request, + @NonNull NetworkCallback networkCallback, int timeoutMs) { checkTimeout(timeoutMs); int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities); requestNetwork(request, networkCallback, timeoutMs, legacyType, getDefaultHandler()); @@ -3298,8 +3311,8 @@ public class ConnectivityManager { * @param timeoutMs The time in milliseconds to attempt looking for a suitable network * before {@link NetworkCallback#onUnavailable} is called. */ - public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback, - Handler handler, int timeoutMs) { + public void requestNetwork(@NonNull NetworkRequest request, + @NonNull NetworkCallback networkCallback, @NonNull Handler handler, int timeoutMs) { checkTimeout(timeoutMs); int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities); CallbackHandler cbHandler = new CallbackHandler(handler); @@ -3371,7 +3384,8 @@ public class ConnectivityManager { * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}. */ - public void requestNetwork(NetworkRequest request, PendingIntent operation) { + public void requestNetwork(@NonNull NetworkRequest request, + @NonNull PendingIntent operation) { printStackTrace(); checkPendingIntentNotNull(operation); try { @@ -3395,7 +3409,7 @@ public class ConnectivityManager { * {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)} with the * corresponding NetworkRequest you'd like to remove. Cannot be null. */ - public void releaseNetworkRequest(PendingIntent operation) { + public void releaseNetworkRequest(@NonNull PendingIntent operation) { printStackTrace(); checkPendingIntentNotNull(operation); try { @@ -3428,7 +3442,8 @@ public class ConnectivityManager { * The callback is invoked on the default internal Handler. */ @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public void registerNetworkCallback(NetworkRequest request, NetworkCallback networkCallback) { + public void registerNetworkCallback(@NonNull NetworkRequest request, + @NonNull NetworkCallback networkCallback) { registerNetworkCallback(request, networkCallback, getDefaultHandler()); } @@ -3443,8 +3458,8 @@ public class ConnectivityManager { * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. */ @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public void registerNetworkCallback( - NetworkRequest request, NetworkCallback networkCallback, Handler handler) { + public void registerNetworkCallback(@NonNull NetworkRequest request, + @NonNull NetworkCallback networkCallback, @NonNull Handler handler) { CallbackHandler cbHandler = new CallbackHandler(handler); NetworkCapabilities nc = request.networkCapabilities; sendRequestForNetwork(nc, networkCallback, 0, LISTEN, TYPE_NONE, cbHandler); @@ -3480,7 +3495,8 @@ public class ConnectivityManager { * comes from {@link PendingIntent#getBroadcast}. Cannot be null. */ @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public void registerNetworkCallback(NetworkRequest request, PendingIntent operation) { + public void registerNetworkCallback(@NonNull NetworkRequest request, + @NonNull PendingIntent operation) { printStackTrace(); checkPendingIntentNotNull(operation); try { @@ -3502,7 +3518,7 @@ public class ConnectivityManager { * The callback is invoked on the default internal Handler. */ @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public void registerDefaultNetworkCallback(NetworkCallback networkCallback) { + public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback) { registerDefaultNetworkCallback(networkCallback, getDefaultHandler()); } @@ -3516,7 +3532,8 @@ public class ConnectivityManager { * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. */ @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public void registerDefaultNetworkCallback(NetworkCallback networkCallback, Handler handler) { + public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback, + @NonNull Handler handler) { // This works because if the NetworkCapabilities are null, // ConnectivityService takes them from the default request. // @@ -3541,7 +3558,7 @@ public class ConnectivityManager { * @param network {@link Network} specifying which network you're interested. * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid. */ - public boolean requestBandwidthUpdate(Network network) { + public boolean requestBandwidthUpdate(@NonNull Network network) { try { return mService.requestBandwidthUpdate(network); } catch (RemoteException e) { @@ -3562,7 +3579,7 @@ public class ConnectivityManager { * * @param networkCallback The {@link NetworkCallback} used when making the request. */ - public void unregisterNetworkCallback(NetworkCallback networkCallback) { + public void unregisterNetworkCallback(@NonNull NetworkCallback networkCallback) { printStackTrace(); checkCallbackNotNull(networkCallback); final List<NetworkRequest> reqs = new ArrayList<>(); @@ -3601,7 +3618,7 @@ public class ConnectivityManager { * {@link #registerNetworkCallback(NetworkRequest, android.app.PendingIntent)}. * Cannot be null. */ - public void unregisterNetworkCallback(PendingIntent operation) { + public void unregisterNetworkCallback(@NonNull PendingIntent operation) { checkPendingIntentNotNull(operation); releaseNetworkRequest(operation); } @@ -3723,7 +3740,7 @@ public class ConnectivityManager { * @return a bitwise OR of zero or more of the {@code MULTIPATH_PREFERENCE_*} constants. */ @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public @MultipathPreference int getMultipathPreference(Network network) { + public @MultipathPreference int getMultipathPreference(@Nullable Network network) { try { return mService.getMultipathPreference(network); } catch (RemoteException e) { @@ -3761,7 +3778,7 @@ public class ConnectivityManager { * the current binding. * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid. */ - public boolean bindProcessToNetwork(Network network) { + public boolean bindProcessToNetwork(@Nullable Network network) { // Forcing callers to call through non-static function ensures ConnectivityManager // instantiated. return setProcessDefaultNetwork(network); @@ -3789,7 +3806,7 @@ public class ConnectivityManager { * is a direct replacement. */ @Deprecated - public static boolean setProcessDefaultNetwork(Network network) { + public static boolean setProcessDefaultNetwork(@Nullable Network network) { int netId = (network == null) ? NETID_UNSET : network.netId; if (netId == NetworkUtils.getBoundNetworkForProcess()) { return true; @@ -3820,6 +3837,7 @@ public class ConnectivityManager { * * @return {@code Network} to which this process is bound, or {@code null}. */ + @Nullable public Network getBoundNetworkForProcess() { // Forcing callers to call thru non-static function ensures ConnectivityManager // instantiated. @@ -3836,6 +3854,7 @@ public class ConnectivityManager { * {@code getBoundNetworkForProcess} is a direct replacement. */ @Deprecated + @Nullable public static Network getProcessDefaultNetwork() { int netId = NetworkUtils.getBoundNetworkForProcess(); if (netId == NETID_UNSET) return null; @@ -3962,6 +3981,7 @@ public class ConnectivityManager { * * @return Hash of network watchlist config file. Null if config does not exist. */ + @Nullable public byte[] getNetworkWatchlistConfigHash() { try { return mService.getNetworkWatchlistConfigHash(); @@ -3983,8 +4003,8 @@ public class ConnectivityManager { * (e.g., if it is associated with the calling VPN app's tunnel) or * {@link android.os.Process#INVALID_UID} if the connection is not found. */ - public int getConnectionOwnerUid(int protocol, InetSocketAddress local, - InetSocketAddress remote) { + public int getConnectionOwnerUid(int protocol, @NonNull InetSocketAddress local, + @NonNull InetSocketAddress remote) { ConnectionInfo connectionInfo = new ConnectionInfo(protocol, local, remote); try { return mService.getConnectionOwnerUid(connectionInfo); diff --git a/core/java/android/net/dhcp/DhcpServingParamsParcel.aidl b/core/java/android/net/dhcp/DhcpServingParamsParcel.aidl new file mode 100644 index 000000000000..7b8b9ee324bc --- /dev/null +++ b/core/java/android/net/dhcp/DhcpServingParamsParcel.aidl @@ -0,0 +1,30 @@ +/** + * + * 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.net.dhcp; + +parcelable DhcpServingParamsParcel { + int serverAddr; + int serverAddrPrefixLength; + int[] defaultRouters; + int[] dnsServers; + int[] excludedAddrs; + long dhcpLeaseTimeSecs; + int linkMtu; + boolean metered; +} + diff --git a/libs/hwui/service/GraphicsStatsService.cpp b/libs/hwui/service/GraphicsStatsService.cpp index 3d50d2d7e59c..29e4256e2ab7 100644 --- a/libs/hwui/service/GraphicsStatsService.cpp +++ b/libs/hwui/service/GraphicsStatsService.cpp @@ -139,6 +139,7 @@ bool GraphicsStatsService::parseFromFile(const std::string& path, uint32_t file_version = *reinterpret_cast<uint32_t*>(addr); if (file_version != sCurrentFileVersion) { ALOGW("file_version mismatch! expected %d got %d", sCurrentFileVersion, file_version); + munmap(addr, sb.st_size); return false; } @@ -150,6 +151,7 @@ bool GraphicsStatsService::parseFromFile(const std::string& path, ALOGW("Parse failed on '%s' error='%s'", path.c_str(), output->InitializationErrorString().c_str()); } + munmap(addr, sb.st_size); return success; } diff --git a/libs/hwui/tests/common/scenes/BitmapFillrate.cpp b/libs/hwui/tests/common/scenes/BitmapFillrate.cpp index 1d3d60716d68..5af7d43d7f66 100644 --- a/libs/hwui/tests/common/scenes/BitmapFillrate.cpp +++ b/libs/hwui/tests/common/scenes/BitmapFillrate.cpp @@ -31,7 +31,7 @@ static bool _BitmapFillrate( class BitmapFillrate : public TestScene { public: - BitmapFillrate(BitmapAllocationTestUtils::BitmapAllocator allocator) + explicit BitmapFillrate(BitmapAllocationTestUtils::BitmapAllocator allocator) : TestScene(), mAllocator(allocator) {} void createContent(int width, int height, Canvas& canvas) override { @@ -70,4 +70,4 @@ private: BitmapAllocationTestUtils::BitmapAllocator mAllocator; std::vector<sp<RenderNode> > mNodes; -};
\ No newline at end of file +}; diff --git a/libs/hwui/tests/common/scenes/BitmapShaders.cpp b/libs/hwui/tests/common/scenes/BitmapShaders.cpp index 15039b5fa976..4ecb54c9f0fd 100644 --- a/libs/hwui/tests/common/scenes/BitmapShaders.cpp +++ b/libs/hwui/tests/common/scenes/BitmapShaders.cpp @@ -26,7 +26,7 @@ static bool _BitmapShaders(BitmapAllocationTestUtils::registerBitmapAllocationSc class BitmapShaders : public TestScene { public: - BitmapShaders(BitmapAllocationTestUtils::BitmapAllocator allocator) + explicit BitmapShaders(BitmapAllocationTestUtils::BitmapAllocator allocator) : TestScene(), mAllocator(allocator) {} sp<RenderNode> card; diff --git a/libs/hwui/tests/common/scenes/TvApp.cpp b/libs/hwui/tests/common/scenes/TvApp.cpp index a64e8444a9b1..286f5f194aed 100644 --- a/libs/hwui/tests/common/scenes/TvApp.cpp +++ b/libs/hwui/tests/common/scenes/TvApp.cpp @@ -48,7 +48,7 @@ static bool _TvAppNoRoundedCornerColorFilter( class TvApp : public TestScene { public: - TvApp(BitmapAllocationTestUtils::BitmapAllocator allocator) + explicit TvApp(BitmapAllocationTestUtils::BitmapAllocator allocator) : TestScene(), mAllocator(allocator) {} sp<RenderNode> mBg; @@ -232,7 +232,7 @@ private: class TvAppNoRoundedCorner : public TvApp { public: - TvAppNoRoundedCorner(BitmapAllocationTestUtils::BitmapAllocator allocator) : TvApp(allocator) {} + explicit TvAppNoRoundedCorner(BitmapAllocationTestUtils::BitmapAllocator allocator) : TvApp(allocator) {} private: virtual float roundedCornerRadius() override { return dp(0); } @@ -240,7 +240,7 @@ private: class TvAppColorFilter : public TvApp { public: - TvAppColorFilter(BitmapAllocationTestUtils::BitmapAllocator allocator) : TvApp(allocator) {} + explicit TvAppColorFilter(BitmapAllocationTestUtils::BitmapAllocator allocator) : TvApp(allocator) {} private: virtual bool useOverlay() override { return false; } @@ -248,7 +248,7 @@ private: class TvAppNoRoundedCornerColorFilter : public TvApp { public: - TvAppNoRoundedCornerColorFilter(BitmapAllocationTestUtils::BitmapAllocator allocator) + explicit TvAppNoRoundedCornerColorFilter(BitmapAllocationTestUtils::BitmapAllocator allocator) : TvApp(allocator) {} private: diff --git a/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp b/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp index ad5fdacc8594..7deb0b1486ea 100644 --- a/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp +++ b/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp @@ -45,7 +45,7 @@ static void testProperty(std::function<void(RenderProperties&)> propSetupCallbac static const int CANVAS_HEIGHT = 100; class PropertyTestCanvas : public TestCanvasBase { public: - PropertyTestCanvas(std::function<void(const SkCanvas&)> callback) + explicit PropertyTestCanvas(std::function<void(const SkCanvas&)> callback) : TestCanvasBase(CANVAS_WIDTH, CANVAS_HEIGHT), mCallback(callback) {} void onDrawRect(const SkRect& rect, const SkPaint& paint) override { EXPECT_EQ(mDrawCounter++, 0); diff --git a/libs/hwui/tests/unit/ThreadBaseTests.cpp b/libs/hwui/tests/unit/ThreadBaseTests.cpp index 1168ff211202..817c1f3d3e43 100644 --- a/libs/hwui/tests/unit/ThreadBaseTests.cpp +++ b/libs/hwui/tests/unit/ThreadBaseTests.cpp @@ -95,7 +95,7 @@ TEST(ThreadBase, lifecyclePerf) { }; struct Counter { - Counter(EventCount* count) : mCount(count) { mCount->construct++; } + explicit Counter(EventCount* count) : mCount(count) { mCount->construct++; } Counter(const Counter& other) : mCount(other.mCount) { if (mCount) mCount->copy++; @@ -148,4 +148,4 @@ TEST(ThreadBase, lifecycle) { ASSERT_EQ(1, dummyObject->getStrongCount()); ASSERT_EQ(2, lifecycleTestHelper(dummyObject)); ASSERT_EQ(1, dummyObject->getStrongCount()); -}
\ No newline at end of file +} diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 190e99f7b221..6d10632a08cd 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -1313,16 +1313,17 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - public void notifyDataConnection(int state, boolean isDataAllowed, - String reason, String apn, String apnType, LinkProperties linkProperties, - NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { + public void notifyDataConnection(int state, boolean isDataAllowed, String apn, String apnType, + LinkProperties linkProperties, + NetworkCapabilities networkCapabilities, int networkType, + boolean roaming) { notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state, - isDataAllowed,reason, apn, apnType, linkProperties, - networkCapabilities, networkType, roaming); + isDataAllowed, apn, apnType, linkProperties, + networkCapabilities, networkType, roaming); } - public void notifyDataConnectionForSubscriber(int subId, int state, - boolean isDataAllowed, String reason, String apn, String apnType, + public void notifyDataConnectionForSubscriber(int subId, int state, boolean isDataAllowed, + String apn, String apnType, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { if (!checkNotifyPermission("notifyDataConnection()" )) { @@ -1331,7 +1332,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (VDBG) { log("notifyDataConnectionForSubscriber: subId=" + subId + " state=" + state + " isDataAllowed=" + isDataAllowed - + " reason='" + reason + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType + " mRecords.size()=" + mRecords.size()); } @@ -1366,7 +1366,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mDataConnectionNetworkType[phoneId] = networkType; } mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType, - apnType, apn, reason, linkProperties, ""); + apnType, apn, linkProperties, ""); for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { @@ -1381,30 +1381,29 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } handleRemoveListLocked(); } - broadcastDataConnectionStateChanged(state, isDataAllowed, reason, apn, - apnType, linkProperties, networkCapabilities, roaming, subId); - broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, reason, + broadcastDataConnectionStateChanged(state, isDataAllowed, apn, apnType, linkProperties, + networkCapabilities, roaming, subId); + broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, linkProperties, ""); } - public void notifyDataConnectionFailed(String reason, String apnType) { + public void notifyDataConnectionFailed(String apnType) { notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, - reason, apnType); + apnType); } - public void notifyDataConnectionFailedForSubscriber(int subId, - String reason, String apnType) { + public void notifyDataConnectionFailedForSubscriber(int subId, String apnType) { if (!checkNotifyPermission("notifyDataConnectionFailed()")) { return; } if (VDBG) { log("notifyDataConnectionFailedForSubscriber: subId=" + subId - + " reason=" + reason + " apnType=" + apnType); + + " apnType=" + apnType); } synchronized (mRecords) { mPreciseDataConnectionState = new PreciseDataConnectionState( TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN, - apnType, "", reason, null, ""); + apnType, "", null, ""); for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { @@ -1417,9 +1416,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } handleRemoveListLocked(); } - broadcastDataConnectionFailed(reason, apnType, subId); + broadcastDataConnectionFailed(apnType, subId); broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN, - TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", reason, null, ""); + TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", null, ""); } public void notifyCellLocation(Bundle cellLocation) { @@ -1529,15 +1528,14 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - public void notifyPreciseDataConnectionFailed(String reason, String apnType, - String apn, String failCause) { + public void notifyPreciseDataConnectionFailed(String apnType, String apn, String failCause) { if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) { return; } synchronized (mRecords) { mPreciseDataConnectionState = new PreciseDataConnectionState( TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN, - apnType, apn, reason, null, failCause); + apnType, apn, null, failCause); for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { @@ -1551,7 +1549,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { handleRemoveListLocked(); } broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN, - TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause); + TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, null, failCause); } @Override @@ -1882,10 +1880,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { android.Manifest.permission.READ_CALL_LOG}); } - private void broadcastDataConnectionStateChanged(int state, - boolean isDataAllowed, - String reason, String apn, String apnType, LinkProperties linkProperties, - NetworkCapabilities networkCapabilities, boolean roaming, int subId) { + private void broadcastDataConnectionStateChanged(int state, boolean isDataAllowed, String apn, + String apnType, LinkProperties linkProperties, + NetworkCapabilities networkCapabilities, + boolean roaming, int subId) { // Note: not reporting to the battery stats service here, because the // status bar takes care of that after taking into account all of the // required info. @@ -1895,9 +1893,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (!isDataAllowed) { intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true); } - if (reason != null) { - intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); - } if (linkProperties != null) { intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties); String iface = linkProperties.getInterfaceName(); @@ -1916,17 +1911,15 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); } - private void broadcastDataConnectionFailed(String reason, String apnType, - int subId) { + private void broadcastDataConnectionFailed(String apnType, int subId) { Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED); - intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason); intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); } private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState, - int backgroundCallState) { + int backgroundCallState) { Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED); intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState); intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState); @@ -1936,16 +1929,16 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } private void broadcastPreciseDataConnectionStateChanged(int state, int networkType, - String apnType, String apn, String reason, LinkProperties linkProperties, - String failCause) { + String apnType, String apn, + LinkProperties linkProperties, + String failCause) { Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED); intent.putExtra(PhoneConstants.STATE_KEY, state); intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType); - if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); if (linkProperties != null) { - intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY,linkProperties); + intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties); } if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause); diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index 9684f4c4ae19..2a000252d6f4 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -126,21 +126,21 @@ public class NetworkMonitor extends StateMachine { private static final int DEFAULT_DATA_STALL_EVALUATION_TYPES = (1 << DATA_STALL_EVALUATION_TYPE_DNS); - static enum EvaluationResult { + enum EvaluationResult { VALIDATED(true), CAPTIVE_PORTAL(false); - final boolean isValidated; + final boolean mIsValidated; EvaluationResult(boolean isValidated) { - this.isValidated = isValidated; + this.mIsValidated = isValidated; } } - static enum ValidationStage { + enum ValidationStage { FIRST_VALIDATION(true), REVALIDATION(false); - final boolean isFirstValidation; + final boolean mIsFirstValidation; ValidationStage(boolean isFirstValidation) { - this.isFirstValidation = isFirstValidation; + this.mIsFirstValidation = isFirstValidation; } } @@ -251,7 +251,7 @@ public class NetworkMonitor extends StateMachine { // Start mReevaluateDelayMs at this value and double. private static final int INITIAL_REEVALUATE_DELAY_MS = 1000; - private static final int MAX_REEVALUATE_DELAY_MS = 10*60*1000; + private static final int MAX_REEVALUATE_DELAY_MS = 10 * 60 * 1000; // Before network has been evaluated this many times, ignore repeated reevaluate requests. private static final int IGNORE_REEVALUATE_ATTEMPTS = 5; private int mReevaluateToken = 0; @@ -261,7 +261,7 @@ public class NetworkMonitor extends StateMachine { // Stop blaming UID that requested re-evaluation after this many attempts. private static final int BLAME_FOR_EVALUATION_ATTEMPTS = 5; // Delay between reevaluations once a captive portal has been found. - private static final int CAPTIVE_PORTAL_REEVALUATE_DELAY_MS = 10*60*1000; + private static final int CAPTIVE_PORTAL_REEVALUATE_DELAY_MS = 10 * 60 * 1000; private static final int NUM_VALIDATION_LOG_LINES = 20; @@ -393,10 +393,17 @@ public class NetworkMonitor extends StateMachine { start(); } + /** + * Request the NetworkMonitor to reevaluate the network. + */ public void forceReevaluation(int responsibleUid) { sendMessage(CMD_FORCE_REEVALUATION, responsibleUid, 0); } + /** + * Send a notification to NetworkMonitor indicating that private DNS settings have changed. + * @param newCfg The new private DNS configuration. + */ public void notifyPrivateDnsSettingsChanged(PrivateDnsConfig newCfg) { // Cancel any outstanding resolutions. removeMessages(CMD_PRIVATE_DNS_SETTINGS_CHANGED); @@ -655,8 +662,9 @@ public class NetworkMonitor extends StateMachine { public boolean processMessage(Message message) { switch (message.what) { case CMD_REEVALUATE: - if (message.arg1 != mReevaluateToken || mUserDoesNotWant) + if (message.arg1 != mReevaluateToken || mUserDoesNotWant) { return HANDLED; + } // Don't bother validating networks that don't satisfy the default request. // This includes: // - VPNs which can be considered explicitly desired by the user and the @@ -813,9 +821,9 @@ public class NetworkMonitor extends StateMachine { } private boolean isStrictModeHostnameResolved() { - return (mPrivateDnsConfig != null) && - mPrivateDnsConfig.hostname.equals(mPrivateDnsProviderHostname) && - (mPrivateDnsConfig.ips.length > 0); + return (mPrivateDnsConfig != null) + && mPrivateDnsConfig.hostname.equals(mPrivateDnsProviderHostname) + && (mPrivateDnsConfig.ips.length > 0); } private void resolveStrictModeHostname() { @@ -852,9 +860,9 @@ public class NetworkMonitor extends StateMachine { private boolean sendPrivateDnsProbe() { // q.v. system/netd/server/dns/DnsTlsTransport.cpp - final String ONE_TIME_HOSTNAME_SUFFIX = "-dnsotls-ds.metric.gstatic.com"; - final String host = UUID.randomUUID().toString().substring(0, 8) + - ONE_TIME_HOSTNAME_SUFFIX; + final String oneTimeHostnameSuffix = "-dnsotls-ds.metric.gstatic.com"; + final String host = UUID.randomUUID().toString().substring(0, 8) + + oneTimeHostnameSuffix; final Stopwatch watch = new Stopwatch().start(); try { final InetAddress[] ips = mNetworkAgentInfo.network().getAllByName(host); @@ -966,7 +974,7 @@ public class NetworkMonitor extends StateMachine { // most one per address family. This ensures we only wait up to 20 seconds for TCP connections // to complete, regardless of how many IP addresses a host has. private static class OneAddressPerFamilyNetwork extends Network { - public OneAddressPerFamilyNetwork(Network network) { + OneAddressPerFamilyNetwork(Network network) { // Always bypass Private DNS. super(network.getPrivateDnsBypassingCopy()); } @@ -1000,7 +1008,8 @@ public class NetworkMonitor extends StateMachine { } public boolean getWifiScansAlwaysAvailableDisabled() { - return mDependencies.getSetting(mContext, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 0; + return mDependencies.getSetting( + mContext, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 0; } private String getCaptivePortalServerHttpsUrl() { @@ -1246,10 +1255,10 @@ public class NetworkMonitor extends StateMachine { // Time how long it takes to get a response to our request long responseTimestamp = SystemClock.elapsedRealtime(); - validationLog(probeType, url, "time=" + (responseTimestamp - requestTimestamp) + "ms" + - " ret=" + httpResponseCode + - " request=" + requestHeader + - " headers=" + urlConnection.getHeaderFields()); + validationLog(probeType, url, "time=" + (responseTimestamp - requestTimestamp) + "ms" + + " ret=" + httpResponseCode + + " request=" + requestHeader + + " headers=" + urlConnection.getHeaderFields()); // NOTE: We may want to consider an "HTTP/1.0 204" response to be a captive // portal. The only example of this seen so far was a captive portal. For // the time being go with prior behavior of assuming it's not a captive @@ -1267,7 +1276,7 @@ public class NetworkMonitor extends StateMachine { // sign-in to an empty page. Probably the result of a broken transparent proxy. // See http://b/9972012. validationLog(probeType, url, - "200 response with Content-length=0 interpreted as 204 response."); + "200 response with Content-length=0 interpreted as 204 response."); httpResponseCode = CaptivePortalProbeResult.SUCCESS_CODE; } else if (urlConnection.getContentLengthLong() == -1) { // When no Content-length (default value == -1), attempt to read a byte from the @@ -1309,7 +1318,7 @@ public class NetworkMonitor extends StateMachine { private final boolean mIsHttps; private volatile CaptivePortalProbeResult mResult = CaptivePortalProbeResult.FAILED; - public ProbeThread(boolean isHttps) { + ProbeThread(boolean isHttps) { mIsHttps = isHttps; } @@ -1443,8 +1452,10 @@ public class NetworkMonitor extends StateMachine { if (cellInfo.isRegistered()) { numRegisteredCellInfo++; if (numRegisteredCellInfo > 1) { - if (VDBG) logw("more than one registered CellInfo." + - " Can't tell which is active. Bailing."); + if (VDBG) { + logw("more than one registered CellInfo." + + " Can't tell which is active. Bailing."); + } return; } if (cellInfo instanceof CellInfoCdma) { @@ -1492,14 +1503,14 @@ public class NetworkMonitor extends StateMachine { } private int networkEventType(ValidationStage s, EvaluationResult r) { - if (s.isFirstValidation) { - if (r.isValidated) { + if (s.mIsFirstValidation) { + if (r.mIsValidated) { return NetworkEvent.NETWORK_FIRST_VALIDATION_SUCCESS; } else { return NetworkEvent.NETWORK_FIRST_VALIDATION_PORTAL_FOUND; } } else { - if (r.isValidated) { + if (r.mIsValidated) { return NetworkEvent.NETWORK_REVALIDATION_SUCCESS; } else { return NetworkEvent.NETWORK_REVALIDATION_PORTAL_FOUND; @@ -1517,7 +1528,7 @@ public class NetworkMonitor extends StateMachine { private void logValidationProbe(long durationMs, int probeType, int probeResult) { int[] transports = mNetworkAgentInfo.networkCapabilities.getTransportTypes(); - boolean isFirstValidation = validationStage().isFirstValidation; + boolean isFirstValidation = validationStage().mIsFirstValidation; ValidationProbeEvent ev = new ValidationProbeEvent(); ev.probeType = ValidationProbeEvent.makeProbeType(probeType, isFirstValidation); ev.returnCode = probeResult; @@ -1535,10 +1546,20 @@ public class NetworkMonitor extends StateMachine { return new Random(); } + /** + * Get the value of a global integer setting. + * @param symbol Name of the setting + * @param defaultValue Value to return if the setting is not defined. + */ public int getSetting(Context context, String symbol, int defaultValue) { return Settings.Global.getInt(context.getContentResolver(), symbol, defaultValue); } + /** + * Get the value of a global String setting. + * @param symbol Name of the setting + * @param defaultValue Value to return if the setting is not defined. + */ public String getSetting(Context context, String symbol, String defaultValue) { final String value = Settings.Global.getString(context.getContentResolver(), symbol); return value != null ? value : defaultValue; diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java index d56b167b9a75..7daf71dda73b 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java +++ b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java @@ -34,32 +34,53 @@ import java.util.ArrayList; * @hide */ public class TetheringDependencies { + /** + * Get a reference to the offload hardware interface to be used by tethering. + */ public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) { return new OffloadHardwareInterface(h, log); } + /** + * Get a reference to the UpstreamNetworkMonitor to be used by tethering. + */ public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx, StateMachine target, SharedLog log, int what) { return new UpstreamNetworkMonitor(ctx, target, log, what); } + /** + * Get a reference to the IPv6TetheringCoordinator to be used by tethering. + */ public IPv6TetheringCoordinator getIPv6TetheringCoordinator( ArrayList<IpServer> notifyList, SharedLog log) { return new IPv6TetheringCoordinator(notifyList, log); } + /** + * Get dependencies to be used by IpServer. + */ public IpServer.Dependencies getIpServerDependencies() { return new IpServer.Dependencies(); } + /** + * Indicates whether tethering is supported on the device. + */ public boolean isTetheringSupported() { return true; } + /** + * Get the NetworkRequest that should be fulfilled by the default network. + */ public NetworkRequest getDefaultNetworkRequest() { return null; } + /** + * Get a reference to the EntitlementManager to be used by tethering. + */ public EntitlementManager getEntitlementManager(Context ctx, SharedLog log, MockableSystemProperties systemProperties) { return new EntitlementManager(ctx, log, systemProperties); diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 9fa42ab024b9..e539ffd5a85f 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -270,14 +270,12 @@ import java.util.concurrent.TimeUnit; * enforcement. * * <p> - * This class uses 2-3 locks to synchronize state: + * This class uses 2 locks to synchronize state: * <ul> * <li>{@code mUidRulesFirstLock}: used to guard state related to individual UIDs (such as firewall * rules). * <li>{@code mNetworkPoliciesSecondLock}: used to guard state related to network interfaces (such * as network policies). - * <li>{@code allLocks}: not a "real" lock, but an indication (through @GuardedBy) that all locks - * must be held. * </ul> * * <p> @@ -419,7 +417,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final Object mUidRulesFirstLock = new Object(); final Object mNetworkPoliciesSecondLock = new Object(); - @GuardedBy("allLocks") volatile boolean mSystemReady; + @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"}) + volatile boolean mSystemReady; @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackground; @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictPower; @@ -545,7 +544,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private final ServiceThread mUidEventThread; - @GuardedBy("allLocks") + @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"}) private final AtomicFile mPolicyFile; private final AppOpsManager mAppOps; diff --git a/services/net/java/android/net/dhcp/DhcpLease.java b/services/net/java/android/net/dhcp/DhcpLease.java index 6cdd2aa8579d..6849cfadc22a 100644 --- a/services/net/java/android/net/dhcp/DhcpLease.java +++ b/services/net/java/android/net/dhcp/DhcpLease.java @@ -58,6 +58,11 @@ public class DhcpLease { mHostname = hostname; } + /** + * Get the clientId associated with this lease, if any. + * + * <p>If the lease is not associated to a clientId, this returns null. + */ @Nullable public byte[] getClientId() { if (mClientId == null) { @@ -97,6 +102,11 @@ public class DhcpLease { (hostname == null ? mHostname : hostname)); } + /** + * Determine whether this lease matches a client with the specified parameters. + * @param clientId clientId of the client if any, or null otherwise. + * @param hwAddr Hardware address of the client. + */ public boolean matchesClient(@Nullable byte[] clientId, @NonNull MacAddress hwAddr) { if (mClientId != null) { return Arrays.equals(mClientId, clientId); @@ -110,7 +120,7 @@ public class DhcpLease { if (!(obj instanceof DhcpLease)) { return false; } - final DhcpLease other = (DhcpLease)obj; + final DhcpLease other = (DhcpLease) obj; return Arrays.equals(mClientId, other.mClientId) && mHwAddr.equals(other.mHwAddr) && mNetAddr.equals(other.mNetAddr) diff --git a/services/net/java/android/net/dhcp/DhcpLeaseRepository.java b/services/net/java/android/net/dhcp/DhcpLeaseRepository.java index 2dda42124c75..b3d0512ba447 100644 --- a/services/net/java/android/net/dhcp/DhcpLeaseRepository.java +++ b/services/net/java/android/net/dhcp/DhcpLeaseRepository.java @@ -29,8 +29,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.net.IpPrefix; import android.net.MacAddress; -import android.net.util.SharedLog; import android.net.dhcp.DhcpServer.Clock; +import android.net.util.SharedLog; import android.util.ArrayMap; import java.net.Inet4Address; @@ -117,7 +117,7 @@ class DhcpLeaseRepository { */ private final LinkedHashMap<Inet4Address, Long> mDeclinedAddrs = new LinkedHashMap<>(); - public DhcpLeaseRepository(@NonNull IpPrefix prefix, @NonNull Set<Inet4Address> reservedAddrs, + DhcpLeaseRepository(@NonNull IpPrefix prefix, @NonNull Set<Inet4Address> reservedAddrs, long leaseTimeMs, @NonNull SharedLog log, @NonNull Clock clock) { updateParams(prefix, reservedAddrs, leaseTimeMs); mLog = log; @@ -250,8 +250,8 @@ class DhcpLeaseRepository { // reqAddr null (RENEWING/REBINDING): client renewing its own lease for clientAddr. // reqAddr set with sid not set (INIT-REBOOT): client verifying configuration. // In both cases, throw if clientAddr or reqAddr does not match the known lease. - throw new InvalidAddressException("Incorrect address for client in " + - (reqAddr != null ? "INIT-REBOOT" : "RENEWING/REBINDING")); + throw new InvalidAddressException("Incorrect address for client in " + + (reqAddr != null ? "INIT-REBOOT" : "RENEWING/REBINDING")); } } diff --git a/services/net/java/android/net/dhcp/DhcpPacketListener.java b/services/net/java/android/net/dhcp/DhcpPacketListener.java index 6f620c5ce30e..dce8b619494e 100644 --- a/services/net/java/android/net/dhcp/DhcpPacketListener.java +++ b/services/net/java/android/net/dhcp/DhcpPacketListener.java @@ -32,32 +32,32 @@ import java.net.InetSocketAddress; */ abstract class DhcpPacketListener extends FdEventsReader<DhcpPacketListener.Payload> { static final class Payload { - final byte[] bytes = new byte[DhcpPacket.MAX_LENGTH]; - Inet4Address srcAddr; - int srcPort; + protected final byte[] mBytes = new byte[DhcpPacket.MAX_LENGTH]; + protected Inet4Address mSrcAddr; + protected int mSrcPort; } - public DhcpPacketListener(@NonNull Handler handler) { + DhcpPacketListener(@NonNull Handler handler) { super(handler, new Payload()); } @Override protected int recvBufSize(@NonNull Payload buffer) { - return buffer.bytes.length; + return buffer.mBytes.length; } @Override protected final void handlePacket(@NonNull Payload recvbuf, int length) { - if (recvbuf.srcAddr == null) { + if (recvbuf.mSrcAddr == null) { return; } try { - final DhcpPacket packet = DhcpPacket.decodeFullPacket(recvbuf.bytes, length, + final DhcpPacket packet = DhcpPacket.decodeFullPacket(recvbuf.mBytes, length, DhcpPacket.ENCAP_BOOTP); - onReceive(packet, recvbuf.srcAddr, recvbuf.srcPort); + onReceive(packet, recvbuf.mSrcAddr, recvbuf.mSrcPort); } catch (DhcpPacket.ParseException e) { - logParseError(recvbuf.bytes, length, e); + logParseError(recvbuf.mBytes, length, e); } } @@ -66,11 +66,11 @@ abstract class DhcpPacketListener extends FdEventsReader<DhcpPacketListener.Payl throws Exception { final InetSocketAddress addr = new InetSocketAddress(); final int read = Os.recvfrom( - fd, packetBuffer.bytes, 0, packetBuffer.bytes.length, 0 /* flags */, addr); + fd, packetBuffer.mBytes, 0, packetBuffer.mBytes.length, 0 /* flags */, addr); // Buffers with null srcAddr will be dropped in handlePacket() - packetBuffer.srcAddr = inet4AddrOrNull(addr); - packetBuffer.srcPort = addr.getPort(); + packetBuffer.mSrcAddr = inet4AddrOrNull(addr); + packetBuffer.mSrcPort = addr.getPort(); return read; } diff --git a/services/net/java/android/net/dhcp/DhcpServer.java b/services/net/java/android/net/dhcp/DhcpServer.java index 35d29e75c0e4..641bba2ed306 100644 --- a/services/net/java/android/net/dhcp/DhcpServer.java +++ b/services/net/java/android/net/dhcp/DhcpServer.java @@ -101,6 +101,13 @@ public class DhcpServer { @NonNull private DhcpServingParams mServingParams; + /** + * Clock to be used by DhcpServer to track time for lease expiration. + * + * <p>The clock should track time as may be measured by clients obtaining a lease. It does not + * need to be monotonous across restarts of the server as long as leases are cleared when the + * server is stopped. + */ public static class Clock { /** * @see SystemClock#elapsedRealtime() @@ -110,13 +117,43 @@ public class DhcpServer { } } + /** + * Dependencies for the DhcpServer. Useful to be mocked in tests. + */ public interface Dependencies { + /** + * Send a packet to the specified datagram socket. + * + * @param fd File descriptor of the socket. + * @param buffer Data to be sent. + * @param dst Destination address of the packet. + */ void sendPacket(@NonNull FileDescriptor fd, @NonNull ByteBuffer buffer, @NonNull InetAddress dst) throws ErrnoException, IOException; + + /** + * Create a DhcpLeaseRepository for the server. + * @param servingParams Parameters used to serve DHCP requests. + * @param log Log to be used by the repository. + * @param clock Clock that the repository must use to track time. + */ DhcpLeaseRepository makeLeaseRepository(@NonNull DhcpServingParams servingParams, @NonNull SharedLog log, @NonNull Clock clock); + + /** + * Create a packet listener that will send packets to be processed. + */ DhcpPacketListener makePacketListener(); + + /** + * Create a clock that the server will use to track time. + */ Clock makeClock(); + + /** + * Add an entry to the ARP cache table. + * @param fd Datagram socket file descriptor that must use the new entry. + */ void addArpEntry(@NonNull Inet4Address ipv4Addr, @NonNull MacAddress ethAddr, @NonNull String ifname, @NonNull FileDescriptor fd) throws IOException; } @@ -134,7 +171,7 @@ public class DhcpServer { return new DhcpLeaseRepository( DhcpServingParams.makeIpPrefix(servingParams.serverAddr), servingParams.excludedAddrs, - servingParams.dhcpLeaseTimeSecs*1000, log.forSubComponent(REPO_TAG), clock); + servingParams.dhcpLeaseTimeSecs * 1000, log.forSubComponent(REPO_TAG), clock); } @Override @@ -212,7 +249,7 @@ public class DhcpServer { } private class ServerHandler extends Handler { - public ServerHandler(@NonNull Looper looper) { + ServerHandler(@NonNull Looper looper) { super(looper); } @@ -496,22 +533,24 @@ public class DhcpServer { } private class PacketListener extends DhcpPacketListener { - public PacketListener() { + PacketListener() { super(mHandler); } @Override - protected void onReceive(DhcpPacket packet, Inet4Address srcAddr, int srcPort) { + protected void onReceive(@NonNull DhcpPacket packet, @NonNull Inet4Address srcAddr, + int srcPort) { processPacket(packet, srcPort); } @Override - protected void logError(String msg, Exception e) { + protected void logError(@NonNull String msg, Exception e) { mLog.e("Error receiving packet: " + msg, e); } @Override - protected void logParseError(byte[] packet, int length, DhcpPacket.ParseException e) { + protected void logParseError(@NonNull byte[] packet, int length, + @NonNull DhcpPacket.ParseException e) { mLog.e("Error parsing packet", e); } diff --git a/services/net/java/android/net/dhcp/DhcpServingParams.java b/services/net/java/android/net/dhcp/DhcpServingParams.java index df15ba1c5507..2780814a2f33 100644 --- a/services/net/java/android/net/dhcp/DhcpServingParams.java +++ b/services/net/java/android/net/dhcp/DhcpServingParams.java @@ -17,6 +17,7 @@ package android.net.dhcp; import static android.net.NetworkUtils.getPrefixMaskAsInet4Address; +import static android.net.NetworkUtils.intToInet4AddressHTH; import static android.net.dhcp.DhcpPacket.INFINITE_LEASE; import static android.net.util.NetworkConstants.IPV4_MAX_MTU; import static android.net.util.NetworkConstants.IPV4_MIN_MTU; @@ -24,6 +25,7 @@ import static android.net.util.NetworkConstants.IPV4_MIN_MTU; import static java.lang.Integer.toUnsignedLong; import android.annotation.NonNull; +import android.annotation.Nullable; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.NetworkUtils; @@ -103,6 +105,37 @@ public class DhcpServingParams { this.metered = metered; } + /** + * Create parameters from a stable AIDL-compatible parcel. + */ + public static DhcpServingParams fromParcelableObject(@NonNull DhcpServingParamsParcel parcel) + throws InvalidParameterException { + final LinkAddress serverAddr = new LinkAddress( + intToInet4AddressHTH(parcel.serverAddr), + parcel.serverAddrPrefixLength); + return new Builder() + .setServerAddr(serverAddr) + .setDefaultRouters(toInet4AddressSet(parcel.defaultRouters)) + .setDnsServers(toInet4AddressSet(parcel.dnsServers)) + .setExcludedAddrs(toInet4AddressSet(parcel.excludedAddrs)) + .setDhcpLeaseTimeSecs(parcel.dhcpLeaseTimeSecs) + .setLinkMtu(parcel.linkMtu) + .setMetered(parcel.metered) + .build(); + } + + private static Set<Inet4Address> toInet4AddressSet(@Nullable int[] addrs) { + if (addrs == null) { + return new HashSet<>(0); + } + + final HashSet<Inet4Address> res = new HashSet<>(); + for (int addr : addrs) { + res.add(intToInet4AddressHTH(addr)); + } + return res; + } + @NonNull public Inet4Address getServerInet4Addr() { return (Inet4Address) serverAddr.getAddress(); @@ -134,13 +167,13 @@ public class DhcpServingParams { * of the parameters. */ public static class Builder { - private LinkAddress serverAddr; - private Set<Inet4Address> defaultRouters; - private Set<Inet4Address> dnsServers; - private Set<Inet4Address> excludedAddrs; - private long dhcpLeaseTimeSecs; - private int linkMtu = MTU_UNSET; - private boolean metered; + private LinkAddress mServerAddr; + private Set<Inet4Address> mDefaultRouters; + private Set<Inet4Address> mDnsServers; + private Set<Inet4Address> mExcludedAddrs; + private long mDhcpLeaseTimeSecs; + private int mLinkMtu = MTU_UNSET; + private boolean mMetered; /** * Set the server address and served prefix for the DHCP server. @@ -148,7 +181,7 @@ public class DhcpServingParams { * <p>This parameter is required. */ public Builder setServerAddr(@NonNull LinkAddress serverAddr) { - this.serverAddr = serverAddr; + this.mServerAddr = serverAddr; return this; } @@ -159,7 +192,7 @@ public class DhcpServingParams { * always be set explicitly before building the {@link DhcpServingParams}. */ public Builder setDefaultRouters(@NonNull Set<Inet4Address> defaultRouters) { - this.defaultRouters = defaultRouters; + this.mDefaultRouters = defaultRouters; return this; } @@ -189,7 +222,7 @@ public class DhcpServingParams { * {@link DhcpServingParams}. */ public Builder setDnsServers(@NonNull Set<Inet4Address> dnsServers) { - this.dnsServers = dnsServers; + this.mDnsServers = dnsServers; return this; } @@ -219,7 +252,7 @@ public class DhcpServingParams { * and do not need to be set here. */ public Builder setExcludedAddrs(@NonNull Set<Inet4Address> excludedAddrs) { - this.excludedAddrs = excludedAddrs; + this.mExcludedAddrs = excludedAddrs; return this; } @@ -239,7 +272,7 @@ public class DhcpServingParams { * <p>This parameter is required. */ public Builder setDhcpLeaseTimeSecs(long dhcpLeaseTimeSecs) { - this.dhcpLeaseTimeSecs = dhcpLeaseTimeSecs; + this.mDhcpLeaseTimeSecs = dhcpLeaseTimeSecs; return this; } @@ -250,7 +283,7 @@ public class DhcpServingParams { * is optional and defaults to {@link #MTU_UNSET}. */ public Builder setLinkMtu(int linkMtu) { - this.linkMtu = linkMtu; + this.mLinkMtu = linkMtu; return this; } @@ -260,7 +293,7 @@ public class DhcpServingParams { * <p>If not set, the default value is false. */ public Builder setMetered(boolean metered) { - this.metered = metered; + this.mMetered = metered; return this; } @@ -274,54 +307,57 @@ public class DhcpServingParams { */ @NonNull public DhcpServingParams build() throws InvalidParameterException { - if (serverAddr == null) { + if (mServerAddr == null) { throw new InvalidParameterException("Missing serverAddr"); } - if (defaultRouters == null) { + if (mDefaultRouters == null) { throw new InvalidParameterException("Missing defaultRouters"); } - if (dnsServers == null) { + if (mDnsServers == null) { // Empty set is OK, but enforce explicitly setting it throw new InvalidParameterException("Missing dnsServers"); } - if (dhcpLeaseTimeSecs <= 0 || dhcpLeaseTimeSecs > toUnsignedLong(INFINITE_LEASE)) { - throw new InvalidParameterException("Invalid lease time: " + dhcpLeaseTimeSecs); + if (mDhcpLeaseTimeSecs <= 0 || mDhcpLeaseTimeSecs > toUnsignedLong(INFINITE_LEASE)) { + throw new InvalidParameterException("Invalid lease time: " + mDhcpLeaseTimeSecs); } - if (linkMtu != MTU_UNSET && (linkMtu < IPV4_MIN_MTU || linkMtu > IPV4_MAX_MTU)) { - throw new InvalidParameterException("Invalid link MTU: " + linkMtu); + if (mLinkMtu != MTU_UNSET && (mLinkMtu < IPV4_MIN_MTU || mLinkMtu > IPV4_MAX_MTU)) { + throw new InvalidParameterException("Invalid link MTU: " + mLinkMtu); } - if (!serverAddr.isIPv4()) { + if (!mServerAddr.isIPv4()) { throw new InvalidParameterException("serverAddr must be IPv4"); } - if (serverAddr.getPrefixLength() < MIN_PREFIX_LENGTH - || serverAddr.getPrefixLength() > MAX_PREFIX_LENGTH) { + if (mServerAddr.getPrefixLength() < MIN_PREFIX_LENGTH + || mServerAddr.getPrefixLength() > MAX_PREFIX_LENGTH) { throw new InvalidParameterException("Prefix length is not in supported range"); } - final IpPrefix prefix = makeIpPrefix(serverAddr); - for (Inet4Address addr : defaultRouters) { + final IpPrefix prefix = makeIpPrefix(mServerAddr); + for (Inet4Address addr : mDefaultRouters) { if (!prefix.contains(addr)) { throw new InvalidParameterException(String.format( - "Default router %s is not in server prefix %s", addr, serverAddr)); + "Default router %s is not in server prefix %s", addr, mServerAddr)); } } final Set<Inet4Address> excl = new HashSet<>(); - if (excludedAddrs != null) { - excl.addAll(excludedAddrs); + if (mExcludedAddrs != null) { + excl.addAll(mExcludedAddrs); } - excl.add((Inet4Address) serverAddr.getAddress()); - excl.addAll(defaultRouters); - excl.addAll(dnsServers); + excl.add((Inet4Address) mServerAddr.getAddress()); + excl.addAll(mDefaultRouters); + excl.addAll(mDnsServers); - return new DhcpServingParams(serverAddr, - Collections.unmodifiableSet(new HashSet<>(defaultRouters)), - Collections.unmodifiableSet(new HashSet<>(dnsServers)), + return new DhcpServingParams(mServerAddr, + Collections.unmodifiableSet(new HashSet<>(mDefaultRouters)), + Collections.unmodifiableSet(new HashSet<>(mDnsServers)), Collections.unmodifiableSet(excl), - dhcpLeaseTimeSecs, linkMtu, metered); + mDhcpLeaseTimeSecs, mLinkMtu, mMetered); } } + /** + * Utility method to create an IpPrefix with the address and prefix length of a LinkAddress. + */ @NonNull static IpPrefix makeIpPrefix(@NonNull LinkAddress addr) { return new IpPrefix(addr.getAddress(), addr.getPrefixLength()); diff --git a/services/net/java/android/net/dhcp/DhcpServingParamsParcelExt.java b/services/net/java/android/net/dhcp/DhcpServingParamsParcelExt.java new file mode 100644 index 000000000000..f068c3ac16e2 --- /dev/null +++ b/services/net/java/android/net/dhcp/DhcpServingParamsParcelExt.java @@ -0,0 +1,172 @@ +/* + * 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.net.dhcp; + +import static android.net.NetworkUtils.inet4AddressToIntHTH; + +import android.annotation.NonNull; +import android.net.LinkAddress; + +import com.google.android.collect.Sets; + +import java.net.Inet4Address; +import java.util.Collection; +import java.util.Set; + +/** + * Subclass of {@link DhcpServingParamsParcel} with additional utility methods for building. + * + * <p>This utility class does not check for validity of the parameters: invalid parameters are + * reported by the receiving module when unparceling the parcel. + * + * @see DhcpServingParams + * @hide + */ +public class DhcpServingParamsParcelExt extends DhcpServingParamsParcel { + public static final int MTU_UNSET = 0; + + /** + * Set the server address and served prefix for the DHCP server. + * + * <p>This parameter is required. + */ + public DhcpServingParamsParcelExt setServerAddr(@NonNull LinkAddress serverAddr) { + this.serverAddr = inet4AddressToIntHTH((Inet4Address) serverAddr.getAddress()); + this.serverAddrPrefixLength = serverAddr.getPrefixLength(); + return this; + } + + /** + * Set the default routers to be advertised to DHCP clients. + * + * <p>Each router must be inside the served prefix. This may be an empty set, but it must + * always be set explicitly. + */ + public DhcpServingParamsParcelExt setDefaultRouters(@NonNull Set<Inet4Address> defaultRouters) { + this.defaultRouters = toIntArray(defaultRouters); + return this; + } + + /** + * Set the default routers to be advertised to DHCP clients. + * + * <p>Each router must be inside the served prefix. This may be an empty list of routers, + * but it must always be set explicitly. + */ + public DhcpServingParamsParcelExt setDefaultRouters(@NonNull Inet4Address... defaultRouters) { + return setDefaultRouters(Sets.newArraySet(defaultRouters)); + } + + /** + * Convenience method to build the parameters with no default router. + * + * <p>Equivalent to calling {@link #setDefaultRouters(Inet4Address...)} with no address. + */ + public DhcpServingParamsParcelExt setNoDefaultRouter() { + return setDefaultRouters(); + } + + /** + * Set the DNS servers to be advertised to DHCP clients. + * + * <p>This may be an empty set, but it must always be set explicitly. + */ + public DhcpServingParamsParcelExt setDnsServers(@NonNull Set<Inet4Address> dnsServers) { + this.dnsServers = toIntArray(dnsServers); + return this; + } + + /** + * Set the DNS servers to be advertised to DHCP clients. + * + * <p>This may be an empty list of servers, but it must always be set explicitly. + */ + public DhcpServingParamsParcelExt setDnsServers(@NonNull Inet4Address... dnsServers) { + return setDnsServers(Sets.newArraySet(dnsServers)); + } + + /** + * Convenience method to build the parameters with no DNS server. + * + * <p>Equivalent to calling {@link #setDnsServers(Inet4Address...)} with no address. + */ + public DhcpServingParamsParcelExt setNoDnsServer() { + return setDnsServers(); + } + + /** + * Set excluded addresses that the DHCP server is not allowed to assign to clients. + * + * <p>This parameter is optional. DNS servers and default routers are always excluded + * and do not need to be set here. + */ + public DhcpServingParamsParcelExt setExcludedAddrs(@NonNull Set<Inet4Address> excludedAddrs) { + this.excludedAddrs = toIntArray(excludedAddrs); + return this; + } + + /** + * Set excluded addresses that the DHCP server is not allowed to assign to clients. + * + * <p>This parameter is optional. DNS servers and default routers are always excluded + * and do not need to be set here. + */ + public DhcpServingParamsParcelExt setExcludedAddrs(@NonNull Inet4Address... excludedAddrs) { + return setExcludedAddrs(Sets.newArraySet(excludedAddrs)); + } + + /** + * Set the lease time for leases assigned by the DHCP server. + * + * <p>This parameter is required. + */ + public DhcpServingParamsParcelExt setDhcpLeaseTimeSecs(long dhcpLeaseTimeSecs) { + this.dhcpLeaseTimeSecs = dhcpLeaseTimeSecs; + return this; + } + + /** + * Set the link MTU to be advertised to DHCP clients. + * + * <p>If set to {@link #MTU_UNSET}, no MTU will be advertised to clients. This parameter + * is optional and defaults to {@link #MTU_UNSET}. + */ + public DhcpServingParamsParcelExt setLinkMtu(int linkMtu) { + this.linkMtu = linkMtu; + return this; + } + + /** + * Set whether the DHCP server should send the ANDROID_METERED vendor-specific option. + * + * <p>If not set, the default value is false. + */ + public DhcpServingParamsParcelExt setMetered(boolean metered) { + this.metered = metered; + return this; + } + + private static int[] toIntArray(@NonNull Collection<Inet4Address> addrs) { + int[] res = new int[addrs.size()]; + int i = 0; + for (Inet4Address addr : addrs) { + res[i] = inet4AddressToIntHTH(addr); + i++; + } + return res; + } +} diff --git a/services/net/java/android/net/util/SharedLog.java b/services/net/java/android/net/util/SharedLog.java index 5a73a4e492ee..74bc1470293f 100644 --- a/services/net/java/android/net/util/SharedLog.java +++ b/services/net/java/android/net/util/SharedLog.java @@ -35,8 +35,8 @@ import java.util.StringJoiner; * @hide */ public class SharedLog { - private final static int DEFAULT_MAX_RECORDS = 500; - private final static String COMPONENT_DELIMITER = "."; + private static final int DEFAULT_MAX_RECORDS = 500; + private static final String COMPONENT_DELIMITER = "."; private enum Category { NONE, @@ -69,6 +69,9 @@ public class SharedLog { mComponent = component; } + /** + * Create a SharedLog based on this log with an additional component prefix on each logged line. + */ public SharedLog forSubComponent(String component) { if (!isRootLogInstance()) { component = mComponent + COMPONENT_DELIMITER + component; @@ -76,6 +79,11 @@ public class SharedLog { return new SharedLog(mLocalLog, mTag, component); } + /** + * Dump the contents of this log. + * + * <p>This method may be called on any thread. + */ public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { mLocalLog.readOnlyLocalLog().dump(fd, writer, args); } @@ -84,10 +92,21 @@ public class SharedLog { // Methods that both log an entry and emit it to the system log. ////// + /** + * Log an error due to an exception. This does not include the exception stacktrace. + * + * <p>The log entry will be also added to the system log. + * @see #e(String, Throwable) + */ public void e(Exception e) { Log.e(mTag, record(Category.ERROR, e.toString())); } + /** + * Log an error message. + * + * <p>The log entry will be also added to the system log. + */ public void e(String msg) { Log.e(mTag, record(Category.ERROR, msg)); } @@ -96,7 +115,7 @@ public class SharedLog { * Log an error due to an exception, with the exception stacktrace if provided. * * <p>The error and exception message appear in the shared log, but the stacktrace is only - * logged in general log output (logcat). + * logged in general log output (logcat). The log entry will be also added to the system log. */ public void e(@NonNull String msg, @Nullable Throwable exception) { if (exception == null) { @@ -106,10 +125,20 @@ public class SharedLog { Log.e(mTag, record(Category.ERROR, msg + ": " + exception.getMessage()), exception); } + /** + * Log an informational message. + * + * <p>The log entry will be also added to the system log. + */ public void i(String msg) { Log.i(mTag, record(Category.NONE, msg)); } + /** + * Log a warning message. + * + * <p>The log entry will be also added to the system log. + */ public void w(String msg) { Log.w(mTag, record(Category.WARN, msg)); } @@ -118,14 +147,30 @@ public class SharedLog { // Methods that only log an entry (and do NOT emit to the system log). ////// + /** + * Log a general message to be only included in the in-memory log. + * + * <p>The log entry will *not* be added to the system log. + */ public void log(String msg) { record(Category.NONE, msg); } + /** + * Log a general, formatted message to be only included in the in-memory log. + * + * <p>The log entry will *not* be added to the system log. + * @see String#format(String, Object...) + */ public void logf(String fmt, Object... args) { log(String.format(fmt, args)); } + /** + * Log a message with MARK level. + * + * <p>The log entry will *not* be added to the system log. + */ public void mark(String msg) { record(Category.MARK, msg); } diff --git a/startop/view_compiler/Android.bp b/startop/view_compiler/Android.bp index 91cec554d7cd..82056e9a33fe 100644 --- a/startop/view_compiler/Android.bp +++ b/startop/view_compiler/Android.bp @@ -34,6 +34,7 @@ cc_library_host_static { defaults: ["viewcompiler_defaults"], srcs: [ "dex_builder.cc", + "dex_layout_compiler.cc", "java_lang_builder.cc", "tinyxml_layout_parser.cc", "util.cc", diff --git a/startop/view_compiler/dex_builder_test/Android.bp b/startop/view_compiler/dex_builder_test/Android.bp index 4449ea0f707e..d4f38ed148c9 100644 --- a/startop/view_compiler/dex_builder_test/Android.bp +++ b/startop/view_compiler/dex_builder_test/Android.bp @@ -14,16 +14,30 @@ // limitations under the License. // +genrule { + name: "generate_compiled_layout", + tools: [":viewcompiler"], + cmd: "$(location :viewcompiler) $(in) --dex --out $(out) --package android.startop.test", + srcs: ["res/layout/layout1.xml"], + out: [ + "layout1.dex", + ], +} + android_test { name: "dex-builder-test", - srcs: ["src/android/startop/test/DexBuilderTest.java"], + srcs: [ + "src/android/startop/test/DexBuilderTest.java", + "src/android/startop/test/LayoutCompilerTest.java", + ], sdk_version: "current", - data: [":generate_dex_testcases"], + data: [":generate_dex_testcases", ":generate_compiled_layout"], static_libs: [ "android-support-test", "guava", ], manifest: "AndroidManifest.xml", + resource_dirs: ["res"], test_config: "AndroidTest.xml", test_suites: ["general-tests"], } diff --git a/startop/view_compiler/dex_builder_test/AndroidTest.xml b/startop/view_compiler/dex_builder_test/AndroidTest.xml index 6f90cf3b81a7..68d8fdc444d8 100644 --- a/startop/view_compiler/dex_builder_test/AndroidTest.xml +++ b/startop/view_compiler/dex_builder_test/AndroidTest.xml @@ -25,6 +25,7 @@ <option name="cleanup" value="true" /> <option name="push" value="trivial.dex->/data/local/tmp/dex-builder-test/trivial.dex" /> <option name="push" value="simple.dex->/data/local/tmp/dex-builder-test/simple.dex" /> + <option name="push" value="layout1.dex->/data/local/tmp/dex-builder-test/layout1.dex" /> </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > diff --git a/startop/view_compiler/dex_builder_test/res/layout/layout1.xml b/startop/view_compiler/dex_builder_test/res/layout/layout1.xml new file mode 100644 index 000000000000..0f9375c6ebce --- /dev/null +++ b/startop/view_compiler/dex_builder_test/res/layout/layout1.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:orientation="vertical" + android:gravity="center"> + + <Button + android:layout_width="match_parent" + android:layout_height="match_parent"/> + <Button + android:layout_width="match_parent" + android:layout_height="match_parent"/> + + </LinearLayout> diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java new file mode 100644 index 000000000000..ce3ce8328559 --- /dev/null +++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java @@ -0,0 +1,46 @@ +/* + * 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.startop.test; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.view.View; +import com.google.common.io.ByteStreams; +import dalvik.system.InMemoryDexClassLoader; +import dalvik.system.PathClassLoader; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.ByteBuffer; +import org.junit.Assert; +import org.junit.Test; + +// Adding tests here requires changes in several other places. See README.md in +// the view_compiler directory for more information. +public class LayoutCompilerTest { + static ClassLoader loadDexFile(String filename) throws Exception { + return new PathClassLoader("/data/local/tmp/dex-builder-test/" + filename, + ClassLoader.getSystemClassLoader()); + } + + @Test + public void loadAndInflaterLayout1() throws Exception { + ClassLoader dex_file = loadDexFile("layout1.dex"); + Class compiled_view = dex_file.loadClass("android.startop.test.CompiledView"); + Method layout1 = compiled_view.getMethod("layout1", Context.class, int.class); + Context context = InstrumentationRegistry.getTargetContext(); + layout1.invoke(null, context, R.layout.layout1); + } +} diff --git a/startop/view_compiler/dex_layout_compiler.cc b/startop/view_compiler/dex_layout_compiler.cc new file mode 100644 index 000000000000..c68793d10399 --- /dev/null +++ b/startop/view_compiler/dex_layout_compiler.cc @@ -0,0 +1,226 @@ +/* + * 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. + */ + +#include "dex_layout_compiler.h" +#include "layout_validation.h" + +#include "android-base/stringprintf.h" + +namespace startop { + +using android::base::StringPrintf; + +void LayoutValidationVisitor::VisitStartTag(const std::u16string& name) { + if (0 == name.compare(u"merge")) { + message_ = "Merge tags are not supported"; + can_compile_ = false; + } + if (0 == name.compare(u"include")) { + message_ = "Include tags are not supported"; + can_compile_ = false; + } + if (0 == name.compare(u"view")) { + message_ = "View tags are not supported"; + can_compile_ = false; + } + if (0 == name.compare(u"fragment")) { + message_ = "Fragment tags are not supported"; + can_compile_ = false; + } +} + +DexViewBuilder::DexViewBuilder(dex::MethodBuilder* method) + : method_{method}, + context_{dex::Value::Parameter(0)}, + resid_{dex::Value::Parameter(1)}, + inflater_{method->MakeRegister()}, + xml_{method->MakeRegister()}, + attrs_{method->MakeRegister()}, + classname_tmp_{method->MakeRegister()}, + xml_next_{method->dex_file()->GetOrDeclareMethod( + dex::TypeDescriptor::FromClassname("android.content.res.XmlResourceParser"), "next", + dex::Prototype{dex::TypeDescriptor::Int()})}, + try_create_view_{method->dex_file()->GetOrDeclareMethod( + dex::TypeDescriptor::FromClassname("android.view.LayoutInflater"), "tryCreateView", + dex::Prototype{dex::TypeDescriptor::FromClassname("android.view.View"), + dex::TypeDescriptor::FromClassname("android.view.View"), + dex::TypeDescriptor::FromClassname("java.lang.String"), + dex::TypeDescriptor::FromClassname("android.content.Context"), + dex::TypeDescriptor::FromClassname("android.util.AttributeSet")})}, + generate_layout_params_{method->dex_file()->GetOrDeclareMethod( + dex::TypeDescriptor::FromClassname("android.view.ViewGroup"), "generateLayoutParams", + dex::Prototype{dex::TypeDescriptor::FromClassname("android.view.ViewGroup$LayoutParams"), + dex::TypeDescriptor::FromClassname("android.util.AttributeSet")})}, + add_view_{method->dex_file()->GetOrDeclareMethod( + dex::TypeDescriptor::FromClassname("android.view.ViewGroup"), "addView", + dex::Prototype{ + dex::TypeDescriptor::Void(), + dex::TypeDescriptor::FromClassname("android.view.View"), + dex::TypeDescriptor::FromClassname("android.view.ViewGroup$LayoutParams")})}, + // The register stack starts with one register, which will be null for the root view. + register_stack_{{method->MakeRegister()}} {} + +void DexViewBuilder::Start() { + dex::DexBuilder* const dex = method_->dex_file(); + + // LayoutInflater inflater = LayoutInflater.from(context); + auto layout_inflater_from = dex->GetOrDeclareMethod( + dex::TypeDescriptor::FromClassname("android.view.LayoutInflater"), + "from", + dex::Prototype{dex::TypeDescriptor::FromClassname("android.view.LayoutInflater"), + dex::TypeDescriptor::FromClassname("android.content.Context")}); + method_->AddInstruction( + dex::Instruction::InvokeStaticObject(layout_inflater_from.id, /*dest=*/inflater_, context_)); + + // Resources res = context.getResources(); + auto context_type = dex::TypeDescriptor::FromClassname("android.content.Context"); + auto resources_type = dex::TypeDescriptor::FromClassname("android.content.res.Resources"); + auto get_resources = + dex->GetOrDeclareMethod(context_type, "getResources", dex::Prototype{resources_type}); + method_->AddInstruction(dex::Instruction::InvokeVirtualObject(get_resources.id, xml_, context_)); + + // XmlResourceParser xml = res.getLayout(resid); + auto xml_resource_parser_type = + dex::TypeDescriptor::FromClassname("android.content.res.XmlResourceParser"); + auto get_layout = + dex->GetOrDeclareMethod(resources_type, + "getLayout", + dex::Prototype{xml_resource_parser_type, dex::TypeDescriptor::Int()}); + method_->AddInstruction(dex::Instruction::InvokeVirtualObject(get_layout.id, xml_, xml_, resid_)); + + // AttributeSet attrs = Xml.asAttributeSet(xml); + auto as_attribute_set = dex->GetOrDeclareMethod( + dex::TypeDescriptor::FromClassname("android.util.Xml"), + "asAttributeSet", + dex::Prototype{dex::TypeDescriptor::FromClassname("android.util.AttributeSet"), + dex::TypeDescriptor::FromClassname("org.xmlpull.v1.XmlPullParser")}); + method_->AddInstruction(dex::Instruction::InvokeStaticObject(as_attribute_set.id, attrs_, xml_)); + + // xml.next(); // start document + method_->AddInstruction(dex::Instruction::InvokeInterface(xml_next_.id, {}, xml_)); +} + +void DexViewBuilder::Finish() {} + +namespace { +std::string ResolveName(const std::string& name) { + if (name == "View") return "android.view.View"; + if (name == "ViewGroup") return "android.view.ViewGroup"; + if (name.find(".") == std::string::npos) { + return StringPrintf("android.widget.%s", name.c_str()); + } + return name; +} +} // namespace + +void DexViewBuilder::StartView(const std::string& name, bool is_viewgroup) { + bool const is_root_view = view_stack_.empty(); + + // xml.next(); // start tag + method_->AddInstruction(dex::Instruction::InvokeInterface(xml_next_.id, {}, xml_)); + + dex::Value view = AcquireRegister(); + // try to create the view using the factories + method_->BuildConstString(classname_tmp_, + name); // TODO: the need to fully qualify the classname + if (is_root_view) { + dex::Value null = AcquireRegister(); + method_->BuildConst4(null, 0); + method_->AddInstruction(dex::Instruction::InvokeVirtualObject( + try_create_view_.id, view, inflater_, null, classname_tmp_, context_, attrs_)); + ReleaseRegister(); + } else { + method_->AddInstruction(dex::Instruction::InvokeVirtualObject( + try_create_view_.id, view, inflater_, GetCurrentView(), classname_tmp_, context_, attrs_)); + } + auto label = method_->MakeLabel(); + // branch if not null + method_->AddInstruction( + dex::Instruction::OpWithArgs(dex::Instruction::Op::kBranchNEqz, /*dest=*/{}, view, label)); + + // If null, create the class directly. + method_->BuildNew(view, + dex::TypeDescriptor::FromClassname(ResolveName(name)), + dex::Prototype{dex::TypeDescriptor::Void(), + dex::TypeDescriptor::FromClassname("android.content.Context"), + dex::TypeDescriptor::FromClassname("android.util.AttributeSet")}, + context_, + attrs_); + + method_->AddInstruction( + dex::Instruction::OpWithArgs(dex::Instruction::Op::kBindLabel, /*dest=*/{}, label)); + + if (is_viewgroup) { + // Cast to a ViewGroup so we can add children later. + const ir::Type* view_group_def = method_->dex_file()->GetOrAddType( + dex::TypeDescriptor::FromClassname("android.view.ViewGroup").descriptor()); + method_->AddInstruction(dex::Instruction::Cast(view, dex::Value::Type(view_group_def->orig_index))); + } + + if (!is_root_view) { + // layout_params = parent.generateLayoutParams(attrs); + dex::Value layout_params{AcquireRegister()}; + method_->AddInstruction(dex::Instruction::InvokeVirtualObject( + generate_layout_params_.id, layout_params, GetCurrentView(), attrs_)); + view_stack_.push_back({view, layout_params}); + } else { + view_stack_.push_back({view, {}}); + } +} + +void DexViewBuilder::FinishView() { + if (view_stack_.size() == 1) { + method_->BuildReturn(GetCurrentView(), /*is_object=*/true); + } else { + // parent.add(view, layout_params) + method_->AddInstruction(dex::Instruction::InvokeVirtual( + add_view_.id, /*dest=*/{}, GetParentView(), GetCurrentView(), GetCurrentLayoutParams())); + // xml.next(); // end tag + method_->AddInstruction(dex::Instruction::InvokeInterface(xml_next_.id, {}, xml_)); + } + PopViewStack(); +} + +dex::Value DexViewBuilder::AcquireRegister() { + top_register_++; + if (register_stack_.size() == top_register_) { + register_stack_.push_back(method_->MakeRegister()); + } + return register_stack_[top_register_]; +} + +void DexViewBuilder::ReleaseRegister() { top_register_--; } + +dex::Value DexViewBuilder::GetCurrentView() const { return view_stack_.back().view; } +dex::Value DexViewBuilder::GetCurrentLayoutParams() const { + return view_stack_.back().layout_params.value(); +} +dex::Value DexViewBuilder::GetParentView() const { + return view_stack_[view_stack_.size() - 2].view; +} + +void DexViewBuilder::PopViewStack() { + const auto& top = view_stack_.back(); + // release the layout params if we have them + if (top.layout_params.has_value()) { + ReleaseRegister(); + } + // Unconditionally release the view register. + ReleaseRegister(); + view_stack_.pop_back(); +} + +} // namespace startop
\ No newline at end of file diff --git a/startop/view_compiler/dex_layout_compiler.h b/startop/view_compiler/dex_layout_compiler.h new file mode 100644 index 000000000000..170a1a610297 --- /dev/null +++ b/startop/view_compiler/dex_layout_compiler.h @@ -0,0 +1,118 @@ +/* + * 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. + */ + +#ifndef DEX_LAYOUT_COMPILER_H_ +#define DEX_LAYOUT_COMPILER_H_ + +#include "dex_builder.h" + +#include <codecvt> +#include <locale> +#include <string> +#include <vector> + +namespace startop { + +// This visitor does the actual view compilation, using a supplied builder. +template <typename Builder> +class LayoutCompilerVisitor { + public: + explicit LayoutCompilerVisitor(Builder* builder) : builder_{builder} {} + + void VisitStartDocument() { builder_->Start(); } + void VisitEndDocument() { builder_->Finish(); } + void VisitStartTag(const std::u16string& name) { + parent_stack_.push_back(ViewEntry{ + std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(name), {}}); + } + void VisitEndTag() { + auto entry = parent_stack_.back(); + parent_stack_.pop_back(); + + if (parent_stack_.empty()) { + GenerateCode(entry); + } else { + parent_stack_.back().children.push_back(entry); + } + } + + private: + struct ViewEntry { + std::string name; + std::vector<ViewEntry> children; + }; + + void GenerateCode(const ViewEntry& view) { + builder_->StartView(view.name, !view.children.empty()); + for (const auto& child : view.children) { + GenerateCode(child); + } + builder_->FinishView(); + } + + Builder* builder_; + + std::vector<ViewEntry> parent_stack_; +}; + +class DexViewBuilder { + public: + DexViewBuilder(dex::MethodBuilder* method); + + void Start(); + void Finish(); + void StartView(const std::string& name, bool is_viewgroup); + void FinishView(); + + private: + // Accessors for the stack of views that are under construction. + dex::Value AcquireRegister(); + void ReleaseRegister(); + dex::Value GetCurrentView() const; + dex::Value GetCurrentLayoutParams() const; + dex::Value GetParentView() const; + void PopViewStack(); + + dex::MethodBuilder* method_; + + // Registers used for code generation + dex::Value const context_; + dex::Value const resid_; + const dex::Value inflater_; + const dex::Value xml_; + const dex::Value attrs_; + const dex::Value classname_tmp_; + + const dex::MethodDeclData xml_next_; + const dex::MethodDeclData try_create_view_; + const dex::MethodDeclData generate_layout_params_; + const dex::MethodDeclData add_view_; + + // used for keeping track of which registers are in use + size_t top_register_{0}; + std::vector<dex::Value> register_stack_; + + // Keep track of the views currently in progress. + struct ViewEntry { + dex::Value view; + std::optional<dex::Value> layout_params; + }; + std::vector<ViewEntry> view_stack_; +}; + +} // namespace startop + +#endif // DEX_LAYOUT_COMPILER_H_ diff --git a/startop/view_compiler/java_lang_builder.cc b/startop/view_compiler/java_lang_builder.cc index 0b8754fc7096..920caeecf58e 100644 --- a/startop/view_compiler/java_lang_builder.cc +++ b/startop/view_compiler/java_lang_builder.cc @@ -67,7 +67,7 @@ void JavaLangViewBuilder::Finish() const { "}\n"; // end CompiledView } -void JavaLangViewBuilder::StartView(const string& class_name) { +void JavaLangViewBuilder::StartView(const string& class_name, bool /*is_viewgroup*/) { const string view_var = MakeVar("view"); const string layout_var = MakeVar("layout"); std::string parent = "null"; diff --git a/startop/view_compiler/java_lang_builder.h b/startop/view_compiler/java_lang_builder.h index c8d20b23cd13..69356d3a6594 100644 --- a/startop/view_compiler/java_lang_builder.h +++ b/startop/view_compiler/java_lang_builder.h @@ -35,7 +35,7 @@ class JavaLangViewBuilder { void Finish() const; // Begin creating a view (i.e. process the opening tag) - void StartView(const std::string& class_name); + void StartView(const std::string& class_name, bool is_viewgroup); // Finish a view, after all of its child nodes have been processed. void FinishView(); diff --git a/startop/view_compiler/main.cc b/startop/view_compiler/main.cc index 609bcf377b46..ae00187e1908 100644 --- a/startop/view_compiler/main.cc +++ b/startop/view_compiler/main.cc @@ -16,8 +16,11 @@ #include "gflags/gflags.h" +#include "android-base/stringprintf.h" #include "dex_builder.h" +#include "dex_layout_compiler.h" #include "java_lang_builder.h" +#include "layout_validation.h" #include "tinyxml_layout_parser.h" #include "util.h" @@ -32,6 +35,12 @@ namespace { using namespace tinyxml2; +using android::base::StringPrintf; +using startop::dex::ClassBuilder; +using startop::dex::DexBuilder; +using startop::dex::MethodBuilder; +using startop::dex::Prototype; +using startop::dex::TypeDescriptor; using namespace startop::util; using std::string; @@ -41,34 +50,44 @@ DEFINE_bool(dex, false, "Generate a DEX file instead of Java"); DEFINE_string(out, kStdoutFilename, "Where to write the generated class"); DEFINE_string(package, "", "The package name for the generated class (required)"); -class ViewCompilerXmlVisitor : public XMLVisitor { +template <typename Visitor> +class XmlVisitorAdapter : public XMLVisitor { public: - explicit ViewCompilerXmlVisitor(JavaLangViewBuilder* builder) : builder_(builder) {} + explicit XmlVisitorAdapter(Visitor* visitor) : visitor_{visitor} {} bool VisitEnter(const XMLDocument& /*doc*/) override { - builder_->Start(); + visitor_->VisitStartDocument(); return true; } bool VisitExit(const XMLDocument& /*doc*/) override { - builder_->Finish(); + visitor_->VisitEndDocument(); return true; } bool VisitEnter(const XMLElement& element, const XMLAttribute* /*firstAttribute*/) override { - builder_->StartView(element.Name()); + visitor_->VisitStartTag( + std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes( + element.Name())); return true; } bool VisitExit(const XMLElement& /*element*/) override { - builder_->FinishView(); + visitor_->VisitEndTag(); return true; } private: - JavaLangViewBuilder* builder_; + Visitor* visitor_; }; +template <typename Builder> +void CompileLayout(XMLDocument* xml, Builder* builder) { + startop::LayoutCompilerVisitor visitor{builder}; + XmlVisitorAdapter<decltype(visitor)> adapter{&visitor}; + xml->Accept(&adapter); +} + } // end namespace int main(int argc, char** argv) { @@ -88,16 +107,8 @@ int main(int argc, char** argv) { return 1; } - if (FLAGS_dex) { - startop::dex::WriteTestDexFile("test.dex"); - return 0; - } - const char* const filename = argv[kFileNameParam]; - const string layout_name = FindLayoutNameFromFilename(filename); - - // We want to generate Java language code to inflate exactly this layout. This means - // generating code to walk the resource XML too. + const string layout_name = startop::util::FindLayoutNameFromFilename(filename); XMLDocument xml; xml.LoadFile(filename); @@ -108,15 +119,34 @@ int main(int argc, char** argv) { return 1; } + const bool is_stdout = FLAGS_out == kStdoutFilename; + std::ofstream outfile; - if (FLAGS_out != kStdoutFilename) { + if (!is_stdout) { outfile.open(FLAGS_out); } - JavaLangViewBuilder builder{ - FLAGS_package, layout_name, FLAGS_out == kStdoutFilename ? std::cout : outfile}; - - ViewCompilerXmlVisitor visitor{&builder}; - xml.Accept(&visitor); + if (FLAGS_dex) { + DexBuilder dex_file; + string class_name = StringPrintf("%s.CompiledView", FLAGS_package.c_str()); + ClassBuilder compiled_view{dex_file.MakeClass(class_name)}; + MethodBuilder method{compiled_view.CreateMethod( + layout_name, + Prototype{TypeDescriptor::FromClassname("android.view.View"), + TypeDescriptor::FromClassname("android.content.Context"), + TypeDescriptor::Int()})}; + startop::DexViewBuilder builder{&method}; + CompileLayout(&xml, &builder); + method.Encode(); + + slicer::MemView image{dex_file.CreateImage()}; + + (is_stdout ? std::cout : outfile).write(image.ptr<const char>(), image.size()); + } else { + // Generate Java language output. + JavaLangViewBuilder builder{FLAGS_package, layout_name, is_stdout ? std::cout : outfile}; + + CompileLayout(&xml, &builder); + } return 0; } diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java index b258f52d58ec..83738997a067 100644 --- a/telephony/java/android/telephony/PreciseDataConnectionState.java +++ b/telephony/java/android/telephony/PreciseDataConnectionState.java @@ -17,10 +17,11 @@ package android.telephony; import android.annotation.UnsupportedAppUsage; +import android.net.LinkProperties; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.TelephonyManager; -import android.net.LinkProperties; + +import java.util.Objects; /** * Contains precise data connection state. @@ -32,7 +33,6 @@ import android.net.LinkProperties; * <li>Network type of the connection. * <li>APN type. * <li>APN. - * <li>Data connection change reason. * <li>The properties of the network link. * <li>Data connection fail cause. * </ul> @@ -45,7 +45,6 @@ public class PreciseDataConnectionState implements Parcelable { private int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; private String mAPNType = ""; private String mAPN = ""; - private String mReason = ""; private LinkProperties mLinkProperties = null; private String mFailCause = ""; @@ -55,14 +54,12 @@ public class PreciseDataConnectionState implements Parcelable { * @hide */ @UnsupportedAppUsage - public PreciseDataConnectionState(int state, int networkType, - String apnType, String apn, String reason, - LinkProperties linkProperties, String failCause) { + public PreciseDataConnectionState(int state, int networkType, String apnType, String apn, + LinkProperties linkProperties, String failCause) { mState = state; mNetworkType = networkType; mAPNType = apnType; mAPN = apn; - mReason = reason; mLinkProperties = linkProperties; mFailCause = failCause; } @@ -83,7 +80,6 @@ public class PreciseDataConnectionState implements Parcelable { mNetworkType = in.readInt(); mAPNType = in.readString(); mAPN = in.readString(); - mReason = in.readString(); mLinkProperties = (LinkProperties)in.readParcelable(null); mFailCause = in.readString(); } @@ -144,14 +140,6 @@ public class PreciseDataConnectionState implements Parcelable { } /** - * Get data connection change reason. - */ - @UnsupportedAppUsage - public String getDataConnectionChangeReason() { - return mReason; - } - - /** * Get the properties of the network link. */ @UnsupportedAppUsage @@ -178,7 +166,6 @@ public class PreciseDataConnectionState implements Parcelable { out.writeInt(mNetworkType); out.writeString(mAPNType); out.writeString(mAPN); - out.writeString(mReason); out.writeParcelable(mLinkProperties, flags); out.writeString(mFailCause); } @@ -197,16 +184,7 @@ public class PreciseDataConnectionState implements Parcelable { @Override public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + mState; - result = prime * result + mNetworkType; - result = prime * result + ((mAPNType == null) ? 0 : mAPNType.hashCode()); - result = prime * result + ((mAPN == null) ? 0 : mAPN.hashCode()); - result = prime * result + ((mReason == null) ? 0 : mReason.hashCode()); - result = prime * result + ((mLinkProperties == null) ? 0 : mLinkProperties.hashCode()); - result = prime * result + ((mFailCause == null) ? 0 : mFailCause.hashCode()); - return result; + return Objects.hash(mState, mNetworkType, mAPNType, mAPN, mLinkProperties, mFailCause); } @Override @@ -252,13 +230,6 @@ public class PreciseDataConnectionState implements Parcelable { if (mNetworkType != other.mNetworkType) { return false; } - if (mReason == null) { - if (other.mReason != null) { - return false; - } - } else if (!mReason.equals(other.mReason)) { - return false; - } if (mState != other.mState) { return false; } @@ -273,7 +244,6 @@ public class PreciseDataConnectionState implements Parcelable { sb.append(", Network type: " + mNetworkType); sb.append(", APN type: " + mAPNType); sb.append(", APN: " + mAPN); - sb.append(", Change reason: " + mReason); sb.append(", Link properties: " + mLinkProperties); sb.append(", Fail cause: " + mFailCause); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 2286ce29b4d3..739c80fd9d97 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -772,7 +772,6 @@ public class TelephonyManager { * The {@link #EXTRA_DATA_NETWORK_TYPE} extra indicates the connection network type. * The {@link #EXTRA_DATA_APN_TYPE} extra indicates the APN type. * The {@link #EXTRA_DATA_APN} extra indicates the APN. - * The {@link #EXTRA_DATA_CHANGE_REASON} extra indicates the connection change reason. * The {@link #EXTRA_DATA_IFACE_PROPERTIES} extra indicates the connection interface. * The {@link #EXTRA_DATA_FAILURE_CAUSE} extra indicates the connection fail cause. * @@ -783,7 +782,6 @@ public class TelephonyManager { * @see #EXTRA_DATA_NETWORK_TYPE * @see #EXTRA_DATA_APN_TYPE * @see #EXTRA_DATA_APN - * @see #EXTRA_DATA_CHANGE_REASON * @see #EXTRA_DATA_IFACE * @see #EXTRA_DATA_FAILURE_CAUSE * @hide @@ -872,18 +870,6 @@ public class TelephonyManager { /** * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast - * for an String representation of the change reason. - * - * <p class="note"> - * Retrieve with - * {@link android.content.Intent#getStringExtra(String name)}. - * - * @hide - */ - public static final String EXTRA_DATA_CHANGE_REASON = PhoneConstants.STATE_CHANGE_REASON_KEY; - - /** - * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast * for an String representation of the data interface. * * <p class="note"> diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index d9f5c3f6d0fa..02a6f311c1da 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -50,13 +50,13 @@ interface ITelephonyRegistry { void notifyDataActivity(int state); void notifyDataActivityForSubscriber(in int subId, int state); void notifyDataConnection(int state, boolean isDataConnectivityPossible, - String reason, String apn, String apnType, in LinkProperties linkProperties, + String apn, String apnType, in LinkProperties linkProperties, in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); void notifyDataConnectionForSubscriber(int subId, int state, boolean isDataConnectivityPossible, - String reason, String apn, String apnType, in LinkProperties linkProperties, + String apn, String apnType, in LinkProperties linkProperties, in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); - void notifyDataConnectionFailed(String reason, String apnType); - void notifyDataConnectionFailedForSubscriber(int subId, String reason, String apnType); + void notifyDataConnectionFailed(String apnType); + void notifyDataConnectionFailedForSubscriber(int subId, String apnType); void notifyCellLocation(in Bundle cellLocation); void notifyCellLocationForSubscriber(in int subId, in Bundle cellLocation); void notifyOtaspChanged(in int otaspMode); @@ -67,7 +67,7 @@ interface ITelephonyRegistry { void notifyPreciseCallState(int ringingCallState, int foregroundCallState, int backgroundCallState); void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause); - void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, + void notifyPreciseDataConnectionFailed(String apnType, String apn, String failCause); void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo); void notifySrvccStateChanged(in int subId, in int lteState); diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java index 21f3b92c6c4f..e87d28c6f9e9 100644 --- a/telephony/java/com/android/internal/telephony/PhoneConstants.java +++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java @@ -79,8 +79,6 @@ public class PhoneConstants { public static final int SIM_ACTIVATION_TYPE_DATA = 1; public static final String PHONE_NAME_KEY = "phoneName"; - public static final String FAILURE_REASON_KEY = "reason"; - public static final String STATE_CHANGE_REASON_KEY = "reason"; public static final String DATA_NETWORK_TYPE_KEY = "networkType"; public static final String DATA_FAILURE_CAUSE_KEY = "failCause"; public static final String DATA_APN_TYPE_KEY = "apnType"; diff --git a/tests/net/java/android/net/dhcp/DhcpLeaseRepositoryTest.java b/tests/net/java/android/net/dhcp/DhcpLeaseRepositoryTest.java index 7f8e7b5456c2..ba0448c98387 100644 --- a/tests/net/java/android/net/dhcp/DhcpLeaseRepositoryTest.java +++ b/tests/net/java/android/net/dhcp/DhcpLeaseRepositoryTest.java @@ -35,8 +35,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.net.IpPrefix; import android.net.MacAddress; -import android.net.util.SharedLog; import android.net.dhcp.DhcpServer.Clock; +import android.net.util.SharedLog; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; @@ -126,7 +126,7 @@ public class DhcpLeaseRepositoryTest { mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), TEST_EXCL_SET, TEST_LEASE_TIME_MS); // /28 should have 16 addresses, 14 w/o the first/last, 11 w/o excluded addresses - requestAddresses((byte)11); + requestAddresses((byte) 11); try { mRepo.getOffer(null, TEST_MAC_2, diff --git a/tests/net/java/android/net/dhcp/DhcpServingParamsParcelExtTest.java b/tests/net/java/android/net/dhcp/DhcpServingParamsParcelExtTest.java new file mode 100644 index 000000000000..4a6f20a043bb --- /dev/null +++ b/tests/net/java/android/net/dhcp/DhcpServingParamsParcelExtTest.java @@ -0,0 +1,113 @@ +/* + * 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.net.dhcp; + +import static android.net.InetAddresses.parseNumericAddress; + +import static com.google.android.collect.Sets.newHashSet; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.net.LinkAddress; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.net.Inet4Address; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class DhcpServingParamsParcelExtTest { + private static final Inet4Address TEST_ADDRESS = inet4Addr("192.168.0.123"); + private static final int TEST_ADDRESS_PARCELED = 0xc0a8007b; + private static final int TEST_PREFIX_LENGTH = 17; + private static final int TEST_LEASE_TIME_SECS = 120; + private static final int TEST_MTU = 1000; + private static final Set<Inet4Address> TEST_ADDRESS_SET = + newHashSet(inet4Addr("192.168.1.123"), inet4Addr("192.168.1.124")); + private static final Set<Integer> TEST_ADDRESS_SET_PARCELED = + newHashSet(0xc0a8017b, 0xc0a8017c); + + private DhcpServingParamsParcelExt mParcel; + + @Before + public void setUp() { + mParcel = new DhcpServingParamsParcelExt(); + } + + @Test + public void testSetServerAddr() { + mParcel.setServerAddr(new LinkAddress(TEST_ADDRESS, TEST_PREFIX_LENGTH)); + + assertEquals(TEST_ADDRESS_PARCELED, mParcel.serverAddr); + assertEquals(TEST_PREFIX_LENGTH, mParcel.serverAddrPrefixLength); + } + + @Test + public void testSetDefaultRouters() { + mParcel.setDefaultRouters(TEST_ADDRESS_SET); + assertEquals(TEST_ADDRESS_SET_PARCELED, asSet(mParcel.defaultRouters)); + } + + @Test + public void testSetDnsServers() { + mParcel.setDnsServers(TEST_ADDRESS_SET); + assertEquals(TEST_ADDRESS_SET_PARCELED, asSet(mParcel.dnsServers)); + } + + @Test + public void testSetExcludedAddrs() { + mParcel.setExcludedAddrs(TEST_ADDRESS_SET); + assertEquals(TEST_ADDRESS_SET_PARCELED, asSet(mParcel.excludedAddrs)); + } + + @Test + public void testSetDhcpLeaseTimeSecs() { + mParcel.setDhcpLeaseTimeSecs(TEST_LEASE_TIME_SECS); + assertEquals(TEST_LEASE_TIME_SECS, mParcel.dhcpLeaseTimeSecs); + } + + @Test + public void testSetLinkMtu() { + mParcel.setLinkMtu(TEST_MTU); + assertEquals(TEST_MTU, mParcel.linkMtu); + } + + @Test + public void testSetMetered() { + mParcel.setMetered(true); + assertTrue(mParcel.metered); + mParcel.setMetered(false); + assertFalse(mParcel.metered); + } + + private static Inet4Address inet4Addr(String addr) { + return (Inet4Address) parseNumericAddress(addr); + } + + private static Set<Integer> asSet(int[] ints) { + return IntStream.of(ints).boxed().collect(Collectors.toSet()); + } +} diff --git a/tests/net/java/android/net/dhcp/DhcpServingParamsTest.java b/tests/net/java/android/net/dhcp/DhcpServingParamsTest.java index b6a4073a64da..2ab224667b8a 100644 --- a/tests/net/java/android/net/dhcp/DhcpServingParamsTest.java +++ b/tests/net/java/android/net/dhcp/DhcpServingParamsTest.java @@ -16,6 +16,7 @@ package android.net.dhcp; +import static android.net.NetworkUtils.inet4AddressToIntHTH; import static android.net.dhcp.DhcpServingParams.MTU_UNSET; import static junit.framework.Assert.assertEquals; @@ -27,6 +28,7 @@ import static java.net.InetAddress.parseNumericAddress; import android.annotation.NonNull; import android.annotation.Nullable; import android.net.LinkAddress; +import android.net.NetworkUtils; import android.net.dhcp.DhcpServingParams.InvalidParameterException; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; @@ -35,8 +37,10 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.lang.reflect.Modifier; import java.net.Inet4Address; import java.util.Arrays; +import java.util.Collection; import java.util.HashSet; import java.util.Set; @@ -56,6 +60,7 @@ public class DhcpServingParamsTest { private static final int TEST_MTU = 1500; private static final Set<Inet4Address> TEST_EXCLUDED_ADDRS = new HashSet<>( Arrays.asList(parseAddr("192.168.0.200"), parseAddr("192.168.0.201"))); + private static final boolean TEST_METERED = true; @Before public void setUp() { @@ -65,7 +70,8 @@ public class DhcpServingParamsTest { .setDnsServers(TEST_DNS_SERVERS) .setServerAddr(TEST_LINKADDR) .setLinkMtu(TEST_MTU) - .setExcludedAddrs(TEST_EXCLUDED_ADDRS); + .setExcludedAddrs(TEST_EXCLUDED_ADDRS) + .setMetered(TEST_METERED); } @Test @@ -91,6 +97,7 @@ public class DhcpServingParamsTest { assertEquals(TEST_DNS_SERVERS, params.dnsServers); assertEquals(TEST_LINKADDR, params.serverAddr); assertEquals(TEST_MTU, params.linkMtu); + assertEquals(TEST_METERED, params.metered); assertContains(params.excludedAddrs, TEST_EXCLUDED_ADDRS); assertContains(params.excludedAddrs, TEST_DEFAULT_ROUTERS); @@ -159,6 +166,39 @@ public class DhcpServingParamsTest { mBuilder.setDefaultRouters(parseAddr("192.168.254.254")).build(); } + @Test + public void testFromParcelableObject() throws InvalidParameterException { + final DhcpServingParams params = mBuilder.build(); + final DhcpServingParamsParcel parcel = new DhcpServingParamsParcel(); + parcel.defaultRouters = toIntArray(TEST_DEFAULT_ROUTERS); + parcel.dhcpLeaseTimeSecs = TEST_LEASE_TIME_SECS; + parcel.dnsServers = toIntArray(TEST_DNS_SERVERS); + parcel.serverAddr = inet4AddressToIntHTH(TEST_SERVER_ADDR); + parcel.serverAddrPrefixLength = TEST_LINKADDR.getPrefixLength(); + parcel.linkMtu = TEST_MTU; + parcel.excludedAddrs = toIntArray(TEST_EXCLUDED_ADDRS); + parcel.metered = TEST_METERED; + final DhcpServingParams parceled = DhcpServingParams.fromParcelableObject(parcel); + + assertEquals(params.defaultRouters, parceled.defaultRouters); + assertEquals(params.dhcpLeaseTimeSecs, parceled.dhcpLeaseTimeSecs); + assertEquals(params.dnsServers, parceled.dnsServers); + assertEquals(params.serverAddr, parceled.serverAddr); + assertEquals(params.linkMtu, parceled.linkMtu); + assertEquals(params.excludedAddrs, parceled.excludedAddrs); + assertEquals(params.metered, parceled.metered); + + // Ensure that we do not miss any field if added in the future + final long numFields = Arrays.stream(DhcpServingParams.class.getDeclaredFields()) + .filter(f -> !Modifier.isStatic(f.getModifiers())) + .count(); + assertEquals(7, numFields); + } + + private static int[] toIntArray(Collection<Inet4Address> addrs) { + return addrs.stream().mapToInt(NetworkUtils::inet4AddressToIntHTH).toArray(); + } + private static <T> void assertContains(@NonNull Set<T> set, @NonNull Set<T> subset) { for (final T elem : subset) { assertContains(set, elem); diff --git a/tests/net/java/android/net/ip/IpServerTest.java b/tests/net/java/android/net/ip/IpServerTest.java index 2c675c68a076..017822896610 100644 --- a/tests/net/java/android/net/ip/IpServerTest.java +++ b/tests/net/java/android/net/ip/IpServerTest.java @@ -16,6 +16,16 @@ package android.net.ip; +import static android.net.ConnectivityManager.TETHERING_BLUETOOTH; +import static android.net.ConnectivityManager.TETHERING_USB; +import static android.net.ConnectivityManager.TETHERING_WIFI; +import static android.net.ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR; +import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR; +import static android.net.ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR; +import static android.net.ip.IpServer.STATE_AVAILABLE; +import static android.net.ip.IpServer.STATE_TETHERED; +import static android.net.ip.IpServer.STATE_UNAVAILABLE; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -31,16 +41,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import static android.net.ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR; -import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR; -import static android.net.ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR; -import static android.net.ConnectivityManager.TETHERING_BLUETOOTH; -import static android.net.ConnectivityManager.TETHERING_USB; -import static android.net.ConnectivityManager.TETHERING_WIFI; -import static android.net.ip.IpServer.STATE_AVAILABLE; -import static android.net.ip.IpServer.STATE_TETHERED; -import static android.net.ip.IpServer.STATE_UNAVAILABLE; - import android.net.INetworkStatsService; import android.net.InterfaceConfiguration; import android.net.IpPrefix; @@ -60,8 +60,6 @@ import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.text.TextUtils; -import java.net.Inet4Address; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -71,6 +69,8 @@ import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.net.Inet4Address; + @RunWith(AndroidJUnit4.class) @SmallTest public class IpServerTest { |