From 6eb14f01bb5681ad95031860a73eae13951c6d83 Mon Sep 17 00:00:00 2001 From: Pengquan Meng Date: Thu, 29 Mar 2018 11:27:22 -0700 Subject: [PATCH] Add apn data structure This add a data structure to store the apn data locally. Test: unit test Bug: 73745458 Bug: 67327863 Merged-In: Iae56583ab1c99f57154461c71a10b74db87ab1bd Change-Id: Iae56583ab1c99f57154461c71a10b74db87ab1bd (cherry picked from commit ee25956f573efcbbb6e1968ff4cdfe24c65e1bb4) --- src/com/android/settings/ApnEditor.java | 87 ++++++++++++++- .../src/com/android/settings/ApnEditorTest.java | 117 +++++++++++++++++++++ 2 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 tests/robotests/src/com/android/settings/ApnEditorTest.java diff --git a/src/com/android/settings/ApnEditor.java b/src/com/android/settings/ApnEditor.java index edf241d09a..fbc4ba9212 100644 --- a/src/com/android/settings/ApnEditor.java +++ b/src/com/android/settings/ApnEditor.java @@ -47,12 +47,12 @@ import android.view.MenuItem; import android.view.View; import android.view.View.OnKeyListener; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.internal.telephony.PhoneConstants; import com.android.internal.util.ArrayUtils; -import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -61,6 +61,9 @@ import java.util.Set; import static android.app.Activity.RESULT_OK; import static android.content.Context.TELEPHONY_SERVICE; +/** + * TODO: After loading all changes, please move this to network package. + */ public class ApnEditor extends SettingsPreferenceFragment implements OnPreferenceChangeListener, OnKeyListener { @@ -1188,4 +1191,86 @@ public class ApnEditor extends SettingsPreferenceFragment } } + public static class InvalidTypeException extends RuntimeException { + InvalidTypeException(String msg) { + super(msg); + } + } + + @VisibleForTesting + static class ApnData { + /** + * The uri correspond to a database row of the apn data. This should be null if the apn + * is not in the database. + */ + Uri mUri; + + /** Each element correspond to a column of the database row. */ + Object[] mData; + + ApnData(int numberOfField) { + mData = new Object[numberOfField]; + } + + ApnData(Uri uri, Cursor cursor) { + mUri = uri; + mData = new Object[cursor.getColumnCount()]; + for (int i = 0; i < mData.length; i++) { + switch (cursor.getType(i)) { + case Cursor.FIELD_TYPE_FLOAT: + mData[i] = cursor.getFloat(i); + break; + case Cursor.FIELD_TYPE_INTEGER: + mData[i] = cursor.getInt(i); + break; + case Cursor.FIELD_TYPE_STRING: + mData[i] = cursor.getString(i); + break; + case Cursor.FIELD_TYPE_BLOB: + mData[i] = cursor.getBlob(i); + break; + default: + mData[i] = null; + } + } + } + + Uri getUri() { + return mUri; + } + + void setUri(Uri uri) { + mUri = uri; + } + + Integer getInteger(int index) throws InvalidTypeException { + if (!isValidTypeOrNull(mData[index], Integer.class)) { + throwInvalidTypeException(Integer.class, mData[index].getClass()); + } + return (Integer) mData[index]; + } + + Integer getInteger(int index, Integer defaultValue) throws InvalidTypeException { + Integer val = getInteger(index); + return val == null ? defaultValue : val; + } + + String getString(int index) throws InvalidTypeException { + if (!isValidTypeOrNull(mData[index], String.class)) { + throwInvalidTypeException(String.class, mData[index].getClass()); + } + return (String) mData[index]; + } + + private boolean isValidTypeOrNull(Object obj, Class expectedClass) { + return obj == null || expectedClass.isInstance(obj); + } + + private void throwInvalidTypeException(Class expectedClass, Class actualClass) { + throw new InvalidTypeException( + String.format( + "Type mismatched, want %s, but is %s", expectedClass, actualClass)); + } + } + } diff --git a/tests/robotests/src/com/android/settings/ApnEditorTest.java b/tests/robotests/src/com/android/settings/ApnEditorTest.java new file mode 100644 index 0000000000..eb9955adb3 --- /dev/null +++ b/tests/robotests/src/com/android/settings/ApnEditorTest.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2018 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.settings; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNull; + +import static org.mockito.Mockito.doReturn; + +import android.database.Cursor; +import android.net.Uri; + +import com.android.settings.ApnEditor.ApnData; +import com.android.settings.ApnEditor.InvalidTypeException; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@RunWith(SettingsRobolectricTestRunner.class) +public class ApnEditorTest { + + private static final int CURSOR_INTEGER_INDEX = 0; + private static final int CURSOR_STRING_INDEX = 1; + + private static final Uri mApnUri = Uri.parse("Apn://row/1"); + + @Mock + private Cursor mCursor; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + initCursor(); + } + + private void initCursor() { + doReturn(2).when(mCursor).getColumnCount(); + doReturn(Integer.valueOf(2)).when(mCursor).getInt(CURSOR_INTEGER_INDEX); + doReturn("str").when(mCursor).getString(CURSOR_STRING_INDEX); + doReturn(Cursor.FIELD_TYPE_INTEGER).when(mCursor).getType(CURSOR_INTEGER_INDEX); + doReturn(Cursor.FIELD_TYPE_STRING).when(mCursor).getType(CURSOR_STRING_INDEX); + } + + @Test(expected = InvalidTypeException.class) + public void testApnData_invalidIntegerType_throwsInvalidTypeException() { + // GIVEN a ApnData constructed from cursor + ApnData data = new ApnData(mApnUri, mCursor); + + // WHEN get a string from an integer column + // THEN the InvalidTypeException is threw + data.getString(CURSOR_INTEGER_INDEX); + } + + @Test(expected = InvalidTypeException.class) + public void testApnData_invalidStringType_throwsInvalidTypeException() { + // GIVEN a ApnData constructed from cursor + ApnData data = new ApnData(mApnUri, mCursor); + + // WHEN get a integer from a string column + // THEN the InvalidTypeException is threw + data.getInteger(CURSOR_STRING_INDEX); + } + + @Test + public void testApnData_validIntegerType_returnCorrectValue() { + // GIVEN a ApnData constructed from cursor + ApnData data = new ApnData(mApnUri, mCursor); + + // WHEN get integer from an integer column + int val = data.getInteger(CURSOR_INTEGER_INDEX); + + // THEN the integer is returned correctly + assertEquals(mCursor.getInt(CURSOR_INTEGER_INDEX), val); + } + + @Test + public void testApnData_validStringType_returnCorrectValue() { + // GIVEN a ApnData constructed from cursor + ApnData data = new ApnData(mApnUri, mCursor); + + // WHEN get string from a string column + String str = data.getString(CURSOR_STRING_INDEX); + + // THEN the integer is returned correctly + assertEquals(mCursor.getString(CURSOR_STRING_INDEX), str); + } + + @Test + public void testApnData_nullValueColumn_returnNull() { + // GIVEN a empty ApnData + ApnData data = new ApnData(3); + + // WHEN get string value from a null column + String str = data.getString(0); + + // THEN the null value is returned + assertNull(str); + } +} -- 2.11.0