Use the full component name to construct route ids.

Provide better disambiguation when a package contains multiple
route providers by using the full component name in the route id.

Also fix a bug handling package updates.

Bug: 11257292
Change-Id: Ice4fee742d73e2e979f2059b89cc4f4d971e0947
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouteProvider.java b/v7/mediarouter/src/android/support/v7/media/MediaRouteProvider.java
index aec7b2b..54596b1 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouteProvider.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouteProvider.java
@@ -16,12 +16,12 @@
 
 package android.support.v7.media;
 
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Handler;
 import android.os.Message;
 import android.support.v7.media.MediaRouter.ControlRequestCallback;
-import android.text.TextUtils;
 
 /**
  * Media route providers are used to publish additional media routes for
@@ -84,7 +84,7 @@
 
         mContext = context;
         if (metadata == null) {
-            mMetadata = new ProviderMetadata(context.getPackageName());
+            mMetadata = new ProviderMetadata(new ComponentName(context, getClass()));
         } else {
             mMetadata = metadata;
         }
@@ -256,30 +256,33 @@
      * </p>
      */
     public static final class ProviderMetadata {
-        private final String mPackageName;
+        private final ComponentName mComponentName;
 
-        /**
-         * Creates a provider metadata object.
-         *
-         * @param packageName The provider application's package name.
-         */
-        public ProviderMetadata(String packageName) {
-            if (TextUtils.isEmpty(packageName)) {
-                throw new IllegalArgumentException("packageName must not be null or empty");
+        ProviderMetadata(ComponentName componentName) {
+            if (componentName == null) {
+                throw new IllegalArgumentException("componentName must not be null");
             }
-            mPackageName = packageName;
+            mComponentName = componentName;
         }
 
         /**
-         * Gets the provider application's package name.
+         * Gets the provider's package name.
          */
         public String getPackageName() {
-            return mPackageName;
+            return mComponentName.getPackageName();
+        }
+
+        /**
+         * Gets the provider's component name.
+         */
+        public ComponentName getComponentName() {
+            return mComponentName;
         }
 
         @Override
         public String toString() {
-            return "ProviderMetadata{ packageName=" + mPackageName + " }";
+            return "ProviderMetadata{ componentName="
+                    + mComponentName.flattenToShortString() + " }";
         }
     }
 
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouter.java b/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
index fbddd9d..7b83cc0 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
@@ -16,6 +16,7 @@
 
 package android.support.v7.media;
 
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -1152,13 +1153,20 @@
         }
 
         /**
-         * Gets the package name of the media route provider service.
+         * Gets the package name of the media route provider.
          */
         public String getPackageName() {
             return mMetadata.getPackageName();
         }
 
         /**
+         * Gets the component name of the media route provider.
+         */
+        public ComponentName getComponentName() {
+            return mMetadata.getComponentName();
+        }
+
+        /**
          * Gets the {@link MediaRouter.RouteInfo routes} published by this route provider.
          */
         public List<RouteInfo> getRoutes() {
@@ -1755,7 +1763,8 @@
             // Although route descriptor ids are unique within a provider, it's
             // possible for there to be two providers with the same package name.
             // Therefore we must dedupe the composite id.
-            String uniqueId = provider.getPackageName() + ":" + routeDescriptorId;
+            String uniqueId = provider.getComponentName().flattenToShortString()
+                    + ":" + routeDescriptorId;
             if (findRouteByUniqueId(uniqueId) < 0) {
                 return uniqueId;
             }
diff --git a/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProvider.java b/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProvider.java
index b9e21b1..641e80d 100644
--- a/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProvider.java
+++ b/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProvider.java
@@ -56,7 +56,7 @@
     private boolean mConnectionReady;
 
     public RegisteredMediaRouteProvider(Context context, ComponentName componentName) {
-        super(context, new ProviderMetadata(componentName.getPackageName()));
+        super(context, new ProviderMetadata(componentName));
 
         mComponentName = componentName;
         mPrivateHandler = new PrivateHandler();
diff --git a/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProviderWatcher.java b/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProviderWatcher.java
index 018fb22..2fb01d2 100644
--- a/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProviderWatcher.java
+++ b/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProviderWatcher.java
@@ -60,8 +60,10 @@
             filter.addAction(Intent.ACTION_PACKAGE_ADDED);
             filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
             filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-            mContext.registerReceiver(mScanPackagesReceiver,
-                    filter, null, mHandler);
+            filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+            filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
+            filter.addDataScheme("package");
+            mContext.registerReceiver(mScanPackagesReceiver, filter, null, mHandler);
 
             // Scan packages.
             // Also has the side-effect of restarting providers if needed.
diff --git a/v7/mediarouter/src/android/support/v7/media/SystemMediaRouteProvider.java b/v7/mediarouter/src/android/support/v7/media/SystemMediaRouteProvider.java
index 9acd789..6a09650 100644
--- a/v7/mediarouter/src/android/support/v7/media/SystemMediaRouteProvider.java
+++ b/v7/mediarouter/src/android/support/v7/media/SystemMediaRouteProvider.java
@@ -17,6 +17,7 @@
 package android.support.v7.media;
 
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -43,7 +44,8 @@
     public static final String DEFAULT_ROUTE_ID = "DEFAULT_ROUTE";
 
     protected SystemMediaRouteProvider(Context context) {
-        super(context, new ProviderMetadata(PACKAGE_NAME));
+        super(context, new ProviderMetadata(new ComponentName(PACKAGE_NAME,
+                SystemMediaRouteProvider.class.getName())));
     }
 
     public static SystemMediaRouteProvider obtain(Context context, SyncCallback syncCallback) {