OSDN Git Service

Protect against invalid authority in account sync pref.
authorFan Zhang <zhfan@google.com>
Thu, 5 Apr 2018 21:44:13 +0000 (14:44 -0700)
committerFan Zhang <zhfan@google.com>
Thu, 5 Apr 2018 22:19:51 +0000 (15:19 -0700)
Some apps might contain account synclets with empty authority. Settings
UI should protect against this type of synclets. Otherwise clicking on
these synclets will crash.

(Also removed some strings that are no longer needed)

Change-Id: I364b45fc67679aa287ff1e04e6f5ac749116543a
Fixes: 74240862
Test: robotests

res/values/strings.xml
src/com/android/settings/accounts/AccountSyncSettings.java
src/com/android/settings/accounts/SyncStateSwitchPreference.java
tests/robotests/src/com/android/settings/accounts/SyncStateSwitchPreferenceTest.java [new file with mode: 0644]

index 7507de2..650f9d9 100644 (file)
     <string name="really_remove_account_message" product="device">Removing this account will delete all of its messages, contacts, and other data from the device!</string>
     <!-- This is shown if the autheticator for a given account fails to remove it. [CHAR LIMIT=NONE] -->
     <string name="remove_account_failed">This change isn\'t allowed by your admin</string>
-    <!-- What to show in messaging that refers to this provider, e.g. AccountSyncSettings -->
-    <string name="provider_label">Push subscriptions</string>
-    <!-- Formatter in AccountSyncSettings for each application we wish to synchronize, e.g. "Sync Calendar" -->
-    <string name="sync_item_title"><xliff:g id="authority" example="Calendar">%s</xliff:g></string>
     <!-- Title of dialog shown when you can't manually sync an item because it's disabled -->
     <string name="cant_sync_dialog_title">Can\u2019t manually sync</string>
     <!-- Messaage shown in dialog when you can't manually sync -->
index d83694d..6b60e87 100644 (file)
@@ -194,25 +194,24 @@ public class AccountSyncSettings extends AccountPreferenceBase {
         } else {
             item.setup(account, authority, packageName, uid);
         }
+        final PackageManager packageManager = getPackageManager();
         item.setPersistent(false);
-        final ProviderInfo providerInfo = getPackageManager().resolveContentProviderAsUser(
+        final ProviderInfo providerInfo = packageManager.resolveContentProviderAsUser(
                 authority, 0, mUserHandle.getIdentifier());
         if (providerInfo == null) {
             return;
         }
-        CharSequence providerLabel = providerInfo.loadLabel(getPackageManager());
+        final CharSequence providerLabel = providerInfo.loadLabel(packageManager);
         if (TextUtils.isEmpty(providerLabel)) {
             Log.e(TAG, "Provider needs a label for authority '" + authority + "'");
             return;
         }
-        String title = getString(R.string.sync_item_title, providerLabel);
-        item.setTitle(title);
+        item.setTitle(providerLabel);
         item.setKey(authority);
     }
 
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-
         MenuItem syncNow = menu.add(0, MENU_SYNC_NOW_ID, 0,
                 getString(R.string.sync_menu_sync_now))
                 .setIcon(R.drawable.ic_menu_refresh_holo_dark);
index 058fedd..456edba 100644 (file)
@@ -21,6 +21,7 @@ import android.app.ActivityManager;
 import android.content.Context;
 import android.support.v14.preference.SwitchPreference;
 import android.support.v7.preference.PreferenceViewHolder;
+import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.View;
@@ -64,6 +65,7 @@ public class SyncStateSwitchPreference extends SwitchPreference {
         mAuthority = authority;
         mPackageName = packageName;
         mUid = uid;
+        setVisible(!TextUtils.isEmpty(mAuthority));
         notifyChanged();
     }
 
diff --git a/tests/robotests/src/com/android/settings/accounts/SyncStateSwitchPreferenceTest.java b/tests/robotests/src/com/android/settings/accounts/SyncStateSwitchPreferenceTest.java
new file mode 100644 (file)
index 0000000..0d45418
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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.accounts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.accounts.Account;
+import android.content.Context;
+import android.os.UserHandle;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class SyncStateSwitchPreferenceTest {
+
+    private Context mContext;
+    private SyncStateSwitchPreference mPreference;
+
+    @Before
+    public void setup() {
+        mContext = RuntimeEnvironment.application;
+    }
+
+    @Test
+    public void setup_validAuthority_shouldBeVisible() {
+        mPreference = new SyncStateSwitchPreference(mContext, null /* attrs */);
+
+        mPreference.setup(new Account("name", "type"), "authority", mContext.getPackageName(),
+                UserHandle.USER_CURRENT);
+
+        assertThat(mPreference.isVisible()).isTrue();
+    }
+
+    @Test
+    public void setup_emptyAuthority_shouldBeInvisible() {
+        mPreference = new SyncStateSwitchPreference(mContext, null /* attrs */);
+
+        mPreference.setup(new Account("name", "type"), null /* authority */,
+                mContext.getPackageName(), UserHandle.USER_CURRENT);
+
+        assertThat(mPreference.isVisible()).isFalse();
+    }
+}