Merge "SampleSyncAdapter sample code." into eclair
diff --git a/build/tools/make_windows_sdk.sh b/build/tools/make_windows_sdk.sh
index 6847f73..d30c956 100755
--- a/build/tools/make_windows_sdk.sh
+++ b/build/tools/make_windows_sdk.sh
@@ -163,8 +163,10 @@
     mkdir -pv "$LIB"/x86_64
     cp -v prebuilt/windows-x86_64/swt/swt.jar  "$LIB"/x86_64/
 
-    # Move the SDK Setup (aka sdklauncher) to the root of the SDK (it was copied in tools above)
-    mv "$TOOLS/sdklauncher.exe" "$TEMP_SDK_DIR/SDK Setup.exe"    
+    # Copy the SDK Setup (aka sdklauncher) to the root of the SDK (it was copied in tools above)
+    # and move it also in SDK/tools/lib (so that tools updates can update the root one too)
+    cp "$TOOLS/sdklauncher.exe" "$TEMP_SDK_DIR/SDK Setup.exe"
+    mv "$TOOLS/sdklauncher.exe" "$LIB/SDK Setup.exe"
 
     # If you want the emulator NOTICE in the tools dir, uncomment the following line:
     # cp -v external/qemu/NOTICE "$TOOLS"/emulator_NOTICE.txt
@@ -173,6 +175,8 @@
     cp -v /cygdrive/c/cygwin/bin/mgwz.dll "$TOOLS"/
 
     # Update a bunch of bat files
+    cp -v sdk/files/post_tools_install.bat            "$LIB"/
+    cp -v sdk/files/find_java.bat                     "$LIB"/
     cp -v sdk/apkbuilder/etc/apkbuilder.bat           "$TOOLS"/
     cp -v sdk/ddms/app/etc/ddms.bat                   "$TOOLS"/
     cp -v sdk/traceview/etc/traceview.bat             "$TOOLS"/
diff --git a/ndk/build/toolchains/arm-eabi-4.4.0/setup.mk b/ndk/build/toolchains/arm-eabi-4.4.0/setup.mk
index cbdeed5..41d85db 100644
--- a/ndk/build/toolchains/arm-eabi-4.4.0/setup.mk
+++ b/ndk/build/toolchains/arm-eabi-4.4.0/setup.mk
@@ -39,8 +39,8 @@
 
 ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
     TARGET_ARCH_CFLAGS := -march=armv7-a \
-                            -mfloat-abi=softfp \
-                            -mfpu=neon
+                          -mfloat-abi=softfp \
+                          -mfpu=vfp
     TARGET_ARCH_LDFLAGS := -Wl,--fix-cortex-a8
 else
     TARGET_ARCH_CFLAGS := -march=armv5te \
diff --git a/ndk/docs/CPU-ARCH-ABIS.TXT b/ndk/docs/CPU-ARCH-ABIS.TXT
index d142db4..b9b88e7 100644
--- a/ndk/docs/CPU-ARCH-ABIS.TXT
+++ b/ndk/docs/CPU-ARCH-ABIS.TXT
@@ -93,12 +93,12 @@
      - The Thumb-2 instruction set extension.
      - The VFP hardware FPU instructions.
 
-  More specifically, VFPv3-D32 is being used, which corresponds to 32
+  More specifically, VFPv3-D16 is being used, which corresponds to 16
   dedicated 64-bit floating point registers provided by the CPU.
 
-  Other extensions described by the v7-a ARM like Advanced SIMD (a.k.a. NEON)
-  or ThumbEE are optional to this ABI, which means that developers should
-  check *at* *runtime* whether the extensions are available and provide
+  Other extensions described by the v7-a ARM like Advanced SIMD (a.k.a. NEON),
+  VFPv3-D32 or ThumbEE are optional to this ABI, which means that developers
+  should check *at* *runtime* whether the extensions are available and provide
   alternative code paths if this is not the case.
 
   (Just like one typically does on x86 systems to check/use MMX/SSE2/etc...
diff --git a/samples/CubeLiveWallpaper/AndroidManifest.xml b/samples/CubeLiveWallpaper/AndroidManifest.xml
index 1c6507b..b7bb876 100644
--- a/samples/CubeLiveWallpaper/AndroidManifest.xml
+++ b/samples/CubeLiveWallpaper/AndroidManifest.xml
@@ -21,6 +21,8 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.livecubes">
 
+    <uses-feature android:name="android.software.live_wallpaper" />
+
     <application
         android:label="@string/wallpapers"
         android:icon="@drawable/ic_launcher_wallpaper">
diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/ILicenseResultListener.aidl b/samples/MarketLicensing/src/com/android/vending/licensing/ILicenseResultListener.aidl
new file mode 100755
index 0000000..869cb16
--- /dev/null
+++ b/samples/MarketLicensing/src/com/android/vending/licensing/ILicenseResultListener.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.vending.licensing;
+
+oneway interface ILicenseResultListener {
+  void verifyLicense(int responseCode, String signedData, String signature);
+}
diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/ILicensingService.aidl b/samples/MarketLicensing/src/com/android/vending/licensing/ILicensingService.aidl
new file mode 100755
index 0000000..9541a20
--- /dev/null
+++ b/samples/MarketLicensing/src/com/android/vending/licensing/ILicensingService.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.vending.licensing;
+
+import com.android.vending.licensing.ILicenseResultListener;
+
+oneway interface ILicensingService {
+  void checkLicense(long nonce, String packageName, in ILicenseResultListener listener);
+}
diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/LicenseChecker.java b/samples/MarketLicensing/src/com/android/vending/licensing/LicenseChecker.java
new file mode 100755
index 0000000..773b8cd
--- /dev/null
+++ b/samples/MarketLicensing/src/com/android/vending/licensing/LicenseChecker.java
@@ -0,0 +1,165 @@
+/*

+ * Copyright (C) 2010 The Android Open Source Project

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+

+package com.android.vending.licensing;

+

+import java.security.SecureRandom;

+

+import android.content.ComponentName;

+import android.content.Context;

+import android.content.Intent;

+import android.content.ServiceConnection;

+import android.content.pm.PackageManager.NameNotFoundException;

+import android.os.IBinder;

+import android.os.RemoteException;

+import android.util.Log;

+

+import com.android.vending.licensing.LicenseCheckerCallback.ApplicationErrorCode;

+import com.android.vending.licensing.Policy.LicenseResponse;

+

+/**

+ * Client library for Android Market license verifications.

+ *

+ * The LicenseChecker is configured via a {@link Policy} which contains the

+ * logic to determine whether a user should have access to the application.

+ * For example, the Policy can define a threshold for allowable number of

+ * server or client failures before the library reports the user as not having

+ * access.

+ *

+ * This library is not thread-safe. Multiple, concurrent checks will result in

+ * an error.

+ */

+public class LicenseChecker implements ServiceConnection {

+    private static final String TAG = "LicenseChecker";

+

+    private static final SecureRandom RANDOM = new SecureRandom();

+

+    private ILicensingService mService;

+

+    /** Validator for the request in progress. */

+    private LicenseValidator mValidator;

+

+    private final Context mContext;

+    private final Policy mPolicy;

+    /** Listener for service (IPC) calls. */

+    private final ResultListener mListener;

+    private final String mPackageName;

+    private final String mVersionCode;

+

+    public LicenseChecker(Context context, Policy policy) {

+        mContext = context;

+        mPolicy = policy;

+        mListener = new ResultListener();

+        mPackageName = mContext.getPackageName();

+        mVersionCode = getVersionCode(context, mPackageName);

+    }

+

+    private boolean isInProgress() {

+        return mValidator != null;

+    }

+

+    /**

+     * Checks if the user should have access to the app.

+     *

+     * @param callback

+     */

+    public synchronized void checkAccess(LicenseCheckerCallback callback) {

+        if (isInProgress()) {

+            callback.applicationError(ApplicationErrorCode.CHECK_IN_PROGRESS);

+        }

+

+        mValidator = new LicenseValidator(mPolicy, callback, generateNonce(), mPackageName,

+            mVersionCode);

+

+        Log.i(TAG, "Binding to licensing service.");

+        boolean bindResult = mContext.bindService(new Intent(ILicensingService.class.getName()),

+            this,  // ServiceConnection.

+            Context.BIND_AUTO_CREATE);

+

+        if (!bindResult) {

+            Log.e(TAG, "Could not bind to service.");

+            callback.dontAllow();

+            // No need to unbind at this point.

+            return;

+        }

+    }

+

+    private class ResultListener extends ILicenseResultListener.Stub {

+        public void verifyLicense(int responseCode, String signedData, String signature) {

+            mValidator.verify(responseCode, signedData, signature);

+            cleanup();

+        }

+    }

+

+    public void onServiceConnected(ComponentName name, IBinder service) {

+        mService = ILicensingService.Stub.asInterface(service);

+

+        try {

+            Log.i(TAG, "Calling checkLicense on service for " + mValidator.getPackageName());

+            mService.checkLicense(mValidator.getNonce(), mValidator.getPackageName(), mListener);

+        } catch (RemoteException e) {

+            Log.w(TAG, "RemoteException in checkLicense call.", e);

+            handleServiceConnectionError();

+            // cleanup unbinds service.

+            cleanup();

+        }

+    }

+

+    public void onServiceDisconnected(ComponentName name) {

+        // Called when the connection with the service has been

+        // unexpectedly disconnected. That is, Market crashed.

+        Log.w(TAG, "Service unexpectedly disconnected.");

+        handleServiceConnectionError();

+        // cleanup unbinds service.

+        cleanup();

+    }

+

+    private void handleServiceConnectionError() {

+        if (mPolicy.allowAccess(LicenseResponse.CLIENT_RETRY)) {

+            mValidator.getCallback().allow();

+        } else {

+            mValidator.getCallback().dontAllow();

+        }

+    }

+

+    /** Resets request state. */

+    private synchronized void cleanup() {

+        mContext.unbindService(this);

+        mValidator = null;

+    }

+

+    /** Generates a nonce (number used once). */

+    private int generateNonce() {

+        return RANDOM.nextInt();

+    }

+

+    /**

+     * Get version code for the application package name.

+     *

+     * @param context

+     * @param packageName application package name

+     * @return the version code or empty string if package not found

+     */

+    private static String getVersionCode(Context context, String packageName) {

+        try {

+            return String.valueOf(context.getPackageManager().getPackageInfo(packageName, 0).

+                versionCode);

+        } catch (NameNotFoundException e) {

+            Log.e(TAG, "Package not found. could not get version code.");

+            return "";

+        }

+    }

+}

diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/LicenseCheckerCallback.java b/samples/MarketLicensing/src/com/android/vending/licensing/LicenseCheckerCallback.java
new file mode 100755
index 0000000..1567497
--- /dev/null
+++ b/samples/MarketLicensing/src/com/android/vending/licensing/LicenseCheckerCallback.java
@@ -0,0 +1,55 @@
+/*

+ * Copyright (C) 2010 The Android Open Source Project

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+

+package com.android.vending.licensing;

+

+/**

+ * Callback for the license checker library.

+ *

+ * Upon checking with the Market server and conferring with the policy, the

+ * library calls a appropriate callback method to communicate the result.

+ */

+public interface LicenseCheckerCallback {

+

+    /**

+     * Allow use. App should proceed as normal.

+     */

+    public void allow();

+

+    /**

+     * Don't allow use. App should inform user and take appropriate action.

+     */

+    public void dontAllow();

+

+    /** Application error codes. */

+    public enum ApplicationErrorCode {

+        /** Package is not installed. */

+        INVALID_PACKAGE_NAME,

+        /** Requested for a package that is not the current app. */

+        NON_MATCHING_UID,

+        /** Market does not know about the package. */

+        NOT_MARKET_MANAGED,

+        /** A previous check request is already in progress.

+         * Only one check is allowed at a time. */

+        CHECK_IN_PROGRESS

+    }

+

+    /**

+     * Error in application code. Caller did not call or set up license

+     * checker correctly. Should be considered fatal.

+     */

+    public void applicationError(ApplicationErrorCode errorCode);

+}

diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/LicenseValidator.java b/samples/MarketLicensing/src/com/android/vending/licensing/LicenseValidator.java
new file mode 100755
index 0000000..135d98e
--- /dev/null
+++ b/samples/MarketLicensing/src/com/android/vending/licensing/LicenseValidator.java
@@ -0,0 +1,165 @@
+/*

+ * Copyright (C) 2010 The Android Open Source Project

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+

+package com.android.vending.licensing;

+

+import android.util.Log;

+

+import com.android.vending.licensing.LicenseCheckerCallback.ApplicationErrorCode;

+import com.android.vending.licensing.Policy.LicenseResponse;

+

+/**

+ * Contains data related to a licensing request and methods to verify

+ * and process the response.

+ */

+class LicenseValidator {

+    private static final String TAG = "LicenseValidator";

+

+    // Server response codes.

+    private static final int LICENSED = 0x0;

+    private static final int NOT_LICENSED = 0x1;

+    private static final int LICENSED_OLD_KEY = 0x2;

+    private static final int ERROR_NOT_MARKET_MANAGED = 0x3;

+    private static final int ERROR_INVALID_KEYS = 0x4;

+    private static final int ERROR_OVER_QUOTA = 0x5;

+

+    private static final int ERROR_CONTACTING_SERVER = 0x101;

+    private static final int ERROR_INVALID_PACKAGE_NAME = 0x102;

+    private static final int ERROR_NON_MATCHING_UID = 0x103;

+

+    private final Policy mPolicy;

+    private final LicenseCheckerCallback mCallback;

+    private final int mNonce;

+    private final String mPackageName;

+    private final String mVersionCode;

+

+    LicenseValidator(Policy policy, LicenseCheckerCallback callback, int nonce, String packageName,

+        String versionCode) {

+        mPolicy = policy;

+        mCallback = callback;

+        mNonce = nonce;

+        mPackageName = packageName;

+        mVersionCode = versionCode;

+    }

+

+    public LicenseCheckerCallback getCallback() {

+        return mCallback;

+    }

+

+    public int getNonce() {

+        return mNonce;

+    }

+

+    public String getPackageName() {

+        return mPackageName;

+    }

+

+    /**

+     * Verifies the response from server and calls appropriate callback method.

+     *

+     * @param responseCode server response code

+     * @param signedData signed data from server

+     * @param signature server signature

+     */

+    public void verify(int responseCode, String signedData, String signature) {

+        // Parse and validate response.

+        // TODO(jyum): decode data with signature.

+        // TODO(jyum): verify timestamp is within reason. However, relying

+        // on device clock may lead to problems?

+        ResponseData data;

+        try {

+            data = ResponseData.parse(signedData);

+        } catch (IllegalArgumentException e) {

+            Log.e(TAG, "Could not parse response.");

+            handleInvalidResponse();

+            return;

+        }

+

+        if (data.responseCode != responseCode) {

+            Log.e(TAG, "Response codes don't match.");

+            handleInvalidResponse();

+            return;

+        }

+

+        if (data.nonce != mNonce) {

+            Log.e(TAG, "Nonce doesn't match.");

+            handleInvalidResponse();

+            return;

+        }

+

+        if (!data.packageName.equals(mPackageName)) {

+            Log.e(TAG, "Package name doesn't match.");

+            handleInvalidResponse();

+            return;

+        }

+

+        if (!data.versionCode.equals(mVersionCode)) {

+            Log.e(TAG, "Version codes don't match.");

+            handleInvalidResponse();

+            return;

+        }

+

+        switch (responseCode) {

+            case LICENSED:

+            case LICENSED_OLD_KEY:

+                handleResponse(LicenseResponse.LICENSED);

+                break;

+            case NOT_LICENSED:

+                handleResponse(LicenseResponse.NOT_LICENSED);

+                break;

+            case ERROR_CONTACTING_SERVER:

+                handleResponse(LicenseResponse.CLIENT_RETRY);

+                break;

+            case ERROR_INVALID_KEYS:

+            case ERROR_OVER_QUOTA:

+                handleResponse(LicenseResponse.SERVER_RETRY);

+                break;

+            case ERROR_INVALID_PACKAGE_NAME:

+                handleApplicationError(ApplicationErrorCode.INVALID_PACKAGE_NAME);

+                break;

+            case ERROR_NON_MATCHING_UID:

+                handleApplicationError(ApplicationErrorCode.NON_MATCHING_UID);

+                break;

+            case ERROR_NOT_MARKET_MANAGED:

+                handleApplicationError(ApplicationErrorCode.NOT_MARKET_MANAGED);

+                break;

+            default:

+                Log.e(TAG, "Unknown response code for license check.");

+                handleInvalidResponse();

+        }

+    }

+

+    /**

+     * Confers with policy and calls appropriate callback method.

+     *

+     * @param response

+     */

+    private void handleResponse(LicenseResponse response) {

+        if (mPolicy.allowAccess(response)) {

+            mCallback.allow();

+        } else {

+            mCallback.dontAllow();

+        }

+    }

+

+    private void handleApplicationError(ApplicationErrorCode code) {

+        mCallback.applicationError(code);

+    }

+

+    private void handleInvalidResponse() {

+        mCallback.dontAllow();

+    }

+}

diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/Policy.java b/samples/MarketLicensing/src/com/android/vending/licensing/Policy.java
new file mode 100755
index 0000000..461c08e
--- /dev/null
+++ b/samples/MarketLicensing/src/com/android/vending/licensing/Policy.java
@@ -0,0 +1,55 @@
+/*

+ * Copyright (C) 2010 The Android Open Source Project

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+

+package com.android.vending.licensing;

+

+/**

+ * Policy used by {@link LicenseChecker} to determine whether a user should

+ * have access to the application.

+ */

+public interface Policy {

+

+    /**

+     * Result of a license check.

+     */

+    public enum LicenseResponse {

+        /**

+         * User is licensed to use the app.

+         */

+        LICENSED,

+        /**

+         * User is not licensed to use the app.

+         */

+        NOT_LICENSED,

+        /**

+         * Retryable error on the client side e.g. no network.

+         */

+        CLIENT_RETRY,

+        /**

+         * Retryable error on the server side e.g. application is over request

+         * quota.

+         */

+        SERVER_RETRY,

+    }

+

+    /**

+     * Determines whether the user should be allowed access.

+     *

+     * @param response result of the license check request

+     * @return true iff access should be allowed

+     */

+    boolean allowAccess(LicenseResponse response);

+}

diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/ResponseData.java b/samples/MarketLicensing/src/com/android/vending/licensing/ResponseData.java
new file mode 100755
index 0000000..3882d56
--- /dev/null
+++ b/samples/MarketLicensing/src/com/android/vending/licensing/ResponseData.java
@@ -0,0 +1,84 @@
+/*

+ * Copyright (C) 2010 The Android Open Source Project

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+

+package com.android.vending.licensing;

+

+import java.util.Iterator;

+import java.util.regex.Pattern;

+

+import android.text.TextUtils;

+

+/**

+ * ResponseData from licensing server.

+ */

+class ResponseData {

+

+    public int responseCode;

+    public int nonce;

+    public String packageName;

+    public String versionCode;

+    public String userId;

+    public long timestamp;

+    /** Response-specific data. */

+    public String extra;

+

+    /**

+     * Parses response string into ResponseData.

+     *

+     * @param responseData response data string

+     * @throws IllegalArgumentException upon parsing error

+     * @return ResponseData object

+     */

+    public static ResponseData parse(String responseData) {

+        // Must parse out main response data and response-specific data.

+        TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(':');

+        splitter.setString(responseData);

+        Iterator<String> it = splitter.iterator();

+        if (!it.hasNext()) {

+            throw new IllegalArgumentException("Blank response.");

+        }

+        final String mainData = it.next();

+

+        // Response-specific (extra) data is optional.

+        String extraData = "";

+        if (it.hasNext()) {

+            extraData = it.next();

+        }

+

+        String [] fields = TextUtils.split(mainData, Pattern.quote("|"));

+        if (fields.length < 5) {

+            throw new IllegalArgumentException("Wrong number of fields.");

+        }

+

+        ResponseData data = new ResponseData();

+        data.extra = extraData;

+        data.responseCode = Integer.parseInt(fields[0]);

+        data.nonce = Integer.parseInt(fields[1]);

+        data.packageName = fields[2];

+        data.versionCode = fields[3];

+        // TODO(jyum): userId is not there yet.

+        // data.userId = fields[4];

+        data.timestamp = Long.parseLong(fields[4]);

+

+        return data;

+    }

+

+    @Override

+    public String toString() {

+        return TextUtils.join("|", new Object [] { responseCode, nonce, packageName, versionCode,

+            userId, timestamp });

+    }

+}

diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/StrictPolicy.java b/samples/MarketLicensing/src/com/android/vending/licensing/StrictPolicy.java
new file mode 100755
index 0000000..ddff8e9
--- /dev/null
+++ b/samples/MarketLicensing/src/com/android/vending/licensing/StrictPolicy.java
@@ -0,0 +1,30 @@
+/*

+ * Copyright (C) 2010 The Android Open Source Project

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+

+package com.android.vending.licensing;

+

+/**

+ * Strict policy.

+ *

+ * Should never be used in a real application as it strictly disallows access

+ * upon retryable errors such as no connection present.

+ */

+public class StrictPolicy implements Policy {

+

+    public boolean allowAccess(LicenseResponse response) {

+        return LicenseResponse.LICENSED == response;

+    }

+}

diff --git a/testrunner/test_defs.xml b/testrunner/test_defs.xml
index ad2017c..68a62e4 100644
--- a/testrunner/test_defs.xml
+++ b/testrunner/test_defs.xml
@@ -191,7 +191,7 @@
 <test name="cts-content"
     build_path="cts/tests/tests/content"
     package="com.android.cts.content"
-    runner="android.test.InstrumentationCtsTestRunner"
+    runner="android.test.InstrumentationTestRunner"
     coverage_target="framework"
     cts="true" />