summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt250
-rw-r--r--core/java/android/app/ContextImpl.java2
-rw-r--r--core/java/android/net/nsd/NsdManager.java677
-rw-r--r--core/java/android/net/nsd/NsdServiceInfo.java (renamed from core/java/android/net/nsd/DnsSdServiceInfo.java)22
-rw-r--r--core/java/android/os/IBinder.java3
-rw-r--r--core/java/android/os/ServiceManagerNative.java36
-rw-r--r--core/java/android/os/SystemProperties.java29
-rw-r--r--core/java/android/os/Trace.java10
-rw-r--r--core/java/android/view/View.java2
-rw-r--r--core/java/android/view/ViewRootImpl.java26
-rw-r--r--core/java/android/view/WindowManagerImpl.java19
-rw-r--r--core/java/android/widget/AbsListView.java78
-rw-r--r--core/java/com/android/internal/util/FileRotator.java63
-rw-r--r--core/jni/android_os_SystemProperties.cpp34
-rw-r--r--core/jni/android_util_Binder.cpp6
-rw-r--r--core/res/res/values-sw600dp/dimens.xml4
-rw-r--r--core/res/res/values/dimens.xml4
-rw-r--r--core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java4
-rw-r--r--graphics/java/android/renderscript/Mesh.java23
-rw-r--r--graphics/java/android/renderscript/ProgramFragment.java6
-rw-r--r--graphics/java/android/renderscript/ProgramRaster.java39
-rw-r--r--graphics/java/android/renderscript/ProgramVertex.java7
-rw-r--r--graphics/java/android/renderscript/RSTextureView.java21
-rw-r--r--graphics/java/android/renderscript/RenderScriptGL.java23
-rw-r--r--packages/SystemUI/res/layout-land/status_bar_recent_panel.xml2
-rw-r--r--packages/SystemUI/res/values-sw600dp-land/values-land-sw600dp/dimens.xml (renamed from core/java/android/net/nsd/NetworkServiceInfo.java)31
-rw-r--r--packages/SystemUI/res/values-sw600dp-port/dimens.xml21
-rw-r--r--packages/SystemUI/res/values-sw600dp/dimens.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/SearchPanelView.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java2
-rw-r--r--services/java/com/android/server/NsdService.java497
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java25
-rwxr-xr-xservices/java/com/android/server/am/ActivityStack.java4
-rw-r--r--services/java/com/android/server/net/NetworkStatsRecorder.java37
-rw-r--r--services/java/com/android/server/net/NetworkStatsService.java4
37 files changed, 1253 insertions, 828 deletions
diff --git a/api/current.txt b/api/current.txt
index ec3d54a..a8bf949 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -12708,21 +12708,6 @@ package android.net.http {
package android.net.nsd {
- public class DnsSdServiceInfo implements android.os.Parcelable {
- ctor public DnsSdServiceInfo();
- method public int describeContents();
- method public java.net.InetAddress getHost();
- method public int getPort();
- method public java.lang.String getServiceName();
- method public java.lang.String getServiceType();
- method public void setHost(java.net.InetAddress);
- method public void setPort(int);
- method public void setServiceName(java.lang.String);
- method public void setServiceType(java.lang.String);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator CREATOR;
- }
-
public class DnsSdTxtRecord implements android.os.Parcelable {
ctor public DnsSdTxtRecord();
ctor public DnsSdTxtRecord(byte[]);
@@ -12739,53 +12724,56 @@ package android.net.nsd {
field public static final android.os.Parcelable.Creator CREATOR;
}
- public class NsdManager {
- method public void deinitialize(android.net.nsd.NsdManager.Channel);
- method public void discoverServices(android.net.nsd.NsdManager.Channel, java.lang.String, android.net.nsd.NsdManager.DnsSdDiscoveryListener);
- method public void initialize(android.content.Context, android.os.Looper, android.net.nsd.NsdManager.ChannelListener);
- method public void registerService(android.net.nsd.NsdManager.Channel, java.lang.String, java.lang.String, int, android.net.nsd.NsdManager.DnsSdRegisterListener);
- method public void resolveService(android.net.nsd.NsdManager.Channel, java.lang.String, java.lang.String, android.net.nsd.NsdManager.DnsSdResolveListener);
- method public void stopServiceDiscovery(android.net.nsd.NsdManager.Channel, android.net.nsd.NsdManager.ActionListener);
- method public void unregisterService(android.net.nsd.NsdManager.Channel, int, android.net.nsd.NsdManager.ActionListener);
+ public final class NsdManager {
+ method public void discoverServices(java.lang.String, int, android.net.nsd.NsdManager.DiscoveryListener);
+ method public void registerService(android.net.nsd.NsdServiceInfo, int, android.net.nsd.NsdManager.RegistrationListener);
+ method public void resolveService(android.net.nsd.NsdServiceInfo, android.net.nsd.NsdManager.ResolveListener);
+ method public void stopServiceDiscovery(android.net.nsd.NsdManager.DiscoveryListener);
+ method public void unregisterService(android.net.nsd.NsdManager.RegistrationListener);
field public static final java.lang.String ACTION_NSD_STATE_CHANGED = "android.net.nsd.STATE_CHANGED";
- field public static final int ALREADY_ACTIVE = 3; // 0x3
- field public static final int BUSY = 2; // 0x2
- field public static final int ERROR = 0; // 0x0
field public static final java.lang.String EXTRA_NSD_STATE = "nsd_state";
- field public static final int MAX_REGS_REACHED = 4; // 0x4
+ field public static final int FAILURE_ALREADY_ACTIVE = 3; // 0x3
+ field public static final int FAILURE_INTERNAL_ERROR = 0; // 0x0
+ field public static final int FAILURE_MAX_LIMIT = 4; // 0x4
field public static final int NSD_STATE_DISABLED = 1; // 0x1
field public static final int NSD_STATE_ENABLED = 2; // 0x2
- field public static final int UNSUPPORTED = 1; // 0x1
- }
-
- public static abstract interface NsdManager.ActionListener {
- method public abstract void onFailure(int);
- method public abstract void onSuccess();
- }
-
- public static class NsdManager.Channel {
+ field public static final int PROTOCOL_DNS_SD = 1; // 0x1
}
- public static abstract interface NsdManager.ChannelListener {
- method public abstract void onChannelConnected(android.net.nsd.NsdManager.Channel);
- method public abstract void onChannelDisconnected();
+ public static abstract interface NsdManager.DiscoveryListener {
+ method public abstract void onDiscoveryStarted(java.lang.String);
+ method public abstract void onDiscoveryStopped(java.lang.String);
+ method public abstract void onServiceFound(android.net.nsd.NsdServiceInfo);
+ method public abstract void onServiceLost(android.net.nsd.NsdServiceInfo);
+ method public abstract void onStartDiscoveryFailed(java.lang.String, int);
+ method public abstract void onStopDiscoveryFailed(java.lang.String, int);
}
- public static abstract interface NsdManager.DnsSdDiscoveryListener {
- method public abstract void onFailure(int);
- method public abstract void onServiceFound(android.net.nsd.DnsSdServiceInfo);
- method public abstract void onServiceLost(android.net.nsd.DnsSdServiceInfo);
- method public abstract void onStarted(java.lang.String);
+ public static abstract interface NsdManager.RegistrationListener {
+ method public abstract void onRegistrationFailed(android.net.nsd.NsdServiceInfo, int);
+ method public abstract void onServiceRegistered(android.net.nsd.NsdServiceInfo);
+ method public abstract void onServiceUnregistered(android.net.nsd.NsdServiceInfo);
+ method public abstract void onUnregistrationFailed(android.net.nsd.NsdServiceInfo, int);
}
- public static abstract interface NsdManager.DnsSdRegisterListener {
- method public abstract void onFailure(int);
- method public abstract void onServiceRegistered(int, android.net.nsd.DnsSdServiceInfo);
+ public static abstract interface NsdManager.ResolveListener {
+ method public abstract void onResolveFailed(android.net.nsd.NsdServiceInfo, int);
+ method public abstract void onServiceResolved(android.net.nsd.NsdServiceInfo);
}
- public static abstract interface NsdManager.DnsSdResolveListener {
- method public abstract void onFailure(int);
- method public abstract void onServiceResolved(android.net.nsd.DnsSdServiceInfo);
+ public final class NsdServiceInfo implements android.os.Parcelable {
+ ctor public NsdServiceInfo();
+ method public int describeContents();
+ method public java.net.InetAddress getHost();
+ method public int getPort();
+ method public java.lang.String getServiceName();
+ method public java.lang.String getServiceType();
+ method public void setHost(java.net.InetAddress);
+ method public void setPort(int);
+ method public void setServiceName(java.lang.String);
+ method public void setServiceType(java.lang.String);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
}
}
@@ -19085,12 +19073,12 @@ package android.renderscript {
method public void transpose();
}
- public class Mesh extends android.renderscript.BaseObj {
- method public android.renderscript.Allocation getIndexSetAllocation(int);
- method public android.renderscript.Mesh.Primitive getPrimitive(int);
- method public int getPrimitiveCount();
- method public android.renderscript.Allocation getVertexAllocation(int);
- method public int getVertexAllocationCount();
+ public deprecated class Mesh extends android.renderscript.BaseObj {
+ method public deprecated android.renderscript.Allocation getIndexSetAllocation(int);
+ method public deprecated android.renderscript.Mesh.Primitive getPrimitive(int);
+ method public deprecated int getPrimitiveCount();
+ method public deprecated android.renderscript.Allocation getVertexAllocation(int);
+ method public deprecated int getVertexAllocationCount();
}
public static deprecated class Mesh.AllocationBuilder {
@@ -19103,27 +19091,27 @@ package android.renderscript {
method public deprecated int getCurrentVertexTypeIndex();
}
- public static class Mesh.Builder {
- ctor public Mesh.Builder(android.renderscript.RenderScript, int);
- method public android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Type, android.renderscript.Mesh.Primitive);
- method public android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Mesh.Primitive);
- method public android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Element, int, android.renderscript.Mesh.Primitive);
- method public android.renderscript.Mesh.Builder addVertexType(android.renderscript.Type) throws java.lang.IllegalStateException;
- method public android.renderscript.Mesh.Builder addVertexType(android.renderscript.Element, int) throws java.lang.IllegalStateException;
- method public android.renderscript.Mesh create();
- method public int getCurrentIndexSetIndex();
- method public int getCurrentVertexTypeIndex();
+ public static deprecated class Mesh.Builder {
+ ctor public deprecated Mesh.Builder(android.renderscript.RenderScript, int);
+ method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Type, android.renderscript.Mesh.Primitive);
+ method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Mesh.Primitive);
+ method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Element, int, android.renderscript.Mesh.Primitive);
+ method public deprecated android.renderscript.Mesh.Builder addVertexType(android.renderscript.Type) throws java.lang.IllegalStateException;
+ method public deprecated android.renderscript.Mesh.Builder addVertexType(android.renderscript.Element, int) throws java.lang.IllegalStateException;
+ method public deprecated android.renderscript.Mesh create();
+ method public deprecated int getCurrentIndexSetIndex();
+ method public deprecated int getCurrentVertexTypeIndex();
}
- public static final class Mesh.Primitive extends java.lang.Enum {
+ public static final deprecated class Mesh.Primitive extends java.lang.Enum {
method public static android.renderscript.Mesh.Primitive valueOf(java.lang.String);
method public static final android.renderscript.Mesh.Primitive[] values();
- enum_constant public static final android.renderscript.Mesh.Primitive LINE;
- enum_constant public static final android.renderscript.Mesh.Primitive LINE_STRIP;
- enum_constant public static final android.renderscript.Mesh.Primitive POINT;
- enum_constant public static final android.renderscript.Mesh.Primitive TRIANGLE;
- enum_constant public static final android.renderscript.Mesh.Primitive TRIANGLE_FAN;
- enum_constant public static final android.renderscript.Mesh.Primitive TRIANGLE_STRIP;
+ enum_constant public static final deprecated android.renderscript.Mesh.Primitive LINE;
+ enum_constant public static final deprecated android.renderscript.Mesh.Primitive LINE_STRIP;
+ enum_constant public static final deprecated android.renderscript.Mesh.Primitive POINT;
+ enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE;
+ enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE_FAN;
+ enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE_STRIP;
}
public static deprecated class Mesh.TriangleMeshBuilder {
@@ -19170,12 +19158,12 @@ package android.renderscript {
enum_constant public static final android.renderscript.Program.TextureType TEXTURE_CUBE;
}
- public class ProgramFragment extends android.renderscript.Program {
+ public deprecated class ProgramFragment extends android.renderscript.Program {
}
- public static class ProgramFragment.Builder extends android.renderscript.Program.BaseProgramBuilder {
- ctor public ProgramFragment.Builder(android.renderscript.RenderScript);
- method public android.renderscript.ProgramFragment create();
+ public static deprecated class ProgramFragment.Builder extends android.renderscript.Program.BaseProgramBuilder {
+ ctor public deprecated ProgramFragment.Builder(android.renderscript.RenderScript);
+ method public deprecated android.renderscript.ProgramFragment create();
}
public deprecated class ProgramFragmentFixedFunction extends android.renderscript.ProgramFragment {
@@ -19207,27 +19195,27 @@ package android.renderscript {
enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.Format RGBA;
}
- public class ProgramRaster extends android.renderscript.BaseObj {
- method public static android.renderscript.ProgramRaster CULL_BACK(android.renderscript.RenderScript);
- method public static android.renderscript.ProgramRaster CULL_FRONT(android.renderscript.RenderScript);
- method public static android.renderscript.ProgramRaster CULL_NONE(android.renderscript.RenderScript);
- method public android.renderscript.ProgramRaster.CullMode getCullMode();
- method public boolean isPointSpriteEnabled();
+ public deprecated class ProgramRaster extends android.renderscript.BaseObj {
+ method public static deprecated android.renderscript.ProgramRaster CULL_BACK(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.ProgramRaster CULL_FRONT(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.ProgramRaster CULL_NONE(android.renderscript.RenderScript);
+ method public deprecated android.renderscript.ProgramRaster.CullMode getCullMode();
+ method public deprecated boolean isPointSpriteEnabled();
}
- public static class ProgramRaster.Builder {
- ctor public ProgramRaster.Builder(android.renderscript.RenderScript);
- method public android.renderscript.ProgramRaster create();
- method public android.renderscript.ProgramRaster.Builder setCullMode(android.renderscript.ProgramRaster.CullMode);
- method public android.renderscript.ProgramRaster.Builder setPointSpriteEnabled(boolean);
+ public static deprecated class ProgramRaster.Builder {
+ ctor public deprecated ProgramRaster.Builder(android.renderscript.RenderScript);
+ method public deprecated android.renderscript.ProgramRaster create();
+ method public deprecated android.renderscript.ProgramRaster.Builder setCullMode(android.renderscript.ProgramRaster.CullMode);
+ method public deprecated android.renderscript.ProgramRaster.Builder setPointSpriteEnabled(boolean);
}
- public static final class ProgramRaster.CullMode extends java.lang.Enum {
+ public static final deprecated class ProgramRaster.CullMode extends java.lang.Enum {
method public static android.renderscript.ProgramRaster.CullMode valueOf(java.lang.String);
method public static final android.renderscript.ProgramRaster.CullMode[] values();
- enum_constant public static final android.renderscript.ProgramRaster.CullMode BACK;
- enum_constant public static final android.renderscript.ProgramRaster.CullMode FRONT;
- enum_constant public static final android.renderscript.ProgramRaster.CullMode NONE;
+ enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode BACK;
+ enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode FRONT;
+ enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode NONE;
}
public class ProgramStore extends android.renderscript.BaseObj {
@@ -19295,15 +19283,15 @@ package android.renderscript {
enum_constant public static final android.renderscript.ProgramStore.DepthFunc NOT_EQUAL;
}
- public class ProgramVertex extends android.renderscript.Program {
- method public android.renderscript.Element getInput(int);
- method public int getInputCount();
+ public deprecated class ProgramVertex extends android.renderscript.Program {
+ method public deprecated android.renderscript.Element getInput(int);
+ method public deprecated int getInputCount();
}
- public static class ProgramVertex.Builder extends android.renderscript.Program.BaseProgramBuilder {
- ctor public ProgramVertex.Builder(android.renderscript.RenderScript);
- method public android.renderscript.ProgramVertex.Builder addInput(android.renderscript.Element) throws java.lang.IllegalStateException;
- method public android.renderscript.ProgramVertex create();
+ public static deprecated class ProgramVertex.Builder extends android.renderscript.Program.BaseProgramBuilder {
+ ctor public deprecated ProgramVertex.Builder(android.renderscript.RenderScript);
+ method public deprecated android.renderscript.ProgramVertex.Builder addInput(android.renderscript.Element) throws java.lang.IllegalStateException;
+ method public deprecated android.renderscript.ProgramVertex create();
}
public deprecated class ProgramVertexFixedFunction extends android.renderscript.ProgramVertex {
@@ -19354,19 +19342,19 @@ package android.renderscript {
method public deprecated void surfaceDestroyed(android.view.SurfaceHolder);
}
- public class RSTextureView extends android.view.TextureView implements android.view.TextureView.SurfaceTextureListener {
- ctor public RSTextureView(android.content.Context);
- ctor public RSTextureView(android.content.Context, android.util.AttributeSet);
- method public android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
- method public void destroyRenderScriptGL();
- method public android.renderscript.RenderScriptGL getRenderScriptGL();
- method public void onSurfaceTextureAvailable(android.graphics.SurfaceTexture, int, int);
- method public boolean onSurfaceTextureDestroyed(android.graphics.SurfaceTexture);
- method public void onSurfaceTextureSizeChanged(android.graphics.SurfaceTexture, int, int);
- method public void onSurfaceTextureUpdated(android.graphics.SurfaceTexture);
- method public void pause();
- method public void resume();
- method public void setRenderScriptGL(android.renderscript.RenderScriptGL);
+ public deprecated class RSTextureView extends android.view.TextureView implements android.view.TextureView.SurfaceTextureListener {
+ ctor public deprecated RSTextureView(android.content.Context);
+ ctor public deprecated RSTextureView(android.content.Context, android.util.AttributeSet);
+ method public deprecated android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
+ method public deprecated void destroyRenderScriptGL();
+ method public deprecated android.renderscript.RenderScriptGL getRenderScriptGL();
+ method public deprecated void onSurfaceTextureAvailable(android.graphics.SurfaceTexture, int, int);
+ method public deprecated boolean onSurfaceTextureDestroyed(android.graphics.SurfaceTexture);
+ method public deprecated void onSurfaceTextureSizeChanged(android.graphics.SurfaceTexture, int, int);
+ method public deprecated void onSurfaceTextureUpdated(android.graphics.SurfaceTexture);
+ method public deprecated void pause();
+ method public deprecated void resume();
+ method public deprecated void setRenderScriptGL(android.renderscript.RenderScriptGL);
}
public class RenderScript {
@@ -19404,28 +19392,28 @@ package android.renderscript {
field protected int mLength;
}
- public class RenderScriptGL extends android.renderscript.RenderScript {
- ctor public RenderScriptGL(android.content.Context, android.renderscript.RenderScriptGL.SurfaceConfig);
- method public void bindProgramFragment(android.renderscript.ProgramFragment);
- method public void bindProgramRaster(android.renderscript.ProgramRaster);
- method public void bindProgramStore(android.renderscript.ProgramStore);
- method public void bindProgramVertex(android.renderscript.ProgramVertex);
- method public void bindRootScript(android.renderscript.Script);
- method public int getHeight();
- method public int getWidth();
- method public void pause();
- method public void resume();
- method public void setSurface(android.view.SurfaceHolder, int, int);
+ public deprecated class RenderScriptGL extends android.renderscript.RenderScript {
+ ctor public deprecated RenderScriptGL(android.content.Context, android.renderscript.RenderScriptGL.SurfaceConfig);
+ method public deprecated void bindProgramFragment(android.renderscript.ProgramFragment);
+ method public deprecated void bindProgramRaster(android.renderscript.ProgramRaster);
+ method public deprecated void bindProgramStore(android.renderscript.ProgramStore);
+ method public deprecated void bindProgramVertex(android.renderscript.ProgramVertex);
+ method public deprecated void bindRootScript(android.renderscript.Script);
+ method public deprecated int getHeight();
+ method public deprecated int getWidth();
+ method public deprecated void pause();
+ method public deprecated void resume();
+ method public deprecated void setSurface(android.view.SurfaceHolder, int, int);
method public deprecated void setSurfaceTexture(android.graphics.SurfaceTexture, int, int);
}
- public static class RenderScriptGL.SurfaceConfig {
- ctor public RenderScriptGL.SurfaceConfig();
- ctor public RenderScriptGL.SurfaceConfig(android.renderscript.RenderScriptGL.SurfaceConfig);
- method public void setAlpha(int, int);
- method public void setColor(int, int);
- method public void setDepth(int, int);
- method public void setSamples(int, int, float);
+ public static deprecated class RenderScriptGL.SurfaceConfig {
+ ctor public deprecated RenderScriptGL.SurfaceConfig();
+ ctor public deprecated RenderScriptGL.SurfaceConfig(android.renderscript.RenderScriptGL.SurfaceConfig);
+ method public deprecated void setAlpha(int, int);
+ method public deprecated void setColor(int, int);
+ method public deprecated void setDepth(int, int);
+ method public deprecated void setSamples(int, int, float);
}
public class Sampler extends android.renderscript.BaseObj {
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 64a05a8..4943c9a 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -387,7 +387,7 @@ class ContextImpl extends Context {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(NSD_SERVICE);
INsdManager service = INsdManager.Stub.asInterface(b);
- return new NsdManager(service);
+ return new NsdManager(ctx.getOuterContext(), service);
}});
// Note: this was previously cached in a static variable, but
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index 77e97e1..08ba728 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -22,12 +22,16 @@ import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.Messenger;
import android.text.TextUtils;
import android.util.Log;
+import android.util.SparseArray;
+
+import java.util.concurrent.CountDownLatch;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
@@ -39,88 +43,73 @@ import com.android.internal.util.Protocol;
* B. Another example use case is an application discovering printers on the network.
*
* <p> The API currently supports DNS based service discovery and discovery is currently
- * limited to a local network over Multicast DNS. In future, it will be extended to
- * support wide area discovery and other service discovery mechanisms.
- * DNS service discovery is described at http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
+ * limited to a local network over Multicast DNS. DNS service discovery is described at
+ * http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
*
* <p> The API is asynchronous and responses to requests from an application are on listener
- * callbacks provided by the application. The application must invoke {@link #initialize} before
- * doing any other operation.
+ * callbacks on a seperate thread.
*
* <p> There are three main operations the API supports - registration, discovery and resolution.
* <pre>
* Application start
* |
- * | <----------------------------------------------
- * initialize() |
- * | |
- * | Wait until channel connects |
- * | before doing any operation |
- * | |
- * onChannelConnected() __________ |
- * | | |
- * | | |
- * | onServiceRegistered() | |
- * Register any local services / | |
- * to be advertised with \ | | If application needs to
- * registerService() onFailure() | | do any further operations
- * | | | again, it needs to
- * | | | initialize() connection
- * discoverServices() | | to framework again
- * | | |
- * Maintain a list to track | |
- * discovered services | |
- * | | |
- * |---------> |-> onChannelDisconnected()
- * | | |
- * | onServiceFound() |
- * | | |
- * | add service to list |
- * | | |
- * |<---------- |
- * | |
- * |---------> |
- * | | |
- * | onServiceLost() |
- * | | |
- * | remove service from list |
- * | | |
- * |<---------- |
- * | |
- * | |
- * | Connect to a service |
- * | from list ? |
- * | |
- * resolveService() |
- * | |
- * onServiceResolved() |
- * | |
- * Establish connection to service |
- * with the host and port information |
- * | |
- * | ___________|
- * deinitialize()
- * when done with all operations
- * or before quit
+ * |
+ * | onServiceRegistered()
+ * Register any local services /
+ * to be advertised with \
+ * registerService() onRegistrationFailed()
+ * |
+ * |
+ * discoverServices()
+ * |
+ * Maintain a list to track
+ * discovered services
+ * |
+ * |--------->
+ * | |
+ * | onServiceFound()
+ * | |
+ * | add service to list
+ * | |
+ * |<----------
+ * |
+ * |--------->
+ * | |
+ * | onServiceLost()
+ * | |
+ * | remove service from list
+ * | |
+ * |<----------
+ * |
+ * |
+ * | Connect to a service
+ * | from list ?
+ * |
+ * resolveService()
+ * |
+ * onServiceResolved()
+ * |
+ * Establish connection to service
+ * with the host and port information
*
* </pre>
* An application that needs to advertise itself over a network for other applications to
* discover it can do so with a call to {@link #registerService}. If Example is a http based
* application that can provide HTML data to peer services, it can register a name "Example"
* with service type "_http._tcp". A successful registration is notified with a callback to
- * {@link DnsSdRegisterListener#onServiceRegistered} and a failure to register is notified
- * over {@link DnsSdRegisterListener#onFailure}
+ * {@link RegistrationListener#onServiceRegistered} and a failure to register is notified
+ * over {@link RegistrationListener#onRegistrationFailed}
*
* <p> A peer application looking for http services can initiate a discovery for "_http._tcp"
* with a call to {@link #discoverServices}. A service found is notified with a callback
- * to {@link DnsSdDiscoveryListener#onServiceFound} and a service lost is notified on
- * {@link DnsSdDiscoveryListener#onServiceLost}.
+ * to {@link DiscoveryListener#onServiceFound} and a service lost is notified on
+ * {@link DiscoveryListener#onServiceLost}.
*
* <p> Once the peer application discovers the "Example" http srevice, and needs to receive data
* from the "Example" application, it can initiate a resolve with {@link #resolveService} to
* resolve the host and port details for the purpose of establishing a connection. A successful
- * resolve is notified on {@link DnsSdResolveListener#onServiceResolved} and a failure is notified
- * on {@link DnsSdResolveListener#onFailure}.
+ * resolve is notified on {@link ResolveListener#onServiceResolved} and a failure is notified
+ * on {@link ResolveListener#onResolveFailed}.
*
* Applications can reserve for a service type at
* http://www.iana.org/form/ports-service. Existing services can be found at
@@ -129,9 +118,9 @@ import com.android.internal.util.Protocol;
* Get an instance of this class by calling {@link android.content.Context#getSystemService(String)
* Context.getSystemService(Context.NSD_SERVICE)}.
*
- * {@see DnsSdServiceInfo}
+ * {@see NsdServiceInfo}
*/
-public class NsdManager {
+public final class NsdManager {
private static final String TAG = "NsdManager";
INsdManager mService;
@@ -204,13 +193,6 @@ public class NsdManager {
public static final int UNREGISTER_SERVICE_SUCCEEDED = BASE + 14;
/** @hide */
- public static final int UPDATE_SERVICE = BASE + 15;
- /** @hide */
- public static final int UPDATE_SERVICE_FAILED = BASE + 16;
- /** @hide */
- public static final int UPDATE_SERVICE_SUCCEEDED = BASE + 17;
-
- /** @hide */
public static final int RESOLVE_SERVICE = BASE + 18;
/** @hide */
public static final int RESOLVE_SERVICE_FAILED = BASE + 19;
@@ -218,17 +200,27 @@ public class NsdManager {
public static final int RESOLVE_SERVICE_SUCCEEDED = BASE + 20;
/** @hide */
- public static final int STOP_RESOLVE = BASE + 21;
- /** @hide */
- public static final int STOP_RESOLVE_FAILED = BASE + 22;
- /** @hide */
- public static final int STOP_RESOLVE_SUCCEEDED = BASE + 23;
-
- /** @hide */
public static final int ENABLE = BASE + 24;
/** @hide */
public static final int DISABLE = BASE + 25;
+ /** @hide */
+ public static final int NATIVE_DAEMON_EVENT = BASE + 26;
+
+ /** Dns based service discovery protocol */
+ public static final int PROTOCOL_DNS_SD = 0x0001;
+
+ private Context mContext;
+
+ private static final int INVALID_LISTENER_KEY = 0;
+ private int mListenerKey = 1;
+ private final SparseArray mListenerMap = new SparseArray();
+ private final SparseArray<NsdServiceInfo> mServiceMap = new SparseArray<NsdServiceInfo>();
+ private final Object mMapLock = new Object();
+
+ private final AsyncChannel mAsyncChannel = new AsyncChannel();
+ private ServiceHandler mHandler;
+ private final CountDownLatch mConnected = new CountDownLatch(1);
/**
* Create a new Nsd instance. Applications use
@@ -238,271 +230,213 @@ public class NsdManager {
* @hide - hide this because it takes in a parameter of type INsdManager, which
* is a system private class.
*/
- public NsdManager(INsdManager service) {
+ public NsdManager(Context context, INsdManager service) {
mService = service;
+ mContext = context;
+ init();
}
/**
- * Passed with onFailure() calls.
+ * Failures are passed with {@link RegistrationListener#onRegistrationFailed},
+ * {@link RegistrationListener#onUnregistrationFailed},
+ * {@link DiscoveryListener#onStartDiscoveryFailed},
+ * {@link DiscoveryListener#onStopDiscoveryFailed} or {@link ResolveListener#onResolveFailed}.
+ *
* Indicates that the operation failed due to an internal error.
*/
- public static final int ERROR = 0;
+ public static final int FAILURE_INTERNAL_ERROR = 0;
/**
- * Passed with onFailure() calls.
- * Indicates that the operation failed because service discovery
- * is unsupported on the device.
- */
- public static final int UNSUPPORTED = 1;
-
- /**
- * Passed with onFailure() calls.
- * Indicates that the operation failed because the framework is
- * busy and unable to service the request.
- */
- public static final int BUSY = 2;
-
- /**
- * Passed with onFailure() calls.
* Indicates that the operation failed because it is already active.
*/
- public static final int ALREADY_ACTIVE = 3;
+ public static final int FAILURE_ALREADY_ACTIVE = 3;
/**
- * Passed with onFailure() calls.
- * Indicates that the operation failed because maximum limit on
- * service registrations has reached.
+ * Indicates that the operation failed because the maximum outstanding
+ * requests from the applications have reached.
*/
- public static final int MAX_REGS_REACHED = 4;
-
- /** Interface for callback invocation when framework channel is connected or lost */
- public interface ChannelListener {
- /**
- * The channel to the framework is connected.
- * Application can initiate calls into the framework using the channel instance passed.
- */
- 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 static final int FAILURE_MAX_LIMIT = 4;
- /** Generic interface for callback invocation for a success or failure */
- public interface ActionListener {
+ /** Interface for callback invocation for service discovery */
+ public interface DiscoveryListener {
- public void onFailure(int errorCode);
+ public void onStartDiscoveryFailed(String serviceType, int errorCode);
- public void onSuccess();
- }
+ public void onStopDiscoveryFailed(String serviceType, int errorCode);
- /** Interface for callback invocation for service discovery */
- public interface DnsSdDiscoveryListener {
+ public void onDiscoveryStarted(String serviceType);
- public void onFailure(int errorCode);
+ public void onDiscoveryStopped(String serviceType);
- public void onStarted(String serviceType);
+ public void onServiceFound(NsdServiceInfo serviceInfo);
- public void onServiceFound(DnsSdServiceInfo serviceInfo);
-
- public void onServiceLost(DnsSdServiceInfo serviceInfo);
+ public void onServiceLost(NsdServiceInfo serviceInfo);
}
/** Interface for callback invocation for service registration */
- public interface DnsSdRegisterListener {
-
- public void onFailure(int errorCode);
+ public interface RegistrationListener {
- public void onServiceRegistered(int registeredId, DnsSdServiceInfo serviceInfo);
- }
+ public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode);
- /** @hide */
- public interface DnsSdUpdateRegistrationListener {
+ public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode);
- public void onFailure(int errorCode);
+ public void onServiceRegistered(NsdServiceInfo serviceInfo);
- public void onServiceUpdated(int registeredId, DnsSdTxtRecord txtRecord);
+ public void onServiceUnregistered(NsdServiceInfo serviceInfo);
}
/** Interface for callback invocation for service resolution */
- public interface DnsSdResolveListener {
+ public interface ResolveListener {
- public void onFailure(int errorCode);
+ public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode);
- public void onServiceResolved(DnsSdServiceInfo serviceInfo);
+ public void onServiceResolved(NsdServiceInfo 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 class ServiceHandler extends Handler {
+ ServiceHandler(Looper looper) {
+ super(looper);
}
- private ChannelListener mChannelListener;
- private DnsSdDiscoveryListener mDnsSdDiscoveryListener;
- private ActionListener mDnsSdStopDiscoveryListener;
- private DnsSdRegisterListener mDnsSdRegisterListener;
- private ActionListener mDnsSdUnregisterListener;
- private DnsSdUpdateRegistrationListener mDnsSdUpdateListener;
- private DnsSdResolveListener mDnsSdResolveListener;
- private ActionListener mDnsSdStopResolveListener;
-
- private AsyncChannel mAsyncChannel;
- private 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 UNREGISTER_SERVICE_FAILED:
- if (mDnsSdUnregisterListener != null) {
- mDnsSdUnregisterListener.onFailure(message.arg1);
- }
- break;
- case UNREGISTER_SERVICE_SUCCEEDED:
- if (mDnsSdUnregisterListener != null) {
- mDnsSdUnregisterListener.onSuccess();
- }
- 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;
- case STOP_RESOLVE_FAILED:
- if (mDnsSdStopResolveListener!= null) {
- mDnsSdStopResolveListener.onFailure(message.arg1);
- }
- break;
- case STOP_RESOLVE_SUCCEEDED:
- if (mDnsSdStopResolveListener != null) {
- mDnsSdStopResolveListener.onSuccess();
- }
- break;
- default:
- Log.d(TAG, "Ignored " + message);
- break;
- }
+ @Override
+ public void handleMessage(Message message) {
+ Object listener = getListener(message.arg2);
+ boolean listenerRemove = true;
+ switch (message.what) {
+ case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+ mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
+ mConnected.countDown();
+ break;
+ case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
+ // Ignore
+ break;
+ case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
+ Log.e(TAG, "Channel lost");
+ break;
+ case DISCOVER_SERVICES_STARTED:
+ String s = ((NsdServiceInfo) message.obj).getServiceType();
+ ((DiscoveryListener) listener).onDiscoveryStarted(s);
+ // Keep listener until stop discovery
+ listenerRemove = false;
+ break;
+ case DISCOVER_SERVICES_FAILED:
+ ((DiscoveryListener) listener).onStartDiscoveryFailed(
+ getNsdService(message.arg2).getServiceType(), message.arg1);
+ break;
+ case SERVICE_FOUND:
+ ((DiscoveryListener) listener).onServiceFound((NsdServiceInfo) message.obj);
+ // Keep listener until stop discovery
+ listenerRemove = false;
+ break;
+ case SERVICE_LOST:
+ ((DiscoveryListener) listener).onServiceLost((NsdServiceInfo) message.obj);
+ // Keep listener until stop discovery
+ listenerRemove = false;
+ break;
+ case STOP_DISCOVERY_FAILED:
+ ((DiscoveryListener) listener).onStopDiscoveryFailed(
+ getNsdService(message.arg2).getServiceType(), message.arg1);
+ break;
+ case STOP_DISCOVERY_SUCCEEDED:
+ ((DiscoveryListener) listener).onDiscoveryStopped(
+ getNsdService(message.arg2).getServiceType());
+ break;
+ case REGISTER_SERVICE_FAILED:
+ ((RegistrationListener) listener).onRegistrationFailed(
+ getNsdService(message.arg2), message.arg1);
+ break;
+ case REGISTER_SERVICE_SUCCEEDED:
+ ((RegistrationListener) listener).onServiceRegistered(
+ (NsdServiceInfo) message.obj);
+ // Keep listener until unregister
+ listenerRemove = false;
+ break;
+ case UNREGISTER_SERVICE_FAILED:
+ ((RegistrationListener) listener).onUnregistrationFailed(
+ getNsdService(message.arg2), message.arg1);
+ break;
+ case UNREGISTER_SERVICE_SUCCEEDED:
+ ((RegistrationListener) listener).onServiceUnregistered(
+ getNsdService(message.arg2));
+ break;
+ case RESOLVE_SERVICE_FAILED:
+ ((ResolveListener) listener).onResolveFailed(
+ getNsdService(message.arg2), message.arg1);
+ break;
+ case RESOLVE_SERVICE_SUCCEEDED:
+ ((ResolveListener) listener).onServiceResolved((NsdServiceInfo) message.obj);
+ break;
+ default:
+ Log.d(TAG, "Ignored " + message);
+ break;
+ }
+ if (listenerRemove) {
+ removeListener(message.arg2);
}
}
- }
+ }
- private static void checkChannel(Channel c) {
- if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
+ private int putListener(Object listener, NsdServiceInfo s) {
+ if (listener == null) return INVALID_LISTENER_KEY;
+ int key;
+ synchronized (mMapLock) {
+ do {
+ key = mListenerKey++;
+ } while (key == INVALID_LISTENER_KEY);
+ mListenerMap.put(key, listener);
+ mServiceMap.put(key, s);
+ }
+ return key;
}
- /**
- * 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. Cannot be null.
- */
- 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");
+ private Object getListener(int key) {
+ if (key == INVALID_LISTENER_KEY) return null;
+ synchronized (mMapLock) {
+ return mListenerMap.get(key);
+ }
+ }
+
+ private NsdServiceInfo getNsdService(int key) {
+ synchronized (mMapLock) {
+ return mServiceMap.get(key);
+ }
+ }
+
+ private void removeListener(int key) {
+ if (key == INVALID_LISTENER_KEY) return;
+ synchronized (mMapLock) {
+ mListenerMap.remove(key);
+ mServiceMap.remove(key);
+ }
+ }
- Channel c = new Channel(srcLooper, listener);
- c.mAsyncChannel.connect(srcContext, c.mHandler, messenger);
+ private int getListenerKey(Object listener) {
+ synchronized (mMapLock) {
+ int valueIndex = mListenerMap.indexOfValue(listener);
+ if (valueIndex != -1) {
+ return mListenerMap.keyAt(valueIndex);
+ }
+ }
+ return INVALID_LISTENER_KEY;
}
+
/**
- * Disconnects application from service discovery framework. No further operations
- * will succeed until a {@link #initialize} is called again.
- *
- * @param c channel initialized with {@link #initialize}
+ * Initialize AsyncChannel
*/
- public void deinitialize(Channel c) {
- checkChannel(c);
- c.mAsyncChannel.disconnect();
+ private void init() {
+ final Messenger messenger = getMessenger();
+ if (messenger == null) throw new RuntimeException("Failed to initialize");
+ HandlerThread t = new HandlerThread("NsdManager");
+ t.start();
+ mHandler = new ServiceHandler(t.getLooper());
+ mAsyncChannel.connect(mContext, mHandler, messenger);
+ try {
+ mConnected.await();
+ } catch (InterruptedException e) {
+ Log.e(TAG, "interrupted wait at init");
+ }
}
/**
@@ -510,45 +444,51 @@ public class NsdManager {
*
* <p> The function call immediately returns after sending a request to register service
* to the framework. The application is notified of a success to initiate
- * discovery through the callback {@link DnsSdRegisterListener#onServiceRegistered} or a failure
- * through {@link DnsSdRegisterListener#onFailure}.
+ * discovery through the callback {@link RegistrationListener#onServiceRegistered} or a failure
+ * through {@link RegistrationListener#onRegistrationFailed}.
*
- * @param c is the channel created at {@link #initialize}
- * @param serviceType The service type being advertised.
- * @param port on which the service is listenering for incoming connections
- * @param listener for success or failure callback. Can be null.
+ * @param serviceInfo The service being registered
+ * @param protocolType The service discovery protocol
+ * @param listener The listener notifies of a successful registration and is used to
+ * unregister this service through a call on {@link #unregisterService}. Cannot be null.
*/
- public void registerService(Channel c, String serviceName, String serviceType, int port,
- DnsSdRegisterListener listener) {
- checkChannel(c);
- if (TextUtils.isEmpty(serviceName) || TextUtils.isEmpty(serviceType)) {
+ public void registerService(NsdServiceInfo serviceInfo, int protocolType,
+ RegistrationListener listener) {
+ if (TextUtils.isEmpty(serviceInfo.getServiceName()) ||
+ TextUtils.isEmpty(serviceInfo.getServiceType())) {
throw new IllegalArgumentException("Service name or type cannot be empty");
}
- if (port <= 0) {
+ if (serviceInfo.getPort() <= 0) {
throw new IllegalArgumentException("Invalid port number");
}
- DnsSdServiceInfo serviceInfo = new DnsSdServiceInfo(serviceName, serviceType, null);
- serviceInfo.setPort(port);
- c.mDnsSdRegisterListener = listener;
- c.mAsyncChannel.sendMessage(REGISTER_SERVICE, serviceInfo);
+ if (listener == null) {
+ throw new IllegalArgumentException("listener cannot be null");
+ }
+ if (protocolType != PROTOCOL_DNS_SD) {
+ throw new IllegalArgumentException("Unsupported protocol");
+ }
+ mAsyncChannel.sendMessage(REGISTER_SERVICE, 0, putListener(listener, serviceInfo),
+ serviceInfo);
}
/**
- * Unregister a service registered through {@link #registerService}
- * @param c is the channel created at {@link #initialize}
- * @param registeredId is obtained at {@link DnsSdRegisterListener#onServiceRegistered}
- * @param listener provides callbacks for success or failure. Can be null.
+ * Unregister a service registered through {@link #registerService}. A successful
+ * unregister is notified to the application with a call to
+ * {@link RegistrationListener#onServiceUnregistered}.
+ *
+ * @param listener This should be the listener object that was passed to
+ * {@link #registerService}. It identifies the service that should be unregistered
+ * and notifies of a successful unregistration.
*/
- public void unregisterService(Channel c, int registeredId, ActionListener listener) {
- checkChannel(c);
- c.mDnsSdUnregisterListener = listener;
- c.mAsyncChannel.sendMessage(UNREGISTER_SERVICE, registeredId);
- }
-
- /** @hide */
- public void updateService(Channel c, int registeredId, DnsSdTxtRecord txtRecord) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(UPDATE_SERVICE, registeredId, 0, txtRecord);
+ public void unregisterService(RegistrationListener listener) {
+ int id = getListenerKey(listener);
+ if (id == INVALID_LISTENER_KEY) {
+ throw new IllegalArgumentException("listener not registered");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener cannot be null");
+ }
+ mAsyncChannel.sendMessage(UNREGISTER_SERVICE, 0, id);
}
/**
@@ -558,51 +498,61 @@ public class NsdManager {
*
* <p> The function call immediately returns after sending a request to start service
* discovery to the framework. The application is notified of a success to initiate
- * discovery through the callback {@link DnsSdDiscoveryListener#onStarted} or a failure
- * through {@link DnsSdDiscoveryListener#onFailure}.
+ * discovery through the callback {@link DiscoveryListener#onDiscoveryStarted} or a failure
+ * through {@link DiscoveryListener#onStartDiscoveryFailed}.
*
* <p> Upon successful start, application is notified when a service is found with
- * {@link DnsSdDiscoveryListener#onServiceFound} or when a service is lost with
- * {@link DnsSdDiscoveryListener#onServiceLost}.
+ * {@link DiscoveryListener#onServiceFound} or when a service is lost with
+ * {@link DiscoveryListener#onServiceLost}.
*
* <p> Upon failure to start, service discovery is not active and application does
* not need to invoke {@link #stopServiceDiscovery}
*
- * @param c is the channel created at {@link #initialize}
* @param serviceType The service type being discovered. Examples include "_http._tcp" for
* http services or "_ipp._tcp" for printers
- * @param listener provides callbacks when service is found or lost. Cannot be null.
+ * @param protocolType The service discovery protocol
+ * @param listener The listener notifies of a successful discovery and is used
+ * to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}.
+ * Cannot be null.
*/
- public void discoverServices(Channel c, String serviceType, DnsSdDiscoveryListener listener) {
- checkChannel(c);
+ public void discoverServices(String serviceType, int protocolType, DiscoveryListener listener) {
if (listener == null) {
- throw new IllegalStateException("Discovery listener needs to be set first");
+ throw new IllegalArgumentException("listener cannot be null");
}
if (TextUtils.isEmpty(serviceType)) {
- throw new IllegalStateException("Service type cannot be empty");
+ throw new IllegalArgumentException("Service type cannot be empty");
}
- DnsSdServiceInfo s = new DnsSdServiceInfo();
+
+ if (protocolType != PROTOCOL_DNS_SD) {
+ throw new IllegalArgumentException("Unsupported protocol");
+ }
+
+ NsdServiceInfo s = new NsdServiceInfo();
s.setServiceType(serviceType);
- c.mDnsSdDiscoveryListener = listener;
- c.mAsyncChannel.sendMessage(DISCOVER_SERVICES, s);
+ mAsyncChannel.sendMessage(DISCOVER_SERVICES, 0, putListener(listener, s), s);
}
/**
* Stop service discovery initiated with {@link #discoverServices}. An active service
- * discovery is notified to the application with {@link DnsSdDiscoveryListener#onStarted}
- * and it stays active until the application invokes a stop service discovery.
+ * discovery is notified to the application with {@link DiscoveryListener#onDiscoveryStarted}
+ * and it stays active until the application invokes a stop service discovery. A successful
+ * stop is notified to with a call to {@link DiscoveryListener#onDiscoveryStopped}.
*
- * <p> Upon failure to start service discovery notified through
- * {@link DnsSdDiscoveryListener#onFailure} service discovery is not active and
- * application does not need to stop it.
+ * <p> Upon failure to stop service discovery, application is notified through
+ * {@link DiscoveryListener#onStopDiscoveryFailed}.
*
- * @param c is the channel created at {@link #initialize}
- * @param listener notifies success or failure. Can be null.
+ * @param listener This should be the listener object that was passed to {@link #discoverServices}.
+ * It identifies the discovery that should be stopped and notifies of a successful stop.
*/
- public void stopServiceDiscovery(Channel c, ActionListener listener) {
- checkChannel(c);
- c.mDnsSdStopDiscoveryListener = listener;
- c.mAsyncChannel.sendMessage(STOP_DISCOVERY);
+ public void stopServiceDiscovery(DiscoveryListener listener) {
+ int id = getListenerKey(listener);
+ if (id == INVALID_LISTENER_KEY) {
+ throw new IllegalArgumentException("service discovery not active on listener");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener cannot be null");
+ }
+ mAsyncChannel.sendMessage(STOP_DISCOVERY, 0, id);
}
/**
@@ -610,30 +560,19 @@ public class NsdManager {
* establishing a connection to fetch the IP and port details on which to setup
* the connection.
*
- * @param c is the channel created at {@link #initialize}
- * @param serviceName of the the service
- * @param serviceType of the service
+ * @param serviceInfo service to be resolved
* @param listener to receive callback upon success or failure. Cannot be null.
*/
- public void resolveService(Channel c, String serviceName, String serviceType,
- DnsSdResolveListener listener) {
- checkChannel(c);
- if (TextUtils.isEmpty(serviceName) || TextUtils.isEmpty(serviceType)) {
+ public void resolveService(NsdServiceInfo serviceInfo, ResolveListener listener) {
+ if (TextUtils.isEmpty(serviceInfo.getServiceName()) ||
+ TextUtils.isEmpty(serviceInfo.getServiceType())) {
throw new IllegalArgumentException("Service name or type cannot be empty");
}
- if (listener == null) throw new
- IllegalStateException("Resolve listener cannot be null");
- c.mDnsSdResolveListener = listener;
- DnsSdServiceInfo serviceInfo = new DnsSdServiceInfo(serviceName, serviceType, null);
- c.mAsyncChannel.sendMessage(RESOLVE_SERVICE, serviceInfo);
- }
-
- /** @hide */
- public void stopServiceResolve(Channel c) {
- checkChannel(c);
- if (c.mDnsSdResolveListener == null) throw new
- IllegalStateException("Resolve listener needs to be set first");
- c.mAsyncChannel.sendMessage(STOP_RESOLVE);
+ if (listener == null) {
+ throw new IllegalArgumentException("listener cannot be null");
+ }
+ mAsyncChannel.sendMessage(RESOLVE_SERVICE, 0, putListener(listener, serviceInfo),
+ serviceInfo);
}
/** Internal use only @hide */
diff --git a/core/java/android/net/nsd/DnsSdServiceInfo.java b/core/java/android/net/nsd/NsdServiceInfo.java
index 66abd3a..205a21d 100644
--- a/core/java/android/net/nsd/DnsSdServiceInfo.java
+++ b/core/java/android/net/nsd/NsdServiceInfo.java
@@ -25,7 +25,7 @@ import java.net.InetAddress;
* A class representing service information for network service discovery
* {@see NsdManager}
*/
-public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
+public final class NsdServiceInfo implements Parcelable {
private String mServiceName;
@@ -37,36 +37,32 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
private int mPort;
- public DnsSdServiceInfo() {
+ public NsdServiceInfo() {
}
/** @hide */
- public DnsSdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) {
+ public NsdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) {
mServiceName = sn;
mServiceType = rt;
mTxtRecord = tr;
}
/** Get the service name */
- @Override
public String getServiceName() {
return mServiceName;
}
/** Set the service name */
- @Override
public void setServiceName(String s) {
mServiceName = s;
}
/** Get the service type */
- @Override
public String getServiceType() {
return mServiceType;
}
/** Set the service type */
- @Override
public void setServiceType(String s) {
mServiceType = s;
}
@@ -132,10 +128,10 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
}
/** Implement the Parcelable interface */
- public static final Creator<DnsSdServiceInfo> CREATOR =
- new Creator<DnsSdServiceInfo>() {
- public DnsSdServiceInfo createFromParcel(Parcel in) {
- DnsSdServiceInfo info = new DnsSdServiceInfo();
+ public static final Creator<NsdServiceInfo> CREATOR =
+ new Creator<NsdServiceInfo>() {
+ public NsdServiceInfo createFromParcel(Parcel in) {
+ NsdServiceInfo info = new NsdServiceInfo();
info.mServiceName = in.readString();
info.mServiceType = in.readString();
info.mTxtRecord = in.readParcelable(null);
@@ -150,8 +146,8 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
return info;
}
- public DnsSdServiceInfo[] newArray(int size) {
- return new DnsSdServiceInfo[size];
+ public NsdServiceInfo[] newArray(int size) {
+ return new NsdServiceInfo[size];
}
};
}
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index 0586d9e..b7bc45f 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -140,6 +140,9 @@ public interface IBinder {
*/
int LIKE_TRANSACTION = ('_'<<24)|('L'<<16)|('I'<<8)|'K';
+ /** @hide */
+ int SYSPROPS_TRANSACTION = ('_'<<24)|('S'<<16)|('P'<<8)|'R';
+
/**
* Flag to {@link #transact}: this is a one-way call, meaning that the
* caller returns immediately, without waiting for a result from the
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index 43b5128..be24426 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -16,6 +16,8 @@
package android.os;
+import java.util.ArrayList;
+
/**
* Native implementation of the service manager. Most clients will only
@@ -151,14 +153,32 @@ class ServiceManagerProxy implements IServiceManager {
}
public String[] listServices() throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- data.writeInterfaceToken(IServiceManager.descriptor);
- mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
- String[] list = reply.readStringArray();
- reply.recycle();
- data.recycle();
- return list;
+ ArrayList<String> services = new ArrayList<String>();
+ int n = 0;
+ while (true) {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IServiceManager.descriptor);
+ data.writeInt(n);
+ n++;
+ try {
+ boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
+ if (!res) {
+ break;
+ }
+ } catch (RuntimeException e) {
+ // The result code that is returned by the C++ code can
+ // cause the call to throw an exception back instead of
+ // returning a nice result... so eat it here and go on.
+ break;
+ }
+ services.add(reply.readString());
+ reply.recycle();
+ data.recycle();
+ }
+ String[] array = new String[services.size()];
+ services.toArray(array);
+ return array;
}
public void setPermissionController(IPermissionController controller)
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 619bf8d..156600e 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -16,6 +16,10 @@
package android.os;
+import java.util.ArrayList;
+
+import android.util.Log;
+
/**
* Gives access to the system properties store. The system properties
@@ -28,12 +32,15 @@ public class SystemProperties
public static final int PROP_NAME_MAX = 31;
public static final int PROP_VALUE_MAX = 91;
+ private static final ArrayList<Runnable> sChangeCallbacks = new ArrayList<Runnable>();
+
private static native String native_get(String key);
private static native String native_get(String key, String def);
private static native int native_get_int(String key, int def);
private static native long native_get_long(String key, long def);
private static native boolean native_get_boolean(String key, boolean def);
private static native void native_set(String key, String def);
+ private static native void native_add_change_callback();
/**
* Get the value for the given key.
@@ -124,4 +131,26 @@ public class SystemProperties
}
native_set(key, val);
}
+
+ public static void addChangeCallback(Runnable callback) {
+ synchronized (sChangeCallbacks) {
+ if (sChangeCallbacks.size() == 0) {
+ native_add_change_callback();
+ }
+ sChangeCallbacks.add(callback);
+ }
+ }
+
+ static void callChangeCallbacks() {
+ synchronized (sChangeCallbacks) {
+ //Log.i("foo", "Calling " + sChangeCallbacks.size() + " change callbacks!");
+ if (sChangeCallbacks.size() == 0) {
+ return;
+ }
+ ArrayList<Runnable> callbacks = new ArrayList<Runnable>(sChangeCallbacks);
+ for (int i=0; i<callbacks.size(); i++) {
+ callbacks.get(i).run();
+ }
+ }
+ }
}
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index 7b6fd64..911183d 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -47,13 +47,21 @@ public final class Trace {
public static final String PROPERTY_TRACE_TAG_ENABLEFLAGS = "debug.atrace.tags.enableflags";
- private static final long sEnabledTags = nativeGetEnabledTags();
+ private static long sEnabledTags = nativeGetEnabledTags();
private static native long nativeGetEnabledTags();
private static native void nativeTraceCounter(long tag, String name, int value);
private static native void nativeTraceBegin(long tag, String name);
private static native void nativeTraceEnd(long tag);
+ static {
+ SystemProperties.addChangeCallback(new Runnable() {
+ @Override public void run() {
+ sEnabledTags = nativeGetEnabledTags();
+ }
+ });
+ }
+
private Trace() {
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 9fa67ac..aad6756 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -17250,7 +17250,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
/**
* Show where the margins, bounds and layout bounds are for each view.
*/
- final boolean mDebugLayout = SystemProperties.getBoolean(DEBUG_LAYOUT_PROPERTY, false);
+ boolean mDebugLayout = SystemProperties.getBoolean(DEBUG_LAYOUT_PROPERTY, false);
/**
* Point used to compute visible regions.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 5f295cb..6e6fab2 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -408,6 +408,7 @@ public final class ViewRootImpl implements ViewParent,
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mAttachInfo.mScreenOn = powerManager.isScreenOn();
+ loadSystemProperties();
}
/**
@@ -846,6 +847,16 @@ public final class ViewRootImpl implements ViewParent,
scheduleTraversals();
}
+ void invalidateWorld(View view) {
+ view.invalidate();
+ if (view instanceof ViewGroup) {
+ ViewGroup parent = (ViewGroup)view;
+ for (int i=0; i<parent.getChildCount(); i++) {
+ invalidateWorld(parent.getChildAt(i));
+ }
+ }
+ }
+
public void invalidateChild(View child, Rect dirty) {
invalidateChildInParent(null, dirty);
}
@@ -2730,6 +2741,7 @@ public final class ViewRootImpl implements ViewParent,
private final static int MSG_INVALIDATE_DISPLAY_LIST = 21;
private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 22;
private final static int MSG_DISPATCH_DONE_ANIMATING = 23;
+ private final static int MSG_INVALIDATE_WORLD = 24;
final class ViewRootHandler extends Handler {
@Override
@@ -2997,6 +3009,9 @@ public final class ViewRootImpl implements ViewParent,
case MSG_DISPATCH_DONE_ANIMATING: {
handleDispatchDoneAnimating();
} break;
+ case MSG_INVALIDATE_WORLD: {
+ invalidateWorld(mView);
+ } break;
}
}
}
@@ -4016,6 +4031,17 @@ public final class ViewRootImpl implements ViewParent,
mHandler.sendMessage(msg);
}
+ public void loadSystemProperties() {
+ boolean layout = SystemProperties.getBoolean(
+ View.DEBUG_LAYOUT_PROPERTY, false);
+ if (layout != mAttachInfo.mDebugLayout) {
+ mAttachInfo.mDebugLayout = layout;
+ if (!mHandler.hasMessages(MSG_INVALIDATE_WORLD)) {
+ mHandler.sendEmptyMessageDelayed(MSG_INVALIDATE_WORLD, 200);
+ }
+ }
+ }
+
private void destroyHardwareRenderer() {
AttachInfo attachInfo = mAttachInfo;
HardwareRenderer hardwareRenderer = attachInfo.mHardwareRenderer;
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index b5690e9..5d33cec 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -23,6 +23,7 @@ import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.opengl.ManagedEGLContext;
import android.os.IBinder;
+import android.os.SystemProperties;
import android.util.AndroidRuntimeException;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
@@ -112,6 +113,8 @@ public class WindowManagerImpl implements WindowManager {
private WindowManager.LayoutParams[] mParams;
private boolean mNeedsEglTerminate;
+ private Runnable mSystemPropertyUpdater = null;
+
private final static Object sLock = new Object();
private final static WindowManagerImpl sWindowManager = new WindowManagerImpl();
private final static HashMap<CompatibilityInfo, WindowManager> sCompatWindowManagers
@@ -237,6 +240,22 @@ public class WindowManagerImpl implements WindowManager {
View panelParentView = null;
synchronized (this) {
+ // Start watching for system property changes.
+ if (mSystemPropertyUpdater == null) {
+ mSystemPropertyUpdater = new Runnable() {
+ @Override public void run() {
+ synchronized (this) {
+ synchronized (this) {
+ for (ViewRootImpl root : mRoots) {
+ root.loadSystemProperties();
+ }
+ }
+ }
+ }
+ };
+ SystemProperties.addChangeCallback(mSystemPropertyUpdater);
+ }
+
// Here's an odd/questionable case: if someone tries to add a
// view multiple times, then we simply bump up a nesting count
// and they need to remove the view the corresponding number of
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 6f33b1e..3aafba5 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -25,6 +25,7 @@ import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
+import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.Parcel;
@@ -57,6 +58,7 @@ import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
@@ -648,6 +650,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private int mGlowPaddingLeft;
private int mGlowPaddingRight;
+ /**
+ * Used for interacting with list items from an accessibility service.
+ */
+ private ListItemAccessibilityDelegate mAccessibilityDelegate;
+
private int mLastAccessibilityScrollEventFromIndex;
private int mLastAccessibilityScrollEventToIndex;
@@ -2121,9 +2128,77 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
child.setLayoutParams(lp);
}
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ if (mAccessibilityDelegate == null) {
+ mAccessibilityDelegate = new ListItemAccessibilityDelegate();
+ }
+ child.setAccessibilityDelegate(mAccessibilityDelegate);
+ }
+
return child;
}
+ class ListItemAccessibilityDelegate extends AccessibilityDelegate {
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+
+ final int position = getPositionForView(host);
+
+ if (position == INVALID_POSITION) {
+ return;
+ }
+
+ if (isClickable()) {
+ info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
+ info.setClickable(true);
+ }
+
+ if (isLongClickable()) {
+ info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
+ info.setLongClickable(true);
+ }
+
+ info.addAction(AccessibilityNodeInfo.ACTION_SELECT);
+
+ if (position == getSelectedItemPosition()) {
+ info.setSelected(true);
+ }
+ }
+
+ @Override
+ public boolean performAccessibilityAction(View host, int action, Bundle arguments) {
+ final int position = getPositionForView(host);
+
+ if (position == INVALID_POSITION) {
+ return false;
+ }
+
+ final long id = getItemIdAtPosition(position);
+
+ switch (action) {
+ case AccessibilityNodeInfo.ACTION_SELECT:
+ setSelection(position);
+ return true;
+ case AccessibilityNodeInfo.ACTION_CLICK:
+ if (!super.performAccessibilityAction(host, action, arguments)) {
+ return performItemClick(host, position, id);
+ }
+ return true;
+ case AccessibilityNodeInfo.ACTION_LONG_CLICK:
+ if (!super.performAccessibilityAction(host, action, arguments)) {
+ return performLongPress(host, position, id);
+ }
+ return true;
+ case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
+ smoothScrollToPosition(position);
+ break;
+ }
+
+ return super.performAccessibilityAction(host, action, arguments);
+ }
+ }
+
void positionSelector(int position, View sel) {
if (position != INVALID_POSITION) {
mSelectorPosition = position;
@@ -5671,6 +5746,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
// Don't reclaim header or footer views, or views that should be ignored
if (lp != null && mRecycler.shouldRecycleViewType(lp.viewType)) {
views.add(child);
+ child.setAccessibilityDelegate(null);
if (listener != null) {
// Pretend they went through the scrap heap
listener.onMovedToScrapHeap(child);
@@ -6226,6 +6302,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mScrapViews[viewType].add(scrap);
}
+ scrap.setAccessibilityDelegate(null);
if (mRecyclerListener != null) {
mRecyclerListener.onMovedToScrapHeap(scrap);
}
@@ -6287,6 +6364,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
lp.scrappedFromPosition = mFirstActivePosition + i;
scrapViews.add(victim);
+ victim.setAccessibilityDelegate(null);
if (hasListener) {
mRecyclerListener.onMovedToScrapHeap(victim);
}
diff --git a/core/java/com/android/internal/util/FileRotator.java b/core/java/com/android/internal/util/FileRotator.java
index 6cfb97d..26235f1 100644
--- a/core/java/com/android/internal/util/FileRotator.java
+++ b/core/java/com/android/internal/util/FileRotator.java
@@ -19,8 +19,6 @@ package com.android.internal.util;
import android.os.FileUtils;
import android.util.Slog;
-import com.android.internal.util.FileRotator.Rewriter;
-
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
@@ -29,8 +27,11 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
import libcore.io.IoUtils;
+import libcore.io.Streams;
/**
* Utility that rotates files over time, similar to {@code logrotate}. There is
@@ -137,10 +138,38 @@ public class FileRotator {
public void deleteAll() {
final FileInfo info = new FileInfo(mPrefix);
for (String name : mBasePath.list()) {
- if (!info.parse(name)) continue;
+ if (info.parse(name)) {
+ // delete each file that matches parser
+ new File(mBasePath, name).delete();
+ }
+ }
+ }
+
+ /**
+ * Dump all files managed by this rotator for debugging purposes.
+ */
+ public void dumpAll(OutputStream os) throws IOException {
+ final ZipOutputStream zos = new ZipOutputStream(os);
+ try {
+ final FileInfo info = new FileInfo(mPrefix);
+ for (String name : mBasePath.list()) {
+ if (info.parse(name)) {
+ final ZipEntry entry = new ZipEntry(name);
+ zos.putNextEntry(entry);
- // delete each file that matches parser
- new File(mBasePath, name).delete();
+ final File file = new File(mBasePath, name);
+ final FileInputStream is = new FileInputStream(file);
+ try {
+ Streams.copy(is, zos);
+ } finally {
+ IoUtils.closeQuietly(is);
+ }
+
+ zos.closeEntry();
+ }
+ }
+ } finally {
+ IoUtils.closeQuietly(zos);
}
}
@@ -159,22 +188,22 @@ public class FileRotator {
public void combineActive(final Reader reader, final Writer writer, long currentTimeMillis)
throws IOException {
rewriteActive(new Rewriter() {
- /** {@inheritDoc} */
+ @Override
public void reset() {
// ignored
}
- /** {@inheritDoc} */
+ @Override
public void read(InputStream in) throws IOException {
reader.read(in);
}
- /** {@inheritDoc} */
+ @Override
public boolean shouldWrite() {
return true;
}
- /** {@inheritDoc} */
+ @Override
public void write(OutputStream out) throws IOException {
writer.write(out);
}
@@ -224,11 +253,11 @@ public class FileRotator {
// write success, delete backup
backupFile.delete();
- } catch (IOException e) {
+ } catch (Throwable t) {
// write failed, delete file and restore backup
file.delete();
backupFile.renameTo(file);
- throw e;
+ throw rethrowAsIoException(t);
}
} else {
@@ -241,11 +270,11 @@ public class FileRotator {
// write success, delete empty backup
backupFile.delete();
- } catch (IOException e) {
+ } catch (Throwable t) {
// write failed, delete file and empty backup
file.delete();
backupFile.delete();
- throw e;
+ throw rethrowAsIoException(t);
}
}
}
@@ -353,6 +382,14 @@ public class FileRotator {
}
}
+ private static IOException rethrowAsIoException(Throwable t) throws IOException {
+ if (t instanceof IOException) {
+ throw (IOException) t;
+ } else {
+ throw new IOException(t.getMessage(), t);
+ }
+ }
+
/**
* Details for a rotated file, either parsed from an existing filename, or
* ready to be built into a new filename.
diff --git a/core/jni/android_os_SystemProperties.cpp b/core/jni/android_os_SystemProperties.cpp
index add616e..677396d1 100644
--- a/core/jni/android_os_SystemProperties.cpp
+++ b/core/jni/android_os_SystemProperties.cpp
@@ -15,7 +15,11 @@
** limitations under the License.
*/
+#define LOG_TAG "SysPropJNI"
+
#include "cutils/properties.h"
+#include "utils/misc.h"
+#include <utils/Log.h>
#include "jni.h"
#include "android_runtime/AndroidRuntime.h"
#include <nativehelper/JNIHelp.h>
@@ -188,6 +192,34 @@ static void SystemProperties_set(JNIEnv *env, jobject clazz,
}
}
+static JavaVM* sVM = NULL;
+static jclass sClazz = NULL;
+static jmethodID sCallChangeCallbacks;
+
+static void do_report_sysprop_change() {
+ //ALOGI("Java SystemProperties: VM=%p, Clazz=%p", sVM, sClazz);
+ if (sVM != NULL && sClazz != NULL) {
+ JNIEnv* env;
+ if (sVM->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0) {
+ //ALOGI("Java SystemProperties: calling %p", sCallChangeCallbacks);
+ env->CallStaticVoidMethod(sClazz, sCallChangeCallbacks);
+ }
+ }
+}
+
+static void SystemProperties_add_change_callback(JNIEnv *env, jobject clazz)
+{
+ // This is called with the Java lock held.
+ if (sVM == NULL) {
+ env->GetJavaVM(&sVM);
+ }
+ if (sClazz == NULL) {
+ sClazz = (jclass) env->NewGlobalRef(clazz);
+ sCallChangeCallbacks = env->GetStaticMethodID(sClazz, "callChangeCallbacks", "()V");
+ add_sysprop_change_callback(do_report_sysprop_change, -10000);
+ }
+}
+
static JNINativeMethod method_table[] = {
{ "native_get", "(Ljava/lang/String;)Ljava/lang/String;",
(void*) SystemProperties_getS },
@@ -201,6 +233,8 @@ static JNINativeMethod method_table[] = {
(void*) SystemProperties_get_boolean },
{ "native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
(void*) SystemProperties_set },
+ { "native_add_change_callback", "()V",
+ (void*) SystemProperties_add_change_callback },
};
int register_android_os_SystemProperties(JNIEnv *env)
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 0f99fb2..04dc49f 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -308,6 +308,12 @@ protected:
env->DeleteLocalRef(excep2);
}
+ // Need to always call through the native implementation of
+ // SYSPROPS_TRANSACTION.
+ if (code == SYSPROPS_TRANSACTION) {
+ BBinder::onTransact(code, data, reply, flags);
+ }
+
//aout << "onTransact to Java code; result=" << res << endl
// << "Transact from " << this << " to Java code returning "
// << reply << ": " << *reply << endl;
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index 61136e3..c5727ea 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -18,6 +18,10 @@
*/
-->
<resources>
+ <!-- The width that is used when creating thumbnails of applications. -->
+ <dimen name="thumbnail_width">200dp</dimen>
+ <!-- The height that is used when creating thumbnails of applications. -->
+ <dimen name="thumbnail_height">177dp</dimen>
<!-- The maximum number of action buttons that should be permitted within
an action bar/action mode. This will be used to determine how many
showAsAction="ifRoom" items can fit. "always" items can override this. -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index f812822..734151b 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -19,9 +19,9 @@
-->
<resources>
<!-- The width that is used when creating thumbnails of applications. -->
- <dimen name="thumbnail_width">120dp</dimen>
+ <dimen name="thumbnail_width">164dp</dimen>
<!-- The height that is used when creating thumbnails of applications. -->
- <dimen name="thumbnail_height">120dp</dimen>
+ <dimen name="thumbnail_height">145dp</dimen>
<!-- The standard size (both width and height) of an application icon that
will be displayed in the app launcher and elsewhere. -->
<dimen name="app_icon_size">48dip</dimen>
diff --git a/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java b/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
index 94d1cb6..95f0e67 100644
--- a/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
@@ -187,12 +187,12 @@ public class FileRotatorTest extends AndroidTestCase {
rotate.combineActive(reader, new Writer() {
public void write(OutputStream out) throws IOException {
new DataOutputStream(out).writeUTF("bar");
- throw new ProtocolException("yikes");
+ throw new NullPointerException("yikes");
}
}, currentTime);
fail("woah, somehow able to write exception");
- } catch (ProtocolException e) {
+ } catch (IOException e) {
// expected from above
}
diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java
index f49a24e..7210513 100644
--- a/graphics/java/android/renderscript/Mesh.java
+++ b/graphics/java/android/renderscript/Mesh.java
@@ -21,6 +21,7 @@ import java.util.Vector;
import android.util.Log;
/**
+ * @deprecated in API 16
* <p>This class is a container for geometric data displayed with
* Renderscript. Internally, a mesh is a collection of allocations that
* represent vertex data (positions, normals, texture
@@ -40,33 +41,40 @@ import android.util.Log;
public class Mesh extends BaseObj {
/**
+ * @deprecated in API 16
* Describes the way mesh vertex data is interpreted when rendering
*
**/
public enum Primitive {
/**
+ * @deprecated in API 16
* Vertex data will be rendered as a series of points
*/
POINT (0),
/**
+ * @deprecated in API 16
* Vertex pairs will be rendered as lines
*/
LINE (1),
/**
+ * @deprecated in API 16
* Vertex data will be rendered as a connected line strip
*/
LINE_STRIP (2),
/**
+ * @deprecated in API 16
* Vertices will be rendered as individual triangles
*/
TRIANGLE (3),
/**
+ * @deprecated in API 16
* Vertices will be rendered as a connected triangle strip
* defined by the first three vertices with each additional
* triangle defined by a new vertex
*/
TRIANGLE_STRIP (4),
/**
+ * @deprecated in API 16
* Vertices will be rendered as a sequence of triangles that all
* share first vertex as the origin
*/
@@ -87,6 +95,7 @@ public class Mesh extends BaseObj {
}
/**
+ * @deprecated in API 16
* @return number of allocations containing vertex data
*
**/
@@ -97,6 +106,7 @@ public class Mesh extends BaseObj {
return mVertexBuffers.length;
}
/**
+ * @deprecated in API 16
* @param slot index in the list of allocations to return
* @return vertex data allocation at the given index
*
@@ -106,6 +116,7 @@ public class Mesh extends BaseObj {
}
/**
+ * @deprecated in API 16
* @return number of primitives or index sets in the mesh
*
**/
@@ -117,6 +128,7 @@ public class Mesh extends BaseObj {
}
/**
+ * @deprecated in API 16
* @param slot locaton within the list of index set allocation
* @return allocation containing primtive index data or null if
* the index data is not specified explicitly
@@ -126,6 +138,7 @@ public class Mesh extends BaseObj {
return mIndexBuffers[slot];
}
/**
+ * @deprecated in API 16
* @param slot locaiton within the list of index set primitives
* @return index set primitive type
*
@@ -168,6 +181,7 @@ public class Mesh extends BaseObj {
}
/**
+ * @deprecated in API 16
* Mesh builder object. It starts empty and requires you to
* add the types necessary to create vertex and index
* allocations.
@@ -190,6 +204,7 @@ public class Mesh extends BaseObj {
Vector mIndexTypes;
/**
+ * @deprecated in API 16
* Creates builder object
* @param rs Context to which the mesh will belong.
* @param usage specifies how the mesh allocations are to be
@@ -205,6 +220,7 @@ public class Mesh extends BaseObj {
}
/**
+ * @deprecated in API 16
* @return internal index of the last vertex buffer type added to
* builder
**/
@@ -213,6 +229,7 @@ public class Mesh extends BaseObj {
}
/**
+ * @deprecated in API 16
* @return internal index of the last index set added to the
* builder
**/
@@ -221,6 +238,7 @@ public class Mesh extends BaseObj {
}
/**
+ * @deprecated in API 16
* Adds a vertex data type to the builder object
*
* @param t type of the vertex data allocation to be created
@@ -240,6 +258,7 @@ public class Mesh extends BaseObj {
}
/**
+ * @deprecated in API 16
* Adds a vertex data type to the builder object
*
* @param e element describing the vertex data layout
@@ -261,6 +280,7 @@ public class Mesh extends BaseObj {
}
/**
+ * @deprecated in API 16
* Adds an index set data type to the builder object
*
* @param t type of the index set data, could be null
@@ -279,6 +299,7 @@ public class Mesh extends BaseObj {
}
/**
+ * @deprecated in API 16
* Adds an index set primitive type to the builder object
*
* @param p primitive type
@@ -296,6 +317,7 @@ public class Mesh extends BaseObj {
}
/**
+ * @deprecated in API 16
* Adds an index set data type to the builder object
*
* @param e element describing the index set data layout
@@ -321,6 +343,7 @@ public class Mesh extends BaseObj {
}
/**
+ * @deprecated in API 16
* Create a Mesh object from the current state of the builder
*
**/
diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java
index fa6e2d4..69968ac 100644
--- a/graphics/java/android/renderscript/ProgramFragment.java
+++ b/graphics/java/android/renderscript/ProgramFragment.java
@@ -21,6 +21,7 @@ import android.util.Log;
/**
+ * @deprecated in API 16
* <p>The Renderscript fragment program, also known as fragment shader is responsible
* for manipulating pixel data in a user defined way. It's constructed from a GLSL
* shader string containing the program body, textures inputs, and a Type object
@@ -41,8 +42,12 @@ public class ProgramFragment extends Program {
super(id, rs);
}
+ /**
+ * @deprecated in API 16
+ */
public static class Builder extends BaseProgramBuilder {
/**
+ * @deprecated in API 16
* Create a builder object.
*
* @param rs Context to which the program will belong.
@@ -52,6 +57,7 @@ public class ProgramFragment extends Program {
}
/**
+ * @deprecated in API 16
* Creates ProgramFragment from the current state of the builder
*
* @return ProgramFragment
diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java
index e40751f..c44521b 100644
--- a/graphics/java/android/renderscript/ProgramRaster.java
+++ b/graphics/java/android/renderscript/ProgramRaster.java
@@ -21,14 +21,27 @@ import android.util.Log;
/**
+ * @deprecated in API 16
* Program raster is primarily used to specify whether point sprites are enabled and to control
* the culling mode. By default, back faces are culled.
**/
public class ProgramRaster extends BaseObj {
+ /**
+ * @deprecated in API 16
+ **/
public enum CullMode {
+ /**
+ * @deprecated in API 16
+ **/
BACK (0),
+ /**
+ * @deprecated in API 16
+ **/
FRONT (1),
+ /**
+ * @deprecated in API 16
+ **/
NONE (2);
int mID;
@@ -48,6 +61,7 @@ public class ProgramRaster extends BaseObj {
}
/**
+ * @deprecated in API 16
* Specifies whether vertices are rendered as screen aligned
* elements of a specified size
* @return whether point sprites are enabled
@@ -57,6 +71,7 @@ public class ProgramRaster extends BaseObj {
}
/**
+ * @deprecated in API 16
* Specifies how triangles are culled based on their orientation
* @return cull mode
*/
@@ -64,6 +79,9 @@ public class ProgramRaster extends BaseObj {
return mCullMode;
}
+ /**
+ * @deprecated in API 16
+ */
public static ProgramRaster CULL_BACK(RenderScript rs) {
if(rs.mProgramRaster_CULL_BACK == null) {
ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -73,6 +91,9 @@ public class ProgramRaster extends BaseObj {
return rs.mProgramRaster_CULL_BACK;
}
+ /**
+ * @deprecated in API 16
+ */
public static ProgramRaster CULL_FRONT(RenderScript rs) {
if(rs.mProgramRaster_CULL_FRONT == null) {
ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -82,6 +103,9 @@ public class ProgramRaster extends BaseObj {
return rs.mProgramRaster_CULL_FRONT;
}
+ /**
+ * @deprecated in API 16
+ */
public static ProgramRaster CULL_NONE(RenderScript rs) {
if(rs.mProgramRaster_CULL_NONE == null) {
ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -91,27 +115,42 @@ public class ProgramRaster extends BaseObj {
return rs.mProgramRaster_CULL_NONE;
}
+ /**
+ * @deprecated in API 16
+ */
public static class Builder {
RenderScript mRS;
boolean mPointSprite;
CullMode mCullMode;
+ /**
+ * @deprecated in API 16
+ */
public Builder(RenderScript rs) {
mRS = rs;
mPointSprite = false;
mCullMode = CullMode.BACK;
}
+ /**
+ * @deprecated in API 16
+ */
public Builder setPointSpriteEnabled(boolean enable) {
mPointSprite = enable;
return this;
}
+ /**
+ * @deprecated in API 16
+ */
public Builder setCullMode(CullMode m) {
mCullMode = m;
return this;
}
+ /**
+ * @deprecated in API 16
+ */
public ProgramRaster create() {
mRS.validate();
int id = mRS.nProgramRasterCreate(mPointSprite, mCullMode.mID);
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index 74d666b..2bd5124 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -43,6 +43,7 @@ import android.util.Log;
/**
+ * @deprecated in API 16
* ProgramVertex, also know as a vertex shader, describes a
* stage in the graphics pipeline responsible for manipulating
* geometric data in a user-defined way.
@@ -55,6 +56,7 @@ public class ProgramVertex extends Program {
}
/**
+ * @deprecated in API 16
* @return number of input attribute elements
*/
public int getInputCount() {
@@ -62,6 +64,7 @@ public class ProgramVertex extends Program {
}
/**
+ * @deprecated in API 16
* @param slot location of the input to return
* @return input attribute element
*/
@@ -73,6 +76,7 @@ public class ProgramVertex extends Program {
}
/**
+ * @deprecated in API 16
* Builder class for creating ProgramVertex objects.
* The builder starts empty and the user must minimally provide
* the GLSL shader code, and the varying inputs. Constant, or
@@ -82,6 +86,7 @@ public class ProgramVertex extends Program {
**/
public static class Builder extends BaseProgramBuilder {
/**
+ * @deprecated in API 16
* Create a builder object.
*
* @param rs Context to which the program will belong.
@@ -91,6 +96,7 @@ public class ProgramVertex extends Program {
}
/**
+ * @deprecated in API 16
* Add varying inputs to the program
*
* @param e element describing the layout of the varying input
@@ -110,6 +116,7 @@ public class ProgramVertex extends Program {
}
/**
+ * @deprecated in API 16
* Creates ProgramVertex from the current state of the builder
*
* @return ProgramVertex
diff --git a/graphics/java/android/renderscript/RSTextureView.java b/graphics/java/android/renderscript/RSTextureView.java
index 30b2f99..ed04000 100644
--- a/graphics/java/android/renderscript/RSTextureView.java
+++ b/graphics/java/android/renderscript/RSTextureView.java
@@ -29,6 +29,7 @@ import android.util.Log;
import android.view.TextureView;
/**
+ * @deprecated in API 16
* The Texture View for a graphics renderscript (RenderScriptGL)
* to draw on.
*
@@ -38,6 +39,7 @@ public class RSTextureView extends TextureView implements TextureView.SurfaceTex
private SurfaceTexture mSurfaceTexture;
/**
+ * @deprecated in API 16
* Standard View constructor. In order to render something, you
* must call {@link android.opengl.GLSurfaceView#setRenderer} to
* register a renderer.
@@ -49,6 +51,7 @@ public class RSTextureView extends TextureView implements TextureView.SurfaceTex
}
/**
+ * @deprecated in API 16
* Standard View constructor. In order to render something, you
* must call {@link android.opengl.GLSurfaceView#setRenderer} to
* register a renderer.
@@ -64,6 +67,9 @@ public class RSTextureView extends TextureView implements TextureView.SurfaceTex
//android.util.Log.e("rs", "getSurfaceTextureListerner " + getSurfaceTextureListener());
}
+ /**
+ * @deprecated in API 16
+ */
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
//Log.e(RenderScript.LOG_TAG, "onSurfaceTextureAvailable");
@@ -74,6 +80,9 @@ public class RSTextureView extends TextureView implements TextureView.SurfaceTex
}
}
+ /**
+ * @deprecated in API 16
+ */
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
//Log.e(RenderScript.LOG_TAG, "onSurfaceTextureSizeChanged");
@@ -84,6 +93,9 @@ public class RSTextureView extends TextureView implements TextureView.SurfaceTex
}
}
+ /**
+ * @deprecated in API 16
+ */
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
//Log.e(RenderScript.LOG_TAG, "onSurfaceTextureDestroyed");
@@ -96,6 +108,9 @@ public class RSTextureView extends TextureView implements TextureView.SurfaceTex
return true;
}
+ /**
+ * @deprecated in API 16
+ */
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
//Log.e(RenderScript.LOG_TAG, "onSurfaceTextureUpdated");
@@ -103,6 +118,7 @@ public class RSTextureView extends TextureView implements TextureView.SurfaceTex
}
/**
+ * @deprecated in API 16
* Inform the view that the activity is paused. The owner of this view must
* call this method when the activity is paused. Calling this method will
* pause the rendering thread.
@@ -115,6 +131,7 @@ public class RSTextureView extends TextureView implements TextureView.SurfaceTex
}
/**
+ * @deprecated in API 16
* Inform the view that the activity is resumed. The owner of this view must
* call this method when the activity is resumed. Calling this method will
* recreate the OpenGL display and resume the rendering
@@ -128,6 +145,7 @@ public class RSTextureView extends TextureView implements TextureView.SurfaceTex
}
/**
+ * @deprecated in API 16
* Create a new RenderScriptGL object and attach it to the
* TextureView if present.
*
@@ -146,6 +164,7 @@ public class RSTextureView extends TextureView implements TextureView.SurfaceTex
}
/**
+ * @deprecated in API 16
* Destroy the RenderScriptGL object associated with this
* TextureView.
*/
@@ -155,6 +174,7 @@ public class RSTextureView extends TextureView implements TextureView.SurfaceTex
}
/**
+ * @deprecated in API 16
* Set a new RenderScriptGL object. This also will attach the
* new object to the TextureView if present.
*
@@ -168,6 +188,7 @@ public class RSTextureView extends TextureView implements TextureView.SurfaceTex
}
/**
+ * @deprecated in API 16
* Returns the previously set RenderScriptGL object.
*
* @return RenderScriptGL
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index dbdbe3d..12c8102 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -29,6 +29,7 @@ import android.view.SurfaceHolder;
import android.view.SurfaceView;
/**
+ * @deprecated in API 16
* The Graphics derivitive of Renderscript. Extends the basic context to add a
* root script which is the display window for graphical output. When the
* system needs to update the display the currently bound root script will be
@@ -46,6 +47,7 @@ public class RenderScriptGL extends RenderScript {
int mHeight;
/**
+ * @deprecated in API 16
* Class which is used to describe a pixel format for a graphical buffer.
* This is used to describe the intended format of the display surface.
*
@@ -66,9 +68,15 @@ public class RenderScriptGL extends RenderScript {
int mSamplesPref = 1;
float mSamplesQ = 1.f;
+ /**
+ * @deprecated in API 16
+ */
public SurfaceConfig() {
}
+ /**
+ * @deprecated in API 16
+ */
public SurfaceConfig(SurfaceConfig sc) {
mDepthMin = sc.mDepthMin;
mDepthPref = sc.mDepthPref;
@@ -93,6 +101,7 @@ public class RenderScriptGL extends RenderScript {
}
/**
+ * @deprecated in API 16
* Set the per-component bit depth for color (red, green, blue). This
* configures the surface for an unsigned integer buffer type.
*
@@ -106,6 +115,7 @@ public class RenderScriptGL extends RenderScript {
}
/**
+ * @deprecated in API 16
* Set the bit depth for alpha. This configures the surface for
* an unsigned integer buffer type.
*
@@ -119,6 +129,7 @@ public class RenderScriptGL extends RenderScript {
}
/**
+ * @deprecated in API 16
* Set the bit depth for the depth buffer. This configures the
* surface for an unsigned integer buffer type. If a minimum of 0
* is specified then its possible no depth buffer will be
@@ -134,6 +145,7 @@ public class RenderScriptGL extends RenderScript {
}
/**
+ * @deprecated in API 16
* Configure the multisample rendering.
*
* @param minimum The required number of samples, must be at least 1.
@@ -157,6 +169,7 @@ public class RenderScriptGL extends RenderScript {
SurfaceConfig mSurfaceConfig;
/**
+ * @deprecated in API 16
* Construct a new RenderScriptGL context.
*
* @param ctx The context.
@@ -187,6 +200,7 @@ public class RenderScriptGL extends RenderScript {
}
/**
+ * @deprecated in API 16
* Bind an os surface
*
*
@@ -223,6 +237,7 @@ public class RenderScriptGL extends RenderScript {
}
/**
+ * @deprecated in API 16
* return the height of the last set surface.
*
* @return int
@@ -232,6 +247,7 @@ public class RenderScriptGL extends RenderScript {
}
/**
+ * @deprecated in API 16
* return the width of the last set surface.
*
* @return int
@@ -241,6 +257,7 @@ public class RenderScriptGL extends RenderScript {
}
/**
+ * @deprecated in API 16
* Temporarly halt calls to the root rendering script.
*
*/
@@ -250,6 +267,7 @@ public class RenderScriptGL extends RenderScript {
}
/**
+ * @deprecated in API 16
* Resume calls to the root rendering script.
*
*/
@@ -260,6 +278,7 @@ public class RenderScriptGL extends RenderScript {
/**
+ * @deprecated in API 16
* Set the script to handle calls to render the primary surface.
*
* @param s Graphics script to process rendering requests.
@@ -270,6 +289,7 @@ public class RenderScriptGL extends RenderScript {
}
/**
+ * @deprecated in API 16
* Set the default ProgramStore object seen as the parent state by the root
* rendering script.
*
@@ -281,6 +301,7 @@ public class RenderScriptGL extends RenderScript {
}
/**
+ * @deprecated in API 16
* Set the default ProgramFragment object seen as the parent state by the
* root rendering script.
*
@@ -292,6 +313,7 @@ public class RenderScriptGL extends RenderScript {
}
/**
+ * @deprecated in API 16
* Set the default ProgramRaster object seen as the parent state by the
* root rendering script.
*
@@ -303,6 +325,7 @@ public class RenderScriptGL extends RenderScript {
}
/**
+ * @deprecated in API 16
* Set the default ProgramVertex object seen as the parent state by the
* root rendering script.
*
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
index fcdd56c..ec2abe0 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
@@ -45,7 +45,7 @@
android:fadingEdge="horizontal"
android:scrollbars="none"
android:fadingEdgeLength="@dimen/status_bar_recents_scroll_fading_edge_length"
- android:layout_gravity="bottom|left"
+ android:layout_gravity="bottom|right"
android:orientation="horizontal"
android:clipToPadding="false"
android:clipChildren="false">
diff --git a/core/java/android/net/nsd/NetworkServiceInfo.java b/packages/SystemUI/res/values-sw600dp-land/values-land-sw600dp/dimens.xml
index 34d83d1..e440de1 100644
--- a/core/java/android/net/nsd/NetworkServiceInfo.java
+++ b/packages/SystemUI/res/values-sw600dp-land/values-land-sw600dp/dimens.xml
@@ -1,32 +1,21 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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
+ * 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);
-
-}
+*/
+-->
+<resources>
+ <!-- Recent Applications parameters -->
+ <dimen name="status_bar_recents_app_label_width">190dip</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values-sw600dp-port/dimens.xml b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
new file mode 100644
index 0000000..7dc91d1
--- /dev/null
+++ b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+*/
+-->
+<resources>
+ <!-- Recent Applications parameters -->
+ <dimen name="status_bar_recents_app_label_width">140dip</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 2ff62a5..2cb99ff 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -39,4 +39,7 @@
<!-- Extra space above the clock in the panel; on this device, zero -->
<dimen name="notification_panel_header_padding_top">0dp</dimen>
+ <!-- Size of application thumbnail -->
+ <dimen name="status_bar_recents_thumbnail_width">200dp</dimen>
+ <dimen name="status_bar_recents_thumbnail_height">177dp</dimen>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index 185ca5b..57f15a8 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -146,7 +146,7 @@ public class SearchPanelView extends FrameLayout implements
}
}
- public void show(boolean show, boolean animate) {
+ public void show(final boolean show, boolean animate) {
if (animate) {
if (mShowing != show) {
mShowing = show;
@@ -156,21 +156,24 @@ public class SearchPanelView extends FrameLayout implements
mShowing = show;
onAnimationEnd(null);
}
- setVisibility(show ? View.VISIBLE : View.GONE);
- if (show) {
- setFocusable(true);
- setFocusableInTouchMode(true);
- requestFocus();
- }
+ postDelayed(new Runnable() {
+ public void run() {
+ setVisibility(show ? View.VISIBLE : View.INVISIBLE);
+ if (show) {
+ setFocusable(true);
+ setFocusableInTouchMode(true);
+ requestFocus();
+ }
+ }
+ }, show ? 0 : 100);
}
public void hide(boolean animate) {
- if (!animate) {
- setVisibility(View.GONE);
- }
if (mBar != null) {
// This will indirectly cause show(false, ...) to get called
mBar.animateCollapse();
+ } else {
+ setVisibility(View.INVISIBLE);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index e865b9c..995ee43 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -91,6 +91,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
private int mThumbnailWidth;
private boolean mFitThumbnailToXY;
private int mRecentItemLayoutId;
+ private boolean mFirstScreenful = true;
public static interface OnRecentsPanelVisibilityChangedListener {
public void onRecentsPanelVisibilityChanged(boolean visible);
@@ -206,6 +207,22 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
}
}
+ public RecentsPanelView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public RecentsPanelView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mContext = context;
+ updateValuesFromResources();
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecentsPanelView,
+ defStyle, 0);
+
+ mRecentItemLayoutId = a.getResourceId(R.styleable.RecentsPanelView_recentItemLayout, 0);
+ a.recycle();
+ }
+
public int numItemsInOneScreenful() {
if (mRecentsContainer instanceof RecentsScrollView){
RecentsScrollView scrollView
@@ -297,6 +314,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
mRecentTasksDirty = true;
mWaitingToShow = false;
mReadyToShow = false;
+ mRecentsNoApps.setVisibility(View.INVISIBLE);
}
if (animate) {
if (mShowing != show) {
@@ -415,21 +433,6 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
super.setVisibility(visibility);
}
- public RecentsPanelView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public RecentsPanelView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- mContext = context;
- updateValuesFromResources();
-
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecentsPanelView,
- defStyle, 0);
-
- mRecentItemLayoutId = a.getResourceId(R.styleable.RecentsPanelView_recentItemLayout, 0);
- }
-
public void updateValuesFromResources() {
final Resources res = mContext.getResources();
mThumbnailWidth = Math.round(res.getDimension(R.dimen.status_bar_recents_thumbnail_width));
@@ -572,7 +575,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
showIfReady();
}
- // additional optimization when we have sofware system buttons - start loading the recent
+ // additional optimization when we have software system buttons - start loading the recent
// tasks on touch down
@Override
public boolean onTouch(View v, MotionEvent ev) {
@@ -631,7 +634,6 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
}
}
- boolean mFirstScreenful;
public void onTasksLoaded(ArrayList<TaskDescription> tasks) {
if (!mFirstScreenful && tasks.size() == 0) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index f53a282..f5f2e28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -467,6 +467,9 @@ public class PhoneStatusBar extends BaseStatusBar {
// .03, the item disappears entirely (as if alpha = 0) and that discontinuity looks
// a bit jarring
mRecentsPanel.setMinSwipeAlpha(0.03f);
+ if (mNavigationBarView != null) {
+ mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPanel);
+ }
}
@Override
@@ -482,7 +485,6 @@ public class PhoneStatusBar extends BaseStatusBar {
WindowManager.LayoutParams lp =
(android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp);
}
@@ -492,7 +494,6 @@ public class PhoneStatusBar extends BaseStatusBar {
WindowManager.LayoutParams lp =
(android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp);
}
@@ -573,8 +574,7 @@ public class PhoneStatusBar extends BaseStatusBar {
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
- | WindowManager.LayoutParams.FLAG_SLIPPERY,
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.OPAQUE);
// this will allow the navbar to run in an overlay on devices that support this
if (ActivityManager.isHighEndGfx(mDisplay)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index a394596..b0830ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -704,7 +704,6 @@ public class TabletStatusBar extends BaseStatusBar implements
WindowManager.LayoutParams lp =
(android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
}
@@ -714,7 +713,6 @@ public class TabletStatusBar extends BaseStatusBar implements
WindowManager.LayoutParams lp =
(android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
}
diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java
index f33bf8b..cc8e6a4 100644
--- a/services/java/com/android/server/NsdService.java
+++ b/services/java/com/android/server/NsdService.java
@@ -20,7 +20,7 @@ import android.content.Context;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.net.nsd.DnsSdServiceInfo;
+import android.net.nsd.NsdServiceInfo;
import android.net.nsd.DnsSdTxtRecord;
import android.net.nsd.INsdManager;
import android.net.nsd.NsdManager;
@@ -32,6 +32,7 @@ import android.os.Messenger;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Slog;
+import android.util.SparseArray;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -72,13 +73,16 @@ public class NsdService extends INsdManager.Stub {
*/
private HashMap<Messenger, ClientInfo> mClients = new HashMap<Messenger, ClientInfo>();
+ /* A map from unique id to client info */
+ private SparseArray<ClientInfo> mIdToClientInfoMap= new SparseArray<ClientInfo>();
+
private AsyncChannel mReplyChannel = new AsyncChannel();
private int INVALID_ID = 0;
private int mUniqueId = 1;
private static final int BASE = Protocol.BASE_NSD_MANAGER;
- private static final int CMD_TO_STRING_COUNT = NsdManager.STOP_RESOLVE - BASE + 1;
+ private static final int CMD_TO_STRING_COUNT = NsdManager.RESOLVE_SERVICE - BASE + 1;
private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
static {
@@ -87,7 +91,6 @@ public class NsdService extends INsdManager.Stub {
sCmdToString[NsdManager.REGISTER_SERVICE - BASE] = "REGISTER";
sCmdToString[NsdManager.UNREGISTER_SERVICE - BASE] = "UNREGISTER";
sCmdToString[NsdManager.RESOLVE_SERVICE - BASE] = "RESOLVE";
- sCmdToString[NsdManager.STOP_RESOLVE - BASE] = "STOP-RESOLVE";
}
private static String cmdToString(int cmd) {
@@ -101,9 +104,9 @@ public class NsdService extends INsdManager.Stub {
private class NsdStateMachine extends StateMachine {
- private DefaultState mDefaultState = new DefaultState();
- private DisabledState mDisabledState = new DisabledState();
- private EnabledState mEnabledState = new EnabledState();
+ private final DefaultState mDefaultState = new DefaultState();
+ private final DisabledState mDisabledState = new DisabledState();
+ private final EnabledState mEnabledState = new EnabledState();
@Override
protected String getMessageInfo(Message msg) {
@@ -151,29 +154,26 @@ public class NsdService extends INsdManager.Stub {
ac.connect(mContext, getHandler(), msg.replyTo);
break;
case NsdManager.DISCOVER_SERVICES:
- mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
- NsdManager.BUSY);
+ replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
break;
case NsdManager.STOP_DISCOVERY:
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
- NsdManager.ERROR);
+ replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
break;
case NsdManager.REGISTER_SERVICE:
- mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
- NsdManager.ERROR);
+ replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
break;
case NsdManager.UNREGISTER_SERVICE:
- mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
- NsdManager.ERROR);
+ replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
break;
case NsdManager.RESOLVE_SERVICE:
- mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
- NsdManager.ERROR);
- break;
- case NsdManager.STOP_RESOLVE:
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
- NsdManager.ERROR);
+ replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
break;
+ case NsdManager.NATIVE_DAEMON_EVENT:
default:
Slog.e(TAG, "Unhandled " + msg);
return NOT_HANDLED;
@@ -217,11 +217,30 @@ public class NsdService extends INsdManager.Stub {
}
}
+ private boolean requestLimitReached(ClientInfo clientInfo) {
+ if (clientInfo.mClientIds.size() >= ClientInfo.MAX_LIMIT) {
+ if (DBG) Slog.d(TAG, "Exceeded max outstanding requests " + clientInfo);
+ return true;
+ }
+ return false;
+ }
+
+ private void storeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
+ clientInfo.mClientIds.put(clientId, globalId);
+ mIdToClientInfoMap.put(globalId, clientInfo);
+ }
+
+ private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
+ clientInfo.mClientIds.remove(clientId);
+ mIdToClientInfoMap.remove(globalId);
+ }
+
@Override
public boolean processMessage(Message msg) {
ClientInfo clientInfo;
- DnsSdServiceInfo servInfo;
+ NsdServiceInfo servInfo;
boolean result = HANDLED;
+ int id;
switch (msg.what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
//First client
@@ -244,111 +263,112 @@ public class NsdService extends INsdManager.Stub {
break;
case NsdManager.DISCOVER_SERVICES:
if (DBG) Slog.d(TAG, "Discover services");
- servInfo = (DnsSdServiceInfo) msg.obj;
+ servInfo = (NsdServiceInfo) msg.obj;
clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mDiscoveryId != INVALID_ID) {
- //discovery already in progress
- if (DBG) Slog.d(TAG, "discovery in progress");
- mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
- NsdManager.ALREADY_ACTIVE);
+
+ if (requestLimitReached(clientInfo)) {
+ replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+ NsdManager.FAILURE_MAX_LIMIT);
break;
}
- clientInfo.mDiscoveryId = getUniqueId();
- if (discoverServices(clientInfo.mDiscoveryId, servInfo.getServiceType())) {
- mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED);
+
+ id = getUniqueId();
+ if (discoverServices(id, servInfo.getServiceType())) {
+ if (DBG) {
+ Slog.d(TAG, "Discover " + msg.arg2 + " " + id +
+ servInfo.getServiceType());
+ }
+ storeRequestMap(msg.arg2, id, clientInfo);
+ replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED, servInfo);
} else {
- mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
- NsdManager.ERROR);
- clientInfo.mDiscoveryId = INVALID_ID;
+ stopServiceDiscovery(id);
+ replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
}
break;
case NsdManager.STOP_DISCOVERY:
if (DBG) Slog.d(TAG, "Stop service discovery");
clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mDiscoveryId == INVALID_ID) {
- //already stopped
- if (DBG) Slog.d(TAG, "discovery already stopped");
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
- NsdManager.ALREADY_ACTIVE);
+
+ try {
+ id = clientInfo.mClientIds.get(msg.arg2).intValue();
+ } catch (NullPointerException e) {
+ replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
break;
}
- if (stopServiceDiscovery(clientInfo.mDiscoveryId)) {
- clientInfo.mDiscoveryId = INVALID_ID;
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
+ removeRequestMap(msg.arg2, id, clientInfo);
+ if (stopServiceDiscovery(id)) {
+ replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
} else {
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
- NsdManager.ERROR);
+ replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
}
break;
case NsdManager.REGISTER_SERVICE:
if (DBG) Slog.d(TAG, "Register service");
clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mRegisteredIds.size() >= ClientInfo.MAX_REG) {
- if (DBG) Slog.d(TAG, "register service exceeds limit");
- mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
- NsdManager.MAX_REGS_REACHED);
+ if (requestLimitReached(clientInfo)) {
+ replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+ NsdManager.FAILURE_MAX_LIMIT);
+ break;
}
- int id = getUniqueId();
- if (registerService(id, (DnsSdServiceInfo) msg.obj)) {
- clientInfo.mRegisteredIds.add(id);
+ id = getUniqueId();
+ if (registerService(id, (NsdServiceInfo) msg.obj)) {
+ if (DBG) Slog.d(TAG, "Register " + msg.arg2 + " " + id);
+ storeRequestMap(msg.arg2, id, clientInfo);
+ // Return success after mDns reports success
} else {
- mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
- NsdManager.ERROR);
+ unregisterService(id);
+ replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
}
break;
case NsdManager.UNREGISTER_SERVICE:
if (DBG) Slog.d(TAG, "unregister service");
clientInfo = mClients.get(msg.replyTo);
- int regId = msg.arg1;
- if (clientInfo.mRegisteredIds.remove(new Integer(regId)) &&
- unregisterService(regId)) {
- mReplyChannel.replyToMessage(msg,
- NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
+ try {
+ id = clientInfo.mClientIds.get(msg.arg2).intValue();
+ } catch (NullPointerException e) {
+ replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
+ break;
+ }
+ removeRequestMap(msg.arg2, id, clientInfo);
+ if (unregisterService(id)) {
+ replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
} else {
- mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
- NsdManager.ERROR);
+ replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
}
break;
- case NsdManager.UPDATE_SERVICE:
- if (DBG) Slog.d(TAG, "Update service");
- //TODO: implement
- mReplyChannel.replyToMessage(msg, NsdManager.UPDATE_SERVICE_FAILED);
- break;
case NsdManager.RESOLVE_SERVICE:
if (DBG) Slog.d(TAG, "Resolve service");
- servInfo = (DnsSdServiceInfo) msg.obj;
+ servInfo = (NsdServiceInfo) msg.obj;
clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mResolveId != INVALID_ID) {
- //first cancel existing resolve
- stopResolveService(clientInfo.mResolveId);
- }
- clientInfo.mResolveId = getUniqueId();
- if (!resolveService(clientInfo.mResolveId, servInfo)) {
- mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
- NsdManager.ERROR);
- clientInfo.mResolveId = INVALID_ID;
- }
- break;
- case NsdManager.STOP_RESOLVE:
- if (DBG) Slog.d(TAG, "Stop resolve");
- clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mResolveId == INVALID_ID) {
- //already stopped
- if (DBG) Slog.d(TAG, "resolve already stopped");
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
- NsdManager.ALREADY_ACTIVE);
+
+ if (clientInfo.mResolvedService != null) {
+ replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+ NsdManager.FAILURE_ALREADY_ACTIVE);
break;
}
- if (stopResolveService(clientInfo.mResolveId)) {
- clientInfo.mResolveId = INVALID_ID;
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_SUCCEEDED);
+
+ id = getUniqueId();
+ if (resolveService(id, servInfo)) {
+ clientInfo.mResolvedService = new NsdServiceInfo();
+ storeRequestMap(msg.arg2, id, clientInfo);
} else {
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
- NsdManager.ERROR);
+ replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
}
break;
+ case NsdManager.NATIVE_DAEMON_EVENT:
+ NativeEvent event = (NativeEvent) msg.obj;
+ handleNativeEvent(event.code, event.raw,
+ NativeDaemonEvent.unescapeArgs(event.raw));
+ break;
default:
result = NOT_HANDLED;
break;
@@ -439,121 +459,144 @@ public class NsdService extends INsdManager.Stub {
public static final int SERVICE_GET_ADDR_SUCCESS = 612;
}
+ private class NativeEvent {
+ int code;
+ String raw;
+
+ NativeEvent(int code, String raw) {
+ this.code = code;
+ this.raw = raw;
+ }
+ }
+
class NativeCallbackReceiver implements INativeDaemonConnectorCallbacks {
public void onDaemonConnected() {
mNativeDaemonConnected.countDown();
}
public boolean onEvent(int code, String raw, String[] cooked) {
- ClientInfo clientInfo;
- DnsSdServiceInfo servInfo;
- int id = Integer.parseInt(cooked[1]);
- switch (code) {
- case NativeResponseCode.SERVICE_FOUND:
- /* NNN uniqueId serviceName regType domain */
- if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw);
- clientInfo = getClientByDiscovery(id);
- if (clientInfo == null) break;
-
- servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null);
- clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, servInfo);
- break;
- case NativeResponseCode.SERVICE_LOST:
- /* NNN uniqueId serviceName regType domain */
- if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw);
- clientInfo = getClientByDiscovery(id);
- if (clientInfo == null) break;
-
- servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null);
- clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, servInfo);
- break;
- case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
- /* NNN uniqueId errorCode */
- if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw);
- clientInfo = getClientByDiscovery(id);
- if (clientInfo == null) break;
-
- clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED,
- NsdManager.ERROR);
- break;
- case NativeResponseCode.SERVICE_REGISTERED:
- /* NNN regId serviceName regType */
- if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw);
- clientInfo = getClientByRegistration(id);
- if (clientInfo == null) break;
-
- servInfo = new DnsSdServiceInfo(cooked[2], null, null);
- clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED,
- id, 0, servInfo);
- break;
- case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
- /* NNN regId errorCode */
- if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw);
- clientInfo = getClientByRegistration(id);
- if (clientInfo == null) break;
-
- clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED,
- NsdManager.ERROR);
- 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 */
- if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw);
- clientInfo = getClientByResolve(id);
- if (clientInfo == null) break;
-
- int index = cooked[2].indexOf(".");
- if (index == -1) {
- Slog.e(TAG, "Invalid service found " + raw);
- break;
- }
- String name = cooked[2].substring(0, index);
- String rest = cooked[2].substring(index);
- String type = rest.replace(".local.", "");
+ // TODO: NDC translates a message to a callback, we could enhance NDC to
+ // directly interact with a state machine through messages
+ NativeEvent event = new NativeEvent(code, raw);
+ mNsdStateMachine.sendMessage(NsdManager.NATIVE_DAEMON_EVENT, event);
+ return true;
+ }
+ }
- clientInfo.mResolvedService = new DnsSdServiceInfo(name, type, null);
- clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4]));
+ private void handleNativeEvent(int code, String raw, String[] cooked) {
+ NsdServiceInfo servInfo;
+ int id = Integer.parseInt(cooked[1]);
+ ClientInfo clientInfo = mIdToClientInfoMap.get(id);
+ if (clientInfo == null) {
+ Slog.e(TAG, "Unique id with no client mapping: " + id);
+ return;
+ }
- stopResolveService(id);
- getAddrInfo(id, cooked[3]);
+ /* This goes in response as msg.arg2 */
+ int clientId = -1;
+ int keyId = clientInfo.mClientIds.indexOfValue(id);
+ if (keyId != -1) {
+ clientId = clientInfo.mClientIds.keyAt(keyId);
+ }
+ switch (code) {
+ case NativeResponseCode.SERVICE_FOUND:
+ /* NNN uniqueId serviceName regType domain */
+ if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw);
+ servInfo = new NsdServiceInfo(cooked[2], cooked[3], null);
+ clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, 0,
+ clientId, servInfo);
+ break;
+ case NativeResponseCode.SERVICE_LOST:
+ /* NNN uniqueId serviceName regType domain */
+ if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw);
+ servInfo = new NsdServiceInfo(cooked[2], cooked[3], null);
+ clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, 0,
+ clientId, servInfo);
+ break;
+ case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
+ /* NNN uniqueId errorCode */
+ if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw);
+ clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+ break;
+ case NativeResponseCode.SERVICE_REGISTERED:
+ /* NNN regId serviceName regType */
+ if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw);
+ servInfo = new NsdServiceInfo(cooked[2], null, null);
+ clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED,
+ id, clientId, servInfo);
+ break;
+ case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
+ /* NNN regId errorCode */
+ if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw);
+ clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+ 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 */
+ if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw);
+ int index = cooked[2].indexOf(".");
+ if (index == -1) {
+ Slog.e(TAG, "Invalid service found " + raw);
break;
- case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
- case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
- /* NNN resolveId errorCode */
- if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
- clientInfo = getClientByResolve(id);
- if (clientInfo == null) break;
+ }
+ String name = cooked[2].substring(0, index);
+ String rest = cooked[2].substring(index);
+ String type = rest.replace(".local.", "");
+
+ clientInfo.mResolvedService.setServiceName(name);
+ clientInfo.mResolvedService.setServiceType(type);
+ clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4]));
+ stopResolveService(id);
+ if (!getAddrInfo(id, cooked[3])) {
clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
- NsdManager.ERROR);
- break;
- case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
- /* NNN resolveId hostname ttl addr */
- if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw);
- clientInfo = getClientByResolve(id);
- if (clientInfo == null || clientInfo.mResolvedService == null) break;
-
- try {
- clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4]));
- clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED,
- clientInfo.mResolvedService);
- clientInfo.mResolvedService = null;
- clientInfo.mResolveId = INVALID_ID;
- } catch (java.net.UnknownHostException e) {
- clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
- NsdManager.ERROR);
- }
- stopGetAddrInfo(id);
- break;
- default:
- break;
- }
- return false;
+ NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+ mIdToClientInfoMap.remove(id);
+ clientInfo.mResolvedService = null;
+ }
+ break;
+ case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
+ /* NNN resolveId errorCode */
+ if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
+ stopResolveService(id);
+ mIdToClientInfoMap.remove(id);
+ clientInfo.mResolvedService = null;
+ clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+ break;
+ case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
+ /* NNN resolveId errorCode */
+ stopGetAddrInfo(id);
+ mIdToClientInfoMap.remove(id);
+ clientInfo.mResolvedService = null;
+ if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
+ clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+ break;
+ case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
+ /* NNN resolveId hostname ttl addr */
+ if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw);
+ try {
+ clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4]));
+ clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED,
+ 0, clientId, clientInfo.mResolvedService);
+ } catch (java.net.UnknownHostException e) {
+ clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+ }
+ stopGetAddrInfo(id);
+ mIdToClientInfoMap.remove(id);
+ clientInfo.mResolvedService = null;
+ break;
+ default:
+ break;
}
}
@@ -579,7 +622,7 @@ public class NsdService extends INsdManager.Stub {
return true;
}
- private boolean registerService(int regId, DnsSdServiceInfo service) {
+ private boolean registerService(int regId, NsdServiceInfo service) {
if (DBG) Slog.d(TAG, "registerService: " + regId + " " + service);
try {
//Add txtlen and txtdata
@@ -637,7 +680,7 @@ public class NsdService extends INsdManager.Stub {
return true;
}
- private boolean resolveService(int resolveId, DnsSdServiceInfo service) {
+ private boolean resolveService(int resolveId, NsdServiceInfo service) {
if (DBG) Slog.d(TAG, "resolveService: " + resolveId + " " + service);
try {
mNativeConnector.execute("mdnssd", "resolve", resolveId, service.getServiceName(),
@@ -700,49 +743,52 @@ public class NsdService extends INsdManager.Stub {
mNsdStateMachine.dump(fd, pw, args);
}
- private ClientInfo getClientByDiscovery(int discoveryId) {
- for (ClientInfo c: mClients.values()) {
- if (c.mDiscoveryId == discoveryId) {
- return c;
- }
- }
- return null;
+ /* arg2 on the source message has an id that needs to be retained in replies
+ * see NsdManager for details */
+ private Message obtainMessage(Message srcMsg) {
+ Message msg = Message.obtain();
+ msg.arg2 = srcMsg.arg2;
+ return msg;
}
- private ClientInfo getClientByResolve(int resolveId) {
- for (ClientInfo c: mClients.values()) {
- if (c.mResolveId == resolveId) {
- return c;
- }
- }
- return null;
+ private void replyToMessage(Message msg, int what) {
+ if (msg.replyTo == null) return;
+ Message dstMsg = obtainMessage(msg);
+ dstMsg.what = what;
+ mReplyChannel.replyToMessage(msg, dstMsg);
}
- private ClientInfo getClientByRegistration(int regId) {
- for (ClientInfo c: mClients.values()) {
- if (c.mRegisteredIds.contains(regId)) {
- return c;
- }
- }
- return null;
+ private void replyToMessage(Message msg, int what, int arg1) {
+ if (msg.replyTo == null) return;
+ Message dstMsg = obtainMessage(msg);
+ dstMsg.what = what;
+ dstMsg.arg1 = arg1;
+ mReplyChannel.replyToMessage(msg, dstMsg);
+ }
+
+ private void replyToMessage(Message msg, int what, Object obj) {
+ if (msg.replyTo == null) return;
+ Message dstMsg = obtainMessage(msg);
+ dstMsg.what = what;
+ dstMsg.obj = obj;
+ mReplyChannel.replyToMessage(msg, dstMsg);
}
/* Information tracked per client */
private class ClientInfo {
- private static final int MAX_REG = 5;
+ private static final int MAX_LIMIT = 10;
private AsyncChannel mChannel;
private Messenger mMessenger;
- private int mDiscoveryId;
- private int mResolveId;
/* Remembers a resolved service until getaddrinfo completes */
- private DnsSdServiceInfo mResolvedService;
- private ArrayList<Integer> mRegisteredIds = new ArrayList<Integer>();
+ private NsdServiceInfo mResolvedService;
+
+ /* A map from client id to unique id sent to mDns */
+ private SparseArray<Integer> mClientIds = new SparseArray<Integer>();
private ClientInfo(AsyncChannel c, Messenger m) {
mChannel = c;
mMessenger = m;
- mDiscoveryId = mResolveId = INVALID_ID;
if (DBG) Slog.d(TAG, "New client, channel: " + c + " messenger: " + m);
}
@@ -751,11 +797,10 @@ public class NsdService extends INsdManager.Stub {
StringBuffer sb = new StringBuffer();
sb.append("mChannel ").append(mChannel).append("\n");
sb.append("mMessenger ").append(mMessenger).append("\n");
- sb.append("mDiscoveryId ").append(mDiscoveryId).append("\n");
- sb.append("mResolveId ").append(mResolveId).append("\n");
sb.append("mResolvedService ").append(mResolvedService).append("\n");
- for(int regId : mRegisteredIds) {
- sb.append("regId ").append(regId).append("\n");
+ for(int i = 0; i< mClientIds.size(); i++) {
+ sb.append("clientId ").append(mClientIds.keyAt(i));
+ sb.append(" mDnsId ").append(mClientIds.valueAt(i)).append("\n");
}
return sb.toString();
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 40f64bf..aa7de82 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1567,6 +1567,31 @@ public final class ActivityManagerService extends ActivityManagerNative
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
+ if (code == SYSPROPS_TRANSACTION) {
+ // We need to tell all apps about the system property change.
+ ArrayList<IBinder> procs = new ArrayList<IBinder>();
+ synchronized(this) {
+ for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
+ final int NA = apps.size();
+ for (int ia=0; ia<NA; ia++) {
+ ProcessRecord app = apps.valueAt(ia);
+ if (app.thread != null) {
+ procs.add(app.thread.asBinder());
+ }
+ }
+ }
+ }
+
+ int N = procs.size();
+ for (int i=0; i<N; i++) {
+ Parcel data2 = Parcel.obtain();
+ try {
+ procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
+ } catch (RemoteException e) {
+ }
+ data2.recycle();
+ }
+ }
try {
return super.onTransact(code, data, reply, flags);
} catch (RuntimeException e) {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 1e14f5b..c300411 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1794,10 +1794,6 @@ final class ActivityStack {
mService.mWindowManager.prepareAppTransition(
WindowManagerPolicy.TRANSIT_NONE, keepCurTransition);
mNoAnimActivities.add(r);
- } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
- mService.mWindowManager.prepareAppTransition(
- WindowManagerPolicy.TRANSIT_TASK_OPEN, keepCurTransition);
- mNoAnimActivities.remove(r);
} else {
mService.mWindowManager.prepareAppTransition(newTask
? WindowManagerPolicy.TRANSIT_TASK_OPEN
diff --git a/services/java/com/android/server/net/NetworkStatsRecorder.java b/services/java/com/android/server/net/NetworkStatsRecorder.java
index 2ce7771..c3ecf54 100644
--- a/services/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/java/com/android/server/net/NetworkStatsRecorder.java
@@ -26,6 +26,7 @@ import android.net.NetworkStats.NonMonotonicObserver;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
import android.net.TrafficStats;
+import android.os.DropBoxManager;
import android.util.Log;
import android.util.MathUtils;
import android.util.Slog;
@@ -34,6 +35,7 @@ import com.android.internal.util.FileRotator;
import com.android.internal.util.IndentingPrintWriter;
import com.google.android.collect.Sets;
+import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
@@ -43,6 +45,8 @@ import java.lang.ref.WeakReference;
import java.util.HashSet;
import java.util.Map;
+import libcore.io.IoUtils;
+
/**
* Logic to record deltas between periodic {@link NetworkStats} snapshots into
* {@link NetworkStatsHistory} that belong to {@link NetworkStatsCollection}.
@@ -56,8 +60,14 @@ public class NetworkStatsRecorder {
private static final boolean LOGD = false;
private static final boolean LOGV = false;
+ private static final String TAG_NETSTATS_DUMP = "netstats_dump";
+
+ /** Dump before deleting in {@link #recoverFromWtf()}. */
+ private static final boolean DUMP_BEFORE_DELETE = true;
+
private final FileRotator mRotator;
private final NonMonotonicObserver<String> mObserver;
+ private final DropBoxManager mDropBox;
private final String mCookie;
private final long mBucketDuration;
@@ -74,9 +84,10 @@ public class NetworkStatsRecorder {
private WeakReference<NetworkStatsCollection> mComplete;
public NetworkStatsRecorder(FileRotator rotator, NonMonotonicObserver<String> observer,
- String cookie, long bucketDuration, boolean onlyTags) {
+ DropBoxManager dropBox, String cookie, long bucketDuration, boolean onlyTags) {
mRotator = checkNotNull(rotator, "missing FileRotator");
mObserver = checkNotNull(observer, "missing NonMonotonicObserver");
+ mDropBox = checkNotNull(dropBox, "missing DropBoxManager");
mCookie = cookie;
mBucketDuration = bucketDuration;
@@ -122,6 +133,7 @@ public class NetworkStatsRecorder {
mComplete = new WeakReference<NetworkStatsCollection>(complete);
} catch (IOException e) {
Log.wtf(TAG, "problem completely reading network stats", e);
+ recoverFromWtf();
}
}
return complete;
@@ -212,6 +224,7 @@ public class NetworkStatsRecorder {
mPending.reset();
} catch (IOException e) {
Log.wtf(TAG, "problem persisting pending stats", e);
+ recoverFromWtf();
}
}
}
@@ -226,6 +239,7 @@ public class NetworkStatsRecorder {
mRotator.rewriteAll(new RemoveUidRewriter(mBucketDuration, uid));
} catch (IOException e) {
Log.wtf(TAG, "problem removing UID " + uid, e);
+ recoverFromWtf();
}
// clear UID from current stats snapshot
@@ -355,4 +369,25 @@ public class NetworkStatsRecorder {
mSinceBoot.dump(pw);
}
}
+
+ /**
+ * Recover from {@link FileRotator} failure by dumping state to
+ * {@link DropBoxManager} and deleting contents.
+ */
+ private void recoverFromWtf() {
+ if (DUMP_BEFORE_DELETE) {
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ try {
+ mRotator.dumpAll(os);
+ } catch (IOException e) {
+ // ignore partial contents
+ os.reset();
+ } finally {
+ IoUtils.closeQuietly(os);
+ }
+ mDropBox.addData(TAG_NETSTATS_DUMP, os.toByteArray(), 0);
+ }
+
+ mRotator.deleteAll();
+ }
}
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 1a56b80..e710b33 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -338,9 +338,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private NetworkStatsRecorder buildRecorder(
String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
+ final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
+ Context.DROPBOX_SERVICE);
return new NetworkStatsRecorder(new FileRotator(
mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
- mNonMonotonicObserver, prefix, config.bucketDuration, includeTags);
+ mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
}
private void shutdownLocked() {