Grant USB device permission by using system permission.

Previously it skips the device permission check by referring package
name. The CL removes the special case and use general MANAGE_USB
system-only permission to skip USB device permission dialog.

BUG=26048722

Change-Id: I3702393a50696209499d1e5f6549dab9fb2cefe4
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index a23a6cb..1e3bcd0 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.RemoteException;
 import android.util.Log;
 
@@ -455,6 +456,21 @@
     }
 
     /**
+     * Grants permission for USB device without showing system dialog.
+     * Only system components can call this function.
+     * @param device to request permissions for
+     *
+     * {@hide}
+     */
+    public void grantPermission(UsbDevice device) {
+        try {
+            mService.grantDevicePermission(device, Process.myUid());
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in grantPermission", e);
+        }
+    }
+
+    /**
      * Returns true if the specified USB function is currently enabled when in device mode.
      * <p>
      * USB functions represent interfaces which are published to the host to access
diff --git a/packages/MtpDocumentsProvider/Android.mk b/packages/MtpDocumentsProvider/Android.mk
index ec18463..3c2fa36 100644
--- a/packages/MtpDocumentsProvider/Android.mk
+++ b/packages/MtpDocumentsProvider/Android.mk
@@ -5,6 +5,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_PACKAGE_NAME := MtpDocumentsProvider
 LOCAL_CERTIFICATE := media
+LOCAL_PRIVILEGED_MODULE := true
 
 include $(BUILD_PACKAGE)
 include $(LOCAL_PATH)/tests/Android.mk
diff --git a/packages/MtpDocumentsProvider/AndroidManifest.xml b/packages/MtpDocumentsProvider/AndroidManifest.xml
index 3861d78..d6042a1 100644
--- a/packages/MtpDocumentsProvider/AndroidManifest.xml
+++ b/packages/MtpDocumentsProvider/AndroidManifest.xml
@@ -3,6 +3,7 @@
           package="com.android.mtp"
           android:sharedUserId="android.media">
     <uses-feature android:name="android.hardware.usb.host" />
+    <uses-permission android:name="android.permission.MANAGE_USB" />
     <application android:label="@string/app_label">
         <provider
             android:name=".MtpDocumentsProvider"
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
index 78a56c1..e7f94b7 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
@@ -26,14 +26,12 @@
 import android.mtp.MtpObjectInfo;
 import android.os.CancellationSignal;
 import android.os.ParcelFileDescriptor;
-import android.os.Process;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.util.ArrayList;
 
 /**
  * The model wrapping android.mtp API.
@@ -63,8 +61,10 @@
         }
 
         if (!mManager.hasPermission(rawDevice)) {
-            // Permission should be obtained via app selection dialog for intent.
-            throw new IOException("No permission to operate USB device.");
+            mManager.grantPermission(rawDevice);
+            if (!mManager.hasPermission(rawDevice)) {
+                throw new IOException("Failed to grant a device permission.");
+            }
         }
 
         final MtpDevice device = new MtpDevice(rawDevice);
diff --git a/services/usb/java/com/android/server/usb/UsbSettingsManager.java b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
index 4786d11..7976cb8 100644
--- a/services/usb/java/com/android/server/usb/UsbSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
@@ -52,12 +52,10 @@
 import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
-import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.PrintWriter;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -984,14 +982,7 @@
     public boolean hasPermission(UsbDevice device) {
         synchronized (mLock) {
             int uid = Binder.getCallingUid();
-            int androidMediaUid;
-            try {
-                androidMediaUid = mPackageManager.getApplicationInfo("com.android.mtp", 0).uid;
-            } catch (NameNotFoundException e) {
-                androidMediaUid = -1;
-            }
-            if (uid == Process.SYSTEM_UID || UserHandle.getAppId(uid) == androidMediaUid ||
-                    mDisablePermissionDialogs) {
+            if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
                 return true;
             }
             SparseBooleanArray uidList = mDevicePermissionMap.get(device.getDeviceName());