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:
@@ -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 -->
|
||||||
|
@@ -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);
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user