Protect against invalid authority in account sync pref.

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
This commit is contained in:
Fan Zhang
2018-04-05 14:44:13 -07:00
parent a8c53f7dcb
commit 76dbb21cb5
4 changed files with 68 additions and 9 deletions

View File

@@ -5922,10 +5922,6 @@
<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> <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] --> <!-- 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> <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 --> <!-- 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> <string name="cant_sync_dialog_title">Can\u2019t manually sync</string>
<!-- Messaage shown in dialog when you can't manually sync --> <!-- Messaage shown in dialog when you can't manually sync -->

View File

@@ -194,25 +194,24 @@ public class AccountSyncSettings extends AccountPreferenceBase {
} else { } else {
item.setup(account, authority, packageName, uid); item.setup(account, authority, packageName, uid);
} }
final PackageManager packageManager = getPackageManager();
item.setPersistent(false); item.setPersistent(false);
final ProviderInfo providerInfo = getPackageManager().resolveContentProviderAsUser( final ProviderInfo providerInfo = packageManager.resolveContentProviderAsUser(
authority, 0, mUserHandle.getIdentifier()); authority, 0, mUserHandle.getIdentifier());
if (providerInfo == null) { if (providerInfo == null) {
return; return;
} }
CharSequence providerLabel = providerInfo.loadLabel(getPackageManager()); final CharSequence providerLabel = providerInfo.loadLabel(packageManager);
if (TextUtils.isEmpty(providerLabel)) { if (TextUtils.isEmpty(providerLabel)) {
Log.e(TAG, "Provider needs a label for authority '" + authority + "'"); Log.e(TAG, "Provider needs a label for authority '" + authority + "'");
return; return;
} }
String title = getString(R.string.sync_item_title, providerLabel); item.setTitle(providerLabel);
item.setTitle(title);
item.setKey(authority); item.setKey(authority);
} }
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
MenuItem syncNow = menu.add(0, MENU_SYNC_NOW_ID, 0, MenuItem syncNow = menu.add(0, MENU_SYNC_NOW_ID, 0,
getString(R.string.sync_menu_sync_now)) getString(R.string.sync_menu_sync_now))
.setIcon(R.drawable.ic_menu_refresh_holo_dark); .setIcon(R.drawable.ic_menu_refresh_holo_dark);

View File

@@ -21,6 +21,7 @@ import android.app.ActivityManager;
import android.content.Context; import android.content.Context;
import android.support.v14.preference.SwitchPreference; import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.PreferenceViewHolder; import android.support.v7.preference.PreferenceViewHolder;
import android.text.TextUtils;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
@@ -64,6 +65,7 @@ public class SyncStateSwitchPreference extends SwitchPreference {
mAuthority = authority; mAuthority = authority;
mPackageName = packageName; mPackageName = packageName;
mUid = uid; mUid = uid;
setVisible(!TextUtils.isEmpty(mAuthority));
notifyChanged(); notifyChanged();
} }

View File

@@ -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();
}
}