Add support for changing p2p device name

Change-Id: Ie13fe2adedd0bac6aa07b3369c4d6a05ef33cd24
Signed-off-by: isheriff@google.com
Signed-off-by: Yoshihiko Ikenaga <yoshihiko.ikenaga@jp.sony.com>
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3a5fdd1..2c49bd2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3270,6 +3270,12 @@
         public static final String WIFI_FREQUENCY_BAND = "wifi_frequency_band";
 
         /**
+         * The Wi-Fi peer-to-peer device name
+         * @hide
+         */
+        public static final String WIFI_P2P_DEVICE_NAME = "wifi_p2p_device_name";
+
+        /**
          * Maximum amount of time in milliseconds to hold a wakelock while waiting for mobile
          * data connectivity to be established after a disconnect from Wi-Fi.
          */
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 018e0a8..b25bf91 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -381,6 +381,13 @@
     /** @hide */
     public static final int RESPONSE_SERVICE                        = BASE + 50;
 
+    /** @hide */
+    public static final int SET_DEVICE_NAME                         = BASE + 51;
+    /** @hide */
+    public static final int SET_DEVICE_NAME_FAILED                  = BASE + 52;
+    /** @hide */
+    public static final int SET_DEVICE_NAME_SUCCEEDED               = BASE + 53;
+
     /**
      * Create a new WifiP2pManager instance. Applications use
      * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
@@ -603,6 +610,7 @@
                     case WifiP2pManager.ADD_SERVICE_REQUEST_FAILED:
                     case WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED:
                     case WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED:
+                    case WifiP2pManager.SET_DEVICE_NAME_FAILED:
                         if (listener != null) {
                             ((ActionListener) listener).onFailure(message.arg1);
                         }
@@ -621,6 +629,7 @@
                     case WifiP2pManager.ADD_SERVICE_REQUEST_SUCCEEDED:
                     case WifiP2pManager.REMOVE_SERVICE_REQUEST_SUCCEEDED:
                     case WifiP2pManager.CLEAR_SERVICE_REQUESTS_SUCCEEDED:
+                    case WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED:
                         if (listener != null) {
                             ((ActionListener) listener).onSuccess();
                         }
@@ -1104,6 +1113,21 @@
     }
 
     /**
+     * Set p2p device name.
+     * @hide
+     * @param c is the channel created at {@link #initialize}
+     * @param listener for callback when group info is available. Can be null.
+     */
+    public void setDeviceName(Channel c, String devName, ActionListener listener) {
+        checkChannel(c);
+        WifiP2pDevice d = new WifiP2pDevice();
+        d.deviceName = devName;
+        c.mAsyncChannel.sendMessage(SET_DEVICE_NAME, 0, c.putListener(listener), d);
+    }
+
+
+
+    /**
      * Get a reference to WifiP2pService handler. This is used to establish
      * an AsyncChannel communication with WifiService
      *
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 6168f0e..77e6187 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -184,7 +184,6 @@
 
         mThisDevice.primaryDeviceType = mContext.getResources().getString(
                 com.android.internal.R.string.config_wifi_p2p_device_type);
-        mThisDevice.deviceName = getDefaultDeviceName();
 
         mP2pStateMachine = new P2pStateMachine(TAG, mP2pSupported);
         mP2pStateMachine.start();
@@ -205,14 +204,6 @@
                 "WifiP2pService");
     }
 
-    /* We use the 4 digits of the ANDROID_ID to have a friendly
-     * default that has low likelihood of collision with a peer */
-    private String getDefaultDeviceName() {
-        String id = Settings.Secure.getString(mContext.getContentResolver(),
-                    Settings.Secure.ANDROID_ID);
-        return "Android_" + id.substring(0,4);
-    }
-
     /**
      * Get a reference to handler. This is used by a client to establish
      * an AsyncChannel communication with WifiP2pService
@@ -376,6 +367,10 @@
                             WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
                             WifiP2pManager.BUSY);
                     break;
+                case WifiP2pManager.SET_DEVICE_NAME:
+                    replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
+                            WifiP2pManager.BUSY);
+                    break;
                 case WifiP2pManager.REQUEST_PEERS:
                     replyToMessage(message, WifiP2pManager.RESPONSE_PEERS, mPeers);
                     break;
@@ -474,6 +469,10 @@
                             WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
                             WifiP2pManager.P2P_UNSUPPORTED);
                     break;
+                case WifiP2pManager.SET_DEVICE_NAME:
+                    replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
+                            WifiP2pManager.P2P_UNSUPPORTED);
+                    break;
                default:
                     return NOT_HANDLED;
             }
@@ -583,6 +582,16 @@
                     mWifiNative.closeSupplicantConnection();
                     transitionTo(mP2pDisablingState);
                     break;
+                case WifiP2pManager.SET_DEVICE_NAME:
+                    WifiP2pDevice d = (WifiP2pDevice) message.obj;
+                    if (d != null && setAndPersistDeviceName(d.deviceName)) {
+                        if (DBG) logd("set device name " + d.deviceName);
+                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED);
+                    } else {
+                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
+                                WifiP2pManager.ERROR);
+                    }
+                    break;
                 case WifiP2pManager.DISCOVER_PEERS:
                     // do not send service discovery request while normal find operation.
                     clearSupplicantServiceRequest();
@@ -1412,8 +1421,39 @@
         }
     }
 
+    private String getPersistedDeviceName() {
+        String deviceName = Settings.Secure.getString(mContext.getContentResolver(),
+                Settings.Secure.WIFI_P2P_DEVICE_NAME);
+        if (deviceName == null) {
+            /* We use the 4 digits of the ANDROID_ID to have a friendly
+             * default that has low likelihood of collision with a peer */
+            String id = Settings.Secure.getString(mContext.getContentResolver(),
+                    Settings.Secure.ANDROID_ID);
+            return "Android_" + id.substring(0,4);
+        }
+        return deviceName;
+    }
+
+    private boolean setAndPersistDeviceName(String devName) {
+        if (devName == null) return false;
+
+        if (!mWifiNative.setDeviceName(devName)) {
+            loge("Failed to set device name " + devName);
+            return false;
+        }
+
+        mThisDevice.deviceName = devName;
+        mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
+
+        Settings.Secure.putString(mContext.getContentResolver(),
+                Settings.Secure.WIFI_P2P_DEVICE_NAME, devName);
+        sendThisDeviceChangedBroadcast();
+        return true;
+    }
+
     private void initializeP2pSettings() {
         mWifiNative.setPersistentReconnect(true);
+        mThisDevice.deviceName = getPersistedDeviceName();
         mWifiNative.setDeviceName(mThisDevice.deviceName);
         //DIRECT-XY-DEVICENAME (XY is randomly generated)
         mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);