Loading core/java/com/android/internal/util/MessageUtils.java 0 → 100644 +127 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 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 com.android.internal.util; import android.os.Message; import android.util.Log; import android.util.SparseArray; import java.lang.reflect.Field; /** * Static utility class for dealing with {@link Message} objects. */ public class MessageUtils { private static final String TAG = MessageUtils.class.getSimpleName(); private static final boolean DBG = false; /** Thrown when two different constants have the same value. */ public static class DuplicateConstantError extends Error { private DuplicateConstantError() {} public DuplicateConstantError(String name1, String name2, int value) { super(String.format("Duplicate constant value: both %s and %s = %d", name1, name2, value)); } } /** * Finds the names of integer constants. Searches the specified {@code classes}, looking for * accessible static integer fields whose names begin with one of the specified {@prefixes}. * * @param classes the classes to examine. * @prefixes only consider fields names starting with one of these prefixes. * @return a {@link SparseArray} mapping integer constants to their names. */ public static SparseArray<String> findMessageNames(Class[] classes, String[] prefixes) { SparseArray<String> messageNames = new SparseArray<>(); for (Class c : classes) { String className = c.getName(); if (DBG) Log.d(TAG, "Examining class " + className); Field[] fields; try { fields = c.getDeclaredFields(); } catch (SecurityException e) { Log.e(TAG, "Can't list fields of class " + className); continue; } for (Field field : fields) { String name = field.getName(); for (String prefix : prefixes) { // Does this look like a constant? if (!name.startsWith(prefix)) { continue; } try { // TODO: can we have the caller try to access the field instead, so we don't // expose constants it does not have access to? field.setAccessible(true); // Fetch the constant's value. int value; try { value = field.getInt(null); } catch (IllegalArgumentException | ExceptionInInitializerError e) { // The field is not an integer (or short or byte), or c's static // initializer failed and we have no idea what its value is. // Either way, give up on this field. break; } // Check for duplicate values. String previousName = messageNames.get(value); if (previousName != null && !previousName.equals(name)) { throw new DuplicateConstantError(name, previousName, value); } messageNames.put(value, name); if (DBG) { Log.d(TAG, String.format("Found constant: %s.%s = %d", className, name, value)); } } catch (SecurityException | IllegalAccessException e) { // Not allowed to make the field accessible, or no access. Ignore. continue; } } } } return messageNames; } /** * Default prefixes for constants. */ public static final String[] DEFAULT_PREFIXES = {"CMD_", "EVENT_"}; /** * Finds the names of integer constants. Searches the specified {@code classes}, looking for * accessible static integer values whose names begin with {@link #DEFAULT_PREFIXES}. * * @param classNames the classes to examine. * @prefixes only consider fields names starting with one of these prefixes. * @return a {@link SparseArray} mapping integer constants to their names. */ public static SparseArray<String> findMessageNames(Class[] classNames) { return findMessageNames(classNames, DEFAULT_PREFIXES); } } services/net/java/android/net/dhcp/DhcpClient.java +8 −27 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.net.dhcp; import com.android.internal.util.HexDump; import com.android.internal.util.Protocol; import com.android.internal.util.State; import com.android.internal.util.MessageUtils; import com.android.internal.util.StateMachine; import com.android.internal.util.WakeupMessage; Loading @@ -32,7 +33,6 @@ import android.net.NetworkUtils; import android.os.IBinder; import android.os.INetworkManagementService; import android.os.Message; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; Loading @@ -40,16 +40,15 @@ import android.system.ErrnoException; import android.system.Os; import android.system.PacketSocketAddress; import android.util.Log; import android.util.SparseArray; import android.util.TimeUtils; import java.io.FileDescriptor; import java.io.IOException; import java.lang.Thread; import java.net.Inet4Address; import java.net.InetSocketAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Random; Loading Loading @@ -131,6 +130,11 @@ public class DhcpClient extends StateMachine { private static final int CMD_TIMEOUT = PRIVATE_BASE + 3; private static final int CMD_ONESHOT_TIMEOUT = PRIVATE_BASE + 4; // For message logging. private static final Class[] sMessageClasses = { DhcpClient.class }; private static final SparseArray<String> sMessageNames = MessageUtils.findMessageNames(sMessageClasses); // DHCP parameters that we request. private static final byte[] REQUESTED_PARAMS = new byte[] { DHCP_SUBNET_MASK, Loading Loading @@ -460,30 +464,7 @@ public class DhcpClient extends StateMachine { } private String messageName(int what) { switch (what) { case CMD_START_DHCP: return "CMD_START_DHCP"; case CMD_STOP_DHCP: return "CMD_STOP_DHCP"; case CMD_RENEW_DHCP: return "CMD_RENEW_DHCP"; case CMD_PRE_DHCP_ACTION: return "CMD_PRE_DHCP_ACTION"; case CMD_PRE_DHCP_ACTION_COMPLETE: return "CMD_PRE_DHCP_ACTION_COMPLETE"; case CMD_POST_DHCP_ACTION: return "CMD_POST_DHCP_ACTION"; case CMD_KICK: return "CMD_KICK"; case CMD_RECEIVED_PACKET: return "CMD_RECEIVED_PACKET"; case CMD_TIMEOUT: return "CMD_TIMEOUT"; case CMD_ONESHOT_TIMEOUT: return "CMD_ONESHOT_TIMEOUT"; default: return Integer.toString(what); } return sMessageNames.get(what, Integer.toString(what)); } private String messageToString(Message message) { Loading services/net/java/android/net/ip/IpManager.java +9 −20 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.net.ip; import com.android.internal.util.MessageUtils; import android.content.Context; import android.net.DhcpResults; import android.net.InterfaceConfiguration; Loading @@ -30,6 +32,7 @@ import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -61,6 +64,11 @@ public class IpManager extends StateMachine { private static final boolean DBG = true; private static final boolean VDBG = false; // For message logging. private static final Class[] sMessageClasses = { IpManager.class, DhcpClient.class }; private static final SparseArray<String> sWhatToString = MessageUtils.findMessageNames(sMessageClasses); /** * Callbacks for handling IpManager events. */ Loading Loading @@ -306,26 +314,7 @@ public class IpManager extends StateMachine { @Override protected String getWhatToString(int what) { // TODO: Investigate switching to reflection. switch (what) { case CMD_STOP: return "CMD_STOP"; case CMD_START: return "CMD_START"; case CMD_CONFIRM: return "CMD_CONFIRM"; case EVENT_PRE_DHCP_ACTION_COMPLETE: return "EVENT_PRE_DHCP_ACTION_COMPLETE"; case EVENT_NETLINK_LINKPROPERTIES_CHANGED: return "EVENT_NETLINK_LINKPROPERTIES_CHANGED"; case DhcpClient.CMD_PRE_DHCP_ACTION: return "DhcpClient.CMD_PRE_DHCP_ACTION"; case DhcpClient.CMD_POST_DHCP_ACTION: return "DhcpClient.CMD_POST_DHCP_ACTION"; case DhcpClient.CMD_ON_QUIT: return "DhcpClient.CMD_ON_QUIT"; } return "UNKNOWN:" + Integer.toString(what); return sWhatToString.get(what, "UNKNOWN: " + Integer.toString(what)); } @Override Loading Loading
core/java/com/android/internal/util/MessageUtils.java 0 → 100644 +127 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 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 com.android.internal.util; import android.os.Message; import android.util.Log; import android.util.SparseArray; import java.lang.reflect.Field; /** * Static utility class for dealing with {@link Message} objects. */ public class MessageUtils { private static final String TAG = MessageUtils.class.getSimpleName(); private static final boolean DBG = false; /** Thrown when two different constants have the same value. */ public static class DuplicateConstantError extends Error { private DuplicateConstantError() {} public DuplicateConstantError(String name1, String name2, int value) { super(String.format("Duplicate constant value: both %s and %s = %d", name1, name2, value)); } } /** * Finds the names of integer constants. Searches the specified {@code classes}, looking for * accessible static integer fields whose names begin with one of the specified {@prefixes}. * * @param classes the classes to examine. * @prefixes only consider fields names starting with one of these prefixes. * @return a {@link SparseArray} mapping integer constants to their names. */ public static SparseArray<String> findMessageNames(Class[] classes, String[] prefixes) { SparseArray<String> messageNames = new SparseArray<>(); for (Class c : classes) { String className = c.getName(); if (DBG) Log.d(TAG, "Examining class " + className); Field[] fields; try { fields = c.getDeclaredFields(); } catch (SecurityException e) { Log.e(TAG, "Can't list fields of class " + className); continue; } for (Field field : fields) { String name = field.getName(); for (String prefix : prefixes) { // Does this look like a constant? if (!name.startsWith(prefix)) { continue; } try { // TODO: can we have the caller try to access the field instead, so we don't // expose constants it does not have access to? field.setAccessible(true); // Fetch the constant's value. int value; try { value = field.getInt(null); } catch (IllegalArgumentException | ExceptionInInitializerError e) { // The field is not an integer (or short or byte), or c's static // initializer failed and we have no idea what its value is. // Either way, give up on this field. break; } // Check for duplicate values. String previousName = messageNames.get(value); if (previousName != null && !previousName.equals(name)) { throw new DuplicateConstantError(name, previousName, value); } messageNames.put(value, name); if (DBG) { Log.d(TAG, String.format("Found constant: %s.%s = %d", className, name, value)); } } catch (SecurityException | IllegalAccessException e) { // Not allowed to make the field accessible, or no access. Ignore. continue; } } } } return messageNames; } /** * Default prefixes for constants. */ public static final String[] DEFAULT_PREFIXES = {"CMD_", "EVENT_"}; /** * Finds the names of integer constants. Searches the specified {@code classes}, looking for * accessible static integer values whose names begin with {@link #DEFAULT_PREFIXES}. * * @param classNames the classes to examine. * @prefixes only consider fields names starting with one of these prefixes. * @return a {@link SparseArray} mapping integer constants to their names. */ public static SparseArray<String> findMessageNames(Class[] classNames) { return findMessageNames(classNames, DEFAULT_PREFIXES); } }
services/net/java/android/net/dhcp/DhcpClient.java +8 −27 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.net.dhcp; import com.android.internal.util.HexDump; import com.android.internal.util.Protocol; import com.android.internal.util.State; import com.android.internal.util.MessageUtils; import com.android.internal.util.StateMachine; import com.android.internal.util.WakeupMessage; Loading @@ -32,7 +33,6 @@ import android.net.NetworkUtils; import android.os.IBinder; import android.os.INetworkManagementService; import android.os.Message; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; Loading @@ -40,16 +40,15 @@ import android.system.ErrnoException; import android.system.Os; import android.system.PacketSocketAddress; import android.util.Log; import android.util.SparseArray; import android.util.TimeUtils; import java.io.FileDescriptor; import java.io.IOException; import java.lang.Thread; import java.net.Inet4Address; import java.net.InetSocketAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Random; Loading Loading @@ -131,6 +130,11 @@ public class DhcpClient extends StateMachine { private static final int CMD_TIMEOUT = PRIVATE_BASE + 3; private static final int CMD_ONESHOT_TIMEOUT = PRIVATE_BASE + 4; // For message logging. private static final Class[] sMessageClasses = { DhcpClient.class }; private static final SparseArray<String> sMessageNames = MessageUtils.findMessageNames(sMessageClasses); // DHCP parameters that we request. private static final byte[] REQUESTED_PARAMS = new byte[] { DHCP_SUBNET_MASK, Loading Loading @@ -460,30 +464,7 @@ public class DhcpClient extends StateMachine { } private String messageName(int what) { switch (what) { case CMD_START_DHCP: return "CMD_START_DHCP"; case CMD_STOP_DHCP: return "CMD_STOP_DHCP"; case CMD_RENEW_DHCP: return "CMD_RENEW_DHCP"; case CMD_PRE_DHCP_ACTION: return "CMD_PRE_DHCP_ACTION"; case CMD_PRE_DHCP_ACTION_COMPLETE: return "CMD_PRE_DHCP_ACTION_COMPLETE"; case CMD_POST_DHCP_ACTION: return "CMD_POST_DHCP_ACTION"; case CMD_KICK: return "CMD_KICK"; case CMD_RECEIVED_PACKET: return "CMD_RECEIVED_PACKET"; case CMD_TIMEOUT: return "CMD_TIMEOUT"; case CMD_ONESHOT_TIMEOUT: return "CMD_ONESHOT_TIMEOUT"; default: return Integer.toString(what); } return sMessageNames.get(what, Integer.toString(what)); } private String messageToString(Message message) { Loading
services/net/java/android/net/ip/IpManager.java +9 −20 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.net.ip; import com.android.internal.util.MessageUtils; import android.content.Context; import android.net.DhcpResults; import android.net.InterfaceConfiguration; Loading @@ -30,6 +32,7 @@ import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -61,6 +64,11 @@ public class IpManager extends StateMachine { private static final boolean DBG = true; private static final boolean VDBG = false; // For message logging. private static final Class[] sMessageClasses = { IpManager.class, DhcpClient.class }; private static final SparseArray<String> sWhatToString = MessageUtils.findMessageNames(sMessageClasses); /** * Callbacks for handling IpManager events. */ Loading Loading @@ -306,26 +314,7 @@ public class IpManager extends StateMachine { @Override protected String getWhatToString(int what) { // TODO: Investigate switching to reflection. switch (what) { case CMD_STOP: return "CMD_STOP"; case CMD_START: return "CMD_START"; case CMD_CONFIRM: return "CMD_CONFIRM"; case EVENT_PRE_DHCP_ACTION_COMPLETE: return "EVENT_PRE_DHCP_ACTION_COMPLETE"; case EVENT_NETLINK_LINKPROPERTIES_CHANGED: return "EVENT_NETLINK_LINKPROPERTIES_CHANGED"; case DhcpClient.CMD_PRE_DHCP_ACTION: return "DhcpClient.CMD_PRE_DHCP_ACTION"; case DhcpClient.CMD_POST_DHCP_ACTION: return "DhcpClient.CMD_POST_DHCP_ACTION"; case DhcpClient.CMD_ON_QUIT: return "DhcpClient.CMD_ON_QUIT"; } return "UNKNOWN:" + Integer.toString(what); return sWhatToString.get(what, "UNKNOWN: " + Integer.toString(what)); } @Override Loading