Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
halo
frameworks_base
Commits
7d024d37
Commit
7d024d37
authored
13 years ago
by
Irfan Sheriff
Browse files
Options
Download
Email Patches
Plain Diff
Add initial framework for DNS service discovery
Change-Id: I53c0b7ebfd75e520ebb7553612f1aa8413b6b79b
parent
26d4452a
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1043 additions
and
270 deletions
+1043
-270
Android.mk
Android.mk
+1
-0
core/java/android/app/ContextImpl.java
core/java/android/app/ContextImpl.java
+10
-0
core/java/android/content/Context.java
core/java/android/content/Context.java
+12
-0
core/java/android/net/nsd/DnsSdTxtRecord.java
core/java/android/net/nsd/DnsSdTxtRecord.java
+285
-269
core/java/android/net/nsd/INsdManager.aidl
core/java/android/net/nsd/INsdManager.aidl
+29
-0
core/java/android/net/nsd/NetworkServiceInfo.java
core/java/android/net/nsd/NetworkServiceInfo.java
+32
-0
core/java/android/net/nsd/NsdManager.java
core/java/android/net/nsd/NsdManager.java
+394
-0
core/java/com/android/internal/util/Protocol.java
core/java/com/android/internal/util/Protocol.java
+1
-1
services/java/com/android/server/NsdService.java
services/java/com/android/server/NsdService.java
+269
-0
services/java/com/android/server/SystemServer.java
services/java/com/android/server/SystemServer.java
+10
-0
No files found.
Android.mk
View file @
7d024d37
...
...
@@ -117,6 +117,7 @@ LOCAL_SRC_FILES += \
core/java/android/net/INetworkPolicyListener.aidl
\
core/java/android/net/INetworkPolicyManager.aidl
\
core/java/android/net/INetworkStatsService.aidl
\
core/java/android/net/nsd/INsdManager.aidl
\
core/java/android/nfc/INdefPushCallback.aidl
\
core/java/android/nfc/INfcAdapter.aidl
\
core/java/android/nfc/INfcAdapterExtras.aidl
\
...
...
This diff is collapsed.
Click to expand it.
core/java/android/app/ContextImpl.java
View file @
7d024d37
...
...
@@ -59,6 +59,8 @@ import android.net.NetworkPolicyManager;
import
android.net.ThrottleManager
;
import
android.net.IThrottleManager
;
import
android.net.Uri
;
import
android.net.nsd.INsdManager
;
import
android.net.nsd.NsdManager
;
import
android.net.wifi.IWifiManager
;
import
android.net.wifi.WifiManager
;
import
android.net.wifi.p2p.IWifiP2pManager
;
...
...
@@ -372,6 +374,14 @@ class ContextImpl extends Context {
ctx
.
mMainThread
.
getHandler
());
}});
registerService
(
NSD_SERVICE
,
new
ServiceFetcher
()
{
@Override
public
Object
createService
(
ContextImpl
ctx
)
{
IBinder
b
=
ServiceManager
.
getService
(
NSD_SERVICE
);
INsdManager
service
=
INsdManager
.
Stub
.
asInterface
(
b
);
return
new
NsdManager
(
service
);
}});
// Note: this was previously cached in a static variable, but
// constructed using mMainThread.getHandler(), so converting
// it to be a regular Context-cached service...
...
...
This diff is collapsed.
Click to expand it.
core/java/android/content/Context.java
View file @
7d024d37
...
...
@@ -1768,6 +1768,18 @@ public abstract class Context {
*/
public
static
final
String
WIFI_P2P_SERVICE
=
"wifip2p"
;
/**
* Use with {@link #getSystemService} to retrieve a {@link
* android.net.NsdManager} for handling management of network service
* discovery
*
* @hide
* @see #getSystemService
* @see android.net.NsdManager
*/
public
static
final
String
NSD_SERVICE
=
"servicediscovery"
;
/**
* Use with {@link #getSystemService} to retrieve a
* {@link android.media.AudioManager} for handling management of volume,
...
...
This diff is collapsed.
Click to expand it.
core/java/android/net/nsd/DnsSdTxtRecord.java
View file @
7d024d37
...
...
@@ -14,276 +14,292 @@
* See the License for the specific language governing permissions and
* limitations under the License.
To do:
- implement remove()
- fix set() to replace existing values
To do:
- implement remove()
- fix set() to replace existing values
*/
package
android.net.nsd
;
package
com.apple.dnssd
;
/**
Object used to construct and parse DNS-SD format TXT records.
For more info see <a href="http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt">DNS-Based Service Discovery</a>, section 6.
*/
public
class
TXTRecord
{
/*
DNS-SD specifies that a TXT record corresponding to an SRV record consist of
a packed array of bytes, each preceded by a length byte. Each string
is an attribute-value pair.
The TXTRecord object stores the entire TXT data as a single byte array, traversing it
as need be to implement its various methods.
*/
static
final
protected
byte
kAttrSep
=
'='
;
protected
byte
[]
fBytes
;
/** Constructs a new, empty TXT record. */
public
TXTRecord
()
{
fBytes
=
new
byte
[
0
];
}
/** Constructs a new TXT record from a byte array in the standard format. */
public
TXTRecord
(
byte
[]
initBytes
)
{
fBytes
=
(
byte
[])
initBytes
.
clone
();
}
/** Set a key/value pair in the TXT record. Setting an existing key will replace its value.<P>
@param key
The key name. Must be ASCII, with no '=' characters.
<P>
@param value
Value to be encoded into bytes using the default platform character set.
*/
public
void
set
(
String
key
,
String
value
)
{
byte
[]
valBytes
=
(
value
!=
null
)
?
value
.
getBytes
()
:
null
;
this
.
set
(
key
,
valBytes
);
}
/** Set a key/value pair in the TXT record. Setting an existing key will replace its value.<P>
@param key
The key name. Must be ASCII, with no '=' characters.
<P>
@param value
Binary representation of the value.
*/
public
void
set
(
String
key
,
byte
[]
value
)
{
byte
[]
keyBytes
;
int
valLen
=
(
value
!=
null
)
?
value
.
length
:
0
;
try
{
keyBytes
=
key
.
getBytes
(
"US-ASCII"
);
}
catch
(
java
.
io
.
UnsupportedEncodingException
uee
)
{
throw
new
IllegalArgumentException
();
}
for
(
int
i
=
0
;
i
<
keyBytes
.
length
;
i
++)
if
(
keyBytes
[
i
]
==
'='
)
throw
new
IllegalArgumentException
();
if
(
keyBytes
.
length
+
valLen
>=
255
)
throw
new
ArrayIndexOutOfBoundsException
();
int
prevLoc
=
this
.
remove
(
key
);
if
(
prevLoc
==
-
1
)
prevLoc
=
this
.
size
();
this
.
insert
(
keyBytes
,
value
,
prevLoc
);
}
protected
void
insert
(
byte
[]
keyBytes
,
byte
[]
value
,
int
index
)
// Insert a key-value pair at index
{
byte
[]
oldBytes
=
fBytes
;
int
valLen
=
(
value
!=
null
)
?
value
.
length
:
0
;
int
insertion
=
0
;
int
newLen
,
avLen
;
// locate the insertion point
for
(
int
i
=
0
;
i
<
index
&&
insertion
<
fBytes
.
length
;
i
++)
insertion
+=
(
0xFF
&
(
fBytes
[
insertion
]
+
1
));
avLen
=
keyBytes
.
length
+
valLen
+
(
value
!=
null
?
1
:
0
);
newLen
=
avLen
+
oldBytes
.
length
+
1
;
fBytes
=
new
byte
[
newLen
];
System
.
arraycopy
(
oldBytes
,
0
,
fBytes
,
0
,
insertion
);
int
secondHalfLen
=
oldBytes
.
length
-
insertion
;
System
.
arraycopy
(
oldBytes
,
insertion
,
fBytes
,
newLen
-
secondHalfLen
,
secondHalfLen
);
fBytes
[
insertion
]
=
(
byte
)
avLen
;
System
.
arraycopy
(
keyBytes
,
0
,
fBytes
,
insertion
+
1
,
keyBytes
.
length
);
if
(
value
!=
null
)
{
fBytes
[
insertion
+
1
+
keyBytes
.
length
]
=
kAttrSep
;
System
.
arraycopy
(
value
,
0
,
fBytes
,
insertion
+
keyBytes
.
length
+
2
,
valLen
);
}
}
/** Remove a key/value pair from the TXT record. Returns index it was at, or -1 if not found. */
public
int
remove
(
String
key
)
{
int
avStart
=
0
;
for
(
int
i
=
0
;
avStart
<
fBytes
.
length
;
i
++)
{
int
avLen
=
fBytes
[
avStart
];
if
(
key
.
length
()
<=
avLen
&&
(
key
.
length
()
==
avLen
||
fBytes
[
avStart
+
key
.
length
()
+
1
]
==
kAttrSep
))
{
String
s
=
new
String
(
fBytes
,
avStart
+
1
,
key
.
length
());
if
(
0
==
key
.
compareToIgnoreCase
(
s
))
{
byte
[]
oldBytes
=
fBytes
;
fBytes
=
new
byte
[
oldBytes
.
length
-
avLen
-
1
];
System
.
arraycopy
(
oldBytes
,
0
,
fBytes
,
0
,
avStart
);
System
.
arraycopy
(
oldBytes
,
avStart
+
avLen
+
1
,
fBytes
,
avStart
,
oldBytes
.
length
-
avStart
-
avLen
-
1
);
return
i
;
}
}
avStart
+=
(
0xFF
&
(
avLen
+
1
));
}
return
-
1
;
}
/** Return the number of keys in the TXT record. */
public
int
size
()
{
int
i
,
avStart
;
for
(
i
=
0
,
avStart
=
0
;
avStart
<
fBytes
.
length
;
i
++)
avStart
+=
(
0xFF
&
(
fBytes
[
avStart
]
+
1
));
return
i
;
}
/** Return true if key is present in the TXT record, false if not. */
public
boolean
contains
(
String
key
)
{
String
s
=
null
;
for
(
int
i
=
0
;
null
!=
(
s
=
this
.
getKey
(
i
));
i
++)
if
(
0
==
key
.
compareToIgnoreCase
(
s
))
return
true
;
return
false
;
}
/** Return a key in the TXT record by zero-based index. Returns null if index exceeds the total number of keys. */
public
String
getKey
(
int
index
)
{
int
avStart
=
0
;
for
(
int
i
=
0
;
i
<
index
&&
avStart
<
fBytes
.
length
;
i
++)
avStart
+=
fBytes
[
avStart
]
+
1
;
if
(
avStart
<
fBytes
.
length
)
{
int
avLen
=
fBytes
[
avStart
];
int
aLen
=
0
;
for
(
aLen
=
0
;
aLen
<
avLen
;
aLen
++)
if
(
fBytes
[
avStart
+
aLen
+
1
]
==
kAttrSep
)
break
;
return
new
String
(
fBytes
,
avStart
+
1
,
aLen
);
}
return
null
;
}
/**
Look up a key in the TXT record by zero-based index and return its value. <P>
Returns null if index exceeds the total number of keys.
Returns null if the key is present with no value.
*/
public
byte
[]
getValue
(
int
index
)
{
int
avStart
=
0
;
byte
[]
value
=
null
;
for
(
int
i
=
0
;
i
<
index
&&
avStart
<
fBytes
.
length
;
i
++)
avStart
+=
fBytes
[
avStart
]
+
1
;
if
(
avStart
<
fBytes
.
length
)
{
int
avLen
=
fBytes
[
avStart
];
int
aLen
=
0
;
for
(
aLen
=
0
;
aLen
<
avLen
;
aLen
++)
{
if
(
fBytes
[
avStart
+
aLen
+
1
]
==
kAttrSep
)
{
value
=
new
byte
[
avLen
-
aLen
-
1
];
System
.
arraycopy
(
fBytes
,
avStart
+
aLen
+
2
,
value
,
0
,
avLen
-
aLen
-
1
);
break
;
}
}
}
return
value
;
}
/** Converts the result of getValue() to a string in the platform default character set. */
public
String
getValueAsString
(
int
index
)
{
byte
[]
value
=
this
.
getValue
(
index
);
return
value
!=
null
?
new
String
(
value
)
:
null
;
}
/** Get the value associated with a key. Will be null if the key is not defined.
Array will have length 0 if the key is defined with an = but no value.<P>
@param forKey
The left-hand side of the key-value pair.
<P>
@return The binary representation of the value.
*/
public
byte
[]
getValue
(
String
forKey
)
{
String
s
=
null
;
int
i
;
for
(
i
=
0
;
null
!=
(
s
=
this
.
getKey
(
i
));
i
++)
if
(
0
==
forKey
.
compareToIgnoreCase
(
s
))
return
this
.
getValue
(
i
);
return
null
;
}
/** Converts the result of getValue() to a string in the platform default character set.<P>
@param forKey
The left-hand side of the key-value pair.
<P>
@return The value represented in the default platform character set.
*/
public
String
getValueAsString
(
String
forKey
)
{
byte
[]
val
=
this
.
getValue
(
forKey
);
return
val
!=
null
?
new
String
(
val
)
:
null
;
}
/** Return the contents of the TXT record as raw bytes. */
public
byte
[]
getRawBytes
()
{
return
(
byte
[])
fBytes
.
clone
();
}
/** Return a string representation of the object. */
public
String
toString
()
{
String
a
,
result
=
null
;
for
(
int
i
=
0
;
null
!=
(
a
=
this
.
getKey
(
i
));
i
++)
{
String
av
=
String
.
valueOf
(
i
)
+
"={"
+
a
;
String
val
=
this
.
getValueAsString
(
i
);
if
(
val
!=
null
)
av
+=
"="
+
val
+
"}"
;
else
av
+=
"}"
;
if
(
result
==
null
)
result
=
av
;
else
result
=
result
+
", "
+
av
;
}
return
result
!=
null
?
result
:
""
;
}
import
android.os.Parcelable
;
import
android.os.Parcel
;
/**
* This class handles TXT record data for DNS based service discovery as specified at
* http://tools.ietf.org/html/draft-cheshire-dnsext-dns-sd-11
*
* DNS-SD specifies that a TXT record corresponding to an SRV record consist of
* a packed array of bytes, each preceded by a length byte. Each string
* is an attribute-value pair.
*
* The DnsSdTxtRecord object stores the entire TXT data as a single byte array, traversing it
* as need be to implement its various methods.
*
* @hide
*/
public
class
DnsSdTxtRecord
implements
Parcelable
{
private
static
final
byte
mSeperator
=
'='
;
private
byte
[]
mData
;
/** Constructs a new, empty TXT record. */
public
DnsSdTxtRecord
()
{
mData
=
new
byte
[
0
];
}
/** Constructs a new TXT record from a byte array in the standard format. */
public
DnsSdTxtRecord
(
byte
[]
data
)
{
mData
=
(
byte
[])
data
.
clone
();
}
/** Copy constructor */
public
DnsSdTxtRecord
(
DnsSdTxtRecord
src
)
{
if
(
src
!=
null
&&
src
.
mData
!=
null
)
{
mData
=
(
byte
[])
src
.
mData
.
clone
();
}
}
/**
* Set a key/value pair. Setting an existing key will replace its value.
* @param key Must be ascii with no '='
* @param value matching value to key
*/
public
void
set
(
String
key
,
String
value
)
{
byte
[]
keyBytes
;
byte
[]
valBytes
;
int
valLen
;
if
(
value
!=
null
)
{
valBytes
=
value
.
getBytes
();
valLen
=
valBytes
.
length
;
}
else
{
valBytes
=
null
;
valLen
=
0
;
}
try
{
keyBytes
=
key
.
getBytes
(
"US-ASCII"
);
}
catch
(
java
.
io
.
UnsupportedEncodingException
e
)
{
throw
new
IllegalArgumentException
(
"key should be US-ASCII"
);
}
for
(
int
i
=
0
;
i
<
keyBytes
.
length
;
i
++)
{
if
(
keyBytes
[
i
]
==
'='
)
{
throw
new
IllegalArgumentException
(
"= is not a valid character in key"
);
}
}
if
(
keyBytes
.
length
+
valLen
>=
255
)
{
throw
new
IllegalArgumentException
(
"Key and Value length cannot exceed 255 bytes"
);
}
int
currentLoc
=
remove
(
key
);
if
(
currentLoc
==
-
1
)
currentLoc
=
keyCount
();
insert
(
keyBytes
,
valBytes
,
currentLoc
);
}
/**
* Get a value for a key
*
* @param key
* @return The value associated with the key
*/
public
String
get
(
String
key
)
{
byte
[]
val
=
this
.
getValue
(
key
);
return
val
!=
null
?
new
String
(
val
)
:
null
;
}
/** Remove a key/value pair. If found, returns the index or -1 if not found */
public
int
remove
(
String
key
)
{
int
avStart
=
0
;
for
(
int
i
=
0
;
avStart
<
mData
.
length
;
i
++)
{
int
avLen
=
mData
[
avStart
];
if
(
key
.
length
()
<=
avLen
&&
(
key
.
length
()
==
avLen
||
mData
[
avStart
+
key
.
length
()
+
1
]
==
mSeperator
))
{
String
s
=
new
String
(
mData
,
avStart
+
1
,
key
.
length
());
if
(
0
==
key
.
compareToIgnoreCase
(
s
))
{
byte
[]
oldBytes
=
mData
;
mData
=
new
byte
[
oldBytes
.
length
-
avLen
-
1
];
System
.
arraycopy
(
oldBytes
,
0
,
mData
,
0
,
avStart
);
System
.
arraycopy
(
oldBytes
,
avStart
+
avLen
+
1
,
mData
,
avStart
,
oldBytes
.
length
-
avStart
-
avLen
-
1
);
return
i
;
}
}
avStart
+=
(
0xFF
&
(
avLen
+
1
));
}
return
-
1
;
}
/** Return the count of keys */
public
int
keyCount
()
{
int
count
=
0
,
nextKey
;
for
(
nextKey
=
0
;
nextKey
<
mData
.
length
;
count
++)
{
nextKey
+=
(
0xFF
&
(
mData
[
nextKey
]
+
1
));
}
return
count
;
}
/** Return true if key is present, false if not. */
public
boolean
contains
(
String
key
)
{
String
s
=
null
;
for
(
int
i
=
0
;
null
!=
(
s
=
this
.
getKey
(
i
));
i
++)
{
if
(
0
==
key
.
compareToIgnoreCase
(
s
))
return
true
;
}
return
false
;
}
/* Gets the size in bytes */
public
int
size
()
{
return
mData
.
length
;
}
/* Gets the raw data in bytes */
public
byte
[]
getRawData
()
{
return
mData
;
}
private
void
insert
(
byte
[]
keyBytes
,
byte
[]
value
,
int
index
)
{
byte
[]
oldBytes
=
mData
;
int
valLen
=
(
value
!=
null
)
?
value
.
length
:
0
;
int
insertion
=
0
;
int
newLen
,
avLen
;
for
(
int
i
=
0
;
i
<
index
&&
insertion
<
mData
.
length
;
i
++)
{
insertion
+=
(
0xFF
&
(
mData
[
insertion
]
+
1
));
}
avLen
=
keyBytes
.
length
+
valLen
+
(
value
!=
null
?
1
:
0
);
newLen
=
avLen
+
oldBytes
.
length
+
1
;
mData
=
new
byte
[
newLen
];
System
.
arraycopy
(
oldBytes
,
0
,
mData
,
0
,
insertion
);
int
secondHalfLen
=
oldBytes
.
length
-
insertion
;
System
.
arraycopy
(
oldBytes
,
insertion
,
mData
,
newLen
-
secondHalfLen
,
secondHalfLen
);
mData
[
insertion
]
=
(
byte
)
avLen
;
System
.
arraycopy
(
keyBytes
,
0
,
mData
,
insertion
+
1
,
keyBytes
.
length
);
if
(
value
!=
null
)
{
mData
[
insertion
+
1
+
keyBytes
.
length
]
=
mSeperator
;
System
.
arraycopy
(
value
,
0
,
mData
,
insertion
+
keyBytes
.
length
+
2
,
valLen
);
}
}
/** Return a key in the TXT record by zero-based index. Returns null if index exceeds the total number of keys. */
private
String
getKey
(
int
index
)
{
int
avStart
=
0
;
for
(
int
i
=
0
;
i
<
index
&&
avStart
<
mData
.
length
;
i
++)
{
avStart
+=
mData
[
avStart
]
+
1
;
}
if
(
avStart
<
mData
.
length
)
{
int
avLen
=
mData
[
avStart
];
int
aLen
=
0
;
for
(
aLen
=
0
;
aLen
<
avLen
;
aLen
++)
{
if
(
mData
[
avStart
+
aLen
+
1
]
==
mSeperator
)
break
;
}
return
new
String
(
mData
,
avStart
+
1
,
aLen
);
}
return
null
;
}
/**
* Look up a key in the TXT record by zero-based index and return its value.
* Returns null if index exceeds the total number of keys.
* Returns null if the key is present with no value.
*/
private
byte
[]
getValue
(
int
index
)
{
int
avStart
=
0
;
byte
[]
value
=
null
;
for
(
int
i
=
0
;
i
<
index
&&
avStart
<
mData
.
length
;
i
++)
{
avStart
+=
mData
[
avStart
]
+
1
;
}
if
(
avStart
<
mData
.
length
)
{
int
avLen
=
mData
[
avStart
];
int
aLen
=
0
;
for
(
aLen
=
0
;
aLen
<
avLen
;
aLen
++)
{
if
(
mData
[
avStart
+
aLen
+
1
]
==
mSeperator
)
{
value
=
new
byte
[
avLen
-
aLen
-
1
];
System
.
arraycopy
(
mData
,
avStart
+
aLen
+
2
,
value
,
0
,
avLen
-
aLen
-
1
);
break
;
}
}
}
return
value
;
}
private
String
getValueAsString
(
int
index
)
{
byte
[]
value
=
this
.
getValue
(
index
);
return
value
!=
null
?
new
String
(
value
)
:
null
;
}
private
byte
[]
getValue
(
String
forKey
)
{
String
s
=
null
;
int
i
;
for
(
i
=
0
;
null
!=
(
s
=
this
.
getKey
(
i
));
i
++)
{
if
(
0
==
forKey
.
compareToIgnoreCase
(
s
))
{
return
this
.
getValue
(
i
);
}
}
return
null
;
}
/**
* Return a string representation.
* Example : {key1=value1},{key2=value2}..
*
* For a key say like "key3" with null value
* {key1=value1},{key2=value2}{key3}
*/
public
String
toString
()
{
String
a
,
result
=
null
;
for
(
int
i
=
0
;
null
!=
(
a
=
this
.
getKey
(
i
));
i
++)
{
String
av
=
"{"
+
a
;
String
val
=
this
.
getValueAsString
(
i
);
if
(
val
!=
null
)
av
+=
"="
+
val
+
"}"
;
else
av
+=
"}"
;
if
(
result
==
null
)
result
=
av
;
else
result
=
result
+
", "
+
av
;
}
return
result
!=
null
?
result
:
""
;
}
/** Implement the Parcelable interface */
public
int
describeContents
()
{
return
0
;
}
/** Implement the Parcelable interface */
public
void
writeToParcel
(
Parcel
dest
,
int
flags
)
{
dest
.
writeByteArray
(
mData
);
}
/** Implement the Parcelable interface */
public
static
final
Creator
<
DnsSdTxtRecord
>
CREATOR
=
new
Creator
<
DnsSdTxtRecord
>()
{
public
DnsSdTxtRecord
createFromParcel
(
Parcel
in
)
{
DnsSdTxtRecord
info
=
new
DnsSdTxtRecord
();
in
.
readByteArray
(
info
.
mData
);
return
info
;
}
public
DnsSdTxtRecord
[]
newArray
(
int
size
)
{
return
new
DnsSdTxtRecord
[
size
];
}
};
}
This diff is collapsed.
Click to expand it.
core/java/android/net/nsd/INsdManager.aidl
0 → 100644
View file @
7d024d37
/**
*
Copyright
(
c
)
2012
,
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
.
nsd
;
import
android
.
os
.
Messenger
;
/**
*
Interface
that
NsdService
implements
*
*
{@
hide
}
*/
interface
INsdManager
{
Messenger
getMessenger
();
}
This diff is collapsed.
Click to expand it.
core/java/android/net/nsd/NetworkServiceInfo.java
0 → 100644
View file @
7d024d37
/*
* Copyright (C) 2012 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.nsd
;
/**
* Interface for a network service.
*
* {@hide}
*/
public
interface
NetworkServiceInfo
{
String
getServiceName
();
void
setServiceName
(
String
s
);
String
getServiceType
();
void
setServiceType
(
String
s
);
}
This diff is collapsed.
Click to expand it.
core/java/android/net/nsd/NsdManager.java
0 → 100644
View file @
7d024d37
/*
* Copyright (C) 2012 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.nsd
;
import
android.content.Context
;
import
android.os.Binder
;
import
android.os.IBinder
;
import
android.os.Handler
;
import
android.os.Looper
;
import
android.os.Message
;
import
android.os.RemoteException
;
import
android.os.Messenger
;
import
android.util.Log
;
import
com.android.internal.util.AsyncChannel
;
import
com.android.internal.util.Protocol
;
/**
* The Network Service Discovery Manager class provides the API for service
* discovery. Service discovery enables applications to discover and connect with services
* on a network. Example applications include a game application discovering another instance
* of the game application or a printer application discovering other printers on a network.
*
* <p> The API is asynchronous and responses to requests from an application are on listener
* callbacks provided by the application. The application needs to do an initialization with
* {@link #initialize} before doing any operation.
*
* <p> Android currently supports DNS based service discovery and it is limited to a local
* network with the use of multicast DNS. In future, this class will be
* extended to support other service discovery mechanisms.
*
* Get an instance of this class by calling {@link android.content.Context#getSystemService(String)
* Context.getSystemService(Context.NSD_SERVICE)}.
* @hide
*
*/
public
class
NsdManager
{
private
static
final
String
TAG
=
"NsdManager"
;
INsdManager
mService
;
private
static
final
int
BASE
=
Protocol
.
BASE_NSD_MANAGER
;
/** @hide */
public
static
final
int
DISCOVER_SERVICES
=
BASE
+
1
;
/** @hide */
public
static
final
int
DISCOVER_SERVICES_STARTED
=
BASE
+
2
;
/** @hide */
public
static
final
int
DISCOVER_SERVICES_FAILED
=
BASE
+
3
;
/** @hide */
public
static
final
int
SERVICE_FOUND
=
BASE
+
4
;
/** @hide */
public
static
final
int
SERVICE_LOST
=
BASE
+
5
;
/** @hide */
public
static
final
int
STOP_DISCOVERY
=
BASE
+
6
;
/** @hide */
public
static
final
int
STOP_DISCOVERY_FAILED
=
BASE
+
7
;
/** @hide */
public
static
final
int
STOP_DISCOVERY_SUCCEEDED
=
BASE
+
8
;
/** @hide */
public
static
final
int
REGISTER_SERVICE
=
BASE
+
9
;
/** @hide */
public
static
final
int
REGISTER_SERVICE_FAILED
=
BASE
+
10
;
/** @hide */
public
static
final
int
REGISTER_SERVICE_SUCCEEDED
=
BASE
+
11
;
/** @hide */
public
static
final
int
UPDATE_SERVICE
=
BASE
+
12
;
/** @hide */
public
static
final
int
UPDATE_SERVICE_FAILED
=
BASE
+
13
;
/** @hide */
public
static
final
int
UPDATE_SERVICE_SUCCEEDED
=
BASE
+
14
;
/** @hide */
public
static
final
int
RESOLVE_SERVICE
=
BASE
+
15
;
/** @hide */
public
static
final
int
RESOLVE_SERVICE_FAILED
=
BASE
+
16
;
/** @hide */
public
static
final
int
RESOLVE_SERVICE_SUCCEEDED
=
BASE
+
17
;
/**
* Create a new Nsd instance. Applications use
* {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
* {@link android.content.Context#NSD_SERVICE Context.NSD_SERVICE}.
* @param service the Binder interface
* @hide - hide this because it takes in a parameter of type INsdManager, which
* is a system private class.
*/
public
NsdManager
(
INsdManager
service
)
{
mService
=
service
;
}
/**
* Indicates that the operation failed due to an internal error.
*/
public
static
final
int
ERROR
=
0
;
/**
* Indicates that the operation failed because service discovery is unsupported on the device.
*/
public
static
final
int
UNSUPPORTED
=
1
;
/**
* Indicates that the operation failed because the framework is busy and
* unable to service the request
*/
public
static
final
int
BUSY
=
2
;
/** Interface for callback invocation when framework channel is connected or lost */
public
interface
ChannelListener
{
public
void
onChannelConnected
(
Channel
c
);
/**
* The channel to the framework has been disconnected.
* Application could try re-initializing using {@link #initialize}
*/
public
void
onChannelDisconnected
();
}
public
interface
ActionListener
{
public
void
onFailure
(
int
errorCode
);
public
void
onSuccess
();
}
public
interface
DnsSdDiscoveryListener
{
public
void
onFailure
(
int
errorCode
);
public
void
onStarted
(
String
registrationType
);
public
void
onServiceFound
(
DnsSdServiceInfo
serviceInfo
);
public
void
onServiceLost
(
DnsSdServiceInfo
serviceInfo
);
}
public
interface
DnsSdRegisterListener
{
public
void
onFailure
(
int
errorCode
);
public
void
onServiceRegistered
(
int
registeredId
,
DnsSdServiceInfo
serviceInfo
);
}
public
interface
DnsSdUpdateRegistrationListener
{
public
void
onFailure
(
int
errorCode
);
public
void
onServiceUpdated
(
int
registeredId
,
DnsSdTxtRecord
txtRecord
);
}
public
interface
DnsSdResolveListener
{
public
void
onFailure
(
int
errorCode
);
public
void
onServiceResolved
(
DnsSdServiceInfo
serviceInfo
);
}
/**
* A channel that connects the application to the NetworkService framework.
* Most service operations require a Channel as an argument. An instance of Channel is obtained
* by doing a call on {@link #initialize}
*/
public
static
class
Channel
{
Channel
(
Looper
looper
,
ChannelListener
l
)
{
mAsyncChannel
=
new
AsyncChannel
();
mHandler
=
new
ServiceHandler
(
looper
);
mChannelListener
=
l
;
}
private
ChannelListener
mChannelListener
;
private
DnsSdDiscoveryListener
mDnsSdDiscoveryListener
;
private
ActionListener
mDnsSdStopDiscoveryListener
;
private
DnsSdRegisterListener
mDnsSdRegisterListener
;
private
DnsSdUpdateRegistrationListener
mDnsSdUpdateListener
;
private
DnsSdResolveListener
mDnsSdResolveListener
;
AsyncChannel
mAsyncChannel
;
ServiceHandler
mHandler
;
class
ServiceHandler
extends
Handler
{
ServiceHandler
(
Looper
looper
)
{
super
(
looper
);
}
@Override
public
void
handleMessage
(
Message
message
)
{
switch
(
message
.
what
)
{
case
AsyncChannel
.
CMD_CHANNEL_HALF_CONNECTED
:
mAsyncChannel
.
sendMessage
(
AsyncChannel
.
CMD_CHANNEL_FULL_CONNECTION
);
break
;
case
AsyncChannel
.
CMD_CHANNEL_FULLY_CONNECTED
:
if
(
mChannelListener
!=
null
)
{
mChannelListener
.
onChannelConnected
(
Channel
.
this
);
}
break
;
case
AsyncChannel
.
CMD_CHANNEL_DISCONNECTED
:
if
(
mChannelListener
!=
null
)
{
mChannelListener
.
onChannelDisconnected
();
mChannelListener
=
null
;
}
break
;
case
DISCOVER_SERVICES_STARTED:
if
(
mDnsSdDiscoveryListener
!=
null
)
{
mDnsSdDiscoveryListener
.
onStarted
((
String
)
message
.
obj
);
}
break
;
case
DISCOVER_SERVICES_FAILED:
if
(
mDnsSdDiscoveryListener
!=
null
)
{
mDnsSdDiscoveryListener
.
onFailure
(
message
.
arg1
);
}
break
;
case
SERVICE_FOUND:
if
(
mDnsSdDiscoveryListener
!=
null
)
{
mDnsSdDiscoveryListener
.
onServiceFound
(
(
DnsSdServiceInfo
)
message
.
obj
);
}
break
;
case
SERVICE_LOST:
if
(
mDnsSdDiscoveryListener
!=
null
)
{
mDnsSdDiscoveryListener
.
onServiceLost
(
(
DnsSdServiceInfo
)
message
.
obj
);
}
break
;
case
STOP_DISCOVERY_FAILED:
if
(
mDnsSdStopDiscoveryListener
!=
null
)
{
mDnsSdStopDiscoveryListener
.
onFailure
(
message
.
arg1
);
}
break
;
case
STOP_DISCOVERY_SUCCEEDED:
if
(
mDnsSdStopDiscoveryListener
!=
null
)
{
mDnsSdStopDiscoveryListener
.
onSuccess
();
}
break
;
case
REGISTER_SERVICE_FAILED:
if
(
mDnsSdRegisterListener
!=
null
)
{
mDnsSdRegisterListener
.
onFailure
(
message
.
arg1
);
}
break
;
case
REGISTER_SERVICE_SUCCEEDED:
if
(
mDnsSdRegisterListener
!=
null
)
{
mDnsSdRegisterListener
.
onServiceRegistered
(
message
.
arg1
,
(
DnsSdServiceInfo
)
message
.
obj
);
}
break
;
case
UPDATE_SERVICE_FAILED:
if
(
mDnsSdUpdateListener
!=
null
)
{
mDnsSdUpdateListener
.
onFailure
(
message
.
arg1
);
}
break
;
case
UPDATE_SERVICE_SUCCEEDED:
if
(
mDnsSdUpdateListener
!=
null
)
{
mDnsSdUpdateListener
.
onServiceUpdated
(
message
.
arg1
,
(
DnsSdTxtRecord
)
message
.
obj
);
}
break
;
case
RESOLVE_SERVICE_FAILED:
if
(
mDnsSdResolveListener
!=
null
)
{
mDnsSdResolveListener
.
onFailure
(
message
.
arg1
);
}
break
;
case
RESOLVE_SERVICE_SUCCEEDED:
if
(
mDnsSdResolveListener
!=
null
)
{
mDnsSdResolveListener
.
onServiceResolved
(
(
DnsSdServiceInfo
)
message
.
obj
);
}
break
;
default
:
Log
.
d
(
TAG
,
"Ignored "
+
message
);
break
;
}
}
}
}
/**
* Registers the application with the service discovery framework. This function
* must be the first to be called before any other operations are performed. No service
* discovery operations must be performed until the ChannelListener callback notifies
* that the channel is connected
*
* @param srcContext is the context of the source
* @param srcLooper is the Looper on which the callbacks are receivied
* @param listener for callback at loss of framework communication.
*/
public
void
initialize
(
Context
srcContext
,
Looper
srcLooper
,
ChannelListener
listener
)
{
Messenger
messenger
=
getMessenger
();
if
(
messenger
==
null
)
throw
new
RuntimeException
(
"Failed to initialize"
);
if
(
listener
==
null
)
throw
new
IllegalArgumentException
(
"ChannelListener cannot be null"
);
Channel
c
=
new
Channel
(
srcLooper
,
listener
);
c
.
mAsyncChannel
.
connect
(
srcContext
,
c
.
mHandler
,
messenger
);
}
/**
* Set the listener for service discovery. Can be null.
*/
public
void
setDiscoveryListener
(
Channel
c
,
DnsSdDiscoveryListener
b
)
{
if
(
c
==
null
)
throw
new
IllegalArgumentException
(
"Channel needs to be initialized"
);
c
.
mDnsSdDiscoveryListener
=
b
;
}
/**
* Set the listener for stop service discovery. Can be null.
*/
public
void
setStopDiscoveryListener
(
Channel
c
,
ActionListener
a
)
{
if
(
c
==
null
)
throw
new
IllegalArgumentException
(
"Channel needs to be initialized"
);
c
.
mDnsSdStopDiscoveryListener
=
a
;
}
/**
* Set the listener for service registration. Can be null.
*/
public
void
setRegisterListener
(
Channel
c
,
DnsSdRegisterListener
b
)
{
if
(
c
==
null
)
throw
new
IllegalArgumentException
(
"Channel needs to be initialized"
);
c
.
mDnsSdRegisterListener
=
b
;
}
/**
* Set the listener for service registration. Can be null.
*/
public
void
setUpdateRegistrationListener
(
Channel
c
,
DnsSdUpdateRegistrationListener
b
)
{
if
(
c
==
null
)
throw
new
IllegalArgumentException
(
"Channel needs to be initialized"
);
c
.
mDnsSdUpdateListener
=
b
;
}
/**
* Set the listener for service resolution. Can be null.
*/
public
void
setResolveListener
(
Channel
c
,
DnsSdResolveListener
b
)
{
if
(
c
==
null
)
throw
new
IllegalArgumentException
(
"Channel needs to be initialized"
);
c
.
mDnsSdResolveListener
=
b
;
}
public
void
registerService
(
Channel
c
,
DnsSdServiceInfo
serviceInfo
)
{
if
(
c
==
null
)
throw
new
IllegalArgumentException
(
"Channel needs to be initialized"
);
if
(
serviceInfo
==
null
)
throw
new
IllegalArgumentException
(
"Null serviceInfo"
);
c
.
mAsyncChannel
.
sendMessage
(
REGISTER_SERVICE
,
serviceInfo
);
}
public
void
updateService
(
Channel
c
,
int
registeredId
,
DnsSdTxtRecord
txtRecord
)
{
if
(
c
==
null
)
throw
new
IllegalArgumentException
(
"Channel needs to be initialized"
);
c
.
mAsyncChannel
.
sendMessage
(
UPDATE_SERVICE
,
registeredId
,
0
,
txtRecord
);
}
public
void
discoverServices
(
Channel
c
,
String
serviceType
)
{
if
(
c
==
null
)
throw
new
IllegalArgumentException
(
"Channel needs to be initialized"
);
if
(
c
.
mDnsSdDiscoveryListener
==
null
)
throw
new
IllegalStateException
(
"Discovery listener needs to be set first"
);
DnsSdServiceInfo
s
=
new
DnsSdServiceInfo
();
s
.
setServiceType
(
serviceType
);
c
.
mAsyncChannel
.
sendMessage
(
DISCOVER_SERVICES
,
s
);
}
public
void
stopServiceDiscovery
(
Channel
c
)
{
if
(
c
==
null
)
throw
new
IllegalArgumentException
(
"Channel needs to be initialized"
);
c
.
mAsyncChannel
.
sendMessage
(
STOP_DISCOVERY
);
}
public
void
resolveService
(
Channel
c
,
DnsSdServiceInfo
serviceInfo
)
{
if
(
c
==
null
)
throw
new
IllegalArgumentException
(
"Channel needs to be initialized"
);
if
(
serviceInfo
==
null
)
throw
new
IllegalArgumentException
(
"Null serviceInfo"
);
if
(
c
.
mDnsSdResolveListener
==
null
)
throw
new
IllegalStateException
(
"Resolve listener needs to be set first"
);
c
.
mAsyncChannel
.
sendMessage
(
RESOLVE_SERVICE
,
serviceInfo
);
}
/**
* Get a reference to NetworkService handler. This is used to establish
* an AsyncChannel communication with the service
*
* @return Messenger pointing to the NetworkService handler
*/
private
Messenger
getMessenger
()
{
try
{
return
mService
.
getMessenger
();
}
catch
(
RemoteException
e
)
{
return
null
;
}
}
}
This diff is collapsed.
Click to expand it.
core/java/com/android/internal/util/Protocol.java
View file @
7d024d37
...
...
@@ -49,7 +49,7 @@ public class Protocol {
public
static
final
int
BASE_DATA_CONNECTION
=
0x00040000
;
public
static
final
int
BASE_DATA_CONNECTION_AC
=
0x00041000
;
public
static
final
int
BASE_DATA_CONNECTION_TRACKER
=
0x00042000
;
public
static
final
int
BASE_DNS_PINGER
=
0x00050000
;
public
static
final
int
BASE_NSD_MANAGER
=
0x00060000
;
//TODO: define all used protocols
}
This diff is collapsed.
Click to expand it.
services/java/com/android/server/NsdService.java
0 → 100644
View file @
7d024d37
/*
* Copyright (C) 2010 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.server
;
import
android.content.Context
;
import
android.content.pm.PackageManager
;
import
android.net.nsd.DnsSdServiceInfo
;
import
android.net.nsd.DnsSdTxtRecord
;
import
android.net.nsd.INsdManager
;
import
android.net.nsd.NsdManager
;
import
android.os.Binder
;
import
android.os.Handler
;
import
android.os.HandlerThread
;
import
android.os.Message
;
import
android.os.Messenger
;
import
android.os.IBinder
;
import
android.util.Slog
;
import
java.io.FileDescriptor
;
import
java.io.PrintWriter
;
import
java.util.ArrayList
;
import
java.util.concurrent.CountDownLatch
;
import
java.util.List
;
import
com.android.internal.app.IBatteryStats
;
import
com.android.internal.telephony.TelephonyIntents
;
import
com.android.internal.util.AsyncChannel
;
import
com.android.server.am.BatteryStatsService
;
import
com.android.server.NativeDaemonConnector.Command
;
import
com.android.internal.R
;
/**
* Network Service Discovery Service handles remote service discovery operation requests by
* implementing the INsdManager interface.
*
* @hide
*/
public
class
NsdService
extends
INsdManager
.
Stub
{
private
static
final
String
TAG
=
"NsdService"
;
private
static
final
String
MDNS_TAG
=
"mDnsConnector"
;
private
static
final
boolean
DBG
=
true
;
private
Context
mContext
;
/**
* Clients receiving asynchronous messages
*/
private
List
<
AsyncChannel
>
mClients
=
new
ArrayList
<
AsyncChannel
>();
private
AsyncChannel
mReplyChannel
=
new
AsyncChannel
();
/**
* Handles client(app) connections
*/
private
class
AsyncServiceHandler
extends
Handler
{
AsyncServiceHandler
(
android
.
os
.
Looper
looper
)
{
super
(
looper
);
}
@Override
public
void
handleMessage
(
Message
msg
)
{
switch
(
msg
.
what
)
{
case
AsyncChannel
.
CMD_CHANNEL_HALF_CONNECTED
:
if
(
msg
.
arg1
==
AsyncChannel
.
STATUS_SUCCESSFUL
)
{
AsyncChannel
c
=
(
AsyncChannel
)
msg
.
obj
;
if
(
DBG
)
Slog
.
d
(
TAG
,
"New client listening to asynchronous messages"
);
c
.
sendMessage
(
AsyncChannel
.
CMD_CHANNEL_FULLY_CONNECTED
);
mClients
.
add
(
c
);
}
else
{
Slog
.
e
(
TAG
,
"Client connection failure, error="
+
msg
.
arg1
);
}
break
;
case
AsyncChannel
.
CMD_CHANNEL_DISCONNECTED
:
if
(
msg
.
arg1
==
AsyncChannel
.
STATUS_SEND_UNSUCCESSFUL
)
{
Slog
.
e
(
TAG
,
"Send failed, client connection lost"
);
}
else
{
if
(
DBG
)
Slog
.
d
(
TAG
,
"Client connection lost with reason: "
+
msg
.
arg1
);
}
mClients
.
remove
((
AsyncChannel
)
msg
.
obj
);
break
;
case
AsyncChannel
.
CMD_CHANNEL_FULL_CONNECTION
:
AsyncChannel
ac
=
new
AsyncChannel
();
ac
.
connect
(
mContext
,
this
,
msg
.
replyTo
);
break
;
case
NsdManager
.
DISCOVER_SERVICES
:
if
(
DBG
)
Slog
.
d
(
TAG
,
"Discover services"
);
DnsSdServiceInfo
s
=
(
DnsSdServiceInfo
)
msg
.
obj
;
discoverServices
(
1
,
s
.
getServiceType
());
mReplyChannel
.
replyToMessage
(
msg
,
NsdManager
.
DISCOVER_SERVICES_STARTED
);
break
;
case
NsdManager
.
STOP_DISCOVERY
:
if
(
DBG
)
Slog
.
d
(
TAG
,
"Stop service discovery"
);
mReplyChannel
.
replyToMessage
(
msg
,
NsdManager
.
STOP_DISCOVERY_FAILED
);
break
;
case
NsdManager
.
REGISTER_SERVICE
:
if
(
DBG
)
Slog
.
d
(
TAG
,
"Register service"
);
mReplyChannel
.
replyToMessage
(
msg
,
NsdManager
.
REGISTER_SERVICE_FAILED
);
break
;
case
NsdManager
.
UPDATE_SERVICE
:
if
(
DBG
)
Slog
.
d
(
TAG
,
"Update service"
);
mReplyChannel
.
replyToMessage
(
msg
,
NsdManager
.
UPDATE_SERVICE_FAILED
);
break
;
default
:
Slog
.
d
(
TAG
,
"NsdServicehandler.handleMessage ignoring msg="
+
msg
);
break
;
}
}
}
private
AsyncServiceHandler
mAsyncServiceHandler
;
private
NativeDaemonConnector
mNativeConnector
;
private
final
CountDownLatch
mNativeDaemonConnected
=
new
CountDownLatch
(
1
);
private
NsdService
(
Context
context
)
{
mContext
=
context
;
HandlerThread
nsdThread
=
new
HandlerThread
(
"NsdService"
);
nsdThread
.
start
();
mAsyncServiceHandler
=
new
AsyncServiceHandler
(
nsdThread
.
getLooper
());
/*
mNativeConnector = new NativeDaemonConnector(new NativeCallbackReceiver(), "mdns", 10,
MDNS_TAG, 25);
Thread th = new Thread(mNativeConnector, MDNS_TAG);
th.start();
*/
}
public
static
NsdService
create
(
Context
context
)
throws
InterruptedException
{
NsdService
service
=
new
NsdService
(
context
);
/* service.mNativeDaemonConnected.await(); */
return
service
;
}
public
Messenger
getMessenger
()
{
return
new
Messenger
(
mAsyncServiceHandler
);
}
/* These should be in sync with system/netd/mDnsResponseCode.h */
class
NativeResponseCode
{
public
static
final
int
SERVICE_FOUND
=
101
;
public
static
final
int
SERVICE_LOST
=
102
;
public
static
final
int
SERVICE_DISCOVERY_FAILED
=
103
;
public
static
final
int
SERVICE_REGISTERED
=
104
;
public
static
final
int
SERVICE_REGISTRATION_FAILED
=
105
;
public
static
final
int
SERVICE_UPDATED
=
106
;
public
static
final
int
SERVICE_UPDATE_FAILED
=
107
;
public
static
final
int
SERVICE_RESOLVED
=
108
;
public
static
final
int
SERVICE_RESOLUTION_FAILED
=
109
;
}
class
NativeCallbackReceiver
implements
INativeDaemonConnectorCallbacks
{
public
void
onDaemonConnected
()
{
mNativeDaemonConnected
.
countDown
();
}
public
boolean
onEvent
(
int
code
,
String
raw
,
String
[]
cooked
)
{
switch
(
code
)
{
case
NativeResponseCode
.
SERVICE_FOUND
:
/* NNN uniqueId serviceName regType */
break
;
case
NativeResponseCode
.
SERVICE_LOST
:
/* NNN uniqueId serviceName regType */
break
;
case
NativeResponseCode
.
SERVICE_DISCOVERY_FAILED
:
/* NNN uniqueId errorCode */
break
;
case
NativeResponseCode
.
SERVICE_REGISTERED
:
/* NNN regId serviceName regType */
break
;
case
NativeResponseCode
.
SERVICE_REGISTRATION_FAILED
:
/* NNN regId errorCode */
break
;
case
NativeResponseCode
.
SERVICE_UPDATED
:
/* NNN regId */
break
;
case
NativeResponseCode
.
SERVICE_UPDATE_FAILED
:
/* NNN regId errorCode */
break
;
case
NativeResponseCode
.
SERVICE_RESOLVED
:
/* NNN resolveId fullName hostName port txtlen txtdata */
break
;
case
NativeResponseCode
.
SERVICE_RESOLUTION_FAILED
:
/* NNN resovleId errorCode */
break
;
default
:
break
;
}
return
false
;
}
}
private
void
registerService
(
int
regId
,
DnsSdServiceInfo
service
)
{
try
{
//Add txtlen and txtdata
mNativeConnector
.
execute
(
"mdnssd"
,
"register"
,
regId
,
service
.
getServiceName
(),
service
.
getServiceType
(),
service
.
getPort
());
}
catch
(
NativeDaemonConnectorException
e
)
{
Slog
.
e
(
TAG
,
"Failed to execute registerService"
);
}
}
private
void
updateService
(
int
regId
,
DnsSdTxtRecord
t
)
{
try
{
if
(
t
==
null
)
return
;
mNativeConnector
.
execute
(
"mdnssd"
,
"update"
,
regId
,
t
.
size
(),
t
.
getRawData
());
}
catch
(
NativeDaemonConnectorException
e
)
{
Slog
.
e
(
TAG
,
"Failed to updateServices"
);
}
}
private
void
discoverServices
(
int
discoveryId
,
String
serviceType
)
{
try
{
mNativeConnector
.
execute
(
"mdnssd"
,
"discover"
,
discoveryId
,
serviceType
);
}
catch
(
NativeDaemonConnectorException
e
)
{
Slog
.
e
(
TAG
,
"Failed to discoverServices"
);
}
}
private
void
stopServiceDiscovery
(
int
discoveryId
)
{
try
{
mNativeConnector
.
execute
(
"mdnssd"
,
"stopdiscover"
,
discoveryId
);
}
catch
(
NativeDaemonConnectorException
e
)
{
Slog
.
e
(
TAG
,
"Failed to stopServiceDiscovery"
);
}
}
private
void
resolveService
(
DnsSdServiceInfo
service
)
{
try
{
mNativeConnector
.
execute
(
"mdnssd"
,
"resolve"
,
service
.
getServiceName
(),
service
.
getServiceType
());
}
catch
(
NativeDaemonConnectorException
e
)
{
Slog
.
e
(
TAG
,
"Failed to resolveService"
);
}
}
@Override
protected
void
dump
(
FileDescriptor
fd
,
PrintWriter
pw
,
String
[]
args
)
{
if
(
mContext
.
checkCallingOrSelfPermission
(
android
.
Manifest
.
permission
.
DUMP
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
pw
.
println
(
"Permission Denial: can't dump ServiceDiscoverService from from pid="
+
Binder
.
getCallingPid
()
+
", uid="
+
Binder
.
getCallingUid
());
return
;
}
pw
.
println
(
"Internal state:"
);
}
}
This diff is collapsed.
Click to expand it.
services/java/com/android/server/SystemServer.java
View file @
7d024d37
...
...
@@ -120,6 +120,7 @@ class ServerThread extends Thread {
ConnectivityService
connectivity
=
null
;
WifiP2pService
wifiP2p
=
null
;
WifiService
wifi
=
null
;
NsdService
serviceDiscovery
=
null
;
IPackageManager
pm
=
null
;
Context
context
=
null
;
WindowManagerService
wm
=
null
;
...
...
@@ -393,6 +394,15 @@ class ServerThread extends Thread {
reportWtf
(
"starting Connectivity Service"
,
e
);
}
try
{
Slog
.
i
(
TAG
,
"Network Service Discovery Service"
);
serviceDiscovery
=
NsdService
.
create
(
context
);
ServiceManager
.
addService
(
Context
.
NSD_SERVICE
,
serviceDiscovery
);
}
catch
(
Throwable
e
)
{
reportWtf
(
"starting Service Discovery Service"
,
e
);
}
try
{
Slog
.
i
(
TAG
,
"Throttle Service"
);
throttle
=
new
ThrottleService
(
context
);
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment