make APIs in SettingsToPropertiesMapper accessible from other package

1. make SettingsToPropertiesMapper public but @hidden so that rescue
party can access APIs here
2. make these APIs public static so that it's easier for rescue party to
use
3. move SettingsToPropertiesMapperTest to services/tests/mockingservicestests/
so that we can use ExtendedMockito to mock static method.

Test: Manually on device by calling APIs from RescueParty
Change-Id: I06f0e54a4513d4735214f5013f9523e8c44d4584
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index cbbbe47..894a704 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -38,8 +38,9 @@
 /**
  * Maps system settings to system properties.
  * <p>The properties are dynamically updated when settings change.
+ * @hide
  */
-class SettingsToPropertiesMapper {
+public class SettingsToPropertiesMapper {
 
     private static final String TAG = "SettingsToPropertiesMapper";
 
@@ -156,8 +157,8 @@
      * during current device booting.
      * @return
      */
-    public boolean isNativeFlagsResetPerformed() {
-        String value = systemPropertiesGet(RESET_PERFORMED_PROPERTY);
+    public static boolean isNativeFlagsResetPerformed() {
+        String value = SystemProperties.get(RESET_PERFORMED_PROPERTY);
         return "true".equals(value);
     }
 
@@ -166,7 +167,7 @@
      * booting.
      * @return
      */
-    public String[] getResetNativeCategories() {
+    public static String[] getResetNativeCategories() {
         if (!isNativeFlagsResetPerformed()) {
             return new String[0];
         }
@@ -214,7 +215,7 @@
         if (value == null) {
             // It's impossible to remove system property, therefore we check previous value to
             // avoid setting an empty string if the property wasn't set.
-            if (TextUtils.isEmpty(systemPropertiesGet(key))) {
+            if (TextUtils.isEmpty(SystemProperties.get(key))) {
                 return;
             }
             value = "";
@@ -224,7 +225,7 @@
         }
 
         try {
-            systemPropertiesSet(key, value);
+            SystemProperties.set(key, value);
         } catch (Exception e) {
             // Failure to set a property can be caused by SELinux denial. This usually indicates
             // that the property wasn't whitelisted in sepolicy.
@@ -250,17 +251,7 @@
     }
 
     @VisibleForTesting
-    protected String systemPropertiesGet(String key) {
-        return SystemProperties.get(key);
-    }
-
-    @VisibleForTesting
-    protected void systemPropertiesSet(String key, String value) {
-        SystemProperties.set(key, value);
-    }
-
-    @VisibleForTesting
-    protected String getResetFlagsFileContent() {
+    static String getResetFlagsFileContent() {
         String content = null;
         try {
             File reset_flag_file = new File(RESET_RECORD_FILE_PATH);
@@ -279,4 +270,4 @@
         String settingValue = Settings.Global.getString(mContentResolver, settingName);
         setProperty(propName, settingValue);
     }
-}
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/am/SettingsToPropertiesMapperTest.java b/services/tests/mockingservicestests/src/com/android/server/am/SettingsToPropertiesMapperTest.java
similarity index 60%
rename from services/tests/servicestests/src/com/android/server/am/SettingsToPropertiesMapperTest.java
rename to services/tests/mockingservicestests/src/com/android/server/am/SettingsToPropertiesMapperTest.java
index 0fd5921..5db8867 100644
--- a/services/tests/servicestests/src/com/android/server/am/SettingsToPropertiesMapperTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/SettingsToPropertiesMapperTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 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,52 +16,98 @@
 
 package com.android.server.am;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyString;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+
 import android.content.ContentResolver;
+import android.os.SystemProperties;
 import android.provider.Settings;
-import android.test.mock.MockContentResolver;
 import android.text.TextUtils;
 
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
 
-import com.android.internal.util.Preconditions;
-import com.android.internal.util.test.FakeSettingsProvider;
-
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+import org.mockito.stubbing.Answer;
 
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 
 /**
- * Tests for {@link SettingsToPropertiesMapper}
- *
- *  Build/Install/Run:
- *  atest FrameworksServicesTests:SettingsToPropertiesMapperTest
+ * Test SettingsToPropertiesMapper.
  */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
 public class SettingsToPropertiesMapperTest {
     private static final String NAME_VALID_CHARACTERS_REGEX = "^[\\w\\-@:]*$";
     private static final String[] TEST_MAPPING = new String[] {
             Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS
     };
 
-    private TestMapper mTestMapper;
-    private MockContentResolver mMockContentResolver;
+    private MockitoSession mSession;
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private ContentResolver mMockContentResolver;
+
+    private SettingsToPropertiesMapper mTestMapper;
+
+    private HashMap<String, String> mSystemSettingsMap;
+    private HashMap<String, String> mGlobalSettingsMap;
 
     @Before
-    public void setupForEach() {
-        // Use FakeSettingsProvider to not affect global state
-        mMockContentResolver = new MockContentResolver(InstrumentationRegistry.getContext());
-        mMockContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
-        mTestMapper = new TestMapper(mMockContentResolver);
+    public void setUp() throws Exception {
+        mSession =
+                ExtendedMockito.mockitoSession().initMocks(
+                        this)
+                        .strictness(Strictness.LENIENT)
+                        .spyStatic(SystemProperties.class)
+                        .spyStatic(Settings.Global.class)
+                        .spyStatic(SettingsToPropertiesMapper.class)
+                        .startMocking();
+        mSystemSettingsMap = new HashMap<>();
+        mGlobalSettingsMap = new HashMap<>();
+
+        // Mock SystemProperties setter and various getters
+        doAnswer((Answer<Void>) invocationOnMock -> {
+                    String key = invocationOnMock.getArgument(0);
+                    String value = invocationOnMock.getArgument(1);
+
+                    mSystemSettingsMap.put(key, value);
+                    return null;
+                }
+        ).when(() -> SystemProperties.set(anyString(), anyString()));
+
+        doAnswer((Answer<String>) invocationOnMock -> {
+                    String key = invocationOnMock.getArgument(0);
+
+                    String storedValue = mSystemSettingsMap.get(key);
+                    return storedValue == null ? "" : storedValue;
+                }
+        ).when(() -> SystemProperties.get(anyString()));
+
+        // Mock Settings.Global methods
+        doAnswer((Answer<String>) invocationOnMock -> {
+                    String key = invocationOnMock.getArgument(1);
+
+                    return mGlobalSettingsMap.get(key);
+                }
+        ).when(() -> Settings.Global.getString(any(), anyString()));
+
+        mTestMapper = new SettingsToPropertiesMapper(
+            mMockContentResolver, TEST_MAPPING, new String[] {});
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mSession.finishMocking();
     }
 
     @Test
@@ -108,30 +154,27 @@
 
     @Test
     public void testUpdatePropertiesFromSettings() {
-        Settings.Global.putString(mMockContentResolver,
-                Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS, "testValue");
+        mGlobalSettingsMap.put(Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS, "testValue");
 
         String systemPropertyName = "persist.device_config.global_settings."
                 + "sqlite_compatibility_wal_flags";
 
         mTestMapper.updatePropertiesFromSettings();
-        String propValue = mTestMapper.systemPropertiesGet(systemPropertyName);
+        String propValue = mSystemSettingsMap.get(systemPropertyName);
         Assert.assertEquals("testValue", propValue);
 
-        Settings.Global.putString(mMockContentResolver,
-                Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS, "testValue2");
+        mGlobalSettingsMap.put(Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS, "testValue2");
         mTestMapper.updatePropertyFromSetting(
                 Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS,
                 systemPropertyName);
-        propValue = mTestMapper.systemPropertiesGet(systemPropertyName);
+        propValue = mSystemSettingsMap.get(systemPropertyName);
         Assert.assertEquals("testValue2", propValue);
 
-        Settings.Global.putString(mMockContentResolver,
-                Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS, null);
+        mGlobalSettingsMap.put(Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS, null);
         mTestMapper.updatePropertyFromSetting(
                 Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS,
                 systemPropertyName);
-        propValue = mTestMapper.systemPropertiesGet(systemPropertyName);
+        propValue = mSystemSettingsMap.get(systemPropertyName);
         Assert.assertEquals("", propValue);
     }
 
@@ -163,71 +206,37 @@
     public void testUpdatePropertiesFromSettings_PropertyAndSettingNotPresent() {
         // Test that empty property will not not be set if setting is not set
         mTestMapper.updatePropertiesFromSettings();
-        String propValue = mTestMapper.systemPropertiesGet("TestProperty");
+        String propValue = mSystemSettingsMap.get("TestProperty");
         Assert.assertNull("Property should not be set if setting is null", propValue);
     }
 
     @Test
     public void testIsNativeFlagsResetPerformed() {
-        mTestMapper.systemPropertiesSet("device_config.reset_performed", "true");
+        mSystemSettingsMap.put("device_config.reset_performed", "true");
         Assert.assertTrue(mTestMapper.isNativeFlagsResetPerformed());
 
-        mTestMapper.systemPropertiesSet("device_config.reset_performed", "false");
+        mSystemSettingsMap.put("device_config.reset_performed", "false");
         Assert.assertFalse(mTestMapper.isNativeFlagsResetPerformed());
 
-        mTestMapper.systemPropertiesSet("device_config.reset_performed", "");
+        mSystemSettingsMap.put("device_config.reset_performed", "");
         Assert.assertFalse(mTestMapper.isNativeFlagsResetPerformed());
     }
 
     @Test
     public void testGetResetNativeCategories() {
-        mTestMapper.systemPropertiesSet("device_config.reset_performed", "");
-        Assert.assertEquals(mTestMapper.getResetNativeCategories().length, 0);
-
-        mTestMapper.systemPropertiesSet("device_config.reset_performed", "true");
-        mTestMapper.setFileContent("");
-        Assert.assertEquals(mTestMapper.getResetNativeCategories().length, 0);
-
-        mTestMapper.systemPropertiesSet("device_config.reset_performed", "true");
-        mTestMapper.setFileContent("persist.device_config.category1.flag;"
+        doReturn("persist.device_config.category1.flag;"
                 + "persist.device_config.category2.flag;persist.device_config.category3.flag;"
-                + "persist.device_config.category3.flag2");
+                + "persist.device_config.category3.flag2")
+            .when(() -> SettingsToPropertiesMapper.getResetFlagsFileContent());
+
+        mSystemSettingsMap.put("device_config.reset_performed", "");
+        Assert.assertEquals(mTestMapper.getResetNativeCategories().length, 0);
+
+        mSystemSettingsMap.put("device_config.reset_performed", "true");
         List<String> categories = Arrays.asList(mTestMapper.getResetNativeCategories());
         Assert.assertEquals(3, categories.size());
         Assert.assertTrue(categories.contains("category1"));
         Assert.assertTrue(categories.contains("category2"));
         Assert.assertTrue(categories.contains("category3"));
     }
-
-    private static class TestMapper extends SettingsToPropertiesMapper {
-        private final Map<String, String> mProps = new HashMap<>();
-
-        private String mFileContent = "";
-
-        TestMapper(ContentResolver contentResolver) {
-            super(contentResolver, TEST_MAPPING, new String[] {});
-        }
-
-        @Override
-        protected String systemPropertiesGet(String key) {
-            Preconditions.checkNotNull(key);
-            return mProps.get(key);
-        }
-
-        @Override
-        protected void systemPropertiesSet(String key, String value) {
-            Preconditions.checkNotNull(value);
-            Preconditions.checkNotNull(key);
-            mProps.put(key, value);
-        }
-
-        protected void setFileContent(String fileContent) {
-            mFileContent = fileContent;
-        }
-
-        @Override
-        protected String getResetFlagsFileContent() {
-            return mFileContent;
-        }
-    }
 }