Updated CTS test for Android Security b/143559931

Bug: 143559931
Bug: 202759784
Test: Ran the new testcase on android-10.0.0_r41 to test with/without patch
Change-Id: I7e261dbb566531e23cb46dc24f9986021219433b
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java
index 12287b0..95c90d4 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -16,43 +16,39 @@
 
 package android.security.cts;
 
-import android.platform.test.annotations.AppModeFull;
+import static org.junit.Assume.assumeNoException;
+
 import android.platform.test.annotations.AsbSecurityTest;
 
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 
-import org.junit.Assert;
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class CVE_2021_0954 extends StsExtraBusinessLogicHostTestBase {
-    private static final String TEST_PKG = "android.security.cts.cve_2021_0954";
-    private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
-    private static final String TEST_APP = "CVE-2021-0954.apk";
-    private ITestDevice device;
+    private static final String TEST_PKG = "android.security.cts.CVE_2021_0954";
 
-    @Before
-    public void setUp() throws Exception {
-        device = getDevice();
-        uninstallPackage(device, TEST_PKG);
-
-        /* Wake up the screen */
-        AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
-        AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
-        AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
-    }
-
-    @AppModeFull
     @AsbSecurityTest(cveBugId = 143559931)
     @Test
     public void testPocCVE_2021_0954() throws Exception {
-        installPackage(TEST_APP);
-        AdbUtils.runCommandLine("pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW",
-                device);
-        runDeviceTests(TEST_PKG, TEST_CLASS, "testVulnerableActivityPresence");
+        try {
+            ITestDevice device = getDevice();
+            uninstallPackage(device, TEST_PKG);
+
+            /* Wake up the screen */
+            AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+            AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+            AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+            installPackage("CVE-2021-0954.apk");
+            AdbUtils.runCommandLine(
+                    "pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW", device);
+            runDeviceTests(TEST_PKG, TEST_PKG + "." + "DeviceTest", "testOverlayButtonPresence");
+        } catch (Exception e) {
+            assumeNoException(e);
+        }
     }
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp
index aa9f71f..59350cf 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -18,10 +18,10 @@
 android_test_helper_app {
     name: "CVE-2021-0954",
     defaults: ["cts_support_defaults"],
-    srcs: ["src/**/*.java"],
+    srcs: [
+        "src/**/*.java"
+    ],
     test_suites: [
-        "cts",
-        "vts10",
         "sts",
     ],
     static_libs: [
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml
index a7e0218..75299c4 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2021 The Android Open Source Project
+  Copyright 2022 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.
@@ -13,25 +13,19 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
+
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
-    package="android.security.cts.cve_2021_0954"
+    package="android.security.cts.CVE_2021_0954"
     android:versionCode="1"
     android:versionName="1.0">
-
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
-
-    <application
-        android:allowBackup="true"
-        android:label="CVE_2021_0954"
-        android:supportsRtl="true">
-        <uses-library android:name="android.test.runner" />
+    <application>
         <service android:name=".PocService"
             android:enabled="true"
-            android:exported="false" />
+            android:exported="true" />
     </application>
-
    <instrumentation
         android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="android.security.cts.cve_2021_0954" />
+        android:targetPackage="android.security.cts.CVE_2021_0954" />
 </manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml
new file mode 100644
index 0000000..363df00
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2022 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.
+  -->
+
+<resources>
+    <integer name="assumptionFailure">-1</integer>
+    <integer name="noAssumptionFailure">0</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml
new file mode 100644
index 0000000..7c4d959
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 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.
+-->
+
+<resources>
+    <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string>
+    <string name="defaultSemaphoreMsg">Could not get message key in shared preferences</string>
+    <string name="cmdDumpsysActivity">dumpsys activity %1$s</string>
+    <string name="empty"></string>
+    <string name="overlayErrorMessage">Device is vulnerable to b/143559931 hence any app with
+    "SYSTEM_ALERT_WINDOW can overlay the %1$s screen</string>
+    <string name="mResumedTrue">mResumed=true</string>
+    <string name="messageKey">message</string>
+    <string name="overlayButtonText">OverlayButton</string>
+    <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+    <string name="resultKey">result</string>
+    <string name="sharedPreferences">CVE_2021_0954_prefs</string>
+    <string name="timedOutPocActivity">Timed out waiting on a result from PocActivity</string>
+    <string name="vulClass">com.android.internal.app.ResolverActivity</string>
+    <string name="vulClassAuto">com.android.car.activityresolver.CarResolverActivity</string>
+    <string name="vulPkg">android</string>
+    <string name="vulPkgAuto">com.android.car.activityresolver</string>
+    <string name="vulActivityNotRunningError">The %1$s is not currently running on the device
+    </string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java
index f986906..9a94ef9 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,17 +14,20 @@
  * limitations under the License.
  */
 
-package android.security.cts.cve_2021_0954;
+package android.security.cts.CVE_2021_0954;
 
 import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assume.assumeNoException;
 
-import android.content.ActivityNotFoundException;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
 import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.pm.PackageManager;
 import android.provider.Settings;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -32,90 +35,107 @@
 import androidx.test.uiautomator.UiDevice;
 import androidx.test.uiautomator.Until;
 
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.io.IOException;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
 import java.util.regex.Pattern;
 
 @RunWith(AndroidJUnit4.class)
 public class DeviceTest {
-    private static final String TEST_PKG = "android.security.cts.cve_2021_0954";
-    private static final String TEST_VULNERABLE_PKG = "android";
-    private static final String TEST_VULNERABLE_ACTIVITY =
-            "com.android.internal.app.ResolverActivity";
-    private static final int LAUNCH_TIMEOUT_MS = 20000;
-    private static final String vulnerableActivityName = "ResolverActivity";
-    private UiDevice mDevice;
-    String activityDump = "";
+    private Context mContext = getApplicationContext();
+    private static final int TIMEOUT_MS = 10000;
 
-    private void startOverlayService() {
-        Context context = getApplicationContext();
-        assertNotNull(context);
-        Intent intent = new Intent(context, PocService.class);
-        assertNotNull(intent);
-
-        if (Settings.canDrawOverlays(getApplicationContext())) {
-            context.startService(intent);
-        } else {
-            try {
-                context.startService(intent);
-            } catch (Exception e) {
-                throw new RuntimeException("Unable to start the overlay service", e);
-            }
-        }
+    private boolean hasFeature(String feature) {
+        return mContext.getPackageManager().hasSystemFeature(feature);
     }
 
-    public void startVulnerableActivity() {
-        Context context = getApplicationContext();
-        Intent intent = new Intent();
-        intent.setClassName(TEST_VULNERABLE_PKG, TEST_VULNERABLE_ACTIVITY);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        try {
-            context.startActivity(intent);
-        } catch (ActivityNotFoundException e) {
-            assumeNoException("Activity not found on device", e);
-        }
+    private boolean isAuto() {
+        return hasFeature(PackageManager.FEATURE_AUTOMOTIVE);
     }
 
-    @Before
-    public void setUp() throws Exception {
-        mDevice = UiDevice.getInstance(getInstrumentation());
+    String getStringRes(int key) {
+        return mContext.getResources().getString(key);
+    }
 
-        /* Start the vulnerable activity */
-        startVulnerableActivity();
-        if (!mDevice.wait(Until.hasObject(By.res("android:id/contentPanel")
-                .clazz("android.widget.ScrollView").pkg("android")), LAUNCH_TIMEOUT_MS)) {
-            return;
-        }
+    String getStringResWithArg(int key, String arg) {
+        return mContext.getResources().getString(key, arg);
+    }
 
-        /* Start the overlay service */
-        startOverlayService();
+    int getIntegerRes(int key) {
+        return mContext.getResources().getInteger(key);
     }
 
     @Test
-    public void testVulnerableActivityPresence() {
-        Pattern overlayTextPattern = Pattern.compile("OverlayButton", Pattern.CASE_INSENSITIVE);
-        if (!mDevice.wait(Until.hasObject(By.text(overlayTextPattern)), LAUNCH_TIMEOUT_MS)) {
-            return;
-        }
-
-        /*
-         * Check if the currently running activity is the vulnerable activity, if not abort the test
-         */
+    public void testOverlayButtonPresence() {
         try {
-            activityDump = mDevice.executeShellCommand("dumpsys activity");
-        } catch (IOException e) {
-            throw new RuntimeException("Could not execute dumpsys activity command");
+            UiDevice device = UiDevice.getInstance(getInstrumentation());
+
+            /* Start the overlay service */
+            assumeTrue(getStringRes(R.string.canNotDrawOverlaysMsg),
+                    Settings.canDrawOverlays(mContext));
+            Intent intent = new Intent(mContext, PocService.class);
+            mContext.startService(intent);
+
+            /* Wait for a result from overlay service */
+            SharedPreferences sharedPrefs = mContext.getSharedPreferences(
+                    getStringRes(R.string.sharedPreferences), Context.MODE_PRIVATE);
+            final Semaphore preferenceChanged = new Semaphore(0);
+            OnSharedPreferenceChangeListener listener = new OnSharedPreferenceChangeListener() {
+                @Override
+                public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+                        String key) {
+                    if (key.equals(getStringRes(R.string.resultKey))) {
+                        preferenceChanged.release();
+                    }
+                }
+            };
+            sharedPrefs.registerOnSharedPreferenceChangeListener(listener);
+            assumeTrue(preferenceChanged.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            int result = sharedPrefs.getInt(getStringRes(R.string.resultKey),
+                    getIntegerRes(R.integer.assumptionFailure));
+            String message = sharedPrefs.getString(getStringRes(R.string.messageKey),
+                    getStringRes(R.string.defaultSemaphoreMsg));
+            assumeTrue(message, result != getIntegerRes(R.integer.assumptionFailure));
+
+            /* Wait for the UI of overlay window to appear */
+            Pattern overlayTextPattern = Pattern.compile(
+                    mContext.getString(R.string.overlayButtonText), Pattern.CASE_INSENSITIVE);
+            assumeTrue(mContext.getString(R.string.overlayUiScreenError),
+                    device.wait(Until.hasObject(By.text(overlayTextPattern)), TIMEOUT_MS));
+
+            /* Start the vulnerable activity */
+            intent = new Intent();
+            String vulActivity = getStringRes(R.string.vulClass);
+            String vulPkg = getStringRes(R.string.vulPkg);
+            if (isAuto()) {
+                vulActivity = getStringRes(R.string.vulClassAuto);
+                vulPkg = getStringRes(R.string.vulPkgAuto);
+            }
+            intent.setClassName(vulPkg, vulActivity);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            mContext.startActivity(intent);
+
+            /* Wait until the object of overlay window is gone */
+            boolean overlayDisallowed =
+                    device.wait(Until.gone(By.pkg(mContext.getPackageName())), TIMEOUT_MS);
+
+            /*
+             * Check if the currently running activity is the vulnerable activity, if not abort the
+             * test
+             */
+            String activityDump = device.executeShellCommand(
+                    getStringResWithArg(R.string.cmdDumpsysActivity, vulActivity));
+            Pattern activityPattern = Pattern.compile(getStringRes(R.string.mResumedTrue));
+            assumeTrue(getStringRes(R.string.vulActivityNotRunningError),
+                    activityPattern.matcher(activityDump).find());
+
+            /* Failing the test as fix is not present */
+            assertTrue(getStringResWithArg(R.string.overlayErrorMessage, vulActivity),
+                    overlayDisallowed);
+        } catch (Exception e) {
+            assumeNoException(e);
         }
-        Pattern activityPattern =
-                Pattern.compile("mResumedActivity.*" + vulnerableActivityName + ".*\n");
-        if (!activityPattern.matcher(activityDump).find()) {
-            return;
-        }
-        String message = "Device is vulnerable to b/143559931 hence any app with "
-                + "SYSTEM_ALERT_WINDOW can overlay the ResolverActivity screen";
-        assertNull(message, mDevice.findObject(By.text(overlayTextPattern)));
     }
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java
index 82b78a2..79270ba 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,47 +14,65 @@
  * limitations under the License.
  */
 
-package android.security.cts.cve_2021_0954;
+package android.security.cts.CVE_2021_0954;
 
 import android.app.Service;
+import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.content.res.Resources;
 import android.graphics.PixelFormat;
-import android.os.Handler;
 import android.os.IBinder;
-import android.provider.Settings;
 import android.view.Gravity;
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
 import android.widget.Button;
 
 public class PocService extends Service {
-    public static Button mButton;
-    private WindowManager mWindowManager;
-    private WindowManager.LayoutParams mLayoutParams;
+    Button mButton;
+    WindowManager mWindowManager;
 
-    private static int getScreenWidth() {
+    private int getScreenWidth() {
         return Resources.getSystem().getDisplayMetrics().widthPixels;
     }
 
-    private static int getScreenHeight() {
+    private int getScreenHeight() {
         return Resources.getSystem().getDisplayMetrics().heightPixels;
     }
 
+    String getStringRes(int key) {
+        return getResources().getString(key);
+    }
+
+    int getIntegerRes(int key) {
+        return getResources().getInteger(key);
+    }
+
     @Override
     public void onCreate() {
-        super.onCreate();
-        mWindowManager = getSystemService(WindowManager.class);
-        mLayoutParams = new WindowManager.LayoutParams();
-        mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-        mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-        mLayoutParams.format = PixelFormat.OPAQUE;
-        mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
-        mLayoutParams.width = getScreenWidth();
-        mLayoutParams.height = getScreenHeight();
-        mLayoutParams.x = getScreenWidth() / 2;
-        mLayoutParams.y = getScreenHeight() / 2;
+        try {
+            super.onCreate();
+            mWindowManager = getSystemService(WindowManager.class);
+            LayoutParams layoutParams = new LayoutParams();
+            layoutParams.type = LayoutParams.TYPE_APPLICATION_OVERLAY;
+            layoutParams.flags =
+                    LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE;
+            layoutParams.format = PixelFormat.OPAQUE;
+            layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
+            layoutParams.width = getScreenWidth();
+            layoutParams.height = getScreenHeight();
+            layoutParams.x = getScreenWidth() / 2;
+            layoutParams.y = getScreenHeight() / 2;
+
+            /* Show the floating window */
+            mButton = new Button(this);
+            mButton.setText(getString(R.string.overlayButtonText));
+            mWindowManager.addView(mButton, layoutParams);
+        } catch (Exception e) {
+            sendTestResult(getIntegerRes(R.integer.assumptionFailure), e.getMessage());
+            return;
+        }
+        sendTestResult(getIntegerRes(R.integer.noAssumptionFailure), getStringRes(R.string.empty));
     }
 
     @Override
@@ -63,31 +81,27 @@
     }
 
     @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        showFloatingWindow();
-        return super.onStartCommand(intent, flags, startId);
-    }
-
-    @Override
     public void onDestroy() {
-        if (mWindowManager != null && mButton != null) {
-            mWindowManager.removeView(mButton);
+        try {
+            if (mWindowManager != null && mButton != null) {
+                mWindowManager.removeView(mButton);
+            }
+            super.onDestroy();
+        } catch (Exception e) {
+            sendTestResult(getIntegerRes(R.integer.assumptionFailure), e.getMessage());
         }
-        super.onDestroy();
     }
 
-    private void showFloatingWindow() {
-        if (Settings.canDrawOverlays(this)) {
-            mButton = new Button(getApplicationContext());
-            mButton.setText("OverlayButton");
-            mWindowManager.addView(mButton, mLayoutParams);
-            new Handler().postDelayed(new Runnable() {
-                @Override
-                public void run() {
-                    onDestroy();
-                }
-            }, 60000); // one minute
-            mButton.setTag(mButton.getVisibility());
+    private void sendTestResult(int result, String message) {
+        try {
+            SharedPreferences sh = getSharedPreferences(getStringRes(R.string.sharedPreferences),
+                    Context.MODE_PRIVATE);
+            SharedPreferences.Editor edit = sh.edit();
+            edit.putInt(getStringRes(R.string.resultKey), result);
+            edit.putString(getStringRes(R.string.messageKey), message);
+            edit.commit();
+        } catch (Exception e) {
+            // ignore the exception
         }
     }
 }