am ade3eca: Implement issue #1783881 (manifest option for adb-install-on

Merge commit 'ade3ecad94d1f4431576f53bae26c35efbf7a2c9'

* commit 'ade3ecad94d1f4431576f53bae26c35efbf7a2c9':
  Implement issue #1783881 (manifest option for adb-install-only apps)
diff --git a/api/4.xml b/api/4.xml
index ab93a47..893301e 100644
--- a/api/4.xml
+++ b/api/4.xml
@@ -31801,97 +31801,6 @@
 >
 </field>
 </class>
-<interface name="IPackageInstallObserver"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="android.os.IInterface">
-</implements>
-<method name="packageInstalled"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageName" type="java.lang.String">
-</parameter>
-<parameter name="returnCode" type="int">
-</parameter>
-<exception name="RemoteException" type="android.os.RemoteException">
-</exception>
-</method>
-</interface>
-<class name="IPackageInstallObserver.Stub"
- extends="android.os.Binder"
- abstract="true"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="android.content.pm.IPackageInstallObserver">
-</implements>
-<constructor name="IPackageInstallObserver.Stub"
- type="android.content.pm.IPackageInstallObserver.Stub"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="asBinder"
- return="android.os.IBinder"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="asInterface"
- return="android.content.pm.IPackageInstallObserver"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="obj" type="android.os.IBinder">
-</parameter>
-</method>
-<method name="onTransact"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="code" type="int">
-</parameter>
-<parameter name="data" type="android.os.Parcel">
-</parameter>
-<parameter name="reply" type="android.os.Parcel">
-</parameter>
-<parameter name="flags" type="int">
-</parameter>
-<exception name="RemoteException" type="android.os.RemoteException">
-</exception>
-</method>
-</class>
 <class name="InstrumentationInfo"
  extends="android.content.pm.PackageItemInfo"
  abstract="false"
@@ -33041,36 +32950,6 @@
 <parameter name="appInfo" type="android.content.pm.ApplicationInfo">
 </parameter>
 </method>
-<method name="installPackage"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageURI" type="android.net.Uri">
-</parameter>
-<parameter name="observer" type="android.content.pm.IPackageInstallObserver">
-</parameter>
-<parameter name="flags" type="int">
-</parameter>
-</method>
-<method name="installPackage"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageURI" type="android.net.Uri">
-</parameter>
-</method>
 <method name="isSafeMode"
  return="boolean"
  abstract="true"
@@ -33344,17 +33223,6 @@
  visibility="public"
 >
 </field>
-<field name="FORWARD_LOCK_PACKAGE"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="GET_ACTIVITIES"
  type="int"
  transient="false"
@@ -33531,270 +33399,6 @@
  visibility="public"
 >
 </field>
-<field name="INSTALL_FAILED_ALREADY_EXISTS"
- type="int"
- transient="false"
- volatile="false"
- value="-1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_CONFLICTING_PROVIDER"
- type="int"
- transient="false"
- volatile="false"
- value="-13"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_DEXOPT"
- type="int"
- transient="false"
- volatile="false"
- value="-11"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_DUPLICATE_PACKAGE"
- type="int"
- transient="false"
- volatile="false"
- value="-5"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_INSUFFICIENT_STORAGE"
- type="int"
- transient="false"
- volatile="false"
- value="-4"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_INVALID_APK"
- type="int"
- transient="false"
- volatile="false"
- value="-2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_INVALID_URI"
- type="int"
- transient="false"
- volatile="false"
- value="-3"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_MISSING_SHARED_LIBRARY"
- type="int"
- transient="false"
- volatile="false"
- value="-9"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_NO_SHARED_USER"
- type="int"
- transient="false"
- volatile="false"
- value="-6"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_OLDER_SDK"
- type="int"
- transient="false"
- volatile="false"
- value="-12"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_REPLACE_COULDNT_DELETE"
- type="int"
- transient="false"
- volatile="false"
- value="-10"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_SHARED_USER_INCOMPATIBLE"
- type="int"
- transient="false"
- volatile="false"
- value="-8"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_UPDATE_INCOMPATIBLE"
- type="int"
- transient="false"
- volatile="false"
- value="-7"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_BAD_MANIFEST"
- type="int"
- transient="false"
- volatile="false"
- value="-101"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME"
- type="int"
- transient="false"
- volatile="false"
- value="-106"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID"
- type="int"
- transient="false"
- volatile="false"
- value="-107"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING"
- type="int"
- transient="false"
- volatile="false"
- value="-105"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES"
- type="int"
- transient="false"
- volatile="false"
- value="-104"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_MANIFEST_EMPTY"
- type="int"
- transient="false"
- volatile="false"
- value="-109"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_MANIFEST_MALFORMED"
- type="int"
- transient="false"
- volatile="false"
- value="-108"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_NOT_APK"
- type="int"
- transient="false"
- volatile="false"
- value="-100"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_NO_CERTIFICATES"
- type="int"
- transient="false"
- volatile="false"
- value="-103"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION"
- type="int"
- transient="false"
- volatile="false"
- value="-102"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_SUCCEEDED"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="MATCH_DEFAULT_ONLY"
  type="int"
  transient="false"
@@ -33850,17 +33454,6 @@
  visibility="public"
 >
 </field>
-<field name="REPLACE_EXISTING_PACKAGE"
- type="int"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="SIGNATURE_FIRST_NOT_SIGNED"
  type="int"
  transient="false"
@@ -101178,23 +100771,6 @@
 <parameter name="appInfo" type="android.content.pm.ApplicationInfo">
 </parameter>
 </method>
-<method name="installPackage"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageURI" type="android.net.Uri">
-</parameter>
-<parameter name="observer" type="android.content.pm.IPackageInstallObserver">
-</parameter>
-<parameter name="flags" type="int">
-</parameter>
-</method>
 <method name="isSafeMode"
  return="boolean"
  abstract="false"
diff --git a/api/current.xml b/api/current.xml
index 141a498..a84f86e 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -7346,6 +7346,17 @@
  visibility="public"
 >
 </field>
+<field name="testOnly"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843378"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="text"
  type="int"
  transient="false"
@@ -34179,6 +34190,17 @@
  visibility="public"
 >
 </field>
+<field name="FLAG_TEST_ONLY"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="512"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="FLAG_UPDATED_SYSTEM_APP"
  type="int"
  transient="false"
@@ -34594,97 +34616,6 @@
 >
 </field>
 </class>
-<interface name="IPackageInstallObserver"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="android.os.IInterface">
-</implements>
-<method name="packageInstalled"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageName" type="java.lang.String">
-</parameter>
-<parameter name="returnCode" type="int">
-</parameter>
-<exception name="RemoteException" type="android.os.RemoteException">
-</exception>
-</method>
-</interface>
-<class name="IPackageInstallObserver.Stub"
- extends="android.os.Binder"
- abstract="true"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="android.content.pm.IPackageInstallObserver">
-</implements>
-<constructor name="IPackageInstallObserver.Stub"
- type="android.content.pm.IPackageInstallObserver.Stub"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="asBinder"
- return="android.os.IBinder"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="asInterface"
- return="android.content.pm.IPackageInstallObserver"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="obj" type="android.os.IBinder">
-</parameter>
-</method>
-<method name="onTransact"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="code" type="int">
-</parameter>
-<parameter name="data" type="android.os.Parcel">
-</parameter>
-<parameter name="reply" type="android.os.Parcel">
-</parameter>
-<parameter name="flags" type="int">
-</parameter>
-<exception name="RemoteException" type="android.os.RemoteException">
-</exception>
-</method>
-</class>
 <class name="InstrumentationInfo"
  extends="android.content.pm.PackageItemInfo"
  abstract="false"
@@ -35847,36 +35778,6 @@
 <parameter name="appInfo" type="android.content.pm.ApplicationInfo">
 </parameter>
 </method>
-<method name="installPackage"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageURI" type="android.net.Uri">
-</parameter>
-<parameter name="observer" type="android.content.pm.IPackageInstallObserver">
-</parameter>
-<parameter name="flags" type="int">
-</parameter>
-</method>
-<method name="installPackage"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageURI" type="android.net.Uri">
-</parameter>
-</method>
 <method name="isSafeMode"
  return="boolean"
  abstract="true"
@@ -36150,17 +36051,6 @@
  visibility="public"
 >
 </field>
-<field name="FORWARD_LOCK_PACKAGE"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="GET_ACTIVITIES"
  type="int"
  transient="false"
@@ -36348,281 +36238,6 @@
  visibility="public"
 >
 </field>
-<field name="INSTALL_FAILED_ALREADY_EXISTS"
- type="int"
- transient="false"
- volatile="false"
- value="-1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_CONFLICTING_PROVIDER"
- type="int"
- transient="false"
- volatile="false"
- value="-13"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_DEXOPT"
- type="int"
- transient="false"
- volatile="false"
- value="-11"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_DUPLICATE_PACKAGE"
- type="int"
- transient="false"
- volatile="false"
- value="-5"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_INSUFFICIENT_STORAGE"
- type="int"
- transient="false"
- volatile="false"
- value="-4"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_INVALID_APK"
- type="int"
- transient="false"
- volatile="false"
- value="-2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_INVALID_URI"
- type="int"
- transient="false"
- volatile="false"
- value="-3"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_MISSING_SHARED_LIBRARY"
- type="int"
- transient="false"
- volatile="false"
- value="-9"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_NEWER_SDK"
- type="int"
- transient="false"
- volatile="false"
- value="-14"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_NO_SHARED_USER"
- type="int"
- transient="false"
- volatile="false"
- value="-6"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_OLDER_SDK"
- type="int"
- transient="false"
- volatile="false"
- value="-12"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_REPLACE_COULDNT_DELETE"
- type="int"
- transient="false"
- volatile="false"
- value="-10"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_SHARED_USER_INCOMPATIBLE"
- type="int"
- transient="false"
- volatile="false"
- value="-8"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_FAILED_UPDATE_INCOMPATIBLE"
- type="int"
- transient="false"
- volatile="false"
- value="-7"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_BAD_MANIFEST"
- type="int"
- transient="false"
- volatile="false"
- value="-101"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME"
- type="int"
- transient="false"
- volatile="false"
- value="-106"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID"
- type="int"
- transient="false"
- volatile="false"
- value="-107"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING"
- type="int"
- transient="false"
- volatile="false"
- value="-105"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES"
- type="int"
- transient="false"
- volatile="false"
- value="-104"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_MANIFEST_EMPTY"
- type="int"
- transient="false"
- volatile="false"
- value="-109"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_MANIFEST_MALFORMED"
- type="int"
- transient="false"
- volatile="false"
- value="-108"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_NOT_APK"
- type="int"
- transient="false"
- volatile="false"
- value="-100"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_NO_CERTIFICATES"
- type="int"
- transient="false"
- volatile="false"
- value="-103"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION"
- type="int"
- transient="false"
- volatile="false"
- value="-102"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="INSTALL_SUCCEEDED"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="MATCH_DEFAULT_ONLY"
  type="int"
  transient="false"
@@ -36678,17 +36293,6 @@
  visibility="public"
 >
 </field>
-<field name="REPLACE_EXISTING_PACKAGE"
- type="int"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="SIGNATURE_FIRST_NOT_SIGNED"
  type="int"
  transient="false"
@@ -114686,25 +114290,6 @@
 <parameter name="appInfo" type="android.content.pm.ApplicationInfo">
 </parameter>
 </method>
-<method name="installPackage"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageURI" type="android.net.Uri">
-</parameter>
-<parameter name="observer" type="android.content.pm.IPackageInstallObserver">
-</parameter>
-<parameter name="flags" type="int">
-</parameter>
-<parameter name="installerPackageName" type="java.lang.String">
-</parameter>
-</method>
 <method name="isSafeMode"
  return="boolean"
  abstract="false"
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index ac62757..8212b92 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -540,6 +540,9 @@
         case PackageManager.INSTALL_FAILED_NEWER_SDK:
             s = "INSTALL_FAILED_NEWER_SDK";
             break;
+        case PackageManager.INSTALL_FAILED_TEST_ONLY:
+            s = "INSTALL_FAILED_TEST_ONLY";
+            break;
         case PackageManager.INSTALL_PARSE_FAILED_NOT_APK:
             s = "INSTALL_PARSE_FAILED_NOT_APK";
             break;
@@ -584,9 +587,9 @@
         String opt;
         while ((opt=nextOption()) != null) {
             if (opt.equals("-l")) {
-                installFlags |= PackageManager.FORWARD_LOCK_PACKAGE;
+                installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
             } else if (opt.equals("-r")) {
-                installFlags |= PackageManager.REPLACE_EXISTING_PACKAGE;
+                installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
             } else if (opt.equals("-i")) {
                 installerPackageName = nextOptionData();
                 if (installerPackageName == null) {
@@ -594,6 +597,8 @@
                     showUsage();
                     return;
                 }
+            } else if (opt.equals("-t")) {
+                installFlags |= PackageManager.INSTALL_ALLOW_TEST;
             } else {
                 System.err.println("Error: Unknown option: " + opt);
                 showUsage();
@@ -821,38 +826,39 @@
         System.err.println("       pm list permissions [-g] [-f] [-d] [-u] [GROUP]");
         System.err.println("       pm list instrumentation [-f] [TARGET-PACKAGE]");        
         System.err.println("       pm path PACKAGE");
-        System.err.println("       pm install [-l] [-r] [-i INSTALLER_PACKAGE_NAME] PATH");
+        System.err.println("       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] PATH");
         System.err.println("       pm uninstall [-k] PACKAGE");
         System.err.println("       pm enable PACKAGE_OR_COMPONENT");
         System.err.println("       pm disable PACKAGE_OR_COMPONENT");
         System.err.println("");
-        System.err.println("The list packages command prints all packages.  Use");
-        System.err.println("the -f option to see their associated file.");
+        System.err.println("The list packages command prints all packages.  Options:");
+        System.err.println("  -f: see their associated file.");
         System.err.println("");
         System.err.println("The list permission-groups command prints all known");
         System.err.println("permission groups.");
         System.err.println("");
         System.err.println("The list permissions command prints all known");
-        System.err.println("permissions, optionally only those in GROUP.  Use");
-        System.err.println("the -g option to organize by group.  Use");
-        System.err.println("the -f option to print all information.  Use");
-        System.err.println("the -s option for a short summary.  Use");
-        System.err.println("the -d option to only list dangerous permissions.  Use");
-        System.err.println("the -u option to list only the permissions users will see.");
+        System.err.println("permissions, optionally only those in GROUP.  Options:");
+        System.err.println("  -g: organize by group.");
+        System.err.println("  -f: print all information.");
+        System.err.println("  -s: short summary.");
+        System.err.println("  -d: only list dangerous permissions.");
+        System.err.println("  -u: list only the permissions users will see.");
         System.err.println("");
         System.err.println("The list instrumentation command prints all instrumentations,");
-        System.err.println("or only those that target a specified package.  Use the -f option");
-        System.err.println("to see their associated file.");
+        System.err.println("or only those that target a specified package.  Options:");
+        System.err.println("  -f: see their associated file.");
         System.err.println("");
         System.err.println("The path command prints the path to the .apk of a package.");
         System.err.println("");
-        System.err.println("The install command installs a package to the system.  Use");
-        System.err.println("the -l option to install the package with FORWARD_LOCK. Use");
-        System.err.println("the -r option to reinstall an exisiting app, keeping its data.");
-        System.err.println("the -i option to specify the installer package name.");
+        System.err.println("The install command installs a package to the system.  Options:");
+        System.err.println("  -l: install the package with FORWARD_LOCK.");
+        System.err.println("  -r: reinstall an exisiting app, keeping its data.");
+        System.err.println("  -t: allow test .apks to be installed.");
+        System.err.println("  -i: specify the installer package name.");
         System.err.println("");
-        System.err.println("The uninstall command removes a package from the system. Use");
-        System.err.println("the -k option to keep the data and cache directories around");
+        System.err.println("The uninstall command removes a package from the system. Options:");
+        System.err.println("  -k: keep the data and cache directories around.");
         System.err.println("after the package removal.");
         System.err.println("");
         System.err.println("The enable and disable commands change the enabled state of");
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index fa9ec6e..88ac04c 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -126,6 +126,12 @@
     public static final int FLAG_TARGETS_SDK = 1<<8;
 
     /**
+     * Value for {@link #flags}: this is set of the application has set
+     * its android:targetSdkVersion to something >= the current SDK version.
+     */
+    public static final int FLAG_TEST_ONLY = 1<<9;
+
+    /**
      * Flags associated with the application.  Any combination of
      * {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE},
      * {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and
diff --git a/core/java/android/content/pm/IPackageInstallObserver.aidl b/core/java/android/content/pm/IPackageInstallObserver.aidl
index e83bbc6..6133365 100644
--- a/core/java/android/content/pm/IPackageInstallObserver.aidl
+++ b/core/java/android/content/pm/IPackageInstallObserver.aidl
@@ -19,7 +19,7 @@
 
 /**
  * API for installation callbacks from the Package Manager.
- *
+ * @hide
  */
 oneway interface IPackageInstallObserver {
     void packageInstalled(in String packageName, int returnCode);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 18e4548..8095990 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -235,14 +235,24 @@
      * Flag parameter for {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} to
      * indicate that this package should be installed as forward locked, i.e. only the app itself
      * should have access to it's code and non-resource assets.
+     * @hide
      */
-    public static final int FORWARD_LOCK_PACKAGE = 0x00000001;
+    public static final int INSTALL_FORWARD_LOCK = 0x00000001;
 
     /**
      * Flag parameter for {@link #installPackage} to indicate that you want to replace an already
-     * installed package, if one exists
+     * installed package, if one exists.
+     * @hide
      */
-    public static final int REPLACE_EXISTING_PACKAGE = 0x00000002;
+    public static final int INSTALL_REPLACE_EXISTING = 0x00000002;
+
+    /**
+     * Flag parameter for {@link #installPackage} to indicate that you want to 
+     * allow test packages (those that have set android:testOnly in their
+     * manifest) to be installed.
+     * @hide
+     */
+    public static final int INSTALL_ALLOW_TEST = 0x00000004;
 
     /**
      * Flag parameter for
@@ -255,6 +265,7 @@
     /**
      * Installation return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} on success.
+     * @hide
      */
     public static final int INSTALL_SUCCEEDED = 1;
 
@@ -262,6 +273,7 @@
      * Installation return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package is
      * already installed.
+     * @hide
      */
     public static final int INSTALL_FAILED_ALREADY_EXISTS = -1;
 
@@ -269,6 +281,7 @@
      * Installation return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package archive
      * file is invalid.
+     * @hide
      */
     public static final int INSTALL_FAILED_INVALID_APK = -2;
 
@@ -276,13 +289,15 @@
      * Installation return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the URI passed in
      * is invalid.
+     * @hide
      */
     public static final int INSTALL_FAILED_INVALID_URI = -3;
 
     /**
      * Installation return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package manager
-     * service found that the device didn't have enough storage space to install the app
+     * service found that the device didn't have enough storage space to install the app.
+     * @hide
      */
     public static final int INSTALL_FAILED_INSUFFICIENT_STORAGE = -4;
 
@@ -290,6 +305,7 @@
      * Installation return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if a
      * package is already installed with the same name.
+     * @hide
      */
     public static final int INSTALL_FAILED_DUPLICATE_PACKAGE = -5;
 
@@ -297,6 +313,7 @@
      * Installation return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
      * the requested shared user does not exist.
+     * @hide
      */
     public static final int INSTALL_FAILED_NO_SHARED_USER = -6;
 
@@ -305,6 +322,7 @@
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
      * a previously installed package of the same name has a different signature
      * than the new package (and the old package's data was not removed).
+     * @hide
      */
     public static final int INSTALL_FAILED_UPDATE_INCOMPATIBLE = -7;
 
@@ -313,6 +331,7 @@
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
      * the new package is requested a shared user which is already installed on the
      * device and does not have matching signature.
+     * @hide
      */
     public static final int INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8;
 
@@ -320,6 +339,7 @@
      * Installation return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
      * the new package uses a shared library that is not available.
+     * @hide
      */
     public static final int INSTALL_FAILED_MISSING_SHARED_LIBRARY = -9;
 
@@ -327,6 +347,7 @@
      * Installation return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
      * the new package uses a shared library that is not available.
+     * @hide
      */
     public static final int INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10;
 
@@ -335,6 +356,7 @@
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
      * the new package failed while optimizing and validating its dex files,
      * either because there was not enough storage or the validation failed.
+     * @hide
      */
     public static final int INSTALL_FAILED_DEXOPT = -11;
 
@@ -343,6 +365,7 @@
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
      * the new package failed because the current SDK version is older than
      * that required by the package.
+     * @hide
      */
     public static final int INSTALL_FAILED_OLDER_SDK = -12;
 
@@ -351,6 +374,7 @@
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
      * the new package failed because it contains a content provider with the
      * same authority as a provider already installed in the system.
+     * @hide
      */
     public static final int INSTALL_FAILED_CONFLICTING_PROVIDER = -13;
 
@@ -359,14 +383,26 @@
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
      * the new package failed because the current SDK version is newer than
      * that required by the package.
+     * @hide
      */
     public static final int INSTALL_FAILED_NEWER_SDK = -14;
 
     /**
+     * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+     * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+     * the new package failed because it has specified that it is a test-only
+     * package and the caller has not supplied the {@link #INSTALL_ALLOW_TEST}
+     * flag.
+     * @hide
+     */
+    public static final int INSTALL_FAILED_TEST_ONLY = -15;
+
+    /**
      * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
      * if the parser was given a path that is not a file, or does not end with the expected
      * '.apk' extension.
+     * @hide
      */
     public static final int INSTALL_PARSE_FAILED_NOT_APK = -100;
 
@@ -374,6 +410,7 @@
      * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
      * if the parser was unable to retrieve the AndroidManifest.xml file.
+     * @hide
      */
     public static final int INSTALL_PARSE_FAILED_BAD_MANIFEST = -101;
 
@@ -381,6 +418,7 @@
      * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
      * if the parser encountered an unexpected exception.
+     * @hide
      */
     public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102;
 
@@ -388,6 +426,7 @@
      * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
      * if the parser did not find any certificates in the .apk.
+     * @hide
      */
     public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103;
 
@@ -395,6 +434,7 @@
      * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
      * if the parser found inconsistent certificates on the files in the .apk.
+     * @hide
      */
     public static final int INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES = -104;
 
@@ -403,6 +443,7 @@
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
      * if the parser encountered a CertificateEncodingException in one of the
      * files in the .apk.
+     * @hide
      */
     public static final int INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING = -105;
 
@@ -410,6 +451,7 @@
      * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
      * if the parser encountered a bad or missing package name in the manifest.
+     * @hide
      */
     public static final int INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106;
 
@@ -417,6 +459,7 @@
      * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
      * if the parser encountered a bad shared user id name in the manifest.
+     * @hide
      */
     public static final int INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID = -107;
 
@@ -424,6 +467,7 @@
      * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
      * if the parser encountered some structural problem in the manifest.
+     * @hide
      */
     public static final int INSTALL_PARSE_FAILED_MANIFEST_MALFORMED = -108;
 
@@ -432,6 +476,7 @@
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
      * if the parser did not find any actionable tags (instrumentation or application)
      * in the manifest.
+     * @hide
      */
     public static final int INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109;
 
@@ -1338,6 +1383,8 @@
     }
 
     /**
+     * @hide
+     * 
      * Install a package. Since this may take a little while, the result will
      * be posted back to the given observer.  An installation will fail if the calling context
      * lacks the {@link android.Manifest.permission#INSTALL_PACKAGES} permission, if the
@@ -1349,36 +1396,10 @@
      * @param observer An observer callback to get notified when the package installation is
      * complete. {@link IPackageInstallObserver#packageInstalled(String, int)} will be
      * called when that happens.  observer may be null to indicate that no callback is desired.
-     * @param flags - possible values: {@link #FORWARD_LOCK_PACKAGE},
-     * {@link #REPLACE_EXISTING_PACKAGE}
-     *
-     * @see #installPackage(android.net.Uri)
-     */
-    public void installPackage(
-            Uri packageURI, IPackageInstallObserver observer, int flags) {
-        installPackage(packageURI, observer, flags, null);
-    }
-
-    /**
-     * Install a package. Since this may take a little while, the result will
-     * be posted back to the given observer.  An installation will fail if the calling context
-     * lacks the {@link android.Manifest.permission#INSTALL_PACKAGES} permission, if the
-     * package named in the package file's manifest is already installed, or if there's no space
-     * available on the device.
-     *
-     * @param packageURI The location of the package file to install.  This can be a 'file:' or a
-     * 'content:' URI.
-     * @param observer An observer callback to get notified when the package installation is
-     * complete. {@link IPackageInstallObserver#packageInstalled(String, int)} will be
-     * called when that happens.  observer may be null to indicate that no callback is desired.
-     * @param flags - possible values: {@link #FORWARD_LOCK_PACKAGE},
-     * {@link #REPLACE_EXISTING_PACKAGE}
+     * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
+     * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
      * @param installerPackageName Optional package name of the application that is performing the
      * installation. This identifies which market the package came from.
-     *
-     * @see #installPackage(android.net.Uri)
-     * 
-     * @hide
      */
     public abstract void installPackage(
             Uri packageURI, IPackageInstallObserver observer, int flags,
@@ -1515,17 +1536,6 @@
             IPackageStatsObserver observer);
 
     /**
-     * Install a package.
-     *
-     * @param packageURI The location of the package file to install
-     *
-     * @see #installPackage(android.net.Uri, IPackageInstallObserver, int, String)
-     */
-    public void installPackage(Uri packageURI) {
-        installPackage(packageURI, null, 0);
-    }
-
-    /**
      * Add a new package to the list of preferred packages.  This new package
      * will be added to the front of the list (removed from its current location
      * if already listed), meaning it will now be preferred over all other
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 12df5bd..a1c0f48 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1187,6 +1187,12 @@
             ai.flags |= ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA;
         }
 
+        if (sa.getBoolean(
+                com.android.internal.R.styleable.AndroidManifestApplication_testOnly,
+                true)) {
+            ai.flags |= ApplicationInfo.FLAG_TEST_ONLY;
+        }
+
         String str;
         str = sa.getNonResourceString(
                 com.android.internal.R.styleable.AndroidManifestApplication_permission);
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 1319c77..7b48267 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -79,6 +79,13 @@
          by applications. -->
     <attr name="allowClearUserData" format="boolean" />
     
+    <!-- Option to indicate this application is only for testing purposes.
+         For example, it may expose functionality or data outside of itself
+         that would cause a security hole, but is useful for testing.  This
+         kind of application can not be installed without the
+         INSTALL_ALLOW_TEST flag, which means only through adb install.  -->
+    <attr name="testOnly" format="boolean" />
+    
     <!-- A unique name for the given item.  This must use a Java-style naming
          convention to ensure the name is unique, for example
          "com.mycompany.MyName". -->  
@@ -635,6 +642,7 @@
         <!-- Name of activity to be launched for managing the application's space on the device. -->
         <attr name="manageSpaceActivity" />
         <attr name="allowClearUserData" />
+        <attr name="testOnly" />
     </declare-styleable>
     
     <!-- The <code>permission</code> tag declares a security permission that can be
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 3d4c1a2..5a80033 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1099,6 +1099,7 @@
    <public type="attr" name="onClick" id="0x0101026f" />
    <public type="attr" name="targetSdkVersion" id="0x01010270" />
    <public type="attr" name="maxSdkVersion" id="0x01010271" />
+   <public type="attr" name="testOnly" id="0x01010272" />
 
    <public type="anim" name="anticipate_interpolator" id="0x010a0007" />
    <public type="anim" name="overshoot_interpolator" id="0x010a0008" />
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index d3bb03c..bee1530 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -3399,7 +3399,7 @@
             oldInstallerPackageName = mSettings.getInstallerPackageName(pkgName);
         }
         
-        int parseFlags = PackageManager.REPLACE_EXISTING_PACKAGE;
+        int parseFlags = PackageManager.INSTALL_REPLACE_EXISTING;
         // First delete the existing package while retaining the data directory
         if (!deletePackageLI(pkgName, false, PackageManager.DONT_DELETE_DATA,
                 res.removedInfo)) {
@@ -3471,7 +3471,7 @@
                 installPackageLI(
                         Uri.fromFile(new File(deletedPackage.mPath)),
                         isForwardLocked(deletedPackage)
-                        ? PackageManager.FORWARD_LOCK_PACKAGE
+                        ? PackageManager.INSTALL_FORWARD_LOCK
                                 : 0, false, oldInstallerPackageName);
             }
         }
@@ -3484,7 +3484,7 @@
             String installerPackageName, PackageInstalledInfo res) {
         PackageParser.Package newPackage = null;
         boolean updatedSettings = false;
-        int parseFlags = PackageManager.REPLACE_EXISTING_PACKAGE |
+        int parseFlags = PackageManager.INSTALL_REPLACE_EXISTING |
                 PackageParser.PARSE_IS_SYSTEM;
         String packageName = deletedPackage.packageName;
         res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
@@ -3700,13 +3700,13 @@
             res.name = pkgName;
             //initialize some variables before installing pkg
             final String pkgFileName = pkgName + ".apk";
-            final File destDir = ((pFlags&PackageManager.FORWARD_LOCK_PACKAGE) != 0)
+            final File destDir = ((pFlags&PackageManager.INSTALL_FORWARD_LOCK) != 0)
                                  ?  mDrmAppPrivateInstallDir
                                  : mAppInstallDir;
             final File destPackageFile = new File(destDir, pkgFileName);
             final String destFilePath = destPackageFile.getAbsolutePath();
             File destResourceFile;
-            if ((pFlags&PackageManager.FORWARD_LOCK_PACKAGE) != 0) {
+            if ((pFlags&PackageManager.INSTALL_FORWARD_LOCK) != 0) {
                 final String publicZipFileName = pkgName + ".zip";
                 destResourceFile = new File(mAppInstallDir, publicZipFileName);
                 forwardLocked = true;
@@ -3725,6 +3725,12 @@
                 res.returnCode = pp.getParseError();
                 break main_flow;
             }
+            if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
+                if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) {
+                    res.returnCode = PackageManager.INSTALL_FAILED_TEST_ONLY;
+                    break main_flow;
+                }
+            }
             if (GET_CERTIFICATES && !pp.collectCertificates(pkg, parseFlags)) {
                 res.returnCode = pp.getParseError();
                 break main_flow;
@@ -3732,7 +3738,7 @@
             
             synchronized (mPackages) {
                 //check if installing already existing package
-                if ((pFlags&PackageManager.REPLACE_EXISTING_PACKAGE) != 0
+                if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0
                         && mPackages.containsKey(pkgName)) {
                     replacingExistingPackage = true;
                 }
diff --git a/test-runner/android/test/mock/MockPackageManager.java b/test-runner/android/test/mock/MockPackageManager.java
index 20929a3..2236663 100644
--- a/test-runner/android/test/mock/MockPackageManager.java
+++ b/test-runner/android/test/mock/MockPackageManager.java
@@ -284,6 +284,9 @@
         throw new UnsupportedOperationException();
     }
 
+    /**
+     * @hide - to match hiding in superclass
+     */
     @Override
     public void installPackage(Uri packageURI, IPackageInstallObserver observer,
             int flags, String installerPackageName) {
@@ -396,11 +399,6 @@
     }
 
     @Override
-    public void installPackage(Uri packageURI) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
     public int getPreferredActivities(List<IntentFilter> outFilters,
             List<ComponentName> outActivities, String packageName) {
         throw new UnsupportedOperationException();