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" />