diff options
Diffstat (limited to 'java/com/android/dialer/calllog')
115 files changed, 4472 insertions, 341 deletions
diff --git a/java/com/android/dialer/calllog/CallLogComponent.java b/java/com/android/dialer/calllog/CallLogComponent.java index 5cdd2b4d0..c7db2a1b8 100644 --- a/java/com/android/dialer/calllog/CallLogComponent.java +++ b/java/com/android/dialer/calllog/CallLogComponent.java @@ -25,6 +25,8 @@ public abstract class CallLogComponent { public abstract CallLogFramework callLogFramework(); + public abstract RefreshAnnotatedCallLogWorker getRefreshAnnotatedCallLogWorker(); + public static CallLogComponent get(Context context) { return ((HasComponent) ((HasRootComponent) context.getApplicationContext()).component()) .callLogComponent(); diff --git a/java/com/android/dialer/calllog/CallLogFramework.java b/java/com/android/dialer/calllog/CallLogFramework.java index 508413b14..788e56b93 100644 --- a/java/com/android/dialer/calllog/CallLogFramework.java +++ b/java/com/android/dialer/calllog/CallLogFramework.java @@ -21,9 +21,10 @@ import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.support.annotation.MainThread; import android.support.annotation.Nullable; +import com.android.dialer.buildtype.BuildType; import com.android.dialer.calllog.datasources.CallLogDataSource; +import com.android.dialer.calllog.datasources.DataSources; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; import javax.inject.Inject; import javax.inject.Singleton; @@ -38,7 +39,6 @@ import javax.inject.Singleton; public final class CallLogFramework implements CallLogDataSource.ContentObserverCallbacks { static final String PREF_FORCE_REBUILD = "callLogFrameworkForceRebuild"; - static final String PREF_LAST_REBUILD_TIMESTAMP_MILLIS = "callLogFrameworkLastRebuild"; private final DataSources dataSources; @@ -49,20 +49,20 @@ public final class CallLogFramework implements CallLogDataSource.ContentObserver this.dataSources = dataSources; } - public boolean isNewCallLogEnabled(Context context) { - return ConfigProviderBindings.get(context).getBoolean("enable_new_call_log_tab", false); - } - /** Registers the content observers for all data sources. */ public void registerContentObservers(Context appContext) { LogUtil.enterBlock("CallLogFramework.registerContentObservers"); - if (!isNewCallLogEnabled(appContext)) { - return; - } - - for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) { - dataSource.registerContentObservers(appContext, this); + // This is the same condition used in MainImpl#isNewUiEnabled. It means that bugfood/debug + // users will have "new call log" content observers firing. These observers usually do simple + // things like writing shared preferences. + // TODO(zachh): Find a way to access Main#isNewUiEnabled without creating a circular dependency. + if (BuildType.get() == BuildType.BUGFOOD || LogUtil.isDebugEnabled()) { + for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) { + dataSource.registerContentObservers(appContext, this); + } + } else { + LogUtil.i("CallLogFramework.registerContentObservers", "not registering content observers"); } } diff --git a/java/com/android/dialer/calllog/CallLogModule.java b/java/com/android/dialer/calllog/CallLogModule.java index d7473a75e..2f2f16d5b 100644 --- a/java/com/android/dialer/calllog/CallLogModule.java +++ b/java/com/android/dialer/calllog/CallLogModule.java @@ -17,11 +17,9 @@ package com.android.dialer.calllog; import com.android.dialer.calllog.datasources.CallLogDataSource; +import com.android.dialer.calllog.datasources.DataSources; import com.android.dialer.calllog.datasources.contacts.ContactsDataSource; import com.android.dialer.calllog.datasources.systemcalllog.SystemCallLogDataSource; -import com.android.dialer.common.concurrent.DefaultDialerExecutorFactory; -import com.android.dialer.common.concurrent.DialerExecutorFactory; -import dagger.Binds; import dagger.Module; import dagger.Provides; import java.util.Arrays; @@ -32,10 +30,6 @@ import java.util.List; @Module public abstract class CallLogModule { - @Binds - abstract DialerExecutorFactory bindDialerExecutorFactory( - DefaultDialerExecutorFactory defaultDialerExecutorFactory); - @Provides static DataSources provideCallLogDataSources( SystemCallLogDataSource systemCallLogDataSource, ContactsDataSource contactsDataSource) { diff --git a/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java b/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java index f9f0c9935..273246649 100644 --- a/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java +++ b/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java @@ -18,91 +18,84 @@ package com.android.dialer.calllog; import android.annotation.TargetApi; import android.content.Context; +import android.content.OperationApplicationException; import android.content.SharedPreferences; -import android.database.sqlite.SQLiteDatabase; import android.os.Build; +import android.os.RemoteException; import android.preference.PreferenceManager; import android.support.annotation.WorkerThread; -import com.android.dialer.calllog.database.AnnotatedCallLog; -import com.android.dialer.calllog.database.CallLogMutations; +import com.android.dialer.calllog.database.CallLogDatabaseComponent; import com.android.dialer.calllog.datasources.CallLogDataSource; +import com.android.dialer.calllog.datasources.CallLogMutations; +import com.android.dialer.calllog.datasources.DataSources; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.DialerExecutor.Worker; +import com.android.dialer.inject.ApplicationContext; import javax.inject.Inject; /** * Worker which brings the annotated call log up to date, if necessary. * - * <p>Accepts a boolean which indicates if the dirty check should be skipped, and returns true if - * the annotated call log was updated. + * <p>Accepts a boolean which indicates if the dirty check should be skipped. */ -public class RefreshAnnotatedCallLogWorker implements Worker<Boolean, Boolean> { +public class RefreshAnnotatedCallLogWorker implements Worker<Boolean, Void> { private final Context appContext; private final DataSources dataSources; @Inject - public RefreshAnnotatedCallLogWorker(Context appContext, DataSources dataSources) { + RefreshAnnotatedCallLogWorker(@ApplicationContext Context appContext, DataSources dataSources) { this.appContext = appContext; this.dataSources = dataSources; } @Override - public Boolean doInBackground(Boolean skipDirtyCheck) { - LogUtil.enterBlock("RefreshAnnotatedCallLogWorker.doInBackgroundFallible"); + public Void doInBackground(Boolean skipDirtyCheck) + throws RemoteException, OperationApplicationException { + LogUtil.enterBlock("RefreshAnnotatedCallLogWorker.doInBackground"); long startTime = System.currentTimeMillis(); - boolean annotatedCallLogUpdated = checkDirtyAndRebuildIfNecessary(appContext, skipDirtyCheck); + checkDirtyAndRebuildIfNecessary(appContext, skipDirtyCheck); LogUtil.i( - "RefreshAnnotatedCallLogWorker.doInBackgroundFallible", - "updated? %s, took %dms", - annotatedCallLogUpdated, + "RefreshAnnotatedCallLogWorker.doInBackground", + "took %dms", System.currentTimeMillis() - startTime); - return annotatedCallLogUpdated; + return null; } @WorkerThread - private boolean checkDirtyAndRebuildIfNecessary(Context appContext, boolean skipDirtyCheck) { + private void checkDirtyAndRebuildIfNecessary(Context appContext, boolean skipDirtyCheck) + throws RemoteException, OperationApplicationException { Assert.isWorkerThread(); long startTime = System.currentTimeMillis(); SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(appContext); - long lastRebuildTimeMillis = - sharedPreferences.getLong(CallLogFramework.PREF_LAST_REBUILD_TIMESTAMP_MILLIS, 0); - if (lastRebuildTimeMillis == 0) { - LogUtil.i( - "RefreshAnnotatedCallLogWorker.checkDirtyAndRebuildIfNecessary", - "annotated call log has never been built, marking it dirty"); - } + // Default to true. If the pref doesn't exist, the annotated call log hasn't been created and + // we just skip isDirty checks and force a rebuild. boolean forceRebuildPrefValue = - sharedPreferences.getBoolean(CallLogFramework.PREF_FORCE_REBUILD, false); + sharedPreferences.getBoolean(CallLogFramework.PREF_FORCE_REBUILD, true); if (forceRebuildPrefValue) { LogUtil.i( "RefreshAnnotatedCallLogWorker.checkDirtyAndRebuildIfNecessary", - "call log has been marked dirty"); + "annotated call log has been marked dirty or does not exist"); } - boolean isDirty = - lastRebuildTimeMillis == 0 - || skipDirtyCheck - || forceRebuildPrefValue - || isDirty(appContext); + boolean isDirty = skipDirtyCheck || forceRebuildPrefValue || isDirty(appContext); + LogUtil.i( "RefreshAnnotatedCallLogWorker.checkDirtyAndRebuildIfNecessary", "isDirty took: %dms", System.currentTimeMillis() - startTime); if (isDirty) { startTime = System.currentTimeMillis(); - rebuild(appContext, lastRebuildTimeMillis); + rebuild(appContext); LogUtil.i( "RefreshAnnotatedCallLogWorker.checkDirtyAndRebuildIfNecessary", "rebuild took: %dms", System.currentTimeMillis() - startTime); - return true; // Annotated call log was updated. } - return false; // Annotated call log was not updated. } @WorkerThread @@ -129,52 +122,58 @@ public class RefreshAnnotatedCallLogWorker implements Worker<Boolean, Boolean> { @TargetApi(Build.VERSION_CODES.M) // Uses try-with-resources @WorkerThread - private void rebuild(Context appContext, long lastRebuildTimeMillis) { + private void rebuild(Context appContext) throws RemoteException, OperationApplicationException { Assert.isWorkerThread(); - // TODO: Start a transaction? - try (SQLiteDatabase database = AnnotatedCallLog.getWritableDatabase(appContext)) { + CallLogMutations mutations = new CallLogMutations(); - CallLogMutations mutations = new CallLogMutations(); + // System call log data source must go first! + CallLogDataSource systemCallLogDataSource = dataSources.getSystemCallLogDataSource(); + String dataSourceName = getName(systemCallLogDataSource); + LogUtil.i("RefreshAnnotatedCallLogWorker.rebuild", "filling %s", dataSourceName); + long startTime = System.currentTimeMillis(); + systemCallLogDataSource.fill(appContext, mutations); + LogUtil.i( + "RefreshAnnotatedCallLogWorker.rebuild", + "%s.fill took: %dms", + dataSourceName, + System.currentTimeMillis() - startTime); - // System call log data source must go first! - CallLogDataSource systemCallLogDataSource = dataSources.getSystemCallLogDataSource(); - String dataSourceName = getName(systemCallLogDataSource); + for (CallLogDataSource dataSource : dataSources.getDataSourcesExcludingSystemCallLog()) { + dataSourceName = getName(dataSource); LogUtil.i("RefreshAnnotatedCallLogWorker.rebuild", "filling %s", dataSourceName); - long startTime = System.currentTimeMillis(); - systemCallLogDataSource.fill(appContext, database, lastRebuildTimeMillis, mutations); + startTime = System.currentTimeMillis(); + dataSource.fill(appContext, mutations); LogUtil.i( - "RefreshAnnotatedCallLogWorker.rebuild", + "CallLogFramework.rebuild", "%s.fill took: %dms", dataSourceName, System.currentTimeMillis() - startTime); + } + LogUtil.i("RefreshAnnotatedCallLogWorker.rebuild", "applying mutations to database"); + startTime = System.currentTimeMillis(); + CallLogDatabaseComponent.get(appContext) + .mutationApplier() + .applyToDatabase(mutations, appContext); + LogUtil.i( + "RefreshAnnotatedCallLogWorker.rebuild", + "applyToDatabase took: %dms", + System.currentTimeMillis() - startTime); - for (CallLogDataSource dataSource : dataSources.getDataSourcesExcludingSystemCallLog()) { - dataSourceName = getName(dataSource); - LogUtil.i("RefreshAnnotatedCallLogWorker.rebuild", "filling %s", dataSourceName); - startTime = System.currentTimeMillis(); - dataSource.fill(appContext, database, lastRebuildTimeMillis, mutations); - LogUtil.i( - "CallLogFramework.rebuild", - "%s.fill took: %dms", - dataSourceName, - System.currentTimeMillis() - startTime); - } - LogUtil.i("RefreshAnnotatedCallLogWorker.rebuild", "applying mutations to database"); + for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) { + dataSourceName = getName(dataSource); + LogUtil.i("RefreshAnnotatedCallLogWorker.rebuild", "onSuccessfulFill'ing %s", dataSourceName); startTime = System.currentTimeMillis(); - mutations.applyToDatabase(database); + dataSource.onSuccessfulFill(appContext); LogUtil.i( - "RefreshAnnotatedCallLogWorker.rebuild", - "applyToDatabase took: %dms", + "CallLogFramework.rebuild", + "%s.onSuccessfulFill took: %dms", + dataSourceName, System.currentTimeMillis() - startTime); } SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(appContext); - sharedPreferences - .edit() - .putBoolean(CallLogFramework.PREF_FORCE_REBUILD, false) - .putLong(CallLogFramework.PREF_LAST_REBUILD_TIMESTAMP_MILLIS, System.currentTimeMillis()) - .commit(); + sharedPreferences.edit().putBoolean(CallLogFramework.PREF_FORCE_REBUILD, false).apply(); } private static String getName(CallLogDataSource dataSource) { diff --git a/java/com/android/dialer/calllog/database/AndroidManifest.xml b/java/com/android/dialer/calllog/database/AndroidManifest.xml new file mode 100644 index 000000000..396a6d9a1 --- /dev/null +++ b/java/com/android/dialer/calllog/database/AndroidManifest.xml @@ -0,0 +1,28 @@ +<!-- + ~ Copyright (C) 2017 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 + --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.dialer.calllog.database"> + + <application> + + <provider + android:authorities="com.android.dialer.annotatedcalllog" + android:exported="false" + android:multiprocess="false" + android:name=".AnnotatedCallLogContentProvider"/> + + </application> +</manifest> diff --git a/java/com/android/dialer/calllog/database/AnnotatedCallLog.java b/java/com/android/dialer/calllog/database/AnnotatedCallLog.java deleted file mode 100644 index 7dca44a60..000000000 --- a/java/com/android/dialer/calllog/database/AnnotatedCallLog.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2017 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.dialer.calllog.database; - -import android.content.Context; -import android.database.sqlite.SQLiteDatabase; -import android.support.annotation.WorkerThread; -import com.android.dialer.common.Assert; - -/** Static methods and constants for interacting with the annotated call log table. */ -public final class AnnotatedCallLog { - - private static final String DATABASE_NAME = "annotated_call_log.db"; - - public static final String TABLE_NAME = "AnnotatedCallLog"; - - /** Column names for the annotated call log table. */ - public static final class Columns { - public static final String ID = "_id"; - public static final String TIMESTAMP = "timestamp"; - public static final String CONTACT_NAME = "contact_name"; - } - - private AnnotatedCallLog() {} - - @WorkerThread - public static SQLiteDatabase getWritableDatabase(Context appContext) { - Assert.isWorkerThread(); - - return new AnnotatedCallLogDatabaseHelper(appContext, DATABASE_NAME).getWritableDatabase(); - } - - @WorkerThread - public static SQLiteDatabase getReadableDatabase(Context appContext) { - Assert.isWorkerThread(); - - return new AnnotatedCallLogDatabaseHelper(appContext, DATABASE_NAME).getReadableDatabase(); - } -} diff --git a/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java b/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java new file mode 100644 index 000000000..9a3d2e20f --- /dev/null +++ b/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2017 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.dialer.calllog.database; + +import android.annotation.TargetApi; +import android.content.ContentProvider; +import android.content.ContentProviderOperation; +import android.content.ContentProviderResult; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.OperationApplicationException; +import android.content.UriMatcher; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteQueryBuilder; +import android.net.Uri; +import android.os.Build; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.CoalescedAnnotatedCallLog; +import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; +import java.util.ArrayList; + +/** {@link ContentProvider} for the annotated call log. */ +public class AnnotatedCallLogContentProvider extends ContentProvider { + + /** + * We sometimes run queries where we potentially pass every ID into a where clause using the + * (?,?,?,...) syntax. The maximum number of host parameters is 999, so that's the maximum size + * this table can be. See https://www.sqlite.org/limits.html for more details. + */ + private static final int MAX_ROWS = 999; + + private static final int ANNOTATED_CALL_LOG_TABLE_CODE = 1; + private static final int ANNOTATED_CALL_LOG_TABLE_ID_CODE = 2; + private static final int COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE = 3; + + private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); + + static { + uriMatcher.addURI( + AnnotatedCallLogContract.AUTHORITY, AnnotatedCallLog.TABLE, ANNOTATED_CALL_LOG_TABLE_CODE); + uriMatcher.addURI( + AnnotatedCallLogContract.AUTHORITY, + AnnotatedCallLog.TABLE + "/#", + ANNOTATED_CALL_LOG_TABLE_ID_CODE); + uriMatcher.addURI( + AnnotatedCallLogContract.AUTHORITY, + CoalescedAnnotatedCallLog.TABLE, + COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE); + } + + private AnnotatedCallLogDatabaseHelper databaseHelper; + private Coalescer coalescer; + + private final ThreadLocal<Boolean> applyingBatch = new ThreadLocal<>(); + + /** Ensures that only a single notification is generated from {@link #applyBatch(ArrayList)}. */ + private boolean isApplyingBatch() { + return applyingBatch.get() != null && applyingBatch.get(); + } + + @Override + public boolean onCreate() { + databaseHelper = new AnnotatedCallLogDatabaseHelper(getContext(), MAX_ROWS); + coalescer = CallLogDatabaseComponent.get(getContext()).coalescer(); + return true; + } + + @TargetApi(Build.VERSION_CODES.M) // Uses try-with-resources + @Nullable + @Override + public Cursor query( + @NonNull Uri uri, + @Nullable String[] projection, + @Nullable String selection, + @Nullable String[] selectionArgs, + @Nullable String sortOrder) { + SQLiteDatabase db = databaseHelper.getReadableDatabase(); + SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); + queryBuilder.setTables(AnnotatedCallLog.TABLE); + int match = uriMatcher.match(uri); + switch (match) { + case ANNOTATED_CALL_LOG_TABLE_ID_CODE: + queryBuilder.appendWhere(AnnotatedCallLog._ID + "=" + ContentUris.parseId(uri)); + // fall through + case ANNOTATED_CALL_LOG_TABLE_CODE: + Cursor cursor = + queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder); + if (cursor != null) { + cursor.setNotificationUri( + getContext().getContentResolver(), AnnotatedCallLog.CONTENT_URI); + } else { + LogUtil.w("AnnotatedCallLogContentProvider.query", "cursor was null"); + } + return cursor; + case COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE: + Assert.checkArgument( + projection == CoalescedAnnotatedCallLog.ALL_COLUMNS, + "only ALL_COLUMNS projection supported for coalesced call log"); + Assert.checkArgument(selection == null, "selection not supported for coalesced call log"); + Assert.checkArgument( + selectionArgs == null, "selection args not supported for coalesced call log"); + Assert.checkArgument(sortOrder == null, "sort order not supported for coalesced call log"); + try (Cursor allAnnotatedCallLogRows = + queryBuilder.query( + db, null, null, null, null, null, AnnotatedCallLog.TIMESTAMP + " DESC")) { + Cursor coalescedRows = coalescer.coalesce(allAnnotatedCallLogRows); + coalescedRows.setNotificationUri( + getContext().getContentResolver(), CoalescedAnnotatedCallLog.CONTENT_URI); + return coalescedRows; + } + default: + throw new IllegalArgumentException("Unknown uri: " + uri); + } + } + + @Nullable + @Override + public String getType(@NonNull Uri uri) { + return AnnotatedCallLog.CONTENT_ITEM_TYPE; + } + + @Nullable + @Override + public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) { + // Javadoc states values is not nullable, even though it is annotated as such (b/38123194)! + Assert.checkArgument(values != null); + + SQLiteDatabase database = databaseHelper.getWritableDatabase(); + int match = uriMatcher.match(uri); + switch (match) { + case ANNOTATED_CALL_LOG_TABLE_CODE: + Assert.checkArgument( + values.get(AnnotatedCallLog._ID) != null, "You must specify an _ID when inserting"); + break; + case ANNOTATED_CALL_LOG_TABLE_ID_CODE: + Long idFromUri = ContentUris.parseId(uri); + Long idFromValues = values.getAsLong(AnnotatedCallLog._ID); + Assert.checkArgument( + idFromValues == null || idFromValues.equals(idFromUri), + "_ID from values %d does not match ID from URI: %s", + idFromValues, + uri); + if (idFromValues == null) { + values.put(AnnotatedCallLog._ID, idFromUri); + } + break; + case COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE: + throw new UnsupportedOperationException("coalesced call log does not support inserting"); + default: + throw new IllegalArgumentException("Unknown uri: " + uri); + } + long id = database.insert(AnnotatedCallLog.TABLE, null, values); + if (id < 0) { + LogUtil.w( + "AnnotatedCallLogContentProvider.insert", + "error inserting row with id: %d", + values.get(AnnotatedCallLog._ID)); + return null; + } + Uri insertedUri = ContentUris.withAppendedId(AnnotatedCallLog.CONTENT_URI, id); + if (!isApplyingBatch()) { + notifyChange(insertedUri); + } + return insertedUri; + } + + @Override + public int delete( + @NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) { + SQLiteDatabase database = databaseHelper.getWritableDatabase(); + final int match = uriMatcher.match(uri); + switch (match) { + case ANNOTATED_CALL_LOG_TABLE_CODE: + break; + case ANNOTATED_CALL_LOG_TABLE_ID_CODE: + Assert.checkArgument(selection == null, "Do not specify selection when deleting by ID"); + Assert.checkArgument( + selectionArgs == null, "Do not specify selection args when deleting by ID"); + long id = ContentUris.parseId(uri); + Assert.checkArgument(id != -1, "error parsing id from uri %s", uri); + selection = getSelectionWithId(id); + break; + case COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE: + throw new UnsupportedOperationException("coalesced call log does not support deleting"); + default: + throw new IllegalArgumentException("Unknown uri: " + uri); + } + int rows = database.delete(AnnotatedCallLog.TABLE, selection, selectionArgs); + if (rows > 0) { + if (!isApplyingBatch()) { + notifyChange(uri); + } + } else { + LogUtil.w("AnnotatedCallLogContentProvider.delete", "no rows deleted"); + } + return rows; + } + + @Override + public int update( + @NonNull Uri uri, + @Nullable ContentValues values, + @Nullable String selection, + @Nullable String[] selectionArgs) { + // Javadoc states values is not nullable, even though it is annotated as such (b/38123194)! + Assert.checkArgument(values != null); + + SQLiteDatabase database = databaseHelper.getWritableDatabase(); + int match = uriMatcher.match(uri); + switch (match) { + case ANNOTATED_CALL_LOG_TABLE_CODE: + break; + case ANNOTATED_CALL_LOG_TABLE_ID_CODE: + Assert.checkArgument( + !values.containsKey(AnnotatedCallLog._ID), "Do not specify _ID when updating by ID"); + Assert.checkArgument(selection == null, "Do not specify selection when updating by ID"); + Assert.checkArgument( + selectionArgs == null, "Do not specify selection args when updating by ID"); + selection = getSelectionWithId(ContentUris.parseId(uri)); + break; + case COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE: + throw new UnsupportedOperationException("coalesced call log does not support updating"); + default: + throw new IllegalArgumentException("Unknown uri: " + uri); + } + int rows = database.update(AnnotatedCallLog.TABLE, values, selection, selectionArgs); + if (rows > 0) { + if (!isApplyingBatch()) { + notifyChange(uri); + } + } else { + LogUtil.w("AnnotatedCallLogContentProvider.update", "no rows updated"); + } + return rows; + } + + /** + * {@inheritDoc} + * + * <p>Note: When applyBatch is used with the AnnotatedCallLog, only a single notification for the + * content URI is generated, not individual notifications for each affected URI. + */ + @NonNull + @Override + public ContentProviderResult[] applyBatch(@NonNull ArrayList<ContentProviderOperation> operations) + throws OperationApplicationException { + ContentProviderResult[] results = new ContentProviderResult[operations.size()]; + if (operations.isEmpty()) { + return results; + } + + SQLiteDatabase database = databaseHelper.getWritableDatabase(); + try { + applyingBatch.set(true); + database.beginTransaction(); + for (int i = 0; i < operations.size(); i++) { + ContentProviderOperation operation = operations.get(i); + int match = uriMatcher.match(operation.getUri()); + switch (match) { + case ANNOTATED_CALL_LOG_TABLE_CODE: + case ANNOTATED_CALL_LOG_TABLE_ID_CODE: + // These are allowed values, continue. + break; + case COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE: + throw new UnsupportedOperationException( + "coalesced call log does not support applyBatch"); + default: + throw new IllegalArgumentException("Unknown uri: " + operation.getUri()); + } + ContentProviderResult result = operation.apply(this, results, i); + if (operations.get(i).isInsert()) { + if (result.uri == null) { + throw new OperationApplicationException("error inserting row"); + } + } else if (result.count == 0) { + /* + * The batches built by MutationApplier happen to contain operations in order of: + * + * 1. Inserts + * 2. Updates + * 3. Deletes + * + * Let's say the last row in the table is row Z, and MutationApplier wishes to update it, + * as well as insert row A. When row A gets inserted, row Z will be deleted via the + * trigger if the table is full. Then later, when we try to process the update for row Z, + * it won't exist. + */ + LogUtil.w( + "AnnotatedCallLogContentProvider.applyBatch", + "update or delete failed, possibly because row got cleaned up"); + } + results[i] = result; + } + database.setTransactionSuccessful(); + } finally { + applyingBatch.set(false); + database.endTransaction(); + } + notifyChange(AnnotatedCallLog.CONTENT_URI); + return results; + } + + private String getSelectionWithId(long id) { + return AnnotatedCallLog._ID + "=" + id; + } + + private void notifyChange(Uri uri) { + getContext().getContentResolver().notifyChange(uri, null); + // Any time the annotated call log changes, we need to also notify observers of the + // CoalescedAnnotatedCallLog, since that is just a massaged in-memory view of the real annotated + // call log table. + getContext().getContentResolver().notifyChange(CoalescedAnnotatedCallLog.CONTENT_URI, null); + } +} diff --git a/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java b/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java index 7b28e5505..e1ec0f6b1 100644 --- a/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java +++ b/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java @@ -16,37 +16,75 @@ package com.android.dialer.calllog.database; -import static com.android.dialer.calllog.database.AnnotatedCallLog.Columns.CONTACT_NAME; -import static com.android.dialer.calllog.database.AnnotatedCallLog.Columns.ID; -import static com.android.dialer.calllog.database.AnnotatedCallLog.Columns.TIMESTAMP; - import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; import com.android.dialer.common.LogUtil; +import java.util.Locale; /** {@link SQLiteOpenHelper} for the AnnotatedCallLog database. */ class AnnotatedCallLogDatabaseHelper extends SQLiteOpenHelper { + private final int maxRows; - AnnotatedCallLogDatabaseHelper(Context appContext, String databaseName) { - super(appContext, databaseName, null, 1); + AnnotatedCallLogDatabaseHelper(Context appContext, int maxRows) { + super(appContext, "annotated_call_log.db", null, 1); + this.maxRows = maxRows; } - private static final String CREATE_SQL = + private static final String CREATE_TABLE_SQL = new StringBuilder() - .append("create table if not exists " + AnnotatedCallLog.TABLE_NAME + " (") - .append(ID + " integer primary key, ") - .append(TIMESTAMP + " integer, ") - .append(CONTACT_NAME + " string") + .append("create table if not exists " + AnnotatedCallLog.TABLE + " (") + // Common columns. + .append(AnnotatedCallLog._ID + " integer primary key, ") + .append(AnnotatedCallLog.TIMESTAMP + " integer, ") + .append(AnnotatedCallLog.NAME + " string, ") + .append(AnnotatedCallLog.FORMATTED_NUMBER + " string, ") + .append(AnnotatedCallLog.PHOTO_URI + " string, ") + .append(AnnotatedCallLog.PHOTO_ID + " integer, ") + .append(AnnotatedCallLog.LOOKUP_URI + " string, ") + .append(AnnotatedCallLog.NUMBER_TYPE_LABEL + " string, ") + .append(AnnotatedCallLog.IS_READ + " integer, ") + .append(AnnotatedCallLog.NEW + " integer, ") + .append(AnnotatedCallLog.GEOCODED_LOCATION + " string, ") + .append(AnnotatedCallLog.PHONE_ACCOUNT_LABEL + " string, ") + .append(AnnotatedCallLog.PHONE_ACCOUNT_COLOR + " integer, ") + .append(AnnotatedCallLog.FEATURES + " integer, ") + .append(AnnotatedCallLog.IS_BUSINESS + " integer, ") + .append(AnnotatedCallLog.IS_VOICEMAIL + " integer, ") + // Columns only in AnnotatedCallLog + .append(AnnotatedCallLog.NUMBER + " blob, ") + .append(AnnotatedCallLog.TYPE + " integer") .append(");") .toString(); + /** Deletes all but the first maxRows rows (by timestamp) to keep the table a manageable size. */ + private static final String CREATE_TRIGGER_SQL = + "create trigger delete_old_rows after insert on " + + AnnotatedCallLog.TABLE + + " when (select count(*) from " + + AnnotatedCallLog.TABLE + + ") > %d" + + " begin delete from " + + AnnotatedCallLog.TABLE + + " where " + + AnnotatedCallLog._ID + + " in (select " + + AnnotatedCallLog._ID + + " from " + + AnnotatedCallLog.TABLE + + " order by timestamp limit (select count(*)-%d" + + " from " + + AnnotatedCallLog.TABLE + + " )); end;"; + @Override public void onCreate(SQLiteDatabase db) { LogUtil.enterBlock("AnnotatedCallLogDatabaseHelper.onCreate"); long startTime = System.currentTimeMillis(); - db.execSQL(CREATE_SQL); - // TODO: Consider logging impression. + db.execSQL(CREATE_TABLE_SQL); + db.execSQL(String.format(Locale.US, CREATE_TRIGGER_SQL, maxRows, maxRows)); + // TODO(zachh): Consider logging impression. LogUtil.i( "AnnotatedCallLogDatabaseHelper.onCreate", "took: %dms", diff --git a/java/com/android/dialer/calllog/database/CallLogDatabaseComponent.java b/java/com/android/dialer/calllog/database/CallLogDatabaseComponent.java new file mode 100644 index 000000000..ede46911c --- /dev/null +++ b/java/com/android/dialer/calllog/database/CallLogDatabaseComponent.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2017 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.dialer.calllog.database; + +import android.content.Context; +import com.android.dialer.inject.HasRootComponent; +import dagger.Subcomponent; + +/** Dagger component for database package. */ +@Subcomponent +public abstract class CallLogDatabaseComponent { + + public abstract Coalescer coalescer(); + + public abstract MutationApplier mutationApplier(); + + public static CallLogDatabaseComponent get(Context context) { + return ((CallLogDatabaseComponent.HasComponent) + ((HasRootComponent) context.getApplicationContext()).component()) + .callLogDatabaseComponent(); + } + + /** Used to refer to the root application component. */ + public interface HasComponent { + CallLogDatabaseComponent callLogDatabaseComponent(); + } +} diff --git a/java/com/android/dialer/calllog/database/CallLogMutations.java b/java/com/android/dialer/calllog/database/CallLogMutations.java deleted file mode 100644 index ec020c6af..000000000 --- a/java/com/android/dialer/calllog/database/CallLogMutations.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2017 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.dialer.calllog.database; - -import android.content.ContentValues; -import android.database.sqlite.SQLiteDatabase; -import android.support.annotation.WorkerThread; -import android.util.ArrayMap; -import android.util.ArraySet; -import com.android.dialer.common.Assert; - -/** A collection of mutations to the annotated call log. */ -public final class CallLogMutations { - - private final ArrayMap<Integer, ContentValues> inserts = new ArrayMap<>(); - private final ArrayMap<Integer, ContentValues> updates = new ArrayMap<>(); - private final ArraySet<Integer> deletes = new ArraySet<>(); - - /** @param contentValues an entire row not including the ID */ - public void insert(int id, ContentValues contentValues) { - inserts.put(id, contentValues); - } - - /** @param contentValues the specific columns to update, not including the ID. */ - public void update(int id, ContentValues contentValues) { - // TODO: Consider merging automatically. - updates.put(id, contentValues); - } - - public void delete(int id) { - deletes.add(id); - } - - public boolean isEmpty() { - return inserts.isEmpty() && updates.isEmpty() && deletes.isEmpty(); - } - - @WorkerThread - public void applyToDatabase(SQLiteDatabase writableDatabase) { - Assert.isWorkerThread(); - - // TODO: Implementation. - } -} diff --git a/java/com/android/dialer/calllog/database/Coalescer.java b/java/com/android/dialer/calllog/database/Coalescer.java new file mode 100644 index 000000000..63fa9f828 --- /dev/null +++ b/java/com/android/dialer/calllog/database/Coalescer.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2017 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.dialer.calllog.database; + +import android.content.ContentValues; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.support.annotation.NonNull; +import android.support.annotation.WorkerThread; +import com.android.dialer.DialerPhoneNumber; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.CoalescedAnnotatedCallLog; +import com.android.dialer.calllog.datasources.CallLogDataSource; +import com.android.dialer.calllog.datasources.DataSources; +import com.android.dialer.common.Assert; +import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil; +import com.google.i18n.phonenumbers.PhoneNumberUtil; +import com.google.protobuf.InvalidProtocolBufferException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import javax.inject.Inject; + +/** + * Coalesces call log rows by combining some adjacent rows. + * + * <p>Applies the business which logic which determines which adjacent rows should be coalasced, and + * then delegates to each data source to determine how individual columns should be aggregated. + */ +public class Coalescer { + + private final DataSources dataSources; + + @Inject + Coalescer(DataSources dataSources) { + this.dataSources = dataSources; + } + + /** + * Reads the entire {@link AnnotatedCallLog} database into memory from the provided {@code + * allAnnotatedCallLog} parameter and then builds and returns a new {@link MatrixCursor} which is + * the result of combining adjacent rows which should be collapsed for display purposes. + * + * @param allAnnotatedCallLogRowsSortedByTimestampDesc all {@link AnnotatedCallLog} rows, sorted + * by timestamp descending + * @return a new {@link MatrixCursor} containing the {@link CoalescedAnnotatedCallLog} rows to + * display + */ + @WorkerThread + @NonNull + Cursor coalesce(@NonNull Cursor allAnnotatedCallLogRowsSortedByTimestampDesc) { + Assert.isWorkerThread(); + + // Note: This method relies on rowsShouldBeCombined to determine which rows should be combined, + // but delegates to data sources to actually aggregate column values. + + DialerPhoneNumberUtil dialerPhoneNumberUtil = + new DialerPhoneNumberUtil(PhoneNumberUtil.getInstance()); + + MatrixCursor allCoalescedRowsMatrixCursor = + new MatrixCursor( + CoalescedAnnotatedCallLog.ALL_COLUMNS, + Assert.isNotNull(allAnnotatedCallLogRowsSortedByTimestampDesc).getCount()); + + if (allAnnotatedCallLogRowsSortedByTimestampDesc.moveToFirst()) { + int coalescedRowId = 0; + + List<ContentValues> currentRowGroup = new ArrayList<>(); + + do { + ContentValues currentRow = + cursorRowToContentValues(allAnnotatedCallLogRowsSortedByTimestampDesc); + + if (currentRowGroup.isEmpty()) { + currentRowGroup.add(currentRow); + continue; + } + + ContentValues previousRow = currentRowGroup.get(currentRowGroup.size() - 1); + + if (!rowsShouldBeCombined(dialerPhoneNumberUtil, previousRow, currentRow)) { + ContentValues coalescedRow = coalesceRowsForAllDataSources(currentRowGroup); + coalescedRow.put(CoalescedAnnotatedCallLog.NUMBER_CALLS, currentRowGroup.size()); + addContentValuesToMatrixCursor( + coalescedRow, allCoalescedRowsMatrixCursor, coalescedRowId++); + currentRowGroup.clear(); + } + currentRowGroup.add(currentRow); + } while (allAnnotatedCallLogRowsSortedByTimestampDesc.moveToNext()); + + // Deal with leftover rows. + ContentValues coalescedRow = coalesceRowsForAllDataSources(currentRowGroup); + coalescedRow.put(CoalescedAnnotatedCallLog.NUMBER_CALLS, currentRowGroup.size()); + addContentValuesToMatrixCursor(coalescedRow, allCoalescedRowsMatrixCursor, coalescedRowId); + } + return allCoalescedRowsMatrixCursor; + } + + private static ContentValues cursorRowToContentValues(Cursor cursor) { + ContentValues values = new ContentValues(); + String[] columns = cursor.getColumnNames(); + int length = columns.length; + for (int i = 0; i < length; i++) { + if (cursor.getType(i) == Cursor.FIELD_TYPE_BLOB) { + values.put(columns[i], cursor.getBlob(i)); + } else { + values.put(columns[i], cursor.getString(i)); + } + } + return values; + } + + /** + * @param row1 a row from {@link AnnotatedCallLog} + * @param row2 a row from {@link AnnotatedCallLog} + */ + private static boolean rowsShouldBeCombined( + DialerPhoneNumberUtil dialerPhoneNumberUtil, ContentValues row1, ContentValues row2) { + // Don't combine rows which don't use the same phone account. + if (!Objects.equals( + row1.getAsString(AnnotatedCallLog.PHONE_ACCOUNT_LABEL), + row2.getAsString(AnnotatedCallLog.PHONE_ACCOUNT_LABEL))) { + return false; + } + DialerPhoneNumber number1; + DialerPhoneNumber number2; + try { + byte[] number1Bytes = row1.getAsByteArray(AnnotatedCallLog.NUMBER); + byte[] number2Bytes = row2.getAsByteArray(AnnotatedCallLog.NUMBER); + + if (number1Bytes == null || number2Bytes == null) { + // Empty numbers should not be combined. + return false; + } + + number1 = DialerPhoneNumber.parseFrom(number1Bytes); + number2 = DialerPhoneNumber.parseFrom(number2Bytes); + } catch (InvalidProtocolBufferException e) { + throw Assert.createAssertionFailException("error parsing DialerPhoneNumber proto", e); + } + + if (!number1.hasDialerInternalPhoneNumber() && !number2.hasDialerInternalPhoneNumber()) { + // Empty numbers should not be combined. + return false; + } + + if (!number1.hasDialerInternalPhoneNumber() || !number2.hasDialerInternalPhoneNumber()) { + // An empty number should not be combined with a non-empty number. + return false; + } + return dialerPhoneNumberUtil.isExactMatch(number1, number2); + } + + /** + * Delegates to data sources to aggregate individual columns to create a new coalesced row. + * + * @param individualRows {@link AnnotatedCallLog} rows sorted by timestamp descending + * @return a {@link CoalescedAnnotatedCallLog} row + */ + private ContentValues coalesceRowsForAllDataSources(List<ContentValues> individualRows) { + ContentValues coalescedValues = new ContentValues(); + for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) { + coalescedValues.putAll(dataSource.coalesce(individualRows)); + } + return coalescedValues; + } + + /** + * @param contentValues a {@link CoalescedAnnotatedCallLog} row + * @param matrixCursor represents {@link CoalescedAnnotatedCallLog} + */ + private static void addContentValuesToMatrixCursor( + ContentValues contentValues, MatrixCursor matrixCursor, int rowId) { + MatrixCursor.RowBuilder rowBuilder = matrixCursor.newRow(); + rowBuilder.add(CoalescedAnnotatedCallLog._ID, rowId); + for (Map.Entry<String, Object> entry : contentValues.valueSet()) { + rowBuilder.add(entry.getKey(), entry.getValue()); + } + } +} diff --git a/java/com/android/dialer/calllog/database/MutationApplier.java b/java/com/android/dialer/calllog/database/MutationApplier.java new file mode 100644 index 000000000..21c8a507d --- /dev/null +++ b/java/com/android/dialer/calllog/database/MutationApplier.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2017 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.dialer.calllog.database; + +import android.content.ContentProviderOperation; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Context; +import android.content.OperationApplicationException; +import android.os.RemoteException; +import android.support.annotation.WorkerThread; +import android.text.TextUtils; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; +import com.android.dialer.calllog.datasources.CallLogMutations; +import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Map.Entry; +import javax.inject.Inject; + +/** Applies {@link CallLogMutations} to the annotated call log. */ +public class MutationApplier { + + @Inject + MutationApplier() {} + + /** Applies the provided {@link CallLogMutations} to the annotated call log. */ + @WorkerThread + public void applyToDatabase(CallLogMutations mutations, Context appContext) + throws RemoteException, OperationApplicationException { + Assert.isWorkerThread(); + + if (mutations.isEmpty()) { + return; + } + + ArrayList<ContentProviderOperation> operations = new ArrayList<>(); + + if (!mutations.getInserts().isEmpty()) { + LogUtil.i( + "CallLogMutations.applyToDatabase", "inserting %d rows", mutations.getInserts().size()); + for (Entry<Long, ContentValues> entry : mutations.getInserts().entrySet()) { + long id = entry.getKey(); + ContentValues contentValues = entry.getValue(); + operations.add( + ContentProviderOperation.newInsert( + ContentUris.withAppendedId(AnnotatedCallLog.CONTENT_URI, id)) + .withValues(contentValues) + .build()); + } + } + + if (!mutations.getUpdates().isEmpty()) { + LogUtil.i( + "CallLogMutations.applyToDatabase", "updating %d rows", mutations.getUpdates().size()); + for (Entry<Long, ContentValues> entry : mutations.getUpdates().entrySet()) { + long id = entry.getKey(); + ContentValues contentValues = entry.getValue(); + operations.add( + ContentProviderOperation.newUpdate( + ContentUris.withAppendedId(AnnotatedCallLog.CONTENT_URI, id)) + .withValues(contentValues) + .build()); + } + } + + if (!mutations.getDeletes().isEmpty()) { + LogUtil.i( + "CallLogMutations.applyToDatabase", "deleting %d rows", mutations.getDeletes().size()); + String[] questionMarks = new String[mutations.getDeletes().size()]; + Arrays.fill(questionMarks, "?"); + + String whereClause = + (AnnotatedCallLog._ID + " in (") + TextUtils.join(",", questionMarks) + ")"; + + String[] whereArgs = new String[mutations.getDeletes().size()]; + int i = 0; + for (long id : mutations.getDeletes()) { + whereArgs[i++] = String.valueOf(id); + } + + operations.add( + ContentProviderOperation.newDelete(AnnotatedCallLog.CONTENT_URI) + .withSelection(whereClause, whereArgs) + .build()); + } + + appContext.getContentResolver().applyBatch(AnnotatedCallLogContract.AUTHORITY, operations); + } +} diff --git a/java/com/android/dialer/calllog/database/annotated_call_log.proto b/java/com/android/dialer/calllog/database/annotated_call_log.proto new file mode 100644 index 000000000..de2bc5f14 --- /dev/null +++ b/java/com/android/dialer/calllog/database/annotated_call_log.proto @@ -0,0 +1,15 @@ +syntax = "proto2"; + +option java_package = "com.android.dialer"; +option java_multiple_files = true; +option optimize_for = LITE_RUNTIME; + +// DIALER_SCRUB.UNCOMMENT_IN_OPEN_SOURCE option optimize_for = LITE_RUNTIME; + +package com.android.dialer; + +// A list of android.provider.CallLog.Calls.TYPE values ordered from newest to +// oldest. +message CallTypes { + repeated int32 type = 1; +} diff --git a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java new file mode 100644 index 000000000..25950f6b9 --- /dev/null +++ b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2017 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.dialer.calllog.database.contract; + +import android.net.Uri; +import android.provider.BaseColumns; +import com.android.dialer.constants.Constants; +import java.util.Arrays; + +/** Contract for the AnnotatedCallLog content provider. */ +public class AnnotatedCallLogContract { + public static final String AUTHORITY = Constants.get().getAnnotatedCallLogProviderAuthority(); + + public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY); + + /** + * Columns shared by {@link AnnotatedCallLog} and {@link CoalescedAnnotatedCallLog}. + * + * <p>When adding columns be sure to update {@link #ALL_COMMON_COLUMNS}. + */ + interface CommonColumns extends BaseColumns { + + /** + * Timestamp of the entry, in milliseconds. + * + * <p>Type: INTEGER (long) + */ + String TIMESTAMP = "timestamp"; + + /** + * Copied from {@link android.provider.CallLog.Calls#CACHED_NAME}. + * + * <p>This is exactly how it should appear to the user. If the user's locale or name display + * preferences change, this column should be rewritten. + * + * <p>Type: TEXT + */ + String NAME = "name"; + + /** + * Copied from {@link android.provider.CallLog.Calls#CACHED_FORMATTED_NUMBER}. + * + * <p>Type: TEXT + */ + String FORMATTED_NUMBER = "formatted_number"; + + /** + * Copied from {@link android.provider.CallLog.Calls#CACHED_PHOTO_URI}. + * + * <p>TYPE: TEXT + */ + String PHOTO_URI = "photo_uri"; + + /** + * Copied from {@link android.provider.CallLog.Calls#CACHED_PHOTO_ID}. + * + * <p>Type: INTEGER (long) + */ + String PHOTO_ID = "photo_id"; + + /** + * Copied from {@link android.provider.CallLog.Calls#CACHED_LOOKUP_URI}. + * + * <p>TYPE: TEXT + */ + String LOOKUP_URI = "lookup_uri"; + + // TODO(zachh): If we need to support photos other than local contacts', add a (blob?) column. + + /** + * The number type as a string to be displayed to the user, for example "Home" or "Mobile". + * + * <p>This column should be updated for the appropriate language when the locale changes. + * + * <p>TYPE: TEXT + */ + String NUMBER_TYPE_LABEL = "number_type_label"; + + /** + * See {@link android.provider.CallLog.Calls#IS_READ}. + * + * <p>TYPE: INTEGER (boolean) + */ + String IS_READ = "is_read"; + + /** + * See {@link android.provider.CallLog.Calls#NEW}. + * + * <p>Type: INTEGER (boolean) + */ + String NEW = "new"; + + /** + * See {@link android.provider.CallLog.Calls#GEOCODED_LOCATION}. + * + * <p>TYPE: TEXT + */ + String GEOCODED_LOCATION = "geocoded_location"; + + /** + * String suitable for display which indicates the phone account used to make the call. + * + * <p>TYPE: TEXT + */ + String PHONE_ACCOUNT_LABEL = "phone_account_label"; + + /** + * The color int for the phone account. + * + * <p>TYPE: INTEGER (int) + */ + String PHONE_ACCOUNT_COLOR = "phone_account_color"; + + /** + * See {@link android.provider.CallLog.Calls#FEATURES}. + * + * <p>TYPE: INTEGER (int) + */ + String FEATURES = "features"; + + /** + * True if a caller ID data source informed us that this is a business number. This is used to + * determine if a generic business avatar should be shown vs. a generic person avatar. + * + * <p>TYPE: INTEGER (boolean) + */ + String IS_BUSINESS = "is_business"; + + /** + * True if this was a call to voicemail. This is used to determine if the voicemail avatar + * should be displayed. + * + * <p>TYPE: INTEGER (boolean) + */ + String IS_VOICEMAIL = "is_voicemail"; + + String[] ALL_COMMON_COLUMNS = + new String[] { + _ID, + TIMESTAMP, + NAME, + FORMATTED_NUMBER, + PHOTO_URI, + PHOTO_ID, + LOOKUP_URI, + NUMBER_TYPE_LABEL, + IS_READ, + NEW, + GEOCODED_LOCATION, + PHONE_ACCOUNT_LABEL, + PHONE_ACCOUNT_COLOR, + FEATURES, + IS_BUSINESS, + IS_VOICEMAIL + }; + } + + /** + * AnnotatedCallLog table. + * + * <p>This contains all of the non-coalesced call log entries. + */ + public static final class AnnotatedCallLog implements CommonColumns { + + public static final String TABLE = "AnnotatedCallLog"; + + /** The content URI for this table. */ + public static final Uri CONTENT_URI = + Uri.withAppendedPath(AnnotatedCallLogContract.CONTENT_URI, TABLE); + + /** The MIME type of a {@link android.content.ContentProvider#getType(Uri)} single entry. */ + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/annotated_call_log"; + + /** + * The phone number called or number the call came from, encoded as a {@link + * com.android.dialer.DialerPhoneNumber} proto. The number may be empty if it was an incoming + * call and the number was unknown. + * + * <p>This column is only present in the annotated call log, and not the coalesced annotated + * call log. The coalesced version uses a formatted number string rather than proto bytes. + * + * <p>Type: BLOB + */ + public static final String NUMBER = "number"; + + /** + * Copied from {@link android.provider.CallLog.Calls#TYPE}. + * + * <p>Type: INTEGER (int) + */ + public static final String TYPE = "type"; + } + + /** + * Coalesced view of the AnnotatedCallLog table. + * + * <p>This is an in-memory view of the {@link AnnotatedCallLog} with some adjacent entries + * collapsed. + * + * <p>When adding columns be sure to update {@link #COLUMNS_ONLY_IN_COALESCED_CALL_LOG}. + */ + public static final class CoalescedAnnotatedCallLog implements CommonColumns { + + public static final String TABLE = "CoalescedAnnotatedCallLog"; + + /** The content URI for this table. */ + public static final Uri CONTENT_URI = + Uri.withAppendedPath(AnnotatedCallLogContract.CONTENT_URI, TABLE); + + /** The MIME type of a {@link android.content.ContentProvider#getType(Uri)} single entry. */ + public static final String CONTENT_ITEM_TYPE = + "vnd.android.cursor.item/coalesced_annotated_call_log"; + + /** + * Number of AnnotatedCallLog rows represented by this CoalescedAnnotatedCallLog row. + * + * <p>Type: INTEGER + */ + public static final String NUMBER_CALLS = "number_calls"; + + /** + * The call types of the most recent 3 calls, encoded as a CallTypes proto. + * + * <p>TYPE: BLOB + */ + public static final String CALL_TYPES = "call_types"; + + /** + * Columns that are only in the {@link CoalescedAnnotatedCallLog} but not the {@link + * AnnotatedCallLog}. + */ + private static final String[] COLUMNS_ONLY_IN_COALESCED_CALL_LOG = + new String[] {NUMBER_CALLS, CALL_TYPES}; + + /** All columns in the {@link CoalescedAnnotatedCallLog}. */ + public static final String[] ALL_COLUMNS = + concat(ALL_COMMON_COLUMNS, COLUMNS_ONLY_IN_COALESCED_CALL_LOG); + } + + private static String[] concat(String[] first, String[] second) { + String[] result = Arrays.copyOf(first, first.length + second.length); + System.arraycopy(second, 0, result, first.length, second.length); + return result; + } +} diff --git a/java/com/android/dialer/calllog/datasources/CallLogDataSource.java b/java/com/android/dialer/calllog/datasources/CallLogDataSource.java index 13d0b842d..3fff3ba53 100644 --- a/java/com/android/dialer/calllog/datasources/CallLogDataSource.java +++ b/java/com/android/dialer/calllog/datasources/CallLogDataSource.java @@ -16,13 +16,39 @@ package com.android.dialer.calllog.datasources; +import android.content.ContentValues; import android.content.Context; -import android.database.sqlite.SQLiteDatabase; import android.support.annotation.MainThread; import android.support.annotation.WorkerThread; -import com.android.dialer.calllog.database.CallLogMutations; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract; +import java.util.List; -/** A source of data for one or more columns in the annotated call log. */ +/** + * A source of data for one or more columns in the annotated call log. + * + * <p>Data sources have three lifecycle operations, which are always called on the same thread and + * in the same order for a particular "checkDirtyAndRebuild" cycle. However, not all operations are + * always invoked. + * + * <ol> + * <li>{@link #isDirty(Context)}: Invoked only if the framework doesn't yet know if a rebuild is + * necessary. + * <li>{@link #fill(Context, CallLogMutations)}: Invoked only if the framework determined a + * rebuild is necessary. + * <li>{@link #onSuccessfulFill(Context)}: Invoked if and only if fill was previously called and + * the mutations provided by the previous fill operation succeeded in being applied. + * </ol> + * + * <p>Because {@link #isDirty(Context)} is not always invoked, {@link #fill(Context, + * CallLogMutations)} shouldn't rely on any state saved during {@link #isDirty(Context)}. It + * <em>is</em> safe to assume that {@link #onSuccessfulFill(Context)} refers to the previous fill + * operation. + * + * <p>The same data source objects may be reused across multiple checkDirtyAndRebuild cycles, so + * implementors should take care to clear any internal state at the start of a new cycle. + * + * <p>{@link #coalesce(List)} may be called from any worker thread at any time. + */ public interface CallLogDataSource { /** @@ -35,6 +61,8 @@ public interface CallLogDataSource { * <p>Most implementations of this method will rely on some sort of last modified timestamp. If it * is impossible for a data source to be modified without the dialer application being notified, * this method may immediately return false. + * + * @see CallLogDataSource class doc for complete lifecyle information */ @WorkerThread boolean isDirty(Context appContext); @@ -43,16 +71,39 @@ public interface CallLogDataSource { * Computes the set of mutations necessary to update the annotated call log with respect to this * data source. * + * @see CallLogDataSource class doc for complete lifecyle information * @param mutations the set of mutations which this method should contribute to. Note that it may * contain inserts from the system call log, and these inserts should be modified by each data * source. */ @WorkerThread - void fill( - Context appContext, - SQLiteDatabase readableDatabase, - long lastRebuildTimeMillis, - CallLogMutations mutations); + void fill(Context appContext, CallLogMutations mutations); + + /** + * Called after database mutations have been applied to all data sources. This is useful for + * saving state such as the timestamp of the last row processed in an underlying database. Note + * that all mutations across all data sources are applied in a single transaction. + * + * @see CallLogDataSource class doc for complete lifecyle information + */ + @WorkerThread + void onSuccessfulFill(Context appContext); + + /** + * Combines raw annotated call log rows into a single coalesced row. + * + * <p>May be called by any worker thread at any time so implementations should take care to be + * threadsafe. (Ideally no state should be required to implement this.) + * + * @param individualRowsSortedByTimestampDesc group of fully populated rows from {@link + * AnnotatedCallLogContract.AnnotatedCallLog} which need to be combined for display purposes. + * This method should not modify this list. + * @return a partial {@link AnnotatedCallLogContract.CoalescedAnnotatedCallLog} row containing + * only columns which this data source is responsible for, which is the result of aggregating + * {@code individualRowsSortedByTimestampDesc}. + */ + @WorkerThread + ContentValues coalesce(List<ContentValues> individualRowsSortedByTimestampDesc); @MainThread void registerContentObservers( diff --git a/java/com/android/dialer/calllog/datasources/CallLogMutations.java b/java/com/android/dialer/calllog/datasources/CallLogMutations.java new file mode 100644 index 000000000..148601d68 --- /dev/null +++ b/java/com/android/dialer/calllog/datasources/CallLogMutations.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2017 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.dialer.calllog.datasources; + +import android.content.ContentValues; +import android.util.ArrayMap; +import android.util.ArraySet; +import com.android.dialer.common.Assert; + +/** A collection of mutations to the annotated call log. */ +public final class CallLogMutations { + + private final ArrayMap<Long, ContentValues> inserts = new ArrayMap<>(); + private final ArrayMap<Long, ContentValues> updates = new ArrayMap<>(); + private final ArraySet<Long> deletes = new ArraySet<>(); + + /** + * @param contentValues an entire row not including the ID + * @throws IllegalStateException if this {@link CallLogMutations} already contains an insert, + * update, or delete with the provided id + */ + public void insert(long id, ContentValues contentValues) { + Assert.checkArgument(!inserts.containsKey(id), "Can't insert row already scheduled for insert"); + Assert.checkArgument(!updates.containsKey(id), "Can't insert row scheduled for update"); + Assert.checkArgument(!deletes.contains(id), "Can't insert row scheduled for delete"); + + inserts.put(id, contentValues); + } + + /** + * Stores a database update using the provided ID and content values. If this {@link + * CallLogMutations} object already contains an update with the specified ID, the existing content + * values are merged with the provided ones, with the provided ones overwriting the existing ones + * for values with the same key. + * + * @param contentValues the specific columns to update, not including the ID. + * @throws IllegalStateException if this {@link CallLogMutations} already contains an insert or + * delete with the provided id + */ + public void update(long id, ContentValues contentValues) { + Assert.checkArgument(!inserts.containsKey(id), "Can't update row scheduled for insert"); + Assert.checkArgument(!deletes.contains(id), "Can't delete row scheduled for delete"); + + ContentValues existingContentValues = updates.get(id); + if (existingContentValues != null) { + existingContentValues.putAll(contentValues); + } else { + updates.put(id, contentValues); + } + } + + /** + * @throws IllegalStateException if this {@link CallLogMutations} already contains an insert, + * update, or delete with the provided id + */ + public void delete(long id) { + Assert.checkArgument(!inserts.containsKey(id), "Can't delete row scheduled for insert"); + Assert.checkArgument(!updates.containsKey(id), "Can't delete row scheduled for update"); + Assert.checkArgument(!deletes.contains(id), "Can't delete row already scheduled for delete"); + + deletes.add(id); + } + + public boolean isEmpty() { + return inserts.isEmpty() && updates.isEmpty() && deletes.isEmpty(); + } + + /** + * Get the pending inserts. + * + * @return the pending inserts where the key is the annotated call log database ID and the values + * are values to be inserted (not including the ID) + */ + public ArrayMap<Long, ContentValues> getInserts() { + return inserts; + } + + /** + * Get the pending updates. + * + * @return the pending updates where the key is the annotated call log database ID and the values + * are values to be updated (not including the ID) + */ + public ArrayMap<Long, ContentValues> getUpdates() { + return updates; + } + + /** + * Get the pending deletes. + * + * @return the annotated call log database IDs corresponding to the rows to be deleted + */ + public ArraySet<Long> getDeletes() { + return deletes; + } +} diff --git a/java/com/android/dialer/calllog/DataSources.java b/java/com/android/dialer/calllog/datasources/DataSources.java index 21d190167..911ca3fa3 100644 --- a/java/com/android/dialer/calllog/DataSources.java +++ b/java/com/android/dialer/calllog/datasources/DataSources.java @@ -14,14 +14,13 @@ * limitations under the License */ -package com.android.dialer.calllog; +package com.android.dialer.calllog.datasources; -import com.android.dialer.calllog.datasources.CallLogDataSource; import com.android.dialer.calllog.datasources.systemcalllog.SystemCallLogDataSource; import java.util.List; /** Immutable lists of data sources used to populate the annotated call log. */ -interface DataSources { +public interface DataSources { SystemCallLogDataSource getSystemCallLogDataSource(); diff --git a/java/com/android/dialer/calllog/datasources/contacts/ContactsDataSource.java b/java/com/android/dialer/calllog/datasources/contacts/ContactsDataSource.java index 355940f6a..f0384b09a 100644 --- a/java/com/android/dialer/calllog/datasources/contacts/ContactsDataSource.java +++ b/java/com/android/dialer/calllog/datasources/contacts/ContactsDataSource.java @@ -16,13 +16,14 @@ package com.android.dialer.calllog.datasources.contacts; +import android.content.ContentValues; import android.content.Context; -import android.database.sqlite.SQLiteDatabase; import android.support.annotation.MainThread; import android.support.annotation.WorkerThread; -import com.android.dialer.calllog.database.CallLogMutations; import com.android.dialer.calllog.datasources.CallLogDataSource; +import com.android.dialer.calllog.datasources.CallLogMutations; import com.android.dialer.common.Assert; +import java.util.List; import javax.inject.Inject; /** Responsible for maintaining the contacts related columns in the annotated call log. */ @@ -36,7 +37,7 @@ public final class ContactsDataSource implements CallLogDataSource { public boolean isDirty(Context appContext) { Assert.isWorkerThread(); - // TODO: Implementation. + // TODO(zachh): Implementation. return false; } @@ -44,17 +45,26 @@ public final class ContactsDataSource implements CallLogDataSource { @Override public void fill( Context appContext, - SQLiteDatabase readableDatabase, - long lastRebuildTimeMillis, CallLogMutations mutations) { Assert.isWorkerThread(); - // TODO: Implementation. + // TODO(zachh): Implementation. + } + + @Override + public void onSuccessfulFill(Context appContext) { + // TODO(zachh): Implementation. + } + + @Override + public ContentValues coalesce(List<ContentValues> individualRowsSortedByTimestampDesc) { + // TODO(zachh): Implementation. + return new ContentValues(); } @MainThread @Override public void registerContentObservers( Context appContext, ContentObserverCallbacks contentObserverCallbacks) { - // TODO: Guard against missing permissions during callback registration. + // TODO(zachh): Guard against missing permissions during callback registration. } } diff --git a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java index ea6663fbe..1bdbb8a1b 100644 --- a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java +++ b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java @@ -16,28 +16,59 @@ package com.android.dialer.calllog.datasources.systemcalllog; +import android.Manifest.permission; +import android.annotation.TargetApi; +import android.content.ContentValues; import android.content.Context; import android.database.ContentObserver; -import android.database.sqlite.SQLiteDatabase; +import android.database.Cursor; import android.net.Uri; +import android.os.Build; import android.os.Handler; +import android.preference.PreferenceManager; import android.provider.CallLog; +import android.provider.CallLog.Calls; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.support.annotation.ColorInt; import android.support.annotation.MainThread; +import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import android.support.annotation.WorkerThread; -import com.android.dialer.calllog.database.CallLogMutations; +import android.telecom.PhoneAccount; +import android.telecom.PhoneAccountHandle; +import android.text.TextUtils; +import android.util.ArraySet; +import com.android.dialer.CallTypes; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.CoalescedAnnotatedCallLog; import com.android.dialer.calllog.datasources.CallLogDataSource; +import com.android.dialer.calllog.datasources.CallLogMutations; +import com.android.dialer.calllog.datasources.util.RowCombiner; +import com.android.dialer.calllogutils.PhoneAccountUtils; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.ThreadUtil; +import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil; +import com.android.dialer.theme.R; import com.android.dialer.util.PermissionsUtil; +import com.google.i18n.phonenumbers.PhoneNumberUtil; +import java.util.Arrays; +import java.util.List; +import java.util.Set; import javax.inject.Inject; /** * Responsible for defining the rows in the annotated call log and maintaining the columns in it * which are derived from the system call log. */ +@SuppressWarnings("MissingPermission") public class SystemCallLogDataSource implements CallLogDataSource { + @VisibleForTesting + static final String PREF_LAST_TIMESTAMP_PROCESSED = "systemCallLogLastTimestampProcessed"; + + @Nullable private Long lastTimestampProcessed; + @Inject public SystemCallLogDataSource() {} @@ -47,10 +78,13 @@ public class SystemCallLogDataSource implements CallLogDataSource { Context appContext, ContentObserverCallbacks contentObserverCallbacks) { Assert.isMainThread(); + LogUtil.enterBlock("SystemCallLogDataSource.registerContentObservers"); + if (!PermissionsUtil.hasCallLogReadPermissions(appContext)) { LogUtil.i("SystemCallLogDataSource.registerContentObservers", "no call log permissions"); return; } + // TODO(zachh): Need to somehow register observers if user enables permission after launch? appContext .getContentResolver() @@ -71,23 +105,328 @@ public class SystemCallLogDataSource implements CallLogDataSource { * column is unused). This means that we can't detect deletes without scanning the entire table, * which would be too slow. So, we just rely on content observers to trigger rebuilds when any * change is made to the system call log. + * + * Just return false unless the table has never been written to. */ - return false; + return !PreferenceManager.getDefaultSharedPreferences(appContext) + .contains(PREF_LAST_TIMESTAMP_PROCESSED); } @WorkerThread @Override - public void fill( - Context appContext, - SQLiteDatabase readableDatabase, - long lastRebuildTimeMillis, - CallLogMutations mutations) { + public void fill(Context appContext, CallLogMutations mutations) { Assert.isWorkerThread(); + lastTimestampProcessed = null; + + if (!PermissionsUtil.hasPermission(appContext, permission.READ_CALL_LOG)) { + LogUtil.i("SystemCallLogDataSource.fill", "no call log permissions"); + return; + } + // This data source should always run first so the mutations should always be empty. - Assert.checkState(mutations.isEmpty()); + Assert.checkArgument(mutations.isEmpty()); + + Set<Long> annotatedCallLogIds = getAnnotatedCallLogIds(appContext); + + LogUtil.i( + "SystemCallLogDataSource.fill", + "found %d existing annotated call log ids", + annotatedCallLogIds.size()); + + handleInsertsAndUpdates(appContext, mutations, annotatedCallLogIds); + handleDeletes(appContext, annotatedCallLogIds, mutations); + } + + @WorkerThread + @Override + public void onSuccessfulFill(Context appContext) { + // If a fill operation was a no-op, lastTimestampProcessed could still be null. + if (lastTimestampProcessed != null) { + PreferenceManager.getDefaultSharedPreferences(appContext) + .edit() + .putLong(PREF_LAST_TIMESTAMP_PROCESSED, lastTimestampProcessed) + .apply(); + } + } + + @Override + public ContentValues coalesce(List<ContentValues> individualRowsSortedByTimestampDesc) { + // TODO(zachh): Complete implementation. + ContentValues coalescedValues = + new RowCombiner(individualRowsSortedByTimestampDesc) + .useMostRecentLong(AnnotatedCallLog.TIMESTAMP) + .useMostRecentLong(AnnotatedCallLog.NEW) + .useMostRecentString(AnnotatedCallLog.NUMBER_TYPE_LABEL) + .useMostRecentString(AnnotatedCallLog.NAME) + .useMostRecentString(AnnotatedCallLog.FORMATTED_NUMBER) + .useMostRecentString(AnnotatedCallLog.PHOTO_URI) + .useMostRecentLong(AnnotatedCallLog.PHOTO_ID) + .useMostRecentString(AnnotatedCallLog.LOOKUP_URI) + .useMostRecentString(AnnotatedCallLog.GEOCODED_LOCATION) + .useSingleValueString(AnnotatedCallLog.PHONE_ACCOUNT_LABEL) + .useSingleValueLong(AnnotatedCallLog.PHONE_ACCOUNT_COLOR) + .combine(); + + CallTypes.Builder callTypes = CallTypes.newBuilder(); + // Store a maximum of 3 call types since that's all we show to users via icons. + for (int i = 0; i < 3 && i < individualRowsSortedByTimestampDesc.size(); i++) { + callTypes.addType( + individualRowsSortedByTimestampDesc.get(i).getAsInteger(AnnotatedCallLog.TYPE)); + } + coalescedValues.put(CoalescedAnnotatedCallLog.CALL_TYPES, callTypes.build().toByteArray()); + + return coalescedValues; + } + + @TargetApi(Build.VERSION_CODES.M) // Uses try-with-resources + private void handleInsertsAndUpdates( + Context appContext, CallLogMutations mutations, Set<Long> existingAnnotatedCallLogIds) { + long previousTimestampProcessed = + PreferenceManager.getDefaultSharedPreferences(appContext) + .getLong(PREF_LAST_TIMESTAMP_PROCESSED, 0L); + + DialerPhoneNumberUtil dialerPhoneNumberUtil = + new DialerPhoneNumberUtil(PhoneNumberUtil.getInstance()); + + // TODO(zachh): Really should be getting last 1000 by timestamp, not by last modified. + try (Cursor cursor = + appContext + .getContentResolver() + .query( + Calls.CONTENT_URI, // Excludes voicemail + new String[] { + Calls._ID, + Calls.DATE, + Calls.LAST_MODIFIED, + Calls.NUMBER, + Calls.TYPE, + Calls.COUNTRY_ISO, + Calls.CACHED_NAME, + Calls.CACHED_FORMATTED_NUMBER, + Calls.CACHED_PHOTO_URI, + Calls.CACHED_PHOTO_ID, + Calls.CACHED_LOOKUP_URI, + Calls.CACHED_NUMBER_TYPE, + Calls.CACHED_NUMBER_LABEL, + Calls.IS_READ, + Calls.NEW, + Calls.GEOCODED_LOCATION, + Calls.PHONE_ACCOUNT_COMPONENT_NAME, + Calls.PHONE_ACCOUNT_ID, + Calls.FEATURES + }, + Calls.LAST_MODIFIED + " > ?", + new String[] {String.valueOf(previousTimestampProcessed)}, + Calls.LAST_MODIFIED + " DESC LIMIT 1000")) { + + if (cursor == null) { + LogUtil.e("SystemCallLogDataSource.handleInsertsAndUpdates", "null cursor"); + return; + } + + LogUtil.i( + "SystemCallLogDataSource.handleInsertsAndUpdates", + "found %d entries to insert/update", + cursor.getCount()); + + if (cursor.moveToFirst()) { + int idColumn = cursor.getColumnIndexOrThrow(Calls._ID); + int dateColumn = cursor.getColumnIndexOrThrow(Calls.DATE); + int lastModifiedColumn = cursor.getColumnIndexOrThrow(Calls.LAST_MODIFIED); + int numberColumn = cursor.getColumnIndexOrThrow(Calls.NUMBER); + int typeColumn = cursor.getColumnIndexOrThrow(Calls.TYPE); + int countryIsoColumn = cursor.getColumnIndexOrThrow(Calls.COUNTRY_ISO); + int cachedNameColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_NAME); + int cachedFormattedNumberColumn = + cursor.getColumnIndexOrThrow(Calls.CACHED_FORMATTED_NUMBER); + int cachedPhotoUriColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_PHOTO_URI); + int cachedPhotoIdColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_PHOTO_ID); + int cachedLookupUriColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_LOOKUP_URI); + int cachedNumberTypeColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_NUMBER_TYPE); + int cachedNumberLabelColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_NUMBER_LABEL); + int isReadColumn = cursor.getColumnIndexOrThrow(Calls.IS_READ); + int newColumn = cursor.getColumnIndexOrThrow(Calls.NEW); + int geocodedLocationColumn = cursor.getColumnIndexOrThrow(Calls.GEOCODED_LOCATION); + int phoneAccountComponentColumn = + cursor.getColumnIndexOrThrow(Calls.PHONE_ACCOUNT_COMPONENT_NAME); + int phoneAccountIdColumn = cursor.getColumnIndexOrThrow(Calls.PHONE_ACCOUNT_ID); + int featuresColumn = cursor.getColumnIndexOrThrow(Calls.FEATURES); + + // The cursor orders by LAST_MODIFIED DESC, so the first result is the most recent timestamp + // processed. + lastTimestampProcessed = cursor.getLong(lastModifiedColumn); + do { + long id = cursor.getLong(idColumn); + long date = cursor.getLong(dateColumn); + String numberAsStr = cursor.getString(numberColumn); + long type = cursor.getInt(typeColumn); + String countryIso = cursor.getString(countryIsoColumn); + String cachedName = cursor.getString(cachedNameColumn); + String formattedNumber = cursor.getString(cachedFormattedNumberColumn); + String cachedPhotoUri = cursor.getString(cachedPhotoUriColumn); + long cachedPhotoId = cursor.getLong(cachedPhotoIdColumn); + String cachedLookupUri = cursor.getString(cachedLookupUriColumn); + int cachedNumberType = cursor.getInt(cachedNumberTypeColumn); + String cachedNumberLabel = cursor.getString(cachedNumberLabelColumn); + int isRead = cursor.getInt(isReadColumn); + int isNew = cursor.getInt(newColumn); + String geocodedLocation = cursor.getString(geocodedLocationColumn); + String phoneAccountComponentName = cursor.getString(phoneAccountComponentColumn); + String phoneAccountId = cursor.getString(phoneAccountIdColumn); + int features = cursor.getInt(featuresColumn); + + ContentValues contentValues = new ContentValues(); + contentValues.put(AnnotatedCallLog.TIMESTAMP, date); + + if (!TextUtils.isEmpty(numberAsStr)) { + byte[] numberAsProtoBytes = + dialerPhoneNumberUtil.parse(numberAsStr, countryIso).toByteArray(); + // TODO(zachh): Need to handle post-dial digits; different on N and M. + contentValues.put(AnnotatedCallLog.NUMBER, numberAsProtoBytes); + } - // TODO: Implementation. + contentValues.put(AnnotatedCallLog.TYPE, type); + contentValues.put(AnnotatedCallLog.NAME, cachedName); + contentValues.put(AnnotatedCallLog.FORMATTED_NUMBER, formattedNumber); + contentValues.put(AnnotatedCallLog.PHOTO_URI, cachedPhotoUri); + contentValues.put(AnnotatedCallLog.PHOTO_ID, cachedPhotoId); + contentValues.put(AnnotatedCallLog.LOOKUP_URI, cachedLookupUri); + + // Phone.getTypeLabel returns "Custom" if given (0, null) which is not of any use. Just + // omit setting the label if there's no information for it. + if (cachedNumberType != 0 || cachedNumberLabel != null) { + contentValues.put( + AnnotatedCallLog.NUMBER_TYPE_LABEL, + Phone.getTypeLabel(appContext.getResources(), cachedNumberType, cachedNumberLabel) + .toString()); + } + contentValues.put(AnnotatedCallLog.IS_READ, isRead); + contentValues.put(AnnotatedCallLog.NEW, isNew); + contentValues.put(AnnotatedCallLog.GEOCODED_LOCATION, geocodedLocation); + populatePhoneAccountLabelAndColor( + appContext, contentValues, phoneAccountComponentName, phoneAccountId); + contentValues.put(AnnotatedCallLog.FEATURES, features); + + if (existingAnnotatedCallLogIds.contains(id)) { + mutations.update(id, contentValues); + } else { + mutations.insert(id, contentValues); + } + } while (cursor.moveToNext()); + } // else no new results, do nothing. + } + } + + private void populatePhoneAccountLabelAndColor( + Context appContext, + ContentValues contentValues, + String phoneAccountComponentName, + String phoneAccountId) { + PhoneAccountHandle phoneAccountHandle = + PhoneAccountUtils.getAccount(phoneAccountComponentName, phoneAccountId); + if (phoneAccountHandle == null) { + return; + } + String label = PhoneAccountUtils.getAccountLabel(appContext, phoneAccountHandle); + if (TextUtils.isEmpty(label)) { + return; + } + contentValues.put(AnnotatedCallLog.PHONE_ACCOUNT_LABEL, label); + + @ColorInt int color = PhoneAccountUtils.getAccountColor(appContext, phoneAccountHandle); + if (color == PhoneAccount.NO_HIGHLIGHT_COLOR) { + color = + appContext + .getResources() + .getColor(R.color.dialer_secondary_text_color, appContext.getTheme()); + } + contentValues.put(AnnotatedCallLog.PHONE_ACCOUNT_COLOR, color); + } + + private static void handleDeletes( + Context appContext, Set<Long> existingAnnotatedCallLogIds, CallLogMutations mutations) { + Set<Long> systemCallLogIds = + getIdsFromSystemCallLogThatMatch(appContext, existingAnnotatedCallLogIds); + LogUtil.i( + "SystemCallLogDataSource.handleDeletes", + "found %d matching entries in system call log", + systemCallLogIds.size()); + Set<Long> idsInAnnotatedCallLogNoLongerInSystemCallLog = new ArraySet<>(); + idsInAnnotatedCallLogNoLongerInSystemCallLog.addAll(existingAnnotatedCallLogIds); + idsInAnnotatedCallLogNoLongerInSystemCallLog.removeAll(systemCallLogIds); + + LogUtil.i( + "SystemCallLogDataSource.handleDeletes", + "found %d call log entries to remove", + idsInAnnotatedCallLogNoLongerInSystemCallLog.size()); + + for (long id : idsInAnnotatedCallLogNoLongerInSystemCallLog) { + mutations.delete(id); + } + } + + @TargetApi(Build.VERSION_CODES.M) // Uses try-with-resources + private static Set<Long> getAnnotatedCallLogIds(Context appContext) { + ArraySet<Long> ids = new ArraySet<>(); + + try (Cursor cursor = + appContext + .getContentResolver() + .query( + AnnotatedCallLog.CONTENT_URI, + new String[] {AnnotatedCallLog._ID}, + null, + null, + null)) { + + if (cursor == null) { + LogUtil.e("SystemCallLogDataSource.getAnnotatedCallLogIds", "null cursor"); + return ids; + } + + if (cursor.moveToFirst()) { + int idColumn = cursor.getColumnIndexOrThrow(AnnotatedCallLog._ID); + do { + ids.add(cursor.getLong(idColumn)); + } while (cursor.moveToNext()); + } + } + return ids; + } + + @TargetApi(Build.VERSION_CODES.M) // Uses try-with-resources + private static Set<Long> getIdsFromSystemCallLogThatMatch( + Context appContext, Set<Long> matchingIds) { + ArraySet<Long> ids = new ArraySet<>(); + + String[] questionMarks = new String[matchingIds.size()]; + Arrays.fill(questionMarks, "?"); + String whereClause = (Calls._ID + " in (") + TextUtils.join(",", questionMarks) + ")"; + String[] whereArgs = new String[matchingIds.size()]; + int i = 0; + for (long id : matchingIds) { + whereArgs[i++] = String.valueOf(id); + } + + try (Cursor cursor = + appContext + .getContentResolver() + .query(Calls.CONTENT_URI, new String[] {Calls._ID}, whereClause, whereArgs, null)) { + + if (cursor == null) { + LogUtil.e("SystemCallLogDataSource.getIdsFromSystemCallLog", "null cursor"); + return ids; + } + + if (cursor.moveToFirst()) { + int idColumn = cursor.getColumnIndexOrThrow(Calls._ID); + do { + ids.add(cursor.getLong(idColumn)); + } while (cursor.moveToNext()); + } + return ids; + } } private static class CallLogObserver extends ContentObserver { diff --git a/java/com/android/dialer/calllog/datasources/util/RowCombiner.java b/java/com/android/dialer/calllog/datasources/util/RowCombiner.java new file mode 100644 index 000000000..adb7a0742 --- /dev/null +++ b/java/com/android/dialer/calllog/datasources/util/RowCombiner.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2017 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.dialer.calllog.datasources.util; + +import android.content.ContentValues; +import com.android.dialer.common.Assert; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +/** Convenience class for aggregating row values. */ +public class RowCombiner { + private final List<ContentValues> individualRowsSortedByTimestampDesc; + private final ContentValues combinedRow = new ContentValues(); + + public RowCombiner(List<ContentValues> individualRowsSortedByTimestampDesc) { + Assert.checkArgument(!individualRowsSortedByTimestampDesc.isEmpty()); + this.individualRowsSortedByTimestampDesc = individualRowsSortedByTimestampDesc; + } + + /** Use the most recent value for the specified column. */ + public RowCombiner useMostRecentLong(String columnName) { + combinedRow.put(columnName, individualRowsSortedByTimestampDesc.get(0).getAsLong(columnName)); + return this; + } + + /** Use the most recent value for the specified column. */ + public RowCombiner useMostRecentString(String columnName) { + combinedRow.put(columnName, individualRowsSortedByTimestampDesc.get(0).getAsString(columnName)); + return this; + } + + /** Asserts that all column values for the given column name are the same, and uses it. */ + public RowCombiner useSingleValueString(String columnName) { + Iterator<ContentValues> iterator = individualRowsSortedByTimestampDesc.iterator(); + String singleValue = iterator.next().getAsString(columnName); + while (iterator.hasNext()) { + String current = iterator.next().getAsString(columnName); + Assert.checkState(Objects.equals(singleValue, current), "Values different for " + columnName); + } + combinedRow.put(columnName, singleValue); + return this; + } + + /** Asserts that all column values for the given column name are the same, and uses it. */ + public RowCombiner useSingleValueLong(String columnName) { + Iterator<ContentValues> iterator = individualRowsSortedByTimestampDesc.iterator(); + Long singleValue = iterator.next().getAsLong(columnName); + while (iterator.hasNext()) { + Long current = iterator.next().getAsLong(columnName); + Assert.checkState(Objects.equals(singleValue, current), "Values different for " + columnName); + } + combinedRow.put(columnName, singleValue); + return this; + } + + public ContentValues combine() { + return combinedRow; + } +} diff --git a/java/com/android/dialer/calllog/ui/AndroidManifest.xml b/java/com/android/dialer/calllog/ui/AndroidManifest.xml index 228167749..eaf71aba8 100644 --- a/java/com/android/dialer/calllog/ui/AndroidManifest.xml +++ b/java/com/android/dialer/calllog/ui/AndroidManifest.xml @@ -13,4 +13,4 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> -<manifest package="com.android.dialer.calllog"/> +<manifest package="com.android.dialer.calllog.ui"/> diff --git a/java/com/android/dialer/calllog/ui/AnnotatedCallLogCursorLoader.java b/java/com/android/dialer/calllog/ui/AnnotatedCallLogCursorLoader.java deleted file mode 100644 index cd8622e80..000000000 --- a/java/com/android/dialer/calllog/ui/AnnotatedCallLogCursorLoader.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2017 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.dialer.calllog.ui; - -import android.annotation.TargetApi; -import android.content.Context; -import android.content.CursorLoader; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.os.Build; -import com.android.dialer.calllog.database.AnnotatedCallLog; -import com.android.dialer.calllog.database.AnnotatedCallLog.Columns; - -/** CursorLoader which reads the annotated call log. */ -class AnnotatedCallLogCursorLoader extends CursorLoader { - - AnnotatedCallLogCursorLoader(Context context) { - super(context); - } - - @TargetApi(Build.VERSION_CODES.M) // Uses try-with-resources - @Override - public Cursor loadInBackground() { - try (SQLiteDatabase readableDatabase = AnnotatedCallLog.getReadableDatabase(getContext())) { - return readableDatabase.rawQuery( - "SELECT * FROM " - + AnnotatedCallLog.TABLE_NAME - + " ORDER BY " - + Columns.TIMESTAMP - + " DESC", - null /* selectionArgs */); - } - } -} diff --git a/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java b/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java new file mode 100644 index 000000000..d89338350 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2017 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.dialer.calllog.ui; + +import android.content.Context; +import android.database.Cursor; +import android.support.annotation.ColorInt; +import android.support.annotation.NonNull; +import android.support.v4.content.CursorLoader; +import com.android.dialer.CallTypes; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.CoalescedAnnotatedCallLog; +import com.android.dialer.common.Assert; +import com.google.protobuf.InvalidProtocolBufferException; + +/** CursorLoader for the coalesced annotated call log. */ +final class CoalescedAnnotatedCallLogCursorLoader extends CursorLoader { + + /** Indexes for CoalescedAnnotatedCallLog.ALL_COLUMNS */ + private static final int ID = 0; + + private static final int TIMESTAMP = 1; + private static final int NAME = 2; + private static final int FORMATTED_NUMBER = 3; + private static final int PHOTO_URI = 4; + private static final int PHOTO_ID = 5; + private static final int LOOKUP_URI = 6; + private static final int NUMBER_TYPE_LABEL = 7; + private static final int IS_READ = 8; + private static final int NEW = 9; + private static final int GEOCODED_LOCATION = 10; + private static final int PHONE_ACCOUNT_LABEL = 11; + private static final int PHONE_ACCOUNT_COLOR = 12; + private static final int FEATURES = 13; + private static final int IS_BUSINESS = 14; + private static final int IS_VOICEMAIL = 15; + private static final int NUMBER_CALLS = 16; + private static final int CALL_TYPES = 17; + + /** Convenience class for accessing values using an abbreviated syntax. */ + static final class Row { + private final Cursor cursor; + + Row(Cursor cursor) { + this.cursor = cursor; + } + + long id() { + return cursor.getInt(ID); + } + + long timestamp() { + return cursor.getLong(TIMESTAMP); + } + + String name() { + return cursor.getString(NAME); + } + + String formattedNumber() { + return cursor.getString(FORMATTED_NUMBER); + } + + String photoUri() { + return cursor.getString(PHOTO_URI); + } + + long photoId() { + return cursor.getLong(PHOTO_ID); + } + + String lookupUri() { + return cursor.getString(LOOKUP_URI); + } + + String numberTypeLabel() { + return cursor.getString(NUMBER_TYPE_LABEL); + } + + boolean isRead() { + return cursor.getInt(IS_READ) == 1; + } + + boolean isNew() { + return cursor.getInt(NEW) == 1; + } + + String geocodedLocation() { + return cursor.getString(GEOCODED_LOCATION); + } + + String phoneAccountLabel() { + return cursor.getString(PHONE_ACCOUNT_LABEL); + } + + @ColorInt + int phoneAccountColor() { + return cursor.getInt(PHONE_ACCOUNT_COLOR); + } + + int features() { + return cursor.getInt(FEATURES); + } + + boolean isBusiness() { + return cursor.getInt(IS_BUSINESS) == 1; + } + + boolean isVoicemail() { + return cursor.getInt(IS_VOICEMAIL) == 1; + } + + int numberCalls() { + return cursor.getInt(NUMBER_CALLS); + } + + @NonNull + CallTypes callTypes() { + try { + return CallTypes.parseFrom(cursor.getBlob(CALL_TYPES)); + } catch (InvalidProtocolBufferException e) { + throw Assert.createAssertionFailException("Couldn't parse call types", e); + } + } + } + + CoalescedAnnotatedCallLogCursorLoader(Context context) { + // CoalescedAnnotatedCallLog requires that PROJECTION be ALL_COLUMNS and the following params be + // null. + super( + context, + CoalescedAnnotatedCallLog.CONTENT_URI, + CoalescedAnnotatedCallLog.ALL_COLUMNS, + null, + null, + null); + } +} diff --git a/java/com/android/dialer/calllog/ui/HeaderViewHolder.java b/java/com/android/dialer/calllog/ui/HeaderViewHolder.java new file mode 100644 index 000000000..e4fe029fa --- /dev/null +++ b/java/com/android/dialer/calllog/ui/HeaderViewHolder.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2017 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.dialer.calllog.ui; + +import android.support.annotation.StringRes; +import android.support.v7.widget.RecyclerView.ViewHolder; +import android.view.View; +import android.widget.TextView; + +/** ViewHolder for {@link NewCallLogAdapter} to display "Today" or "Older" divider row. */ +final class HeaderViewHolder extends ViewHolder { + + private TextView headerTextView; + + HeaderViewHolder(View view) { + super(view); + headerTextView = view.findViewById(R.id.new_call_log_header_text); + } + + void setHeader(@StringRes int header) { + headerTextView.setText(header); + } +} diff --git a/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java b/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java new file mode 100644 index 000000000..b922a6e3b --- /dev/null +++ b/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2017 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.dialer.calllog.ui; + +import android.database.Cursor; +import android.support.annotation.IntDef; +import android.support.annotation.Nullable; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.ViewHolder; +import android.view.LayoutInflater; +import android.view.ViewGroup; +import com.android.dialer.calllogutils.CallLogDates; +import com.android.dialer.common.Assert; +import com.android.dialer.time.Clock; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** {@link RecyclerView.Adapter} for the new call log fragment. */ +final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> { + + /** IntDef for the different types of rows that can be shown in the call log. */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({RowType.HEADER_TODAY, RowType.HEADER_OLDER, RowType.CALL_LOG_ENTRY}) + @interface RowType { + /** Header that displays "Today". */ + int HEADER_TODAY = 1; + /** Header that displays "Older". */ + int HEADER_OLDER = 2; + /** A row representing a call log entry (which could represent one or more calls). */ + int CALL_LOG_ENTRY = 3; + } + + private final Cursor cursor; + private final Clock clock; + + /** Null when the "Today" header should not be displayed. */ + @Nullable private final Integer todayHeaderPosition; + /** Null when the "Older" header should not be displayed. */ + @Nullable private final Integer olderHeaderPosition; + + NewCallLogAdapter(Cursor cursor, Clock clock) { + this.cursor = cursor; + this.clock = clock; + + // Calculate header adapter positions by reading cursor. + long currentTimeMillis = clock.currentTimeMillis(); + if (cursor.moveToNext()) { + CoalescedAnnotatedCallLogCursorLoader.Row firstRow = + new CoalescedAnnotatedCallLogCursorLoader.Row(cursor); + if (CallLogDates.isSameDay(currentTimeMillis, firstRow.timestamp())) { + this.todayHeaderPosition = 0; + int adapterPosition = 2; // Accounted for "Today" header and first row. + while (cursor.moveToNext()) { + CoalescedAnnotatedCallLogCursorLoader.Row row = + new CoalescedAnnotatedCallLogCursorLoader.Row(cursor); + if (CallLogDates.isSameDay(currentTimeMillis, row.timestamp())) { + adapterPosition++; + } else { + this.olderHeaderPosition = adapterPosition; + return; + } + } + this.olderHeaderPosition = null; // Didn't find any "Older" rows. + } else { + this.todayHeaderPosition = null; // Didn't find any "Today" rows. + this.olderHeaderPosition = 0; + } + } else { // There are no rows, just need to set these because they are final. + this.todayHeaderPosition = null; + this.olderHeaderPosition = null; + } + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup viewGroup, @RowType int viewType) { + switch (viewType) { + case RowType.HEADER_TODAY: + case RowType.HEADER_OLDER: + return new HeaderViewHolder( + LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.new_call_log_header, viewGroup, false)); + case RowType.CALL_LOG_ENTRY: + return new NewCallLogViewHolder( + LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.new_call_log_entry, viewGroup, false), + clock); + default: + throw Assert.createUnsupportedOperationFailException("Unsupported view type: " + viewType); + } + } + + @Override + public void onBindViewHolder(ViewHolder viewHolder, int position) { + if (viewHolder instanceof HeaderViewHolder) { + HeaderViewHolder headerViewHolder = (HeaderViewHolder) viewHolder; + @RowType int viewType = getItemViewType(position); + if (viewType == RowType.HEADER_OLDER) { + headerViewHolder.setHeader(R.string.new_call_log_header_older); + } else if (viewType == RowType.HEADER_TODAY) { + headerViewHolder.setHeader(R.string.new_call_log_header_today); + } else { + throw Assert.createIllegalStateFailException( + "Unexpected view type " + viewType + " at position: " + position); + } + return; + } + NewCallLogViewHolder newCallLogViewHolder = (NewCallLogViewHolder) viewHolder; + int previousHeaders = 0; + if (todayHeaderPosition != null && position > todayHeaderPosition) { + previousHeaders++; + } + if (olderHeaderPosition != null && position > olderHeaderPosition) { + previousHeaders++; + } + cursor.moveToPosition(position - previousHeaders); + newCallLogViewHolder.bind(cursor); + } + + @Override + @RowType + public int getItemViewType(int position) { + if (todayHeaderPosition != null && position == todayHeaderPosition) { + return RowType.HEADER_TODAY; + } + if (olderHeaderPosition != null && position == olderHeaderPosition) { + return RowType.HEADER_OLDER; + } + return RowType.CALL_LOG_ENTRY; + } + + @Override + public int getItemCount() { + int numberOfHeaders = 0; + if (todayHeaderPosition != null) { + numberOfHeaders++; + } + if (olderHeaderPosition != null) { + numberOfHeaders++; + } + return cursor.getCount() + numberOfHeaders; + } +} diff --git a/java/com/android/dialer/calllog/ui/NewCallLogFragment.java b/java/com/android/dialer/calllog/ui/NewCallLogFragment.java index b8f2b1326..ab7381347 100644 --- a/java/com/android/dialer/calllog/ui/NewCallLogFragment.java +++ b/java/com/android/dialer/calllog/ui/NewCallLogFragment.java @@ -15,32 +15,38 @@ */ package com.android.dialer.calllog.ui; -import android.app.Fragment; -import android.app.LoaderManager.LoaderCallbacks; -import android.content.Context; -import android.content.Loader; import android.database.Cursor; import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.LoaderManager.LoaderCallbacks; +import android.support.v4.content.Loader; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.CursorAdapter; -import android.widget.ListView; -import android.widget.SimpleCursorAdapter; -import android.widget.TextView; import com.android.dialer.calllog.CallLogComponent; import com.android.dialer.calllog.CallLogFramework; import com.android.dialer.calllog.CallLogFramework.CallLogUi; -import com.android.dialer.calllog.database.AnnotatedCallLog.Columns; import com.android.dialer.common.LogUtil; -import java.text.SimpleDateFormat; -import java.util.Locale; +import com.android.dialer.common.concurrent.DialerExecutor; +import com.android.dialer.common.concurrent.DialerExecutorComponent; +import com.android.dialer.common.concurrent.DialerExecutorFactory; /** The "new" call log fragment implementation, which is built on top of the annotated call log. */ public final class NewCallLogFragment extends Fragment implements CallLogUi, LoaderCallbacks<Cursor> { - private CursorAdapter cursorAdapter; + /* + * This is a reasonable time that it might take between related call log writes, that also + * shouldn't slow down single-writes too much. For example, when populating the database using + * the simulator, using this value results in ~6 refresh cycles (on a release build) to write 120 + * call log entries. + */ + private static final long WAIT_MILLIS = 100L; + + private DialerExecutor<Boolean> refreshAnnotatedCallLogTask; + private RecyclerView recyclerView; public NewCallLogFragment() { LogUtil.enterBlock("NewCallLogFragment.NewCallLogFragment"); @@ -52,8 +58,28 @@ public final class NewCallLogFragment extends Fragment LogUtil.enterBlock("NewCallLogFragment.onCreate"); - CallLogFramework callLogFramework = CallLogComponent.get(getContext()).callLogFramework(); + CallLogComponent component = CallLogComponent.get(getContext()); + CallLogFramework callLogFramework = component.callLogFramework(); callLogFramework.attachUi(this); + + DialerExecutorFactory dialerExecutorFactory = + DialerExecutorComponent.get(getContext()).dialerExecutorFactory(); + + // TODO(zachh): Use support fragment manager and add support for them in executors library. + refreshAnnotatedCallLogTask = + dialerExecutorFactory + .createUiTaskBuilder( + getActivity().getFragmentManager(), + "NewCallLogFragment.refreshAnnotatedCallLog", + component.getRefreshAnnotatedCallLogWorker()) + .build(); + } + + @Override + public void onStart() { + super.onStart(); + + LogUtil.enterBlock("NewCallLogFragment.onStart"); } @Override @@ -64,6 +90,9 @@ public final class NewCallLogFragment extends Fragment CallLogFramework callLogFramework = CallLogComponent.get(getContext()).callLogFramework(); callLogFramework.attachUi(this); + + // TODO(zachh): Consider doing this when fragment becomes visible. + checkAnnotatedCallLogDirtyAndRefreshIfNecessary(); } @Override @@ -82,57 +111,48 @@ public final class NewCallLogFragment extends Fragment LogUtil.enterBlock("NewCallLogFragment.onCreateView"); View view = inflater.inflate(R.layout.new_call_log_fragment, container, false); - ListView listView = (ListView) view.findViewById(R.id.list); + recyclerView = view.findViewById(R.id.new_call_log_recycler_view); - this.cursorAdapter = - new MyCursorAdapter( - getContext(), - R.layout.new_call_log_entry, - null /* cursor */, - new String[] {Columns.TIMESTAMP, Columns.CONTACT_NAME}, - new int[] {R.id.timestamp, R.id.contact_name}, - 0); - listView.setAdapter(cursorAdapter); - - getLoaderManager().initLoader(0, null, this); + getLoaderManager().restartLoader(0, null, this); return view; } + private void checkAnnotatedCallLogDirtyAndRefreshIfNecessary() { + LogUtil.enterBlock("NewCallLogFragment.checkAnnotatedCallLogDirtyAndRefreshIfNecessary"); + refreshAnnotatedCallLogTask.executeSerialWithWait(false /* skipDirtyCheck */, WAIT_MILLIS); + } + @Override public void invalidateUi() { LogUtil.enterBlock("NewCallLogFragment.invalidateUi"); - // TODO: Implementation. + refreshAnnotatedCallLogTask.executeSerialWithWait(true /* skipDirtyCheck */, WAIT_MILLIS); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { - // TODO: This is sort of weird, do we need to implement a content provider? - return new AnnotatedCallLogCursorLoader(getContext()); + LogUtil.enterBlock("NewCallLogFragment.onCreateLoader"); + return new CoalescedAnnotatedCallLogCursorLoader(getContext()); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor newCursor) { - cursorAdapter.swapCursor(newCursor); + LogUtil.enterBlock("NewCallLogFragment.onLoadFinished"); + + if (newCursor == null) { + // This might be possible when the annotated call log hasn't been created but we're trying + // to show the call log. + LogUtil.w("NewCallLogFragment.onLoadFinished", "null cursor"); + return; + } + // TODO(zachh): Handle empty cursor by showing empty view. + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.setAdapter(new NewCallLogAdapter(newCursor, System::currentTimeMillis)); } @Override public void onLoaderReset(Loader<Cursor> loader) { - cursorAdapter.swapCursor(null); - } - - private static class MyCursorAdapter extends SimpleCursorAdapter { - - MyCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) { - super(context, layout, c, from, to, flags); - } - - @Override - public void setViewText(TextView view, String text) { - if (view.getId() == R.id.timestamp) { - text = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US).format(Long.valueOf(text)); - } - view.setText(text); - } + LogUtil.enterBlock("NewCallLogFragment.onLoaderReset"); + recyclerView.setAdapter(null); } } diff --git a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java new file mode 100644 index 000000000..e198a38e8 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2017 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.dialer.calllog.ui; + +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.provider.CallLog.Calls; +import android.support.v7.widget.RecyclerView; +import android.text.TextUtils; +import android.view.View; +import android.widget.QuickContactBadge; +import android.widget.TextView; +import com.android.dialer.calllog.ui.CoalescedAnnotatedCallLogCursorLoader.Row; +import com.android.dialer.calllogutils.CallLogDates; +import com.android.dialer.calllogutils.CallTypeIconsView; +import com.android.dialer.contactphoto.ContactPhotoManager; +import com.android.dialer.lettertile.LetterTileDrawable; +import com.android.dialer.oem.MotorolaUtils; +import com.android.dialer.time.Clock; +import java.util.Locale; + +/** {@link RecyclerView.ViewHolder} for the new call log. */ +final class NewCallLogViewHolder extends RecyclerView.ViewHolder { + + private final Context context; + private final TextView primaryTextView; + private final TextView secondaryTextView; + private final QuickContactBadge quickContactBadge; + private final CallTypeIconsView primaryCallTypeIconsView; // Used for Wifi, HD icons + private final CallTypeIconsView secondaryCallTypeIconsView; // Used for call types + private final TextView phoneAccountView; + private final Clock clock; + + NewCallLogViewHolder(View view, Clock clock) { + super(view); + this.context = view.getContext(); + primaryTextView = view.findViewById(R.id.primary_text); + secondaryTextView = view.findViewById(R.id.secondary_text); + quickContactBadge = view.findViewById(R.id.quick_contact_photo); + primaryCallTypeIconsView = view.findViewById(R.id.primary_call_type_icons); + secondaryCallTypeIconsView = view.findViewById(R.id.secondary_call_type_icons); + phoneAccountView = view.findViewById(R.id.phone_account); + this.clock = clock; + } + + /** @param cursor a cursor from {@link CoalescedAnnotatedCallLogCursorLoader}. */ + void bind(Cursor cursor) { + CoalescedAnnotatedCallLogCursorLoader.Row row = + new CoalescedAnnotatedCallLogCursorLoader.Row(cursor); + + // TODO(zachh): Handle RTL properly. + primaryTextView.setText(buildPrimaryText(row)); + secondaryTextView.setText(buildSecondaryText(row)); + + if (row.isNew()) { + // TODO(zachh): Figure out correct styling for new/missed/unread calls. + primaryTextView.setTextAppearance(R.style.primary_textview_new_call); + // TODO(zachh): Styling for call type icons when the call is new. + secondaryTextView.setTextAppearance(R.style.secondary_textview_new_call); + } + + setPhoto(row); + setPrimaryCallTypes(row); + setSecondaryCallTypes(row); + setPhoneAccounts(row); + } + + private String buildPrimaryText(CoalescedAnnotatedCallLogCursorLoader.Row row) { + StringBuilder primaryText = new StringBuilder(); + if (!TextUtils.isEmpty(row.name())) { + primaryText.append(row.name()); + } else if (!TextUtils.isEmpty(row.formattedNumber())) { + primaryText.append(row.formattedNumber()); + } else { + // TODO(zachh): Handle CallLog.Calls.PRESENTATION_*, including Verizon restricted numbers. + primaryText.append(context.getText(R.string.new_call_log_unknown)); + } + if (row.numberCalls() > 1) { + primaryText.append(String.format(Locale.getDefault(), " (%d)", row.numberCalls())); + } + return primaryText.toString(); + } + + private String buildSecondaryText(CoalescedAnnotatedCallLogCursorLoader.Row row) { + /* + * Rules: (Duo video, )?$Label|$Location • Date + * + * Examples: + * Duo Video, Mobile • Now + * Duo Video • 11:45pm + * Mobile • 11:45pm + * Mobile • Sunday + * Brooklyn, NJ • Jan 15 + * + * Date rules: + * if < 1 minute ago: "Now"; else if today: HH:MM(am|pm); else if < 3 days: day; else: MON D + */ + StringBuilder secondaryText = new StringBuilder(); + if ((row.features() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO) { + // TODO(zachh): Add "Duo" prefix? + secondaryText.append(context.getText(R.string.new_call_log_video)); + } + String numberTypeLabel = row.numberTypeLabel(); + if (!TextUtils.isEmpty(numberTypeLabel)) { + if (secondaryText.length() > 0) { + secondaryText.append(", "); + } + secondaryText.append(numberTypeLabel); + } else { // If there's a number type label, don't show the location. + String location = row.geocodedLocation(); + if (!TextUtils.isEmpty(location)) { + if (secondaryText.length() > 0) { + secondaryText.append(", "); + } + secondaryText.append(location); + } + } + if (secondaryText.length() > 0) { + secondaryText.append(" • "); + } + secondaryText.append( + CallLogDates.newCallLogTimestampLabel(context, clock.currentTimeMillis(), row.timestamp())); + return secondaryText.toString(); + } + + private void setPhoto(Row row) { + // TODO(zachh): Set the contact type. + ContactPhotoManager.getInstance(context) + .loadDialerThumbnailOrPhoto( + quickContactBadge, + row.lookupUri() == null ? null : Uri.parse(row.lookupUri()), + row.photoId(), + row.photoUri() == null ? null : Uri.parse(row.photoUri()), + row.name(), + LetterTileDrawable.TYPE_DEFAULT); + } + + private void setPrimaryCallTypes(Row row) { + // Only HD and Wifi icons are shown following the primary text. + primaryCallTypeIconsView.setShowHd( + MotorolaUtils.shouldShowHdIconInCallLog(context, row.features())); + primaryCallTypeIconsView.setShowWifi( + MotorolaUtils.shouldShowWifiIconInCallLog(context, row.features())); + } + + private void setSecondaryCallTypes(Row row) { + // Only call type icons are shown before the secondary text. + for (int callType : row.callTypes().getTypeList()) { + secondaryCallTypeIconsView.add(callType); + } + // TODO(zachh): Per new mocks, may need to add method to CallTypeIconsView to disable coloring. + } + + private void setPhoneAccounts(Row row) { + if (row.phoneAccountLabel() != null) { + phoneAccountView.setText(row.phoneAccountLabel()); + phoneAccountView.setTextColor(row.phoneAccountColor()); + phoneAccountView.setVisibility(View.VISIBLE); + } + } +} diff --git a/java/com/android/dialer/calllog/ui/res/layout/new_call_log_entry.xml b/java/com/android/dialer/calllog/ui/res/layout/new_call_log_entry.xml index ee3efd002..77ba68124 100644 --- a/java/com/android/dialer/calllog/ui/res/layout/new_call_log_entry.xml +++ b/java/com/android/dialer/calllog/ui/res/layout/new_call_log_entry.xml @@ -15,19 +15,97 @@ ~ limitations under the License --> -<LinearLayout +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="horizontal"> + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/call_log_entry_top_margin" + android:paddingTop="@dimen/call_log_entry_padding_top_start" + android:paddingBottom="@dimen/call_log_entry_padding_bottom_end" + android:paddingStart="@dimen/call_log_entry_padding_top_start" + android:paddingEnd="@dimen/call_log_entry_padding_bottom_end" + android:gravity="center_vertical"> - <TextView - android:id="@+id/timestamp" - android:layout_width="wrap_content" - android:layout_height="wrap_content"/> + <QuickContactBadge + android:id="@+id/quick_contact_photo" + android:layout_width="@dimen/call_log_entry_photo_size" + android:layout_height="@dimen/call_log_entry_photo_size" + android:layout_centerVertical="true" + android:padding="@dimen/call_log_entry_photo_padding" + android:focusable="true"/> - <TextView - android:id="@+id/contact_name" + <LinearLayout android:layout_width="wrap_content" - android:layout_height="wrap_content"/> -</LinearLayout>
\ No newline at end of file + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:layout_toEndOf="@+id/quick_contact_photo" + android:layout_toStartOf="@+id/menu_button" + android:orientation="vertical"> + + <!-- TODO(zachh): Optimize this layout --> + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal"> + + <TextView + android:id="@+id/primary_text" + style="@style/PrimaryText" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/call_log_entry_photo_text_margin"/> + + <!-- HD and Wifi icons are shown adjacent to primary text. Call types are shown adjacent to + secondary text (below). --> + <com.android.dialer.calllogutils.CallTypeIconsView + android:id="@+id/primary_call_type_icons" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="12dp" + android:layout_gravity="center_vertical"/> + + </LinearLayout> + + <!-- TODO(zachh): Optimize this layout --> + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal"> + + <!-- Only call types are shown adjacent to secondary text. HD and Wifi icons are shown + adjacent to primary text (above). --> + <com.android.dialer.calllogutils.CallTypeIconsView + android:id="@+id/secondary_call_type_icons" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="12dp" + android:layout_gravity="center_vertical"/> + + <TextView + android:id="@+id/secondary_text" + style="@style/SecondaryText" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/call_log_entry_photo_text_margin"/> + </LinearLayout> + + <TextView + android:id="@+id/phone_account" + style="@style/SecondaryText" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/call_log_entry_photo_text_margin" + android:visibility="gone"/> + </LinearLayout> + + <ImageView + android:id="@+id/menu_button" + android:layout_width="@dimen/call_log_entry_menu_button_size" + android:layout_height="@dimen/call_log_entry_menu_button_size" + android:layout_alignParentEnd="true" + android:layout_centerVertical="true" + android:background="?android:attr/selectableItemBackgroundBorderless" + android:scaleType="center" + android:src="@drawable/quantum_ic_more_vert_vd_theme_24" + android:tint="@color/dialer_secondary_text_color"/> +</RelativeLayout> diff --git a/java/com/android/dialer/calllog/ui/res/layout/new_call_log_fragment.xml b/java/com/android/dialer/calllog/ui/res/layout/new_call_log_fragment.xml index 433dbdd0f..e1d8410b6 100644 --- a/java/com/android/dialer/calllog/ui/res/layout/new_call_log_fragment.xml +++ b/java/com/android/dialer/calllog/ui/res/layout/new_call_log_fragment.xml @@ -15,8 +15,9 @@ ~ limitations under the License --> -<ListView +<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/list" + android:id="@+id/new_call_log_recycler_view" android:layout_width="match_parent" - android:layout_height="match_parent"/> + android:layout_height="match_parent" + android:background="@color/background_dialer_light"/> diff --git a/java/com/android/dialer/calllog/ui/res/layout/new_call_log_header.xml b/java/com/android/dialer/calllog/ui/res/layout/new_call_log_header.xml new file mode 100644 index 000000000..13575db55 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/layout/new_call_log_header.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:height="48dp"> + <TextView + android:id="@+id/new_call_log_header_text" + style="@style/SecondaryText" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/call_log_action_icon_margin_start" + android:layout_centerVertical="true"/> +</RelativeLayout> diff --git a/java/com/android/dialer/calllog/ui/res/values-af/strings.xml b/java/com/android/dialer/calllog/ui/res/values-af/strings.xml new file mode 100644 index 000000000..c6b69b508 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-af/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Onbekend"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Vandag"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Ouer"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-am/strings.xml b/java/com/android/dialer/calllog/ui/res/values-am/strings.xml new file mode 100644 index 000000000..adde37b37 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-am/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"ቪዲዮ"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"ያልታወቀ"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"ዛሬ"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"የቆዩ"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-ar/strings.xml b/java/com/android/dialer/calllog/ui/res/values-ar/strings.xml new file mode 100644 index 000000000..492ee4280 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-ar/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"فيديو"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"غير معروف"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"اليوم"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"أقدم"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-az/strings.xml b/java/com/android/dialer/calllog/ui/res/values-az/strings.xml new file mode 100644 index 000000000..1e7e57bf3 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-az/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Naməlum"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Bu gün"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Keçmiş"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-b+sr+Latn/strings.xml b/java/com/android/dialer/calllog/ui/res/values-b+sr+Latn/strings.xml new file mode 100644 index 000000000..e60fa61bc --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-b+sr+Latn/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video poziv"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Nepoznat broj"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Danas"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Ranije"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-be/strings.xml b/java/com/android/dialer/calllog/ui/res/values-be/strings.xml new file mode 100644 index 000000000..c4e80c162 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-be/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Відэа"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Невядома"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Сёння"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Больш старыя"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-bg/strings.xml b/java/com/android/dialer/calllog/ui/res/values-bg/strings.xml new file mode 100644 index 000000000..8806cc161 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-bg/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Видеообаждане"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Неизвестен"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Днес"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"По-стари"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-bn/strings.xml b/java/com/android/dialer/calllog/ui/res/values-bn/strings.xml new file mode 100644 index 000000000..5c374d11a --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-bn/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"ভিডিও"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"অজানা"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"আজ"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"পুরনো"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-bs/strings.xml b/java/com/android/dialer/calllog/ui/res/values-bs/strings.xml new file mode 100644 index 000000000..3d1b302ca --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-bs/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Videozapis"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Nepoznato"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Danas"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Starije"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-ca/strings.xml b/java/com/android/dialer/calllog/ui/res/values-ca/strings.xml new file mode 100644 index 000000000..54d07f594 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-ca/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Vídeo"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Desconeguts"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Avui"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Anteriors"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-cs/strings.xml b/java/com/android/dialer/calllog/ui/res/values-cs/strings.xml new file mode 100644 index 000000000..40a9cb1f2 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-cs/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Neznámý volající"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Dnes"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Starší"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-da/strings.xml b/java/com/android/dialer/calllog/ui/res/values-da/strings.xml new file mode 100644 index 000000000..46a87a4c4 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-da/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Ukendt"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"I dag"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Ældre"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-de/strings.xml b/java/com/android/dialer/calllog/ui/res/values-de/strings.xml new file mode 100644 index 000000000..e587bb3d6 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-de/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Unbekannt"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Heute"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Ältere"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-el/strings.xml b/java/com/android/dialer/calllog/ui/res/values-el/strings.xml new file mode 100644 index 000000000..9f40423dc --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-el/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Βίντεο"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Άγνωστος"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Σήμερα"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Παλαιότερες"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-en-rAU/strings.xml b/java/com/android/dialer/calllog/ui/res/values-en-rAU/strings.xml new file mode 100644 index 000000000..b442d5a16 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-en-rAU/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Unknown"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Today"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Older"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-en-rGB/strings.xml b/java/com/android/dialer/calllog/ui/res/values-en-rGB/strings.xml new file mode 100644 index 000000000..b442d5a16 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-en-rGB/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Unknown"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Today"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Older"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-en-rIN/strings.xml b/java/com/android/dialer/calllog/ui/res/values-en-rIN/strings.xml new file mode 100644 index 000000000..b442d5a16 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-en-rIN/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Unknown"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Today"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Older"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-es-rUS/strings.xml b/java/com/android/dialer/calllog/ui/res/values-es-rUS/strings.xml new file mode 100644 index 000000000..5cfdae785 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-es-rUS/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Desconocido"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Hoy"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Anterior"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-es/strings.xml b/java/com/android/dialer/calllog/ui/res/values-es/strings.xml new file mode 100644 index 000000000..c23e7cf74 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-es/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Vídeo"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Desconocidas"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Hoy"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Anteriores"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-et/strings.xml b/java/com/android/dialer/calllog/ui/res/values-et/strings.xml new file mode 100644 index 000000000..0199758d7 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-et/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Tundmatu"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Täna"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Vanem"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-eu/strings.xml b/java/com/android/dialer/calllog/ui/res/values-eu/strings.xml new file mode 100644 index 000000000..eea5b7866 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-eu/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Bideoa"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Ezezagunak"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Gaurkoak"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Zaharragoak"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-fa/strings.xml b/java/com/android/dialer/calllog/ui/res/values-fa/strings.xml new file mode 100644 index 000000000..0b9b19f51 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-fa/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"ویدیو"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"نامشخص"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"امروز"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"قدیمیتر"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-fi/strings.xml b/java/com/android/dialer/calllog/ui/res/values-fi/strings.xml new file mode 100644 index 000000000..295488278 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-fi/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Videopuhelu"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Tuntematon"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Tänään"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Vanhemmat"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-fr-rCA/strings.xml b/java/com/android/dialer/calllog/ui/res/values-fr-rCA/strings.xml new file mode 100644 index 000000000..dd1a34cb1 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-fr-rCA/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Vidéo"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Inconnu"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Aujourd\'hui"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Plus anciens"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-fr/strings.xml b/java/com/android/dialer/calllog/ui/res/values-fr/strings.xml new file mode 100644 index 000000000..ddeaf1925 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-fr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Vidéo"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Numéro inconnu"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Aujourd\'hui"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Plus anciens"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-gl/strings.xml b/java/com/android/dialer/calllog/ui/res/values-gl/strings.xml new file mode 100644 index 000000000..248611923 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-gl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Vídeo"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Descoñecidos"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Hoxe"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Anteriores"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-gu/strings.xml b/java/com/android/dialer/calllog/ui/res/values-gu/strings.xml new file mode 100644 index 000000000..6235641d0 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-gu/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"વીડિઓ"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"અજાણ"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"આજે"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"જૂનું"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-hi/strings.xml b/java/com/android/dialer/calllog/ui/res/values-hi/strings.xml new file mode 100644 index 000000000..3c3ccc8ef --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-hi/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"वीडियो"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"अज्ञात"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"आज"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"पुराना"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-hr/strings.xml b/java/com/android/dialer/calllog/ui/res/values-hr/strings.xml new file mode 100644 index 000000000..614f46c3a --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-hr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Videopoziv"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Nepoznato"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Danas"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Stariji"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-hu/strings.xml b/java/com/android/dialer/calllog/ui/res/values-hu/strings.xml new file mode 100644 index 000000000..0dc4e9295 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-hu/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Videó"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Ismeretlen"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Ma"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Korábbi"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-hy/strings.xml b/java/com/android/dialer/calllog/ui/res/values-hy/strings.xml new file mode 100644 index 000000000..6c13619ef --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-hy/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Տեսանյութ"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Անհայտ"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Այսօր"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Ավելի հին"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-in/strings.xml b/java/com/android/dialer/calllog/ui/res/values-in/strings.xml new file mode 100644 index 000000000..ee18199df --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-in/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Tidak diketahui"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Hari ini"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Lebih lama"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-is/strings.xml b/java/com/android/dialer/calllog/ui/res/values-is/strings.xml new file mode 100644 index 000000000..80cf17ed8 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-is/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Myndsímtal"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Óþekkt"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Í dag"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Eldra"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-it/strings.xml b/java/com/android/dialer/calllog/ui/res/values-it/strings.xml new file mode 100644 index 000000000..039081ea6 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-it/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Sconosciuto"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Oggi"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Meno recenti"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-iw/strings.xml b/java/com/android/dialer/calllog/ui/res/values-iw/strings.xml new file mode 100644 index 000000000..4d906edf6 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-iw/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"וידאו"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"לא ידוע"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"היום"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"ישנות יותר"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-ja/strings.xml b/java/com/android/dialer/calllog/ui/res/values-ja/strings.xml new file mode 100644 index 000000000..660392d2f --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-ja/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"ビデオ"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"不明"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"今日"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"昨日以前"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-ka/strings.xml b/java/com/android/dialer/calllog/ui/res/values-ka/strings.xml new file mode 100644 index 000000000..a6787839c --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-ka/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"ვიდეო"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"უცნობი"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"დღეს"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"უფრო ძველი"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-kk/strings.xml b/java/com/android/dialer/calllog/ui/res/values-kk/strings.xml new file mode 100644 index 000000000..830285926 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-kk/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Бейне"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Белгісіз"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Бүгін"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Ескілеу"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-km/strings.xml b/java/com/android/dialer/calllog/ui/res/values-km/strings.xml new file mode 100644 index 000000000..dfaca9af8 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-km/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"វីដេអូ"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"មិនស្គាល់"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"ថ្ងៃនេះ"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"ចាស់ៗ"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-kn/strings.xml b/java/com/android/dialer/calllog/ui/res/values-kn/strings.xml new file mode 100644 index 000000000..5c764a29c --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-kn/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"ವೀಡಿಯೊ"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"ಅಪರಿಚಿತ"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"ಇಂದು"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"ಹಳೆಯದು"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-ko/strings.xml b/java/com/android/dialer/calllog/ui/res/values-ko/strings.xml new file mode 100644 index 000000000..094c3d93b --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-ko/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"동영상"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"알 수 없음"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"오늘"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"이전"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-ky/strings.xml b/java/com/android/dialer/calllog/ui/res/values-ky/strings.xml new file mode 100644 index 000000000..d15a2b2b6 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-ky/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Видео"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Белгисиз"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Бүгүн"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Мурункураак"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-lo/strings.xml b/java/com/android/dialer/calllog/ui/res/values-lo/strings.xml new file mode 100644 index 000000000..b869bbd48 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-lo/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"ວິດີໂອ"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"ບໍ່ຮູ້ຈັກ"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"ມື້ນີ້"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"ເກົ່າກວ່າ"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-lt/strings.xml b/java/com/android/dialer/calllog/ui/res/values-lt/strings.xml new file mode 100644 index 000000000..1701fa298 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-lt/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Vaizdo įrašas"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Nežinoma"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Šiandien"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Senesni"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-lv/strings.xml b/java/com/android/dialer/calllog/ui/res/values-lv/strings.xml new file mode 100644 index 000000000..adce799f7 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-lv/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Videozvans"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Nezināmi"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Šodien"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Vecāki zvani"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-mk/strings.xml b/java/com/android/dialer/calllog/ui/res/values-mk/strings.xml new file mode 100644 index 000000000..e347f1a07 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-mk/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Видео"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Непознато"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Денес"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Постари"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-ml/strings.xml b/java/com/android/dialer/calllog/ui/res/values-ml/strings.xml new file mode 100644 index 000000000..7d1fcd115 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-ml/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"വീഡിയോ"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"അജ്ഞാതം"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"ഇന്ന്"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"പഴയത്"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-mn/strings.xml b/java/com/android/dialer/calllog/ui/res/values-mn/strings.xml new file mode 100644 index 000000000..bdaf835a2 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-mn/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Видео"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Тодорхойгүй"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Өнөөдөр"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Хуучин"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-mr/strings.xml b/java/com/android/dialer/calllog/ui/res/values-mr/strings.xml new file mode 100644 index 000000000..5c348d16d --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-mr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"व्हिडिओ"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"अज्ञात"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"आज"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"अधिक जुने"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-ms/strings.xml b/java/com/android/dialer/calllog/ui/res/values-ms/strings.xml new file mode 100644 index 000000000..ee18199df --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-ms/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Tidak diketahui"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Hari ini"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Lebih lama"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-my/strings.xml b/java/com/android/dialer/calllog/ui/res/values-my/strings.xml new file mode 100644 index 000000000..f841bd51f --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-my/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"ဗီဒီယို"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"အမည်မသိ"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"ယနေ့"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"ယခင်နေ့များက"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-nb/strings.xml b/java/com/android/dialer/calllog/ui/res/values-nb/strings.xml new file mode 100644 index 000000000..9cf3273f2 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-nb/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Ukjent"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"I dag"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Eldre"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-ne/strings.xml b/java/com/android/dialer/calllog/ui/res/values-ne/strings.xml new file mode 100644 index 000000000..dc1c617e4 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-ne/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"भिडियो कल"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"अज्ञात कल"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"आज"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"अझ पुरानो"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-nl/strings.xml b/java/com/android/dialer/calllog/ui/res/values-nl/strings.xml new file mode 100644 index 000000000..96531873c --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-nl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Onbekend"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Vandaag"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Ouder"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-no/strings.xml b/java/com/android/dialer/calllog/ui/res/values-no/strings.xml new file mode 100644 index 000000000..9cf3273f2 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-no/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Ukjent"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"I dag"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Eldre"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-pa/strings.xml b/java/com/android/dialer/calllog/ui/res/values-pa/strings.xml new file mode 100644 index 000000000..797b55ed6 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-pa/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"ਵੀਡੀਓ"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"ਅਗਿਆਤ"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"ਅੱਜ"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"ਵਧੇਰੇ ਪੁਰਾਣਾ"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-pl/strings.xml b/java/com/android/dialer/calllog/ui/res/values-pl/strings.xml new file mode 100644 index 000000000..3c600288a --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-pl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Rozmowa wideo"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Nieznany"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Dzisiaj"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Starsze"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-pt-rBR/strings.xml b/java/com/android/dialer/calllog/ui/res/values-pt-rBR/strings.xml new file mode 100644 index 000000000..7b65f3a26 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-pt-rBR/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Vídeo"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Número desconhecido"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Hoje"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Mais antigas"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-pt-rPT/strings.xml b/java/com/android/dialer/calllog/ui/res/values-pt-rPT/strings.xml new file mode 100644 index 000000000..f7491b97e --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-pt-rPT/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Vídeo"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Desconhecido"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Hoje"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Mais antigas"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-pt/strings.xml b/java/com/android/dialer/calllog/ui/res/values-pt/strings.xml new file mode 100644 index 000000000..7b65f3a26 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-pt/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Vídeo"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Número desconhecido"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Hoje"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Mais antigas"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-ro/strings.xml b/java/com/android/dialer/calllog/ui/res/values-ro/strings.xml new file mode 100644 index 000000000..5446a7109 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-ro/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Necunoscut"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Astăzi"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Mai vechi"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-ru/strings.xml b/java/com/android/dialer/calllog/ui/res/values-ru/strings.xml new file mode 100644 index 000000000..b8d85e986 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-ru/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Видеовызов"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Неизвестно"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Сегодня"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Раньше"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-si/strings.xml b/java/com/android/dialer/calllog/ui/res/values-si/strings.xml new file mode 100644 index 000000000..0aad640ea --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-si/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"වීඩියෝ"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"නොදන්නා"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"අද"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"වඩා පරණ"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-sk/strings.xml b/java/com/android/dialer/calllog/ui/res/values-sk/strings.xml new file mode 100644 index 000000000..083fad4f4 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-sk/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Neznáme"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Dnes"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Staršie"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-sl/strings.xml b/java/com/android/dialer/calllog/ui/res/values-sl/strings.xml new file mode 100644 index 000000000..38b651ed2 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-sl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Neznano"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Danes"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Starejše"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-sq/strings.xml b/java/com/android/dialer/calllog/ui/res/values-sq/strings.xml new file mode 100644 index 000000000..f5659af4b --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-sq/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"I panjohur"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Sot"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Më të vjetra"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-sr/strings.xml b/java/com/android/dialer/calllog/ui/res/values-sr/strings.xml new file mode 100644 index 000000000..dfae73305 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-sr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Видео позив"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Непознат број"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Данас"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Раније"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-sv/strings.xml b/java/com/android/dialer/calllog/ui/res/values-sv/strings.xml new file mode 100644 index 000000000..20c2fda22 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-sv/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Okänd"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"I dag"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Äldre"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-sw/strings.xml b/java/com/android/dialer/calllog/ui/res/values-sw/strings.xml new file mode 100644 index 000000000..04390619f --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-sw/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Haijulikani"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Leo"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Za zamani"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-ta/strings.xml b/java/com/android/dialer/calllog/ui/res/values-ta/strings.xml new file mode 100644 index 000000000..f883fecc9 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-ta/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"வீடியோ"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"தெரியாத எண்கள்"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"இன்று"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"பழையவை"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-te/strings.xml b/java/com/android/dialer/calllog/ui/res/values-te/strings.xml new file mode 100644 index 000000000..6c3bd442c --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-te/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"వీడియో"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"తెలియదు"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"ఈ రోజు"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"పాతది"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-th/strings.xml b/java/com/android/dialer/calllog/ui/res/values-th/strings.xml new file mode 100644 index 000000000..8afc82acc --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-th/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"วิดีโอ"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"ไม่ทราบ"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"วันนี้"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"เก่ากว่า"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-tl/strings.xml b/java/com/android/dialer/calllog/ui/res/values-tl/strings.xml new file mode 100644 index 000000000..34d6f2c8e --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-tl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Hindi Alam"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Ngayong araw"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Mas Luma"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-tr/strings.xml b/java/com/android/dialer/calllog/ui/res/values-tr/strings.xml new file mode 100644 index 000000000..e7ada3ded --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-tr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Görünt. görüşme"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Bilinmiyor"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Bugün"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Eski"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-uk/strings.xml b/java/com/android/dialer/calllog/ui/res/values-uk/strings.xml new file mode 100644 index 000000000..0de770d0b --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-uk/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Відео"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Невідомо"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Сьогодні"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Старіші"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-ur/strings.xml b/java/com/android/dialer/calllog/ui/res/values-ur/strings.xml new file mode 100644 index 000000000..16ae08a94 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-ur/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"ویڈیو"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"نامعلوم"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"آج"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"قدیم تر"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-uz/strings.xml b/java/com/android/dialer/calllog/ui/res/values-uz/strings.xml new file mode 100644 index 000000000..22e4d18c1 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-uz/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video suhbat"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Noma’lum"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Bugun"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Eskiroq"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-vi/strings.xml b/java/com/android/dialer/calllog/ui/res/values-vi/strings.xml new file mode 100644 index 000000000..a70de21fa --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-vi/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Video"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Không xác định"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Hôm nay"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Cũ hơn"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-zh-rCN/strings.xml b/java/com/android/dialer/calllog/ui/res/values-zh-rCN/strings.xml new file mode 100644 index 000000000..ae4c6450b --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-zh-rCN/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"视频通话"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"未知"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"今天"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"更早"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-zh-rHK/strings.xml b/java/com/android/dialer/calllog/ui/res/values-zh-rHK/strings.xml new file mode 100644 index 000000000..4e7829292 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-zh-rHK/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"影片"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"不明"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"今天"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"較舊"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-zh-rTW/strings.xml b/java/com/android/dialer/calllog/ui/res/values-zh-rTW/strings.xml new file mode 100644 index 000000000..4b6b73680 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-zh-rTW/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"視訊通話"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"不明"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"今天"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"較舊"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values-zu/strings.xml b/java/com/android/dialer/calllog/ui/res/values-zu/strings.xml new file mode 100644 index 000000000..675e632d9 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values-zu/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="new_call_log_video" msgid="8414984483082880050">"Ividiyo"</string> + <string name="new_call_log_unknown" msgid="7873134340045098010">"Akwaziwa"</string> + <string name="new_call_log_header_today" msgid="3849627842127894230">"Namhlanje"</string> + <string name="new_call_log_header_older" msgid="5879512250610285872">"Okudala"</string> +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values/dimens.xml b/java/com/android/dialer/calllog/ui/res/values/dimens.xml new file mode 100644 index 000000000..bfb4c99d7 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values/dimens.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> +<resources> + + <!-- call log entries --> + <dimen name="call_log_entry_top_margin">6dp</dimen> + <dimen name="call_log_entry_padding_bottom_end">16dp</dimen> + <dimen name="call_log_entry_padding_top_start">12dp</dimen> + <dimen name="call_log_entry_photo_size">48dp</dimen> + <dimen name="call_log_entry_photo_padding">4dp</dimen> + <dimen name="call_log_entry_photo_text_margin">8dp</dimen> + <dimen name="call_log_entry_menu_button_size">48dp</dimen> + +</resources> diff --git a/java/com/android/dialer/calllog/ui/res/values/strings.xml b/java/com/android/dialer/calllog/ui/res/values/strings.xml new file mode 100644 index 000000000..9b044ca08 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values/strings.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> + +<resources> + + <!-- Text to show in call log for a video call. [CHAR LIMIT=16] --> + <string name="new_call_log_video">Video</string> + + <!-- String used to display calls from unknown numbers in the call log. [CHAR LIMIT=30] --> + <string name="new_call_log_unknown">Unknown</string> + + <!-- Header in call log to group calls from the current day. [CHAR LIMIT=30] --> + <string name="new_call_log_header_today">Today</string> + + <!-- Header in call log to group calls from before the current day. [CHAR LIMIT=30] --> + <string name="new_call_log_header_older">Older</string> + +</resources>
\ No newline at end of file diff --git a/java/com/android/dialer/calllog/ui/res/values/styles.xml b/java/com/android/dialer/calllog/ui/res/values/styles.xml new file mode 100644 index 000000000..23cb93e1a --- /dev/null +++ b/java/com/android/dialer/calllog/ui/res/values/styles.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2016 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 + --> +<resources> + + <style name="primary_textview_new_call"> + <item name="android:fontFamily">sans-serif-medium</item> + </style> + + <style name="secondary_textview_new_call"> + <item name="android:textColor">@color/missed_call</item> + <item name="android:fontFamily">sans-serif-medium</item> + </style> + +</resources>
\ No newline at end of file |