From 1bc7ac3bfae5071950ee75fecfa7e958fb608d1b Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Tue, 20 Jun 2017 14:53:49 -0700 Subject: [PATCH] Load regulatory info from /data/misc Bug: 62837579 Test: settings test Change-Id: I84ef037174a1839993d02e8cd46d159398be1ddc --- .../settings/RegulatoryInfoDisplayActivity.java | 49 ++++++++++++-- .../RegulatoryInfoDisplayActivityTest.java | 75 ++++++++++++++++++++-- 2 files changed, 113 insertions(+), 11 deletions(-) diff --git a/src/com/android/settings/RegulatoryInfoDisplayActivity.java b/src/com/android/settings/RegulatoryInfoDisplayActivity.java index fd94b677f9..043071c9ed 100644 --- a/src/com/android/settings/RegulatoryInfoDisplayActivity.java +++ b/src/com/android/settings/RegulatoryInfoDisplayActivity.java @@ -20,15 +20,20 @@ import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.SystemProperties; +import android.support.annotation.VisibleForTesting; import android.text.TextUtils; import android.view.Gravity; import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import java.util.Locale; + /** * {@link Activity} that displays regulatory information for the "Regulatory information" * preference item, and when "*#07#" is dialed on the Phone keypad. To enable this feature, @@ -41,7 +46,12 @@ import android.widget.TextView; */ public class RegulatoryInfoDisplayActivity extends Activity implements DialogInterface.OnDismissListener { + private final String REGULATORY_INFO_RESOURCE = "regulatory_info"; + private static final String DEFAULT_REGULATORY_INFO_FILEPATH = + "/data/misc/elabel/regulatory_info.png"; + private static final String REGULATORY_INFO_FILEPATH_TEMPLATE = + "/data/misc/elabel/regulatory_info_%s.png"; /** * Display the regulatory info graphic in a dialog window. @@ -60,7 +70,18 @@ public class RegulatoryInfoDisplayActivity extends Activity implements .setOnDismissListener(this); boolean regulatoryInfoDrawableExists = false; - int resId = getResourceId(); + + final String regulatoryInfoFile = getRegulatoryInfoImageFileName(); + final Bitmap regulatoryInfoBitmap = BitmapFactory.decodeFile(regulatoryInfoFile); + + if (regulatoryInfoBitmap != null) { + regulatoryInfoDrawableExists = true; + } + + int resId = 0; + if (!regulatoryInfoDrawableExists) { + resId = getResourceId(); + } if (resId != 0) { try { Drawable d = getDrawable(resId); @@ -77,8 +98,12 @@ public class RegulatoryInfoDisplayActivity extends Activity implements if (regulatoryInfoDrawableExists) { View view = getLayoutInflater().inflate(R.layout.regulatory_info, null); - ImageView image = (ImageView) view.findViewById(R.id.regulatoryInfo); - image.setImageResource(resId); + ImageView image = view.findViewById(R.id.regulatoryInfo); + if (regulatoryInfoBitmap != null) { + image.setImageBitmap(regulatoryInfoBitmap); + } else { + image.setImageResource(resId); + } builder.setView(view); builder.show(); } else if (regulatoryText.length() > 0) { @@ -99,7 +124,7 @@ public class RegulatoryInfoDisplayActivity extends Activity implements REGULATORY_INFO_RESOURCE, "drawable", getPackageName()); // When hardware sku property exists, use regulatory_info_ resource if valid. - String sku = SystemProperties.get("ro.boot.hardware.sku", ""); + final String sku = getSku(); if (!TextUtils.isEmpty(sku)) { String regulatory_info_res = REGULATORY_INFO_RESOURCE + "_" + sku.toLowerCase(); int id = getResources().getIdentifier( @@ -115,4 +140,20 @@ public class RegulatoryInfoDisplayActivity extends Activity implements public void onDismiss(DialogInterface dialog) { finish(); // close the activity } + + @VisibleForTesting + public static String getSku() { + return SystemProperties.get("ro.boot.hardware.sku", ""); + } + + @VisibleForTesting + public static String getRegulatoryInfoImageFileName() { + final String sku = getSku(); + if (TextUtils.isEmpty(sku)) { + return DEFAULT_REGULATORY_INFO_FILEPATH; + } else { + return String.format(Locale.US, REGULATORY_INFO_FILEPATH_TEMPLATE, + sku.toLowerCase()); + } + } } diff --git a/tests/unit/src/com/android/settings/RegulatoryInfoDisplayActivityTest.java b/tests/unit/src/com/android/settings/RegulatoryInfoDisplayActivityTest.java index 70087aea49..b1d94d46a1 100644 --- a/tests/unit/src/com/android/settings/RegulatoryInfoDisplayActivityTest.java +++ b/tests/unit/src/com/android/settings/RegulatoryInfoDisplayActivityTest.java @@ -16,35 +16,45 @@ package com.android.settings; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.RootMatchers.isDialog; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static junit.framework.Assert.fail; - import android.app.Instrumentation; +import android.app.UiAutomation; import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; +import android.graphics.Bitmap; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; +import android.util.Log; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.matcher.RootMatchers.isDialog; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static junit.framework.Assert.fail; + @RunWith(AndroidJUnit4.class) @SmallTest public class RegulatoryInfoDisplayActivityTest { + private static final String TAG = "RegulatoryInfoTest"; private Instrumentation mInstrumentation; private Intent mRegulatoryInfoIntent; + private UiAutomation mUiAutomation; @Before public void setUp() { mInstrumentation = InstrumentationRegistry.getInstrumentation(); + mUiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); mRegulatoryInfoIntent = new Intent("android.settings.SHOW_REGULATORY_INFO") .addCategory(Intent.CATEGORY_DEFAULT) .setPackage(mInstrumentation.getTargetContext().getPackageName()); @@ -88,4 +98,55 @@ public class RegulatoryInfoDisplayActivityTest { .check(matches(isDisplayed())); } + @Test + public void launchRegulatoryInfo_withInfoImage_shouldDisplay() throws IOException { + // TODO: Remove "setenforce 0" when selinux rules is updated to give read permission for + // regulatory info. + mUiAutomation.executeShellCommand("setenforce 0"); + + final boolean tempFileCreated = ensureRegulatoryInfoImageExists(); + try { + final Context context = mInstrumentation.getTargetContext(); + final boolean hasRegulatoryInfo = context.getResources() + .getBoolean(R.bool.config_show_regulatory_info); + + if (!hasRegulatoryInfo) { + return; + } + // Launch intent + mInstrumentation.startActivitySync(mRegulatoryInfoIntent); + + onView(withId(R.id.regulatoryInfo)) + .inRoot(isDialog()) + .check(matches(isDisplayed())); + } finally { + if (tempFileCreated) { + final String filename = + RegulatoryInfoDisplayActivity.getRegulatoryInfoImageFileName(); + new File(filename).delete(); + Log.d(TAG, "Deleting temp file " + filename); + } + } + } + + /** + * Ensures regulatory label image exists on disk. + * + * @return true if a test image is created. + */ + private boolean ensureRegulatoryInfoImageExists() throws IOException { + final String filename = RegulatoryInfoDisplayActivity.getRegulatoryInfoImageFileName(); + if (new File(filename).exists()) { + return false; + } + Log.d(TAG, "Creating temp file " + filename); + final Bitmap bitmap = Bitmap.createBitmap(400 /* width */, 400 /* height */, + Bitmap.Config.ARGB_8888); + final FileOutputStream out = new FileOutputStream(filename); + bitmap.compress(Bitmap.CompressFormat.PNG, 100 /* quality */, out); + out.close(); + return true; + } + + } -- 2.11.0